forked from OSchip/llvm-project
[ELF2] - Implemented rel[a].plt sections
.rela.plt contains list of elements in the PLT, which are liable to the relocation during the dynamic linking. Differential Revision: http://reviews.llvm.org/D13569 llvm-svn: 249816
This commit is contained in:
parent
c4cb3b10dc
commit
b352b9ce69
|
@ -48,6 +48,10 @@ template <> RelocationSection<ELF32BE> *Out<ELF32BE>::RelaDyn = nullptr;
|
||||||
template <> RelocationSection<ELF32LE> *Out<ELF32LE>::RelaDyn = nullptr;
|
template <> RelocationSection<ELF32LE> *Out<ELF32LE>::RelaDyn = nullptr;
|
||||||
template <> RelocationSection<ELF64BE> *Out<ELF64BE>::RelaDyn = nullptr;
|
template <> RelocationSection<ELF64BE> *Out<ELF64BE>::RelaDyn = nullptr;
|
||||||
template <> RelocationSection<ELF64LE> *Out<ELF64LE>::RelaDyn = nullptr;
|
template <> RelocationSection<ELF64LE> *Out<ELF64LE>::RelaDyn = nullptr;
|
||||||
|
template <> RelocationSection<ELF32BE> *Out<ELF32BE>::RelaPlt = nullptr;
|
||||||
|
template <> RelocationSection<ELF32LE> *Out<ELF32LE>::RelaPlt = nullptr;
|
||||||
|
template <> RelocationSection<ELF64BE> *Out<ELF64BE>::RelaPlt = nullptr;
|
||||||
|
template <> RelocationSection<ELF64LE> *Out<ELF64LE>::RelaPlt = nullptr;
|
||||||
template <> StringTableSection<false> *Out<ELF32BE>::DynStrTab = nullptr;
|
template <> StringTableSection<false> *Out<ELF32BE>::DynStrTab = nullptr;
|
||||||
template <> StringTableSection<false> *Out<ELF32LE>::DynStrTab = nullptr;
|
template <> StringTableSection<false> *Out<ELF32LE>::DynStrTab = nullptr;
|
||||||
template <> StringTableSection<true> *Out<ELF64BE>::DynStrTab = nullptr;
|
template <> StringTableSection<true> *Out<ELF64BE>::DynStrTab = nullptr;
|
||||||
|
@ -139,10 +143,9 @@ void PltSection<ELFT>::finalize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
RelocationSection<ELFT>::RelocationSection(bool IsRela)
|
RelocationSection<ELFT>::RelocationSection(StringRef Name, bool IsRela)
|
||||||
: OutputSectionBase<ELFT::Is64Bits>(IsRela ? ".rela.dyn" : ".rel.dyn",
|
: OutputSectionBase<ELFT::Is64Bits>(Name, IsRela ? llvm::ELF::SHT_RELA
|
||||||
IsRela ? llvm::ELF::SHT_RELA
|
: llvm::ELF::SHT_REL,
|
||||||
: llvm::ELF::SHT_REL,
|
|
||||||
llvm::ELF::SHF_ALLOC),
|
llvm::ELF::SHF_ALLOC),
|
||||||
IsRela(IsRela) {
|
IsRela(IsRela) {
|
||||||
this->Header.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
|
this->Header.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
|
||||||
|
@ -300,6 +303,13 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
|
||||||
++NumEntries; // DT_RELASZ / DT_RELSZ
|
++NumEntries; // DT_RELASZ / DT_RELSZ
|
||||||
++NumEntries; // DT_RELAENT / DT_RELENT
|
++NumEntries; // DT_RELAENT / DT_RELENT
|
||||||
}
|
}
|
||||||
|
if (Out<ELFT>::RelaPlt->hasRelocs()) {
|
||||||
|
++NumEntries; // DT_JMPREL
|
||||||
|
++NumEntries; // DT_PLTRELSZ
|
||||||
|
++NumEntries; // DT_PLTGOT
|
||||||
|
++NumEntries; // DT_PLTREL
|
||||||
|
}
|
||||||
|
|
||||||
++NumEntries; // DT_SYMTAB
|
++NumEntries; // DT_SYMTAB
|
||||||
++NumEntries; // DT_SYMENT
|
++NumEntries; // DT_SYMENT
|
||||||
++NumEntries; // DT_STRTAB
|
++NumEntries; // DT_STRTAB
|
||||||
|
@ -367,6 +377,12 @@ template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
|
||||||
WriteVal(IsRela ? DT_RELAENT : DT_RELENT,
|
WriteVal(IsRela ? DT_RELAENT : DT_RELENT,
|
||||||
IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel));
|
IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel));
|
||||||
}
|
}
|
||||||
|
if (Out<ELFT>::RelaPlt->hasRelocs()) {
|
||||||
|
WritePtr(DT_JMPREL, Out<ELFT>::RelaPlt->getVA());
|
||||||
|
WriteVal(DT_PLTRELSZ, Out<ELFT>::RelaPlt->getSize());
|
||||||
|
WritePtr(DT_PLTGOT, Out<ELFT>::Got->getVA());
|
||||||
|
WriteVal(DT_PLTREL, Out<ELFT>::RelaPlt->isRela() ? DT_RELA : DT_REL);
|
||||||
|
}
|
||||||
|
|
||||||
WritePtr(DT_SYMTAB, Out<ELFT>::DynSymTab->getVA());
|
WritePtr(DT_SYMTAB, Out<ELFT>::DynSymTab->getVA());
|
||||||
WritePtr(DT_SYMENT, sizeof(Elf_Sym));
|
WritePtr(DT_SYMENT, sizeof(Elf_Sym));
|
||||||
|
|
|
@ -171,7 +171,7 @@ class RelocationSection final : public OutputSectionBase<ELFT::Is64Bits> {
|
||||||
typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
|
typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RelocationSection(bool IsRela);
|
RelocationSection(StringRef Name, bool IsRela);
|
||||||
void addReloc(const DynamicReloc<ELFT> &Reloc) { Relocs.push_back(Reloc); }
|
void addReloc(const DynamicReloc<ELFT> &Reloc) { Relocs.push_back(Reloc); }
|
||||||
void finalize() override;
|
void finalize() override;
|
||||||
void writeTo(uint8_t *Buf) override;
|
void writeTo(uint8_t *Buf) override;
|
||||||
|
@ -289,6 +289,7 @@ template <class ELFT> struct Out {
|
||||||
static OutputSection<ELFT> *Bss;
|
static OutputSection<ELFT> *Bss;
|
||||||
static PltSection<ELFT> *Plt;
|
static PltSection<ELFT> *Plt;
|
||||||
static RelocationSection<ELFT> *RelaDyn;
|
static RelocationSection<ELFT> *RelaDyn;
|
||||||
|
static RelocationSection<ELFT> *RelaPlt;
|
||||||
static StringTableSection<ELFT::Is64Bits> *DynStrTab;
|
static StringTableSection<ELFT::Is64Bits> *DynStrTab;
|
||||||
static StringTableSection<ELFT::Is64Bits> *StrTab;
|
static StringTableSection<ELFT::Is64Bits> *StrTab;
|
||||||
static SymbolTableSection<ELFT> *DynSymTab;
|
static SymbolTableSection<ELFT> *DynSymTab;
|
||||||
|
|
|
@ -134,8 +134,11 @@ template <class ELFT> static void doWriteResult(SymbolTable *Symtab) {
|
||||||
Out<ELFT>::DynSymTab = &DynSymTab;
|
Out<ELFT>::DynSymTab = &DynSymTab;
|
||||||
HashTableSection<ELFT> HashTab;
|
HashTableSection<ELFT> HashTab;
|
||||||
Out<ELFT>::HashTab = &HashTab;
|
Out<ELFT>::HashTab = &HashTab;
|
||||||
RelocationSection<ELFT> RelaDyn(Symtab->shouldUseRela());
|
bool IsRela = Symtab->shouldUseRela();
|
||||||
|
RelocationSection<ELFT> RelaDyn(IsRela ? ".rela.dyn" : ".rel.dyn", IsRela);
|
||||||
Out<ELFT>::RelaDyn = &RelaDyn;
|
Out<ELFT>::RelaDyn = &RelaDyn;
|
||||||
|
RelocationSection<ELFT> RelaPlt(IsRela ? ".rela.plt" : ".rel.plt", IsRela);
|
||||||
|
Out<ELFT>::RelaPlt = &RelaPlt;
|
||||||
DynamicSection<ELFT> Dynamic(*Symtab);
|
DynamicSection<ELFT> Dynamic(*Symtab);
|
||||||
Out<ELFT>::Dynamic = &Dynamic;
|
Out<ELFT>::Dynamic = &Dynamic;
|
||||||
|
|
||||||
|
@ -233,11 +236,15 @@ void Writer<ELFT>::scanRelocs(
|
||||||
Out<ELFT>::Got->addEntry(Body);
|
Out<ELFT>::Got->addEntry(Body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (canBePreempted(Body)) {
|
|
||||||
|
bool CanBePreempted = canBePreempted(Body);
|
||||||
|
if (CanBePreempted)
|
||||||
Body->setUsedInDynamicReloc();
|
Body->setUsedInDynamicReloc();
|
||||||
Out<ELFT>::RelaDyn->addReloc({C, RI});
|
if (CanBePreempted || (Config->Shared && !Target->isRelRelative(Type))) {
|
||||||
} else if (Config->Shared && !Target->isRelRelative(Type)) {
|
if (Body && Body->isInPlt())
|
||||||
Out<ELFT>::RelaDyn->addReloc({C, RI});
|
Out<ELFT>::RelaPlt->addReloc({C, RI});
|
||||||
|
else
|
||||||
|
Out<ELFT>::RelaDyn->addReloc({C, RI});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,6 +473,8 @@ template <class ELFT> void Writer<ELFT>::createSections() {
|
||||||
OutputSections.push_back(Out<ELFT>::DynStrTab);
|
OutputSections.push_back(Out<ELFT>::DynStrTab);
|
||||||
if (Out<ELFT>::RelaDyn->hasRelocs())
|
if (Out<ELFT>::RelaDyn->hasRelocs())
|
||||||
OutputSections.push_back(Out<ELFT>::RelaDyn);
|
OutputSections.push_back(Out<ELFT>::RelaDyn);
|
||||||
|
if (Out<ELFT>::RelaPlt->hasRelocs())
|
||||||
|
OutputSections.push_back(Out<ELFT>::RelaPlt);
|
||||||
}
|
}
|
||||||
if (!Out<ELFT>::Got->empty())
|
if (!Out<ELFT>::Got->empty())
|
||||||
OutputSections.push_back(Out<ELFT>::Got);
|
OutputSections.push_back(Out<ELFT>::Got);
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
// CHECK-NEXT: AddressAlignment: 16
|
// CHECK-NEXT: AddressAlignment: 16
|
||||||
|
|
||||||
// CHECK: Relocations [
|
// CHECK: Relocations [
|
||||||
// CHECK-NEXT: Section ({{.*}}) .rel.dyn {
|
// CHECK-NEXT: Section ({{.*}}) .rel.plt {
|
||||||
// CHECK-NEXT: 0x13050 R_386_GLOB_DAT bar 0x0
|
// CHECK-NEXT: 0x13058 R_386_GLOB_DAT bar 0x0
|
||||||
// CHECK-NEXT: 0x13054 R_386_GLOB_DAT zed 0x0
|
// CHECK-NEXT: 0x1305C R_386_GLOB_DAT zed 0x0
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
// CHECK-NEXT: ]
|
// CHECK-NEXT: ]
|
||||||
|
|
||||||
|
@ -38,15 +38,15 @@
|
||||||
// DISASM-NEXT: 12005: e9 06 00 00 00 jmp 6
|
// DISASM-NEXT: 12005: e9 06 00 00 00 jmp 6
|
||||||
// DISASM-NEXT: 1200a: e9 09 00 00 00 jmp 9
|
// DISASM-NEXT: 1200a: e9 09 00 00 00 jmp 9
|
||||||
|
|
||||||
// 0x13050 = 77904
|
// 0x13058 = 77912
|
||||||
// 0x13054 = 77908
|
// 0x1305C = 77916
|
||||||
|
|
||||||
// DISASM: Disassembly of section .plt:
|
// DISASM: Disassembly of section .plt:
|
||||||
// DISASM-NEXT: .plt:
|
// DISASM-NEXT: .plt:
|
||||||
// DISASM-NEXT: 12010: ff 25 {{.*}} jmpl *77904
|
// DISASM-NEXT: 12010: ff 25 {{.*}} jmpl *77912
|
||||||
// DISASM-NEXT: 12016: 90 nop
|
// DISASM-NEXT: 12016: 90 nop
|
||||||
// DISASM-NEXT: 12017: 90 nop
|
// DISASM-NEXT: 12017: 90 nop
|
||||||
// DISASM-NEXT: 12018: ff 25 {{.*}} jmpl *77908
|
// DISASM-NEXT: 12018: ff 25 {{.*}} jmpl *77916
|
||||||
// DISASM-NEXT: 1201e: 90 nop
|
// DISASM-NEXT: 1201e: 90 nop
|
||||||
// DISASM-NEXT: 1201f: 90 nop
|
// DISASM-NEXT: 1201f: 90 nop
|
||||||
|
|
||||||
|
|
|
@ -20,10 +20,10 @@
|
||||||
// CHECK-NEXT: AddressAlignment: 16
|
// CHECK-NEXT: AddressAlignment: 16
|
||||||
|
|
||||||
// CHECK: Relocations [
|
// CHECK: Relocations [
|
||||||
// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
|
// CHECK-NEXT: Section ({{.*}}) .rela.plt {
|
||||||
// CHECK-NEXT: 0x30A0 R_X86_64_GLOB_DAT bar 0x0
|
// CHECK-NEXT: 0x30B0 R_X86_64_GLOB_DAT bar 0x0
|
||||||
// CHECK-NEXT: 0x30A8 R_X86_64_GLOB_DAT zed 0x0
|
// CHECK-NEXT: 0x30B8 R_X86_64_GLOB_DAT zed 0x0
|
||||||
// CHECK-NEXT: 0x30B0 R_X86_64_GLOB_DAT _start 0x0
|
// CHECK-NEXT: 0x30C0 R_X86_64_GLOB_DAT _start 0x0
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
// CHECK-NEXT: ]
|
// CHECK-NEXT: ]
|
||||||
|
|
||||||
|
@ -39,15 +39,15 @@
|
||||||
// DISASM-NEXT: 2005: e9 {{.*}} jmp 22
|
// DISASM-NEXT: 2005: e9 {{.*}} jmp 22
|
||||||
// DISASM-NEXT: 200a: e9 {{.*}} jmp 25
|
// DISASM-NEXT: 200a: e9 {{.*}} jmp 25
|
||||||
|
|
||||||
// 0x130A0 - 0x12026 = 4218
|
// 0x30B0 - 0x2026 = 4234
|
||||||
// 0x130A8 - 0x1202e = 4218
|
// 0x30B8 - 0x202e = 4234
|
||||||
|
|
||||||
// DISASM: Disassembly of section .plt:
|
// DISASM: Disassembly of section .plt:
|
||||||
// DISASM-NEXT: .plt:
|
// DISASM-NEXT: .plt:
|
||||||
// DISASM-NEXT: 2020: ff 25 {{.*}} jmpq *4218(%rip)
|
// DISASM-NEXT: 2020: ff 25 {{.*}} jmpq *4234(%rip)
|
||||||
// DISASM-NEXT: 2026: 90 nop
|
// DISASM-NEXT: 2026: 90 nop
|
||||||
// DISASM-NEXT: 2027: 90 nop
|
// DISASM-NEXT: 2027: 90 nop
|
||||||
// DISASM-NEXT: 2028: ff 25 {{.*}} jmpq *4218(%rip)
|
// DISASM-NEXT: 2028: ff 25 {{.*}} jmpq *4234(%rip)
|
||||||
// DISASM-NEXT: 202e: 90 nop
|
// DISASM-NEXT: 202e: 90 nop
|
||||||
// DISASM-NEXT: 202f: 90 nop
|
// DISASM-NEXT: 202f: 90 nop
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
// SEC-NEXT: SHF_ALLOC
|
// SEC-NEXT: SHF_ALLOC
|
||||||
// SEC-NEXT: SHF_WRITE
|
// SEC-NEXT: SHF_WRITE
|
||||||
// SEC-NEXT: ]
|
// SEC-NEXT: ]
|
||||||
// SEC-NEXT: Address: 0x130A0
|
// SEC-NEXT: Address: 0x130E0
|
||||||
// SEC-NEXT: Offset:
|
// SEC-NEXT: Offset:
|
||||||
// SEC-NEXT: Size: 16
|
// SEC-NEXT: Size: 16
|
||||||
// SEC-NEXT: Link: 0
|
// SEC-NEXT: Link: 0
|
||||||
|
@ -93,7 +93,7 @@ R_X86_64_64:
|
||||||
R_X86_64_GOTPCREL:
|
R_X86_64_GOTPCREL:
|
||||||
.long zed@gotpcrel
|
.long zed@gotpcrel
|
||||||
|
|
||||||
// 0x130A8 - 0x11008 = 8352
|
// 0x130E8 - 0x11008 = 8416
|
||||||
// 8352 = 0x80200000 in little endian
|
// 8416 = 0xE0200000 in little endian
|
||||||
// CHECK: Contents of section .R_X86_64_GOTPCREL
|
// CHECK: Contents of section .R_X86_64_GOTPCREL
|
||||||
// CHECK-NEXT: 11008 a0200000
|
// CHECK-NEXT: 11008 e0200000
|
||||||
|
|
Loading…
Reference in New Issue