Index: ELF/Relocations.cpp =================================================================== --- ELF/Relocations.cpp +++ ELF/Relocations.cpp @@ -714,18 +714,20 @@ if (needsPlt(Expr)) { if (Body.isInPlt()) continue; - In::Plt->addEntry(Body); - uint32_t Rel; - if (Body.isGnuIFunc() && !Preemptible) - Rel = Target->IRelativeRel; - else - Rel = Target->PltRel; - - In::GotPlt->addEntry(Body); - In::RelaPlt->addReloc({Rel, In::GotPlt, - Body.getGotPltOffset(), !Preemptible, - &Body, 0}); + if (Body.isGnuIFunc() && !Preemptible) { + In::Iplt->addEntry(Body); + In::IgotPlt->addEntry(Body); + In::RelaIplt->addReloc({Target->IRelativeRel, In::IgotPlt, + Body.getGotPltOffset(), + !Preemptible, &Body, 0}); + } else { + In::Plt->addEntry(Body); + In::GotPlt->addEntry(Body); + In::RelaPlt->addReloc({Target->PltRel, In::GotPlt, + Body.getGotPltOffset(), !Preemptible, + &Body, 0}); + } continue; } Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -117,6 +117,12 @@ // True if this symbol is referenced by 32-bit GOT relocations. unsigned Is32BitMipsGot : 1; + // True if this symbol is in the Iplt sub-section of the Plt + unsigned IsInIplt : 1; + + // True if this symbol is in the IGot sub-section of the .got.plt or .got + unsigned IsInIGot : 1; + // The following fields have the same meaning as the ELF symbol attributes. uint8_t Type; // symbol type uint8_t StOther; // st_other field value Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -95,8 +95,8 @@ SymbolBody::SymbolBody(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type) : SymbolKind(K), NeedsCopyOrPltAddr(false), IsLocal(IsLocal), - IsInGlobalMipsGot(false), Is32BitMipsGot(false), Type(Type), - StOther(StOther), Name(Name) {} + IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false), + IsInIGot(false), Type(Type), StOther(StOther), Name(Name) {} // Returns true if a symbol can be replaced at load-time by a symbol // with the same name defined in other ELF executable or DSO. @@ -151,6 +151,8 @@ } template typename ELFT::uint SymbolBody::getGotPltVA() const { + if (this->IsInIGot) + return In::IgotPlt->getVA() + getGotPltOffset(); return In::GotPlt->getVA() + getGotPltOffset(); } @@ -159,6 +161,8 @@ } template typename ELFT::uint SymbolBody::getPltVA() const { + if (this->IsInIplt) + return In::Iplt->getVA() + PltIndex * Target->PltEntrySize; return In::Plt->getVA() + Target->PltHeaderSize + PltIndex * Target->PltEntrySize; } Index: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ ELF/SyntheticSections.h @@ -206,6 +206,25 @@ std::vector Entries; }; +// The IgotPltSection is a Got associated with the IpltSection for GNU Ifunc +// Symbols that will be relocated by Target->IRelativeRel. +// On most Targets the IgotPltSection will immediately follow the GotPltSection +// on ARM the IgotPltSection will immediately follow the GotSection. +template +class IgotPltSection final : public SyntheticSection { + typedef typename ELFT::uint uintX_t; + +public: + IgotPltSection(); + void addEntry(SymbolBody &Sym); + size_t getSize() const override; + void writeTo(uint8_t *Buf) override; + bool empty() const override { return Entries.empty(); } + +private: + std::vector Entries; +}; + template class StringTableSection final : public SyntheticSection { public: @@ -431,6 +450,21 @@ std::vector> Entries; }; +// The IpltSection is a variant of Plt for recording entries for GNU Ifunc +// symbols that will be subject to a Target->IRelativeRel +// The IpltSection immediately follows the Plt section in the Output Section +template class IpltSection final : public SyntheticSection { +public: + IpltSection(); + void writeTo(uint8_t *Buf) override; + size_t getSize() const override; + void addEntry(SymbolBody &Sym); + bool empty() const override { return Entries.empty(); } + +private: + std::vector> Entries; +}; + template class GdbIndexSection final : public SyntheticSection { typedef typename ELFT::uint uintX_t; @@ -644,12 +678,15 @@ static GotSection *Got; static MipsGotSection *MipsGot; static GotPltSection *GotPlt; + static IgotPltSection *IgotPlt; static HashTableSection *HashTab; static InputSection *Interp; static MipsRldMapSection *MipsRldMap; static PltSection *Plt; + static IpltSection *Iplt; static RelocationSection *RelaDyn; static RelocationSection *RelaPlt; + static RelocationSection *RelaIplt; static StringTableSection *ShStrTab; static StringTableSection *StrTab; static SymbolTableSection *SymTab; @@ -669,12 +706,15 @@ template GotSection *In::Got; template MipsGotSection *In::MipsGot; template GotPltSection *In::GotPlt; +template IgotPltSection *In::IgotPlt; template HashTableSection *In::HashTab; template InputSection *In::Interp; template MipsRldMapSection *In::MipsRldMap; template PltSection *In::Plt; +template IpltSection *In::Iplt; template RelocationSection *In::RelaDyn; template RelocationSection *In::RelaPlt; +template RelocationSection *In::RelaIplt; template StringTableSection *In::ShStrTab; template StringTableSection *In::StrTab; template SymbolTableSection *In::SymTab; Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -707,6 +707,36 @@ } } +// On ARM the IgotPltSection is part of the GotSection, on other Targets it is +// part of the .got.plt +template +IgotPltSection::IgotPltSection() + : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, + Target->GotPltEntrySize, + Config->EMachine == EM_ARM ? ".got" : ".got.plt") { +} + +template void IgotPltSection::addEntry(SymbolBody &Sym) { + Sym.IsInIGot = true; + Sym.GotPltIndex = Entries.size(); + Entries.push_back(&Sym); +} + +template size_t IgotPltSection::getSize() const { + return (Entries.size()) * Target->GotPltEntrySize; +} + +template void IgotPltSection::writeTo(uint8_t *Buf) { + for (const SymbolBody *B : Entries) { + if (Config->EMachine == EM_ARM) + // On ARM we are actually part of the Got and not GotPlt. + write32le(Buf, B->getVA()); + else + Target->writeGotPlt(Buf, *B); + Buf += sizeof(uintX_t); + } +} + template StringTableSection::StringTableSection(StringRef Name, bool Dynamic) : SyntheticSection(Dynamic ? (uintX_t)SHF_ALLOC : 0, SHT_STRTAB, 1, @@ -805,11 +835,10 @@ return; // Already finalized. this->Link = In::DynStrTab->OutSec->SectionIndex; - - if (!In::RelaDyn->empty()) { + if (In::RelaDyn->OutSec->Size > 0) { bool IsRela = Config->Rela; add({IsRela ? DT_RELA : DT_REL, In::RelaDyn}); - add({IsRela ? DT_RELASZ : DT_RELSZ, In::RelaDyn->getSize()}); + add({IsRela ? DT_RELASZ : DT_RELSZ, In::RelaDyn->OutSec->Size}); add({IsRela ? DT_RELAENT : DT_RELENT, uintX_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))}); @@ -822,9 +851,9 @@ add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels}); } } - if (!In::RelaPlt->empty()) { + if (In::RelaPlt->OutSec->Size > 0) { add({DT_JMPREL, In::RelaPlt}); - add({DT_PLTRELSZ, In::RelaPlt->getSize()}); + add({DT_PLTRELSZ, In::RelaPlt->OutSec->Size}); add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT, In::GotPlt}); add({DT_PLTREL, uint64_t(Config->Rela ? DT_RELA : DT_REL)}); @@ -1401,6 +1430,36 @@ } template +IpltSection::IpltSection() + : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, + ".plt") {} + +template void IpltSection::writeTo(uint8_t *Buf) { + // The IRelative relocations do not support lazy binding so no header is + // needed + size_t Off = 0; + for (auto &I : Entries) { + const SymbolBody *B = I.first; + unsigned RelOff = I.second + In::Plt->getSize(); + uint64_t Got = B->getGotPltVA(); + uint64_t Plt = this->getVA() + Off; + Target->writePlt(Buf + Off, Got, Plt, B->PltIndex, RelOff); + Off += Target->PltEntrySize; + } +} + +template void IpltSection::addEntry(SymbolBody &Sym) { + Sym.PltIndex = Entries.size(); + Sym.IsInIplt = true; + unsigned RelOff = In::RelaIplt->getRelocOffset(); + Entries.push_back(std::make_pair(&Sym, RelOff)); +} + +template size_t IpltSection::getSize() const { + return Entries.size() * Target->PltEntrySize; +} + +template GdbIndexSection::GdbIndexSection() : SyntheticSection(0, SHT_PROGBITS, 1, ".gdb_index") {} @@ -1750,6 +1809,11 @@ template class elf::GotPltSection; template class elf::GotPltSection; +template class elf::IgotPltSection; +template class elf::IgotPltSection; +template class elf::IgotPltSection; +template class elf::IgotPltSection; + template class elf::StringTableSection; template class elf::StringTableSection; template class elf::StringTableSection; @@ -1785,6 +1849,11 @@ template class elf::PltSection; template class elf::PltSection; +template class elf::IpltSection; +template class elf::IpltSection; +template class elf::IpltSection; +template class elf::IpltSection; + template class elf::GdbIndexSection; template class elf::GdbIndexSection; template class elf::GdbIndexSection; Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -336,6 +336,8 @@ In::GotPlt = make>(); Symtab::X->Sections.push_back(In::GotPlt); + In::IgotPlt = make>(); + Symtab::X->Sections.push_back(In::IgotPlt); if (Config->GdbIndex) { In::GdbIndex = make>(); @@ -347,9 +349,18 @@ In::RelaPlt = make>( Config->Rela ? ".rela.plt" : ".rel.plt", false /*Sort*/); Symtab::X->Sections.push_back(In::RelaPlt); + // The RelaIplt immediately follows .rel.plt (.rel.dyn for ARM) to ensure + // that the IRelative relocations are processed last by the dynamic loader + In::RelaIplt = make>( + Config->Rela ? ".rela.plt" : (Config->EMachine == EM_ARM) ? ".rel.dyn" + : ".rel.plt", + false /*Sort*/); + Symtab::X->Sections.push_back(In::RelaIplt); In::Plt = make>(); Symtab::X->Sections.push_back(In::Plt); + In::Iplt = make>(); + Symtab::X->Sections.push_back(In::Iplt); if (Config->EhFrameHdr) { In::EhFrameHdr = make>(); @@ -631,10 +642,10 @@ if (In::DynSymTab) return; StringRef S = Config->Rela ? "__rela_iplt_start" : "__rel_iplt_start"; - addOptionalRegular(S, In::RelaPlt, 0); + addOptionalRegular(S, In::RelaIplt, 0); S = Config->Rela ? "__rela_iplt_end" : "__rel_iplt_end"; - addOptionalRegular(S, In::RelaPlt, -1); + addOptionalRegular(S, In::RelaIplt, -1); } // The linker is expected to define some symbols depending on @@ -1011,11 +1022,13 @@ // symbol table section (DynSymTab) must be the first one. finalizeSynthetic( {In::DynSymTab, In::GnuHashTab, In::HashTab, - In::SymTab, In::ShStrTab, In::StrTab, In::VerDef, - In::DynStrTab, In::GdbIndex, In::Got, - In::MipsGot, In::GotPlt, In::RelaDyn, - In::RelaPlt, In::Plt, In::EhFrameHdr, In::VerSym, - In::VerNeed, In::Dynamic}); + In::SymTab, In::ShStrTab, In::StrTab, + In::VerDef, In::DynStrTab, In::GdbIndex, + In::Got, In::MipsGot, In::IgotPlt, + In::GotPlt, In::RelaDyn, In::RelaIplt, + In::RelaPlt, In::Plt, In::Iplt, + In::Plt, In::EhFrameHdr, In::VerSym, + In::VerNeed, In::Dynamic}); } template void Writer::addPredefinedSections() { Index: test/ELF/aarch64-gnu-ifunc.s =================================================================== --- test/ELF/aarch64-gnu-ifunc.s +++ test/ELF/aarch64-gnu-ifunc.s @@ -22,8 +22,8 @@ // CHECK-NEXT: } // CHECK: Relocations [ // CHECK-NEXT: Section ({{.*}}) .rela.plt { -// CHECK-NEXT: 0x30018 R_AARCH64_IRELATIVE -// CHECK-NEXT: 0x30020 R_AARCH64_IRELATIVE +// CHECK-NEXT: 0x30000 R_AARCH64_IRELATIVE +// CHECK-NEXT: 0x30008 R_AARCH64_IRELATIVE // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK: Symbols [ @@ -98,34 +98,27 @@ // 344 = 0x158 // 392 = 0x188 -// DISASM: Disassembly of section .text: + +// DISASM: Disassembly of section .text: // DISASM-NEXT: foo: // DISASM-NEXT: 20000: c0 03 5f d6 ret -// DISASM: bar: +// DISASM: bar: // DISASM-NEXT: 20004: c0 03 5f d6 ret // DISASM: _start: -// DISASM-NEXT: 20008: 0e 00 00 94 bl #56 -// DISASM-NEXT: 2000c: 11 00 00 94 bl #68 -// DISASM-NEXT: 20010: 42 60 05 91 add x2, x2, #344 -// DISASM-NEXT: 20014: 42 20 06 91 add x2, x2, #392 +// DISASM-NEXT: 20008: 06 00 00 94 bl #24 +// DISASM-NEXT: 2000c: 09 00 00 94 bl #36 +// DISASM-NEXT: 20010: 42 60 05 91 add x2, x2, #344 +// DISASM-NEXT: 20014: 42 20 06 91 add x2, x2, #392 // DISASM-NEXT: Disassembly of section .plt: // DISASM-NEXT: .plt: -// DISASM-NEXT: 20020: f0 7b bf a9 stp x16, x30, [sp, #-16]! -// DISASM-NEXT: 20024: 90 00 00 90 adrp x16, #65536 -// DISASM-NEXT: 20028: 11 0a 40 f9 ldr x17, [x16, #16] -// DISASM-NEXT: 2002c: 10 42 00 91 add x16, x16, #16 -// DISASM-NEXT: 20030: 20 02 1f d6 br x17 -// DISASM-NEXT: 20034: 1f 20 03 d5 nop -// DISASM-NEXT: 20038: 1f 20 03 d5 nop -// DISASM-NEXT: 2003c: 1f 20 03 d5 nop -// DISASM-NEXT: 20040: 90 00 00 90 adrp x16, #65536 -// DISASM-NEXT: 20044: 11 0e 40 f9 ldr x17, [x16, #24] -// DISASM-NEXT: 20048: 10 62 00 91 add x16, x16, #24 -// DISASM-NEXT: 2004c: 20 02 1f d6 br x17 -// DISASM-NEXT: 20050: 90 00 00 90 adrp x16, #65536 -// DISASM-NEXT: 20054: 11 12 40 f9 ldr x17, [x16, #32] -// DISASM-NEXT: 20058: 10 82 00 91 add x16, x16, #32 -// DISASM-NEXT: 2005c: 20 02 1f d6 br x17 +// DISASM-NEXT: 20020: 90 00 00 90 adrp x16, #65536 +// DISASM-NEXT: 20024: 11 02 40 f9 ldr x17, [x16] +// DISASM-NEXT: 20028: 10 02 00 91 add x16, x16, #0 +// DISASM-NEXT: 2002c: 20 02 1f d6 br x17 +// DISASM-NEXT: 20030: 90 00 00 90 adrp x16, #65536 +// DISASM-NEXT: 20034: 11 06 40 f9 ldr x17, [x16, #8] +// DISASM-NEXT: 20038: 10 22 00 91 add x16, x16, #8 +// DISASM-NEXT: 2003c: 20 02 1f d6 br x17 .text .type foo STT_GNU_IFUNC Index: test/ELF/arm-gnu-ifunc.s =================================================================== --- test/ELF/arm-gnu-ifunc.s +++ test/ELF/arm-gnu-ifunc.s @@ -24,51 +24,63 @@ movw r0,:lower16:__rel_iplt_end movt r0,:upper16:__rel_iplt_end -// CHECK: Sections [ -// CHECK: Section { -// CHECK: Index: 1 -// CHECK-NEXT: Name: .rel.plt -// CHECK-NEXT: Type: SHT_REL -// CHECK-NEXT: Flags [ -// CHECK-NEXT: SHF_ALLOC -// CHECK-NEXT: ] -// CHECK-NEXT: Address: [[REL:.*]] -// CHECK-NEXT: Offset: -// CHECK-NEXT: Size: 16 -// CHECK-NEXT: Link: -// CHECK-NEXT: Info: -// CHECK-NEXT: AddressAlignment: 4 -// CHECK-NEXT: EntrySize: 8 -// CHECK-NEXT: } -// CHECK: Relocations [ -// CHECK-NEXT: Section (1) .rel.plt { -// CHECK-NEXT: 0x1200C R_ARM_IRELATIVE -// CHECK-NEXT: 0x12010 R_ARM_IRELATIVE -// CHECK-NEXT: } -// CHECK-NEXT:] -// CHECK: Symbols [ -// CHECK: Symbol { -// CHECK: Name: __rel_iplt_end -// CHECK-NEXT: Value: 0x100E4 -// CHECK-NEXT: Size: 0 -// CHECK-NEXT: Binding: Local -// CHECK-NEXT: Type: None -// CHECK-NEXT: Other [ -// CHECK-NEXT: STV_HIDDEN -// CHECK-NEXT: ] -// CHECK-NEXT: Section: .rel.plt -// CHECK-NEXT: } -// CHECK-NEXT: Symbol { -// CHECK-NEXT: Name: __rel_iplt_start -// CHECK-NEXT: Value: 0x100D4 -// CHECK-NEXT: Size: 0 -// CHECK-NEXT: Binding: Local -// CHECK-NEXT: Type: None -// CHECK-NEXT: Other [ -// CHECK-NEXT: STV_HIDDEN -// CHECK-NEXT: ] -// CHECK-NEXT: Section: .rel.plt -// CHECK-NEXT: } +// CHECK: Sections [ +// CHECK: Section { +// CHECK: Section { +// CHECK: Name: .rel.dyn +// CHECK-NEXT: Type: SHT_REL +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x100F4 +// CHECK-NEXT: Offset: 0xF4 +// CHECK-NEXT: Size: 16 +// CHECK: Name: .plt +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_EXECINSTR +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x11020 +// CHECK-NEXT: Offset: 0x1020 +// CHECK-NEXT: Size: 32 +// CHECK: Name: .got +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x12000 +// CHECK-NEXT: Offset: 0x2000 +// CHECK-NEXT: Size: 8 +// CHECK: Relocations [ +// CHECK-NEXT: Section (1) .rel.dyn { +// CHECK-NEXT: 0x12000 R_ARM_IRELATIVE +// CHECK-NEXT: 0x12004 R_ARM_IRELATIVE +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK: Symbol { +// CHECK: Name: __rel_iplt_end (6) +// CHECK-NEXT: Value: 0x10104 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .rel.dyn +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: __rel_iplt_start +// CHECK-NEXT: Value: 0x100F4 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .rel.dyn +// CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: _start // CHECK-NEXT: Value: 0x11008 @@ -97,35 +109,29 @@ // CHECK-NEXT: Section: .text // CHECK-NEXT: } -// DISASM: Disassembly of section .text: +// DISASM: Disassembly of section .text: // DISASM-NEXT: foo: -// DISASM-NEXT: 11000: 1e ff 2f e1 bx lr -// DISASM: bar: -// DISASM-NEXT: 11004: 1e ff 2f e1 bx lr -// DISASM: _start: -// DISASM-NEXT: 11008: 09 00 00 eb bl #36 -// DISASM-NEXT: 1100c: 0c 00 00 eb bl #48 -// DISASM-NEXT: 11010: d4 00 00 e3 movw r0, #212 -// DISASM-NEXT: 11014: 01 00 40 e3 movt r0, #1 -// r0 = 212 + 1 * 65536 = 100D4 = __rel_iplt_start -// DISASM-NEXT: 11018: e4 00 00 e3 movw r0, #228 -// DISASM-NEXT: 1101c: 01 00 40 e3 movt r0, #1 -// r1 = 228 + 1 * 65536 = 100E4 = __rel_iplt_end +// DISASM-NEXT: 11000: 1e ff 2f e1 bx lr +// DISASM: bar: +// DISASM-NEXT: 11004: 1e ff 2f e1 bx lr +// DISASM: _start: +// DISASM-NEXT: 11008: 04 00 00 eb bl #16 +// DISASM-NEXT: 1100c: 07 00 00 eb bl #28 +// 1 * 65536 + 244 = 0x100f4 __rel_iplt_start +// DISASM-NEXT: 11010: f4 00 00 e3 movw r0, #244 +// DISASM-NEXT: 11014: 01 00 40 e3 movt r0, #1 +// 1 * 65536 + 260 = 0x10104 __rel_iplt_end +// DISASM-NEXT: 11018: 04 01 00 e3 movw r0, #260 +// DISASM-NEXT: 1101c: 01 00 40 e3 movt r0, #1 // DISASM-NEXT: Disassembly of section .plt: // DISASM-NEXT: .plt: -// DISASM-NEXT: 11020: 04 e0 2d e5 str lr, [sp, #-4]! -// DISASM-NEXT: 11024: 04 e0 9f e5 ldr lr, [pc, #4] -// DISASM-NEXT: 11028: 0e e0 8f e0 add lr, pc, lr -// DISASM-NEXT: 1102c: 08 f0 be e5 ldr pc, [lr, #8]! -// 0x0fd0 + 0x11028 + 0x8 = 0x12000 -// DISASM-NEXT: 11030: d0 0f 00 00 -// DISASM-NEXT: 11034: 04 c0 9f e5 ldr r12, [pc, #4] -// DISASM-NEXT: 11038: 0f c0 8c e0 add r12, r12, pc -// DISASM-NEXT: 1103c: 00 f0 9c e5 ldr pc, [r12] -// 0x0fcc + 0x11038 + 0x8 = 0x1200C -// DISASM-NEXT: 11040: cc 0f 00 00 -// DISASM-NEXT: 11044: 04 c0 9f e5 ldr r12, [pc, #4] -// DISASM-NEXT: 11048: 0f c0 8c e0 add r12, r12, pc -// DISASM-NEXT: 1104c: 00 f0 9c e5 ldr pc, [r12] -// 0x0fc0 + 0x11048 + 0x8 = 0x12010 -// DISASM-NEXT: 11050: c0 0f 00 00 +// DISASM-NEXT: 11020: 04 c0 9f e5 ldr r12, [pc, #4] +// DISASM-NEXT: 11024: 0f c0 8c e0 add r12, r12, pc +// 11024 + 8 + fd4 = 0x12000 +// DISASM-NEXT: 11028: 00 f0 9c e5 ldr pc, [r12] +// DISASM-NEXT: 1102c: d4 0f 00 00 +// DISASM-NEXT: 11030: 04 c0 9f e5 ldr r12, [pc, #4] +// DISASM-NEXT: 11034: 0f c0 8c e0 add r12, r12, pc +// 11034 + 8 + fc8 = 0x12004 +// DISASM-NEXT: 11038: 00 f0 9c e5 ldr pc, [r12] +// DISASM-NEXT: 1103c: c8 0f 00 00 Index: test/ELF/gnu-ifunc-i386.s =================================================================== --- test/ELF/gnu-ifunc-i386.s +++ test/ELF/gnu-ifunc-i386.s @@ -22,8 +22,8 @@ // CHECK-NEXT: } // CHECK: Relocations [ // CHECK-NEXT: Section ({{.*}}) .rel.plt { -// CHECK-NEXT: 0x1200C R_386_IRELATIVE -// CHECK-NEXT: 0x12010 R_386_IRELATIVE +// CHECK-NEXT: 0x12000 R_386_IRELATIVE +// CHECK-NEXT: 0x12004 R_386_IRELATIVE // CHECK-NEXT: } // CHECK-NEXT: ] @@ -88,30 +88,24 @@ // CHECK-NEXT: } // CHECK-NEXT:] -// DISASM: Disassembly of section .text: +// DISASM: Disassembly of section .text: // DISASM-NEXT: foo: -// DISASM-NEXT: 11000: c3 retl -// DISASM: bar: -// DISASM-NEXT: 11001: c3 retl +// DISASM-NEXT: 11000: c3 retl +// DISASM: bar: +// DISASM-NEXT: 11001: c3 retl // DISASM: _start: -// DISASM-NEXT: 11002: e8 29 00 00 00 calll 41 -// DISASM-NEXT: 11007: e8 34 00 00 00 calll 52 +// DISASM-NEXT: 11002: e8 19 00 00 00 calll 25 +// DISASM-NEXT: 11007: e8 24 00 00 00 calll 36 // DISASM-NEXT: 1100c: ba d4 00 01 00 movl $65748, %edx // DISASM-NEXT: 11011: ba e4 00 01 00 movl $65764, %edx // DISASM-NEXT: Disassembly of section .plt: // DISASM-NEXT: .plt: -// DISASM-NEXT: 11020: ff 35 04 20 01 00 pushl 73732 -// DISASM-NEXT: 11026: ff 25 08 20 01 00 jmpl *73736 -// DISASM-NEXT: 1102c: 90 nop -// DISASM-NEXT: 1102d: 90 nop -// DISASM-NEXT: 1102e: 90 nop -// DISASM-NEXT: 1102f: 90 nop -// DISASM-NEXT: 11030: ff 25 0c 20 01 00 jmpl *73740 -// DISASM-NEXT: 11036: 68 00 00 00 00 pushl $0 -// DISASM-NEXT: 1103b: e9 e0 ff ff ff jmp -32 <.plt> -// DISASM-NEXT: 11040: ff 25 10 20 01 00 jmpl *73744 -// DISASM-NEXT: 11046: 68 08 00 00 00 pushl $8 -// DISASM-NEXT: 1104b: e9 d0 ff ff ff jmp -48 <.plt> +// DISASM-NEXT: 11020: ff 25 00 20 01 00 jmpl *73728 +// DISASM-NEXT: 11026: 68 10 00 00 00 pushl $16 +// DISASM-NEXT: 1102b: e9 e0 ff ff ff jmp -32 <_start+0xE> +// DISASM-NEXT: 11030: ff 25 04 20 01 00 jmpl *73732 +// DISASM-NEXT: 11036: 68 18 00 00 00 pushl $24 +// DISASM-NEXT: 1103b: e9 d0 ff ff ff jmp -48 <_start+0xE> .text .type foo STT_GNU_IFUNC Index: test/ELF/gnu-ifunc.s =================================================================== --- test/ELF/gnu-ifunc.s +++ test/ELF/gnu-ifunc.s @@ -22,8 +22,8 @@ // CHECK-NEXT: } // CHECK: Relocations [ // CHECK-NEXT: Section ({{.*}}) .rela.plt { -// CHECK-NEXT: 0x202018 R_X86_64_IRELATIVE -// CHECK-NEXT: 0x202020 R_X86_64_IRELATIVE +// CHECK-NEXT: 0x202000 R_X86_64_IRELATIVE +// CHECK-NEXT: 0x202008 R_X86_64_IRELATIVE // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK: Symbols [ @@ -87,28 +87,25 @@ // CHECK-NEXT: } // CHECK-NEXT: ] -// DISASM: Disassembly of section .text: +// DISASM: Disassembly of section .text: // DISASM-NEXT: foo: -// DISASM-NEXT: 201000: {{.*}} retq +// DISASM-NEXT: 201000: {{.*}} retq // DISASM: bar: -// DISASM-NEXT: 201001: {{.*}} retq +// DISASM-NEXT: 201001: {{.*}} retq // DISASM: _start: -// DISASM-NEXT: 201002: {{.*}} callq 41 -// DISASM-NEXT: 201007: {{.*}} callq 52 -// DISASM-NEXT: 20100c: {{.*}} movl $2097496, %edx -// DISASM-NEXT: 201011: {{.*}} movl $2097544, %edx -// DISASM-NEXT: 201016: {{.*}} movl $2097545, %edx +// DISASM-NEXT: 201002: {{.*}} callq 25 +// DISASM-NEXT: 201007: {{.*}} callq 36 +// DISASM-NEXT: 20100c: {{.*}} movl $2097496, %edx +// DISASM-NEXT: 201011: {{.*}} movl $2097544, %edx +// DISASM-NEXT: 201016: {{.*}} movl $2097545, %edx // DISASM-NEXT: Disassembly of section .plt: // DISASM-NEXT: .plt: -// DISASM-NEXT: 201020: {{.*}} pushq 4066(%rip) -// DISASM-NEXT: 201026: {{.*}} jmpq *4068(%rip) -// DISASM-NEXT: 20102c: {{.*}} nopl (%rax) -// DISASM-NEXT: 201030: {{.*}} jmpq *4066(%rip) -// DISASM-NEXT: 201036: {{.*}} pushq $0 -// DISASM-NEXT: 20103b: {{.*}} jmp -32 -// DISASM-NEXT: 201040: {{.*}} jmpq *4058(%rip) -// DISASM-NEXT: 201046: {{.*}} pushq $1 -// DISASM-NEXT: 20104b: {{.*}} jmp -48 +// DISASM-NEXT: 201020: {{.*}} jmpq *4058(%rip) +// DISASM-NEXT: 201026: {{.*}} pushq $0 +// DISASM-NEXT: 20102b: {{.*}} jmp -32 <_start+0xE> +// DISASM-NEXT: 201030: {{.*}} jmpq *4050(%rip) +// DISASM-NEXT: 201036: {{.*}} pushq $1 +// DISASM-NEXT: 20103b: {{.*}} jmp -48 <_start+0xE> .text .type foo STT_GNU_IFUNC