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;
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");
}
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;
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");
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.
// 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.
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
# 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:
- 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
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
...
# 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:
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
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
...