Index: lld/trunk/ELF/OutputSections.h =================================================================== --- lld/trunk/ELF/OutputSections.h +++ lld/trunk/ELF/OutputSections.h @@ -171,7 +171,7 @@ typedef typename llvm::object::ELFFile::uintX_t uintX_t; public: - RelocationSection(bool IsRela); + RelocationSection(StringRef Name, bool IsRela); void addReloc(const DynamicReloc &Reloc) { Relocs.push_back(Reloc); } void finalize() override; void writeTo(uint8_t *Buf) override; @@ -289,6 +289,7 @@ static OutputSection *Bss; static PltSection *Plt; static RelocationSection *RelaDyn; + static RelocationSection *RelaPlt; static StringTableSection *DynStrTab; static StringTableSection *StrTab; static SymbolTableSection *DynSymTab; Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -48,6 +48,10 @@ template <> RelocationSection *Out::RelaDyn = nullptr; template <> RelocationSection *Out::RelaDyn = nullptr; template <> RelocationSection *Out::RelaDyn = nullptr; +template <> RelocationSection *Out::RelaPlt = nullptr; +template <> RelocationSection *Out::RelaPlt = nullptr; +template <> RelocationSection *Out::RelaPlt = nullptr; +template <> RelocationSection *Out::RelaPlt = nullptr; template <> StringTableSection *Out::DynStrTab = nullptr; template <> StringTableSection *Out::DynStrTab = nullptr; template <> StringTableSection *Out::DynStrTab = nullptr; @@ -139,10 +143,9 @@ } template -RelocationSection::RelocationSection(bool IsRela) - : OutputSectionBase(IsRela ? ".rela.dyn" : ".rel.dyn", - IsRela ? llvm::ELF::SHT_RELA - : llvm::ELF::SHT_REL, +RelocationSection::RelocationSection(StringRef Name, bool IsRela) + : OutputSectionBase(Name, IsRela ? llvm::ELF::SHT_RELA + : llvm::ELF::SHT_REL, llvm::ELF::SHF_ALLOC), IsRela(IsRela) { this->Header.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); @@ -300,6 +303,13 @@ ++NumEntries; // DT_RELASZ / DT_RELSZ ++NumEntries; // DT_RELAENT / DT_RELENT } + if (Out::RelaPlt->hasRelocs()) { + ++NumEntries; // DT_JMPREL + ++NumEntries; // DT_PLTRELSZ + ++NumEntries; // DT_PLTGOT + ++NumEntries; // DT_PLTREL + } + ++NumEntries; // DT_SYMTAB ++NumEntries; // DT_SYMENT ++NumEntries; // DT_STRTAB @@ -367,6 +377,12 @@ WriteVal(IsRela ? DT_RELAENT : DT_RELENT, IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel)); } + if (Out::RelaPlt->hasRelocs()) { + WritePtr(DT_JMPREL, Out::RelaPlt->getVA()); + WriteVal(DT_PLTRELSZ, Out::RelaPlt->getSize()); + WritePtr(DT_PLTGOT, Out::Got->getVA()); + WriteVal(DT_PLTREL, Out::RelaPlt->isRela() ? DT_RELA : DT_REL); + } WritePtr(DT_SYMTAB, Out::DynSymTab->getVA()); WritePtr(DT_SYMENT, sizeof(Elf_Sym)); Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -134,8 +134,11 @@ Out::DynSymTab = &DynSymTab; HashTableSection HashTab; Out::HashTab = &HashTab; - RelocationSection RelaDyn(Symtab->shouldUseRela()); + bool IsRela = Symtab->shouldUseRela(); + RelocationSection RelaDyn(IsRela ? ".rela.dyn" : ".rel.dyn", IsRela); Out::RelaDyn = &RelaDyn; + RelocationSection RelaPlt(IsRela ? ".rela.plt" : ".rel.plt", IsRela); + Out::RelaPlt = &RelaPlt; DynamicSection Dynamic(*Symtab); Out::Dynamic = &Dynamic; @@ -233,11 +236,15 @@ Out::Got->addEntry(Body); } } - if (canBePreempted(Body)) { + + bool CanBePreempted = canBePreempted(Body); + if (CanBePreempted) Body->setUsedInDynamicReloc(); - Out::RelaDyn->addReloc({C, RI}); - } else if (Config->Shared && !Target->isRelRelative(Type)) { - Out::RelaDyn->addReloc({C, RI}); + if (CanBePreempted || (Config->Shared && !Target->isRelRelative(Type))) { + if (Body && Body->isInPlt()) + Out::RelaPlt->addReloc({C, RI}); + else + Out::RelaDyn->addReloc({C, RI}); } } } @@ -466,6 +473,8 @@ OutputSections.push_back(Out::DynStrTab); if (Out::RelaDyn->hasRelocs()) OutputSections.push_back(Out::RelaDyn); + if (Out::RelaPlt->hasRelocs()) + OutputSections.push_back(Out::RelaPlt); } if (!Out::Got->empty()) OutputSections.push_back(Out::Got); Index: lld/trunk/test/elf2/plt-i686.s =================================================================== --- lld/trunk/test/elf2/plt-i686.s +++ lld/trunk/test/elf2/plt-i686.s @@ -20,9 +20,9 @@ // CHECK-NEXT: AddressAlignment: 16 // CHECK: Relocations [ -// CHECK-NEXT: Section ({{.*}}) .rel.dyn { -// CHECK-NEXT: 0x13050 R_386_GLOB_DAT bar 0x0 -// CHECK-NEXT: 0x13054 R_386_GLOB_DAT zed 0x0 +// CHECK-NEXT: Section ({{.*}}) .rel.plt { +// CHECK-NEXT: 0x13058 R_386_GLOB_DAT bar 0x0 +// CHECK-NEXT: 0x1305C R_386_GLOB_DAT zed 0x0 // CHECK-NEXT: } // CHECK-NEXT: ] @@ -38,15 +38,15 @@ // DISASM-NEXT: 12005: e9 06 00 00 00 jmp 6 // DISASM-NEXT: 1200a: e9 09 00 00 00 jmp 9 -// 0x13050 = 77904 -// 0x13054 = 77908 +// 0x13058 = 77912 +// 0x1305C = 77916 // DISASM: Disassembly of section .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: 12017: 90 nop -// DISASM-NEXT: 12018: ff 25 {{.*}} jmpl *77908 +// DISASM-NEXT: 12018: ff 25 {{.*}} jmpl *77916 // DISASM-NEXT: 1201e: 90 nop // DISASM-NEXT: 1201f: 90 nop Index: lld/trunk/test/elf2/plt.s =================================================================== --- lld/trunk/test/elf2/plt.s +++ lld/trunk/test/elf2/plt.s @@ -20,10 +20,10 @@ // CHECK-NEXT: AddressAlignment: 16 // CHECK: Relocations [ -// CHECK-NEXT: Section ({{.*}}) .rela.dyn { -// CHECK-NEXT: 0x30A0 R_X86_64_GLOB_DAT bar 0x0 -// CHECK-NEXT: 0x30A8 R_X86_64_GLOB_DAT zed 0x0 -// CHECK-NEXT: 0x30B0 R_X86_64_GLOB_DAT _start 0x0 +// CHECK-NEXT: Section ({{.*}}) .rela.plt { +// CHECK-NEXT: 0x30B0 R_X86_64_GLOB_DAT bar 0x0 +// CHECK-NEXT: 0x30B8 R_X86_64_GLOB_DAT zed 0x0 +// CHECK-NEXT: 0x30C0 R_X86_64_GLOB_DAT _start 0x0 // CHECK-NEXT: } // CHECK-NEXT: ] @@ -39,15 +39,15 @@ // DISASM-NEXT: 2005: e9 {{.*}} jmp 22 // DISASM-NEXT: 200a: e9 {{.*}} jmp 25 -// 0x130A0 - 0x12026 = 4218 -// 0x130A8 - 0x1202e = 4218 +// 0x30B0 - 0x2026 = 4234 +// 0x30B8 - 0x202e = 4234 // DISASM: Disassembly of section .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: 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: 202f: 90 nop Index: lld/trunk/test/elf2/relocation.s =================================================================== --- lld/trunk/test/elf2/relocation.s +++ lld/trunk/test/elf2/relocation.s @@ -22,7 +22,7 @@ // SEC-NEXT: SHF_ALLOC // SEC-NEXT: SHF_WRITE // SEC-NEXT: ] -// SEC-NEXT: Address: 0x130A0 +// SEC-NEXT: Address: 0x130E0 // SEC-NEXT: Offset: // SEC-NEXT: Size: 16 // SEC-NEXT: Link: 0 @@ -93,7 +93,7 @@ R_X86_64_GOTPCREL: .long zed@gotpcrel -// 0x130A8 - 0x11008 = 8352 -// 8352 = 0x80200000 in little endian +// 0x130E8 - 0x11008 = 8416 +// 8416 = 0xE0200000 in little endian // CHECK: Contents of section .R_X86_64_GOTPCREL -// CHECK-NEXT: 11008 a0200000 +// CHECK-NEXT: 11008 e0200000