COFF: Fix SECREL and SECTION relocations.
SECREL should sets the 32-bit offset of the target from the beginning of *target's* output section. Previously, the offset from the beginning of source's output section was used instead. SECTION means the target section's index, and not the source section's index. This patch fixes that issue too. llvm-svn: 243535
This commit is contained in:
parent
b4731a5847
commit
eb26e1d03c
|
@ -50,8 +50,9 @@ static void add32(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); }
|
|||
static void add64(uint8_t *P, int64_t V) { write64le(P, read64le(P) + V); }
|
||||
static void or16(uint8_t *P, uint16_t V) { write16le(P, read16le(P) | V); }
|
||||
|
||||
void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, uint64_t S,
|
||||
void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, Defined *Sym,
|
||||
uint64_t P) {
|
||||
uint64_t S = Sym->getRVA();
|
||||
switch (Type) {
|
||||
case IMAGE_REL_AMD64_ADDR32: add32(Off, S + Config->ImageBase); break;
|
||||
case IMAGE_REL_AMD64_ADDR64: add64(Off, S + Config->ImageBase); break;
|
||||
|
@ -62,22 +63,23 @@ void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, uint64_t S,
|
|||
case IMAGE_REL_AMD64_REL32_3: add32(Off, S - P - 7); break;
|
||||
case IMAGE_REL_AMD64_REL32_4: add32(Off, S - P - 8); break;
|
||||
case IMAGE_REL_AMD64_REL32_5: add32(Off, S - P - 9); break;
|
||||
case IMAGE_REL_AMD64_SECTION: add16(Off, Out->SectionIndex); break;
|
||||
case IMAGE_REL_AMD64_SECREL: add32(Off, S - Out->getRVA()); break;
|
||||
case IMAGE_REL_AMD64_SECTION: add16(Off, Sym->getSectionIndex()); break;
|
||||
case IMAGE_REL_AMD64_SECREL: add32(Off, Sym->getSecrel()); break;
|
||||
default:
|
||||
llvm::report_fatal_error("Unsupported relocation type");
|
||||
}
|
||||
}
|
||||
|
||||
void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, uint64_t S,
|
||||
void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, Defined *Sym,
|
||||
uint64_t P) {
|
||||
uint64_t S = Sym->getRVA();
|
||||
switch (Type) {
|
||||
case IMAGE_REL_I386_ABSOLUTE: break;
|
||||
case IMAGE_REL_I386_DIR32: add32(Off, S + Config->ImageBase); break;
|
||||
case IMAGE_REL_I386_DIR32NB: add32(Off, S); break;
|
||||
case IMAGE_REL_I386_REL32: add32(Off, S - P - 4); break;
|
||||
case IMAGE_REL_I386_SECTION: add16(Off, Out->SectionIndex); break;
|
||||
case IMAGE_REL_I386_SECREL: add32(Off, S - Out->getRVA()); break;
|
||||
case IMAGE_REL_I386_SECTION: add16(Off, Sym->getSectionIndex()); break;
|
||||
case IMAGE_REL_I386_SECREL: add32(Off, Sym->getSecrel()); break;
|
||||
default:
|
||||
llvm::report_fatal_error("Unsupported relocation type");
|
||||
}
|
||||
|
@ -100,8 +102,9 @@ static void applyBranchImm(uint8_t *Off, int32_t V) {
|
|||
or16(Off + 2, ((V >> 1) & 0x7ff) | (J2 << 11) | (J1 << 13));
|
||||
}
|
||||
|
||||
void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, uint64_t S,
|
||||
void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, Defined *Sym,
|
||||
uint64_t P) {
|
||||
uint64_t S = Sym->getRVA();
|
||||
switch (Type) {
|
||||
case IMAGE_REL_ARM_ADDR32: add32(Off, S + Config->ImageBase); break;
|
||||
case IMAGE_REL_ARM_ADDR32NB: add32(Off, S); break;
|
||||
|
@ -124,17 +127,17 @@ void SectionChunk::writeTo(uint8_t *Buf) {
|
|||
for (const coff_relocation &Rel : Relocs) {
|
||||
uint8_t *Off = Buf + FileOff + Rel.VirtualAddress;
|
||||
SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex)->repl();
|
||||
uint64_t S = cast<Defined>(Body)->getRVA();
|
||||
Defined *Sym = cast<Defined>(Body);
|
||||
uint64_t P = RVA + Rel.VirtualAddress;
|
||||
switch (Config->Machine) {
|
||||
case AMD64:
|
||||
applyRelX64(Off, Rel.Type, S, P);
|
||||
applyRelX64(Off, Rel.Type, Sym, P);
|
||||
break;
|
||||
case I386:
|
||||
applyRelX86(Off, Rel.Type, S, P);
|
||||
applyRelX86(Off, Rel.Type, Sym, P);
|
||||
break;
|
||||
case ARMNT:
|
||||
applyRelARM(Off, Rel.Type, S, P);
|
||||
applyRelARM(Off, Rel.Type, Sym, P);
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("unknown machine type");
|
||||
|
|
|
@ -137,9 +137,9 @@ public:
|
|||
StringRef getSectionName() const override { return SectionName; }
|
||||
void getBaserels(std::vector<Baserel> *Res) override;
|
||||
bool isCOMDAT() const;
|
||||
void applyRelX64(uint8_t *Off, uint16_t Type, uint64_t S, uint64_t P);
|
||||
void applyRelX86(uint8_t *Off, uint16_t Type, uint64_t S, uint64_t P);
|
||||
void applyRelARM(uint8_t *Off, uint16_t Type, uint64_t S, uint64_t P);
|
||||
void applyRelX64(uint8_t *Off, uint16_t Type, Defined *Sym, uint64_t P);
|
||||
void applyRelX86(uint8_t *Off, uint16_t Type, Defined *Sym, uint64_t P);
|
||||
void applyRelARM(uint8_t *Off, uint16_t Type, Defined *Sym, uint64_t P);
|
||||
|
||||
// Called if the garbage collector decides to not include this chunk
|
||||
// in a final output. It's supposed to print out a log message to stdout.
|
||||
|
|
|
@ -130,6 +130,14 @@ public:
|
|||
// Returns the file offset of this symbol in the final executable.
|
||||
// The writer uses this information to apply relocations.
|
||||
uint64_t getFileOff();
|
||||
|
||||
// Returns the RVA relative to the beginning of the output section.
|
||||
// Used to implement SECREL relocation type.
|
||||
uint64_t getSecrel();
|
||||
|
||||
// Returns the output section index.
|
||||
// Used to implement SECTION relocation type.
|
||||
uint64_t getSectionIndex();
|
||||
};
|
||||
|
||||
// Symbols defined via a COFF object file.
|
||||
|
|
|
@ -678,5 +678,17 @@ void Writer::addBaserelBlocks(OutputSection *Dest, std::vector<Baserel> &V) {
|
|||
Dest->addChunk(new (Buf) BaserelChunk(Page, &V[I], &V[0] + J));
|
||||
}
|
||||
|
||||
uint64_t Defined::getSecrel() {
|
||||
if (auto *D = dyn_cast<DefinedRegular>(this))
|
||||
return getRVA() - D->getChunk()->getOutputSection()->getRVA();
|
||||
llvm::report_fatal_error("SECREL relocation points to a non-regular symbol");
|
||||
}
|
||||
|
||||
uint64_t Defined::getSectionIndex() {
|
||||
if (auto *D = dyn_cast<DefinedRegular>(this))
|
||||
return D->getChunk()->getOutputSection()->SectionIndex;
|
||||
llvm::report_fatal_error("SECTION relocation points to a non-regular symbol");
|
||||
}
|
||||
|
||||
} // namespace coff
|
||||
} // namespace lld
|
||||
|
|
|
@ -3,16 +3,17 @@
|
|||
# RUN: llvm-objdump -d %t.exe | FileCheck %s
|
||||
|
||||
# CHECK: .text:
|
||||
# CHECK: 1000: a1 00 10 00 40 00 00 00 00
|
||||
# CHECK: 1009: a1 00 10 00 40 01 00 00 00
|
||||
# CHECK: 1012: a1 00 10 00 00 00 00 00 00
|
||||
# CHECK: 101b: a1 e0 ff ff ff 00 00 00 00
|
||||
# CHECK: 1024: a1 d6 ff ff ff 00 00 00 00
|
||||
# CHECK: 102d: a1 cc ff ff ff 00 00 00 00
|
||||
# CHECK: 1036: a1 c2 ff ff ff 00 00 00 00
|
||||
# CHECK: 103f: a1 b8 ff ff ff 00 00 00 00
|
||||
# CHECK: 1048: a1 ae ff ff ff 00 00 00 00
|
||||
# CHECK: 1051: a1 01 00 00 00 00 00 00 00
|
||||
# CHECK: 1000: a1 03 20 00 40 00 00 00 00
|
||||
# CHECK: 1009: a1 03 20 00 40 01 00 00 00
|
||||
# CHECK: 1012: a1 03 20 00 00 00 00 00 00
|
||||
# CHECK: 101b: a1 e3 0f 00 00 00 00 00 00
|
||||
# CHECK: 1024: a1 d9 0f 00 00 00 00 00 00
|
||||
# CHECK: 102d: a1 cf 0f 00 00 00 00 00 00
|
||||
# CHECK: 1036: a1 c5 0f 00 00 00 00 00 00
|
||||
# CHECK: 103f: a1 bb 0f 00 00 00 00 00 00
|
||||
# CHECK: 1048: a1 b1 0f 00 00 00 00 00 00
|
||||
# CHECK: 1051: a1 02 00 00 00 00 00 00 00
|
||||
# CHECK: 105a: a1 03 00 00 00 00 00 00 00
|
||||
|
||||
---
|
||||
header:
|
||||
|
@ -22,41 +23,45 @@ sections:
|
|||
- Name: .text
|
||||
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 4096
|
||||
SectionData: A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000
|
||||
SectionData: A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000
|
||||
Relocations:
|
||||
- VirtualAddress: 1
|
||||
SymbolName: main
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_ADDR32
|
||||
- VirtualAddress: 10
|
||||
SymbolName: main
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_ADDR64
|
||||
- VirtualAddress: 19
|
||||
SymbolName: main
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_ADDR32NB
|
||||
- VirtualAddress: 28
|
||||
SymbolName: main
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_REL32
|
||||
- VirtualAddress: 37
|
||||
SymbolName: main
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_REL32_1
|
||||
- VirtualAddress: 46
|
||||
SymbolName: main
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_REL32_2
|
||||
- VirtualAddress: 55
|
||||
SymbolName: main
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_REL32_3
|
||||
- VirtualAddress: 64
|
||||
SymbolName: main
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_REL32_4
|
||||
- VirtualAddress: 73
|
||||
SymbolName: main
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_REL32_5
|
||||
- VirtualAddress: 82
|
||||
SymbolName: main
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_SECTION
|
||||
- VirtualAddress: 91
|
||||
SymbolName: main
|
||||
SymbolName: foo
|
||||
Type: IMAGE_REL_AMD64_SECREL
|
||||
- Name: .zzz
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
|
||||
Alignment: 4096
|
||||
SectionData: 0000000000000000
|
||||
symbols:
|
||||
- Name: .text
|
||||
Value: 0
|
||||
|
@ -70,10 +75,28 @@ symbols:
|
|||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: .zzz
|
||||
Value: 0
|
||||
SectionNumber: 2
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 8
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: main
|
||||
Value: 0
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: foo
|
||||
Value: 3
|
||||
SectionNumber: 2
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
...
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
# RUN: llvm-objdump -d %t.exe | FileCheck %s
|
||||
|
||||
# CHECK: .text:
|
||||
# CHECK: 1000: a1 00 00 00 00
|
||||
# CHECK: 1005: a1 00 10 40 00
|
||||
# CHECK: 100a: a1 00 10 00 00
|
||||
# CHECK: 100f: a1 ec ff ff ff
|
||||
# CHECK: 1014: a1 00 00 01 00
|
||||
# CHECK: 1019: a1 00 00 00 00
|
||||
# CHECK: 1000: a1 00 00 00 00
|
||||
# CHECK: 1005: a1 03 20 40 00
|
||||
# CHECK: 100a: a1 03 20 00 00
|
||||
# CHECK: 100f: a1 ef 0f 00 00
|
||||
# CHECK: 1014: a1 00 00 02 00
|
||||
# CHECK: 1019: a1 03 00 00 00
|
||||
|
||||
---
|
||||
header:
|
||||
|
@ -21,23 +21,27 @@ sections:
|
|||
SectionData: A100000000A100000000A100000000A100000000A100000000A100000000
|
||||
Relocations:
|
||||
- VirtualAddress: 1
|
||||
SymbolName: _main
|
||||
SymbolName: _foo
|
||||
Type: IMAGE_REL_I386_ABSOLUTE
|
||||
- VirtualAddress: 6
|
||||
SymbolName: _main
|
||||
SymbolName: _foo
|
||||
Type: IMAGE_REL_I386_DIR32
|
||||
- VirtualAddress: 11
|
||||
SymbolName: _main
|
||||
SymbolName: _foo
|
||||
Type: IMAGE_REL_I386_DIR32NB
|
||||
- VirtualAddress: 16
|
||||
SymbolName: _main
|
||||
SymbolName: _foo
|
||||
Type: IMAGE_REL_I386_REL32
|
||||
- VirtualAddress: 23
|
||||
SymbolName: _main
|
||||
SymbolName: _foo
|
||||
Type: IMAGE_REL_I386_SECTION
|
||||
- VirtualAddress: 26
|
||||
SymbolName: _main
|
||||
SymbolName: _foo
|
||||
Type: IMAGE_REL_I386_SECREL
|
||||
- Name: .zzz
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
|
||||
Alignment: 4096
|
||||
SectionData: 0000000000000000
|
||||
symbols:
|
||||
- Name: .text
|
||||
Value: 0
|
||||
|
@ -51,10 +55,28 @@ symbols:
|
|||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: .zzz
|
||||
Value: 0
|
||||
SectionNumber: 2
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 8
|
||||
NumberOfRelocations: 0
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
- Name: _main
|
||||
Value: 0
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
- Name: _foo
|
||||
Value: 3
|
||||
SectionNumber: 2
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
|
||||
...
|
||||
|
|
Loading…
Reference in New Issue