[lld] r289045 - [ELF] ifunc implementation using synthetic sections
Peter Smith via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 8 04:58:56 PST 2016
Author: psmith
Date: Thu Dec 8 06:58:55 2016
New Revision: 289045
URL: http://llvm.org/viewvc/llvm-project?rev=289045&view=rev
Log:
[ELF] ifunc implementation using synthetic sections
This change introduces new synthetic sections IpltSection, IgotPltSection
that represent the ifunc entries that would previously have been put in
the PltSection and the GotPltSection. The separation makes sure that
the R_*_IRELATIVE relocations are placed after the non R_*_IRELATIVE
relocations, which permits ifunc resolvers to know that the .got.plt
slots will be initialized prior to the resolver being called.
A secondary benefit is that for ARM we can move the IgotPltSection and its
dynamic relocations to the .got and .rel.dyn as the ARM glibc expects all
the R_*_IRELATIVE relocations to be in the .rel.dyn
Differential revision: https://reviews.llvm.org/D27406
Added:
lld/trunk/test/ELF/Inputs/arm-shared.s (with props)
lld/trunk/test/ELF/Inputs/shared2-x86-64.s (with props)
lld/trunk/test/ELF/aarch64-gnu-ifunc-plt.s (with props)
lld/trunk/test/ELF/arm-gnu-ifunc-plt.s (with props)
lld/trunk/test/ELF/gnu-ifunc-plt.s (with props)
lld/trunk/test/ELF/gnu-ifunc-shared.s (with props)
Modified:
lld/trunk/ELF/Relocations.cpp
lld/trunk/ELF/Symbols.cpp
lld/trunk/ELF/Symbols.h
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/SyntheticSections.h
lld/trunk/ELF/Writer.cpp
lld/trunk/test/ELF/aarch64-gnu-ifunc.s
lld/trunk/test/ELF/arm-gnu-ifunc.s
lld/trunk/test/ELF/gnu-ifunc-i386.s
lld/trunk/test/ELF/gnu-ifunc.s
Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=289045&r1=289044&r2=289045&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Thu Dec 8 06:58:55 2016
@@ -719,18 +719,20 @@ static void scanRelocs(InputSectionBase<
if (needsPlt(Expr)) {
if (Body.isInPlt())
continue;
- In<ELFT>::Plt->addEntry(Body);
- uint32_t Rel;
- if (Body.isGnuIFunc() && !Preemptible)
- Rel = Target->IRelativeRel;
- else
- Rel = Target->PltRel;
-
- In<ELFT>::GotPlt->addEntry(Body);
- In<ELFT>::RelaPlt->addReloc({Rel, In<ELFT>::GotPlt,
- Body.getGotPltOffset<ELFT>(), !Preemptible,
- &Body, 0});
+ if (Body.isGnuIFunc() && !Preemptible) {
+ In<ELFT>::Iplt->addEntry(Body);
+ In<ELFT>::IgotPlt->addEntry(Body);
+ In<ELFT>::RelaIplt->addReloc({Target->IRelativeRel, In<ELFT>::IgotPlt,
+ Body.getGotPltOffset<ELFT>(),
+ !Preemptible, &Body, 0});
+ } else {
+ In<ELFT>::Plt->addEntry(Body);
+ In<ELFT>::GotPlt->addEntry(Body);
+ In<ELFT>::RelaPlt->addReloc({Target->PltRel, In<ELFT>::GotPlt,
+ Body.getGotPltOffset<ELFT>(), !Preemptible,
+ &Body, 0});
+ }
continue;
}
Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=289045&r1=289044&r2=289045&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Thu Dec 8 06:58:55 2016
@@ -95,8 +95,8 @@ static typename ELFT::uint getSymVA(cons
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 <class ELFT> typename ELFT::uin
}
template <class ELFT> typename ELFT::uint SymbolBody::getGotPltVA() const {
+ if (this->IsInIgot)
+ return In<ELFT>::IgotPlt->getVA() + getGotPltOffset<ELFT>();
return In<ELFT>::GotPlt->getVA() + getGotPltOffset<ELFT>();
}
@@ -159,6 +161,8 @@ template <class ELFT> typename ELFT::uin
}
template <class ELFT> typename ELFT::uint SymbolBody::getPltVA() const {
+ if (this->IsInIplt)
+ return In<ELFT>::Iplt->getVA() + PltIndex * Target->PltEntrySize;
return In<ELFT>::Plt->getVA() + Target->PltHeaderSize +
PltIndex * Target->PltEntrySize;
}
Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=289045&r1=289044&r2=289045&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Thu Dec 8 06:58:55 2016
@@ -117,6 +117,12 @@ public:
// 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
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=289045&r1=289044&r2=289045&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Thu Dec 8 06:58:55 2016
@@ -707,6 +707,36 @@ template <class ELFT> void GotPltSection
}
}
+// On ARM the IgotPltSection is part of the GotSection, on other Targets it is
+// part of the .got.plt
+template <class ELFT>
+IgotPltSection<ELFT>::IgotPltSection()
+ : SyntheticSection<ELFT>(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
+ Target->GotPltEntrySize,
+ Config->EMachine == EM_ARM ? ".got" : ".got.plt") {
+}
+
+template <class ELFT> void IgotPltSection<ELFT>::addEntry(SymbolBody &Sym) {
+ Sym.IsInIgot = true;
+ Sym.GotPltIndex = Entries.size();
+ Entries.push_back(&Sym);
+}
+
+template <class ELFT> size_t IgotPltSection<ELFT>::getSize() const {
+ return Entries.size() * Target->GotPltEntrySize;
+}
+
+template <class ELFT> void IgotPltSection<ELFT>::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<ELFT>());
+ else
+ Target->writeGotPlt(Buf, *B);
+ Buf += sizeof(uintX_t);
+ }
+}
+
template <class ELFT>
StringTableSection<ELFT>::StringTableSection(StringRef Name, bool Dynamic)
: SyntheticSection<ELFT>(Dynamic ? (uintX_t)SHF_ALLOC : 0, SHT_STRTAB, 1,
@@ -805,11 +835,10 @@ template <class ELFT> void DynamicSectio
return; // Already finalized.
this->Link = In<ELFT>::DynStrTab->OutSec->SectionIndex;
-
- if (!In<ELFT>::RelaDyn->empty()) {
+ if (In<ELFT>::RelaDyn->OutSec->Size > 0) {
bool IsRela = Config->Rela;
add({IsRela ? DT_RELA : DT_REL, In<ELFT>::RelaDyn});
- add({IsRela ? DT_RELASZ : DT_RELSZ, In<ELFT>::RelaDyn->getSize()});
+ add({IsRela ? DT_RELASZ : DT_RELSZ, In<ELFT>::RelaDyn->OutSec->Size});
add({IsRela ? DT_RELAENT : DT_RELENT,
uintX_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))});
@@ -822,9 +851,9 @@ template <class ELFT> void DynamicSectio
add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels});
}
}
- if (!In<ELFT>::RelaPlt->empty()) {
+ if (In<ELFT>::RelaPlt->OutSec->Size > 0) {
add({DT_JMPREL, In<ELFT>::RelaPlt});
- add({DT_PLTRELSZ, In<ELFT>::RelaPlt->getSize()});
+ add({DT_PLTRELSZ, In<ELFT>::RelaPlt->OutSec->Size});
add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT,
In<ELFT>::GotPlt});
add({DT_PLTREL, uint64_t(Config->Rela ? DT_RELA : DT_REL)});
@@ -1401,6 +1430,36 @@ template <class ELFT> size_t PltSection<
}
template <class ELFT>
+IpltSection<ELFT>::IpltSection()
+ : SyntheticSection<ELFT>(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16,
+ ".plt") {}
+
+template <class ELFT> void IpltSection<ELFT>::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<ELFT>::Plt->getSize();
+ uint64_t Got = B->getGotPltVA<ELFT>();
+ uint64_t Plt = this->getVA() + Off;
+ Target->writePlt(Buf + Off, Got, Plt, B->PltIndex, RelOff);
+ Off += Target->PltEntrySize;
+ }
+}
+
+template <class ELFT> void IpltSection<ELFT>::addEntry(SymbolBody &Sym) {
+ Sym.PltIndex = Entries.size();
+ Sym.IsInIplt = true;
+ unsigned RelOff = In<ELFT>::RelaIplt->getRelocOffset();
+ Entries.push_back(std::make_pair(&Sym, RelOff));
+}
+
+template <class ELFT> size_t IpltSection<ELFT>::getSize() const {
+ return Entries.size() * Target->PltEntrySize;
+}
+
+template <class ELFT>
GdbIndexSection<ELFT>::GdbIndexSection()
: SyntheticSection<ELFT>(0, SHT_PROGBITS, 1, ".gdb_index") {}
@@ -1750,6 +1809,11 @@ template class elf::GotPltSection<ELF32B
template class elf::GotPltSection<ELF64LE>;
template class elf::GotPltSection<ELF64BE>;
+template class elf::IgotPltSection<ELF32LE>;
+template class elf::IgotPltSection<ELF32BE>;
+template class elf::IgotPltSection<ELF64LE>;
+template class elf::IgotPltSection<ELF64BE>;
+
template class elf::StringTableSection<ELF32LE>;
template class elf::StringTableSection<ELF32BE>;
template class elf::StringTableSection<ELF64LE>;
@@ -1785,6 +1849,11 @@ template class elf::PltSection<ELF32BE>;
template class elf::PltSection<ELF64LE>;
template class elf::PltSection<ELF64BE>;
+template class elf::IpltSection<ELF32LE>;
+template class elf::IpltSection<ELF32BE>;
+template class elf::IpltSection<ELF64LE>;
+template class elf::IpltSection<ELF64BE>;
+
template class elf::GdbIndexSection<ELF32LE>;
template class elf::GdbIndexSection<ELF32BE>;
template class elf::GdbIndexSection<ELF64LE>;
Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=289045&r1=289044&r2=289045&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Thu Dec 8 06:58:55 2016
@@ -206,6 +206,25 @@ private:
std::vector<const SymbolBody *> 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 ELFT>
+class IgotPltSection final : public SyntheticSection<ELFT> {
+ 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<const SymbolBody *> Entries;
+};
+
template <class ELFT>
class StringTableSection final : public SyntheticSection<ELFT> {
public:
@@ -431,6 +450,21 @@ private:
std::vector<std::pair<const SymbolBody *, unsigned>> 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 ELFT> class IpltSection final : public SyntheticSection<ELFT> {
+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<std::pair<const SymbolBody *, unsigned>> Entries;
+};
+
template <class ELFT>
class GdbIndexSection final : public SyntheticSection<ELFT> {
typedef typename ELFT::uint uintX_t;
@@ -644,12 +678,15 @@ template <class ELFT> struct In {
static GotSection<ELFT> *Got;
static MipsGotSection<ELFT> *MipsGot;
static GotPltSection<ELFT> *GotPlt;
+ static IgotPltSection<ELFT> *IgotPlt;
static HashTableSection<ELFT> *HashTab;
static InputSection<ELFT> *Interp;
static MipsRldMapSection<ELFT> *MipsRldMap;
static PltSection<ELFT> *Plt;
+ static IpltSection<ELFT> *Iplt;
static RelocationSection<ELFT> *RelaDyn;
static RelocationSection<ELFT> *RelaPlt;
+ static RelocationSection<ELFT> *RelaIplt;
static StringTableSection<ELFT> *ShStrTab;
static StringTableSection<ELFT> *StrTab;
static SymbolTableSection<ELFT> *SymTab;
@@ -669,12 +706,15 @@ template <class ELFT> GnuHashTableSectio
template <class ELFT> GotSection<ELFT> *In<ELFT>::Got;
template <class ELFT> MipsGotSection<ELFT> *In<ELFT>::MipsGot;
template <class ELFT> GotPltSection<ELFT> *In<ELFT>::GotPlt;
+template <class ELFT> IgotPltSection<ELFT> *In<ELFT>::IgotPlt;
template <class ELFT> HashTableSection<ELFT> *In<ELFT>::HashTab;
template <class ELFT> InputSection<ELFT> *In<ELFT>::Interp;
template <class ELFT> MipsRldMapSection<ELFT> *In<ELFT>::MipsRldMap;
template <class ELFT> PltSection<ELFT> *In<ELFT>::Plt;
+template <class ELFT> IpltSection<ELFT> *In<ELFT>::Iplt;
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaDyn;
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaPlt;
+template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaIplt;
template <class ELFT> StringTableSection<ELFT> *In<ELFT>::ShStrTab;
template <class ELFT> StringTableSection<ELFT> *In<ELFT>::StrTab;
template <class ELFT> SymbolTableSection<ELFT> *In<ELFT>::SymTab;
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=289045&r1=289044&r2=289045&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Dec 8 06:58:55 2016
@@ -356,6 +356,8 @@ template <class ELFT> void Writer<ELFT>:
In<ELFT>::GotPlt = make<GotPltSection<ELFT>>();
Symtab<ELFT>::X->Sections.push_back(In<ELFT>::GotPlt);
+ In<ELFT>::IgotPlt = make<IgotPltSection<ELFT>>();
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::IgotPlt);
if (Config->GdbIndex) {
In<ELFT>::GdbIndex = make<GdbIndexSection<ELFT>>();
@@ -368,8 +370,17 @@ template <class ELFT> void Writer<ELFT>:
Config->Rela ? ".rela.plt" : ".rel.plt", false /*Sort*/);
Symtab<ELFT>::X->Sections.push_back(In<ELFT>::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<ELFT>::RelaIplt = make<RelocationSection<ELFT>>(
+ (Config->EMachine == EM_ARM) ? ".rel.dyn" : In<ELFT>::RelaPlt->Name,
+ false /*Sort*/);
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::RelaIplt);
+
In<ELFT>::Plt = make<PltSection<ELFT>>();
Symtab<ELFT>::X->Sections.push_back(In<ELFT>::Plt);
+ In<ELFT>::Iplt = make<IpltSection<ELFT>>();
+ Symtab<ELFT>::X->Sections.push_back(In<ELFT>::Iplt);
if (Config->EhFrameHdr) {
In<ELFT>::EhFrameHdr = make<EhFrameHeader<ELFT>>();
@@ -651,10 +662,10 @@ template <class ELFT> void Writer<ELFT>:
if (In<ELFT>::DynSymTab)
return;
StringRef S = Config->Rela ? "__rela_iplt_start" : "__rel_iplt_start";
- addOptionalRegular<ELFT>(S, In<ELFT>::RelaPlt, 0);
+ addOptionalRegular<ELFT>(S, In<ELFT>::RelaIplt, 0);
S = Config->Rela ? "__rela_iplt_end" : "__rel_iplt_end";
- addOptionalRegular<ELFT>(S, In<ELFT>::RelaPlt, -1);
+ addOptionalRegular<ELFT>(S, In<ELFT>::RelaIplt, -1);
}
// The linker is expected to define some symbols depending on
@@ -1036,11 +1047,13 @@ template <class ELFT> void Writer<ELFT>:
// symbol table section (DynSymTab) must be the first one.
finalizeSynthetic<ELFT>(
{In<ELFT>::DynSymTab, In<ELFT>::GnuHashTab, In<ELFT>::HashTab,
- In<ELFT>::SymTab, In<ELFT>::ShStrTab, In<ELFT>::StrTab, In<ELFT>::VerDef,
- In<ELFT>::DynStrTab, In<ELFT>::GdbIndex, In<ELFT>::Got,
- In<ELFT>::MipsGot, In<ELFT>::GotPlt, In<ELFT>::RelaDyn,
- In<ELFT>::RelaPlt, In<ELFT>::Plt, In<ELFT>::EhFrameHdr, In<ELFT>::VerSym,
- In<ELFT>::VerNeed, In<ELFT>::Dynamic});
+ In<ELFT>::SymTab, In<ELFT>::ShStrTab, In<ELFT>::StrTab,
+ In<ELFT>::VerDef, In<ELFT>::DynStrTab, In<ELFT>::GdbIndex,
+ In<ELFT>::Got, In<ELFT>::MipsGot, In<ELFT>::IgotPlt,
+ In<ELFT>::GotPlt, In<ELFT>::RelaDyn, In<ELFT>::RelaIplt,
+ In<ELFT>::RelaPlt, In<ELFT>::Plt, In<ELFT>::Iplt,
+ In<ELFT>::Plt, In<ELFT>::EhFrameHdr, In<ELFT>::VerSym,
+ In<ELFT>::VerNeed, In<ELFT>::Dynamic});
}
template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
Added: lld/trunk/test/ELF/Inputs/arm-shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/arm-shared.s?rev=289045&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/arm-shared.s (added)
+++ lld/trunk/test/ELF/Inputs/arm-shared.s Thu Dec 8 06:58:55 2016
@@ -0,0 +1,8 @@
+.syntax unified
+.global bar2
+.type bar2, %function
+bar2:
+
+.global zed2
+.type zed2, %function
+zed2:
Propchange: lld/trunk/test/ELF/Inputs/arm-shared.s
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lld/trunk/test/ELF/Inputs/arm-shared.s
------------------------------------------------------------------------------
svn:keywords = Rev Date Author URL Id
Added: lld/trunk/test/ELF/Inputs/shared2-x86-64.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/shared2-x86-64.s?rev=289045&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/shared2-x86-64.s (added)
+++ lld/trunk/test/ELF/Inputs/shared2-x86-64.s Thu Dec 8 06:58:55 2016
@@ -0,0 +1,9 @@
+.global bar2
+.type bar2, @function
+bar2:
+ ret
+
+.global zed2
+.type zed2, @function
+zed2:
+ ret
Propchange: lld/trunk/test/ELF/Inputs/shared2-x86-64.s
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lld/trunk/test/ELF/Inputs/shared2-x86-64.s
------------------------------------------------------------------------------
svn:keywords = Rev Date Author URL Id
Added: lld/trunk/test/ELF/aarch64-gnu-ifunc-plt.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/aarch64-gnu-ifunc-plt.s?rev=289045&view=auto
==============================================================================
--- lld/trunk/test/ELF/aarch64-gnu-ifunc-plt.s (added)
+++ lld/trunk/test/ELF/aarch64-gnu-ifunc-plt.s Thu Dec 8 06:58:55 2016
@@ -0,0 +1,85 @@
+// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %S/Inputs/shared2.s -o %t1.o
+// RUN: ld.lld %t1.o --shared -o %t.so
+// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
+// RUN: ld.lld %t.so %t.o -o %tout
+// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
+// RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT
+// RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s
+// REQUIRES: aarch64
+
+// Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt
+// CHECK: Relocations [
+// CHECK-NEXT: Section (4) .rela.plt {
+// CHECK: 0x40018 R_AARCH64_JUMP_SLOT bar2 0x0
+// CHECK-NEXT: 0x40020 R_AARCH64_JUMP_SLOT zed2 0x0
+// CHECK-NEXT: 0x40028 R_AARCH64_IRELATIVE - 0x20000
+// CHECK-NEXT: 0x40030 R_AARCH64_IRELATIVE - 0x20004
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+
+// Check that .got.plt entries point back to PLT header
+// GOTPLT: Contents of section .got.plt:
+// GOTPLT-NEXT: 40000 00000000 00000000 00000000 00000000
+// GOTPLT-NEXT: 40010 00000000 00000000 20000200 00000000
+// GOTPLT-NEXT: 40020 20000200 00000000 20000200 00000000
+// GOTPLT-NEXT: 40030 20000200 00000000
+
+// Check that the PLTRELSZ tag includes the IRELATIVE relocations
+// CHECK: DynamicSection [
+// CHECK: 0x0000000000000002 PLTRELSZ 96 (bytes)
+
+// Check that a PLT header is written and the ifunc entries appear last
+// DISASM: Disassembly of section .text:
+// DISASM-NEXT: foo:
+// DISASM-NEXT: 20000: c0 03 5f d6 ret
+// DISASM: bar:
+// DISASM-NEXT: 20004: c0 03 5f d6 ret
+// DISASM: _start:
+// DISASM-NEXT: 20008: 16 00 00 94 bl #88
+// DISASM-NEXT: 2000c: 19 00 00 94 bl #100
+// DISASM-NEXT: 20010: 0c 00 00 94 bl #48
+// DISASM-NEXT: 20014: 0f 00 00 94 bl #60
+// DISASM-NEXT: Disassembly of section .plt:
+// DISASM-NEXT: .plt:
+// DISASM-NEXT: 20020: f0 7b bf a9 stp x16, x30, [sp, #-16]!
+// DISASM-NEXT: 20024: 10 01 00 90 adrp x16, #131072
+// 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: 10 01 00 90 adrp x16, #131072
+// 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: 10 01 00 90 adrp x16, #131072
+// 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: 20060: 10 01 00 90 adrp x16, #131072
+// DISASM-NEXT: 20064: 11 16 40 f9 ldr x17, [x16, #40]
+// DISASM-NEXT: 20068: 10 a2 00 91 add x16, x16, #40
+// DISASM-NEXT: 2006c: 20 02 1f d6 br x17
+// DISASM-NEXT: 20070: 10 01 00 90 adrp x16, #131072
+// DISASM-NEXT: 20074: 11 1a 40 f9 ldr x17, [x16, #48]
+// DISASM-NEXT: 20078: 10 c2 00 91 add x16, x16, #48
+// DISASM-NEXT: 2007c: 20 02 1f d6 br x17
+
+.text
+.type foo STT_GNU_IFUNC
+.globl foo
+foo:
+ ret
+
+.type bar STT_GNU_IFUNC
+.globl bar
+bar:
+ ret
+
+.globl _start
+_start:
+ bl foo
+ bl bar
+ bl bar2
+ bl zed2
Propchange: lld/trunk/test/ELF/aarch64-gnu-ifunc-plt.s
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lld/trunk/test/ELF/aarch64-gnu-ifunc-plt.s
------------------------------------------------------------------------------
svn:keywords = Rev Date Author URL Id
Modified: lld/trunk/test/ELF/aarch64-gnu-ifunc.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/aarch64-gnu-ifunc.s?rev=289045&r1=289044&r2=289045&view=diff
==============================================================================
--- lld/trunk/test/ELF/aarch64-gnu-ifunc.s (original)
+++ lld/trunk/test/ELF/aarch64-gnu-ifunc.s Thu Dec 8 06:58:55 2016
@@ -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
Added: lld/trunk/test/ELF/arm-gnu-ifunc-plt.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-gnu-ifunc-plt.s?rev=289045&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-gnu-ifunc-plt.s (added)
+++ lld/trunk/test/ELF/arm-gnu-ifunc-plt.s Thu Dec 8 06:58:55 2016
@@ -0,0 +1,93 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %S/Inputs/arm-shared.s -o %t1.o
+// RUN: ld.lld %t1.o --shared -o %t.so
+// RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %s -o %t.o
+// RUN: ld.lld %t.so %t.o -o %tout
+// RUN: llvm-objdump -triple=armv7a-linux-gnueabihf -d %tout | FileCheck %s --check-prefix=DISASM
+// RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT
+// RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s
+// REQUIRES: arm
+
+// Check that the IRELATIVE relocations are last in the .got
+// CHECK: Relocations [
+// CHECK-NEXT: Section (4) .rel.dyn {
+// CHECK-NEXT: 0x12078 R_ARM_GLOB_DAT bar2 0x0
+// CHECK-NEXT: 0x1207C R_ARM_GLOB_DAT zed2 0x0
+// CHECK-NEXT: 0x12080 R_ARM_IRELATIVE - 0x0
+// CHECK-NEXT: 0x12084 R_ARM_IRELATIVE - 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: Section (5) .rel.plt {
+// CHECK-NEXT: 0x1300C R_ARM_JUMP_SLOT bar2 0x0
+// CHECK-NEXT: 0x13010 R_ARM_JUMP_SLOT zed2 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+
+// Check that the GOT entries refer back to the ifunc resolver
+// GOTPLT: Contents of section .got:
+// GOTPLT-NEXT: 12078 00000000 00000000 00100100 04100100
+// GOTPLT-NEXT: Contents of section .got.plt:
+// GOTPLT-NEXT: 13000 00000000 00000000 00000000 20100100
+// GOTPLT-NEXT: 13010 20100100
+
+// 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: 14 00 00 eb bl #80
+// DISASM-NEXT: 1100c: 17 00 00 eb bl #92
+// DISASM: 11010: 00 00 00 00 .word 0x00000000
+// DISASM-NEXT: 11014: 04 00 00 00 .word 0x00000004
+// DISASM: 11018: 05 00 00 eb bl #20
+// DISASM-NEXT: 1101c: 08 00 00 eb bl #32
+// 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]!
+// DISASM-NEXT: 11030: d0 1f 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]
+// DISASM-NEXT: 11040: cc 1f 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]
+// DISASM-NEXT: 11050: c0 1f 00 00
+// Alignment to 16 byte boundary not strictly necessary on ARM, but harmless
+// DISASM-NEXT: 11054: 00 00 00 00 andeq r0, r0, r0
+// DISASM-NEXT: 11058: 00 00 00 00 andeq r0, r0, r0
+// DISASM-NEXT: 1105c: 00 00 00 00 andeq r0, r0, r0
+// DISASM-NEXT: 11060: 04 c0 9f e5 ldr r12, [pc, #4]
+// DISASM-NEXT: 11064: 0f c0 8c e0 add r12, r12, pc
+// DISASM-NEXT: 11068: 00 f0 9c e5 ldr pc, [r12]
+// DISASM-NEXT: 1106c: 14 10 00 00
+// DISASM-NEXT: 11070: 04 c0 9f e5 ldr r12, [pc, #4]
+// DISASM-NEXT: 11074: 0f c0 8c e0 add r12, r12, pc
+// DISASM-NEXT: 11078: 00 f0 9c e5 ldr pc, [r12]
+// DISASM-NEXT: 1107c: 08 10 00 00
+
+
+.syntax unified
+.text
+.type foo STT_GNU_IFUNC
+.globl foo
+foo:
+ bx lr
+
+.type bar STT_GNU_IFUNC
+.globl bar
+bar:
+ bx lr
+
+.globl _start
+_start:
+ bl foo
+ bl bar
+ // Create entries in the .got and .rel.dyn so that we don't just have
+ // IRELATIVE
+ .word bar2(got)
+ .word zed2(got)
+ bl bar2
+ bl zed2
Propchange: lld/trunk/test/ELF/arm-gnu-ifunc-plt.s
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lld/trunk/test/ELF/arm-gnu-ifunc-plt.s
------------------------------------------------------------------------------
svn:keywords = Rev Date Author URL Id
Modified: lld/trunk/test/ELF/arm-gnu-ifunc.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-gnu-ifunc.s?rev=289045&r1=289044&r2=289045&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-gnu-ifunc.s (original)
+++ lld/trunk/test/ELF/arm-gnu-ifunc.s Thu Dec 8 06:58:55 2016
@@ -24,51 +24,63 @@ _start:
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 @@ _start:
// 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
Modified: lld/trunk/test/ELF/gnu-ifunc-i386.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/gnu-ifunc-i386.s?rev=289045&r1=289044&r2=289045&view=diff
==============================================================================
--- lld/trunk/test/ELF/gnu-ifunc-i386.s (original)
+++ lld/trunk/test/ELF/gnu-ifunc-i386.s Thu Dec 8 06:58:55 2016
@@ -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
Added: lld/trunk/test/ELF/gnu-ifunc-plt.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/gnu-ifunc-plt.s?rev=289045&view=auto
==============================================================================
--- lld/trunk/test/ELF/gnu-ifunc-plt.s (added)
+++ lld/trunk/test/ELF/gnu-ifunc-plt.s Thu Dec 8 06:58:55 2016
@@ -0,0 +1,74 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/shared2-x86-64.s -o %t1.o
+// RUN: ld.lld %t1.o --shared -o %t.so
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+// RUN: ld.lld %t.so %t.o -o %tout
+// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
+// RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT
+// RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s
+// REQUIRES: x86
+
+// Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt
+// CHECK: Relocations [
+// CHECK-NEXT: Section (4) .rela.plt {
+// CHECK-NEXT: 0x203018 R_X86_64_JUMP_SLOT bar2 0x0
+// CHECK-NEXT: 0x203020 R_X86_64_JUMP_SLOT zed2 0x0
+// CHECK-NEXT: 0x203028 R_X86_64_IRELATIVE - 0x201000
+// CHECK-NEXT: 0x203030 R_X86_64_IRELATIVE - 0x201001
+
+// Check that .got.plt entries point back to PLT header
+// GOTPLT: Contents of section .got.plt:
+// GOTPLT-NEXT: 203000 00202000 00000000 00000000 00000000 . .............
+// GOTPLT-NEXT: 203010 00000000 00000000 36102000 00000000 ........6. .....
+// GOTPLT-NEXT: 203020 46102000 00000000 56102000 00000000 F. .....V. .....
+// GOTPLT-NEXT: 203030 66102000 00000000
+
+// Check that the PLTRELSZ tag includes the IRELATIVE relocations
+// CHECK: DynamicSection [
+// CHECK: 0x0000000000000002 PLTRELSZ 96 (bytes)
+
+// Check that a PLT header is written and the ifunc entries appear last
+// DISASM: Disassembly of section .text:
+// DISASM-NEXT: foo:
+// DISASM-NEXT: 201000: c3 retq
+// DISASM: bar:
+// DISASM-NEXT: 201001: c3 retq
+// DISASM: _start:
+// DISASM-NEXT: 201002: e8 49 00 00 00 callq 73
+// DISASM-NEXT: 201007: e8 54 00 00 00 callq 84
+// DISASM-NEXT: 20100c: e8 1f 00 00 00 callq 31
+// DISASM-NEXT: 201011: e8 2a 00 00 00 callq 42
+// DISASM-NEXT: Disassembly of section .plt:
+// DISASM-NEXT: .plt:
+// DISASM-NEXT: 201020: ff 35 e2 1f 00 00 pushq 8162(%rip)
+// DISASM-NEXT: 201026: ff 25 e4 1f 00 00 jmpq *8164(%rip)
+// DISASM-NEXT: 20102c: 0f 1f 40 00 nopl (%rax)
+// DISASM-NEXT: 201030: ff 25 e2 1f 00 00 jmpq *8162(%rip)
+// DISASM-NEXT: 201036: 68 00 00 00 00 pushq $0
+// DISASM-NEXT: 20103b: e9 e0 ff ff ff jmp -32 <.plt>
+// DISASM-NEXT: 201040: ff 25 da 1f 00 00 jmpq *8154(%rip)
+// DISASM-NEXT: 201046: 68 01 00 00 00 pushq $1
+// DISASM-NEXT: 20104b: e9 d0 ff ff ff jmp -48 <.plt>
+// DISASM-NEXT: 201050: ff 25 d2 1f 00 00 jmpq *8146(%rip)
+// DISASM-NEXT: 201056: 68 00 00 00 00 pushq $0
+// DISASM-NEXT: 20105b: e9 e0 ff ff ff jmp -32 <.plt+0x20>
+// DISASM-NEXT: 201060: ff 25 ca 1f 00 00 jmpq *8138(%rip)
+// DISASM-NEXT: 201066: 68 01 00 00 00 pushq $1
+// DISASM-NEXT: 20106b: e9 d0 ff ff ff jmp -48 <.plt+0x20>
+
+.text
+.type foo STT_GNU_IFUNC
+.globl foo
+foo:
+ ret
+
+.type bar STT_GNU_IFUNC
+.globl bar
+bar:
+ ret
+
+.globl _start
+_start:
+ call foo
+ call bar
+ call bar2
+ call zed2
Propchange: lld/trunk/test/ELF/gnu-ifunc-plt.s
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lld/trunk/test/ELF/gnu-ifunc-plt.s
------------------------------------------------------------------------------
svn:keywords = Rev Date Author URL Id
Added: lld/trunk/test/ELF/gnu-ifunc-shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/gnu-ifunc-shared.s?rev=289045&view=auto
==============================================================================
--- lld/trunk/test/ELF/gnu-ifunc-shared.s (added)
+++ lld/trunk/test/ELF/gnu-ifunc-shared.s Thu Dec 8 06:58:55 2016
@@ -0,0 +1,66 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+// RUN: ld.lld --shared -o %t.so %t.o
+// RUN: llvm-objdump -d %t.so | FileCheck %s --check-prefix=DISASM
+// RUN: llvm-readobj -r %t.so | FileCheck %s
+
+// Check that an IRELATIVE relocation is used for a non-preemptible ifunc
+// handler and a JUMP_SLOT is used for a preemptible ifunc
+// DISASM: Disassembly of section .text:
+// DISASM-NEXT: fct:
+// DISASM-NEXT: 1000: c3 retq
+// DISASM: fct2:
+// DISASM-NEXT: 1001: c3 retq
+// DISASM: f1:
+// DISASM-NEXT: 1002: e8 49 00 00 00 callq 73
+// DISASM-NEXT: 1007: e8 24 00 00 00 callq 36
+// DISASM-NEXT: 100c: e8 2f 00 00 00 callq 47
+// DISASM-NEXT: 1011: c3 retq
+// DISASM: f2:
+// DISASM-NEXT: 1012: c3 retq
+// DISASM-NEXT: Disassembly of section .plt:
+// DISASM-NEXT: .plt:
+// DISASM-NEXT: 1020: ff 35 e2 1f 00 00 pushq 8162(%rip)
+// DISASM-NEXT: 1026: ff 25 e4 1f 00 00 jmpq *8164(%rip)
+// DISASM-NEXT: 102c: 0f 1f 40 00 nopl (%rax)
+// DISASM-NEXT: 1030: ff 25 e2 1f 00 00 jmpq *8162(%rip)
+// DISASM-NEXT: 1036: 68 00 00 00 00 pushq $0
+// DISASM-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt>
+// DISASM-NEXT: 1040: ff 25 da 1f 00 00 jmpq *8154(%rip)
+// DISASM-NEXT: 1046: 68 01 00 00 00 pushq $1
+// DISASM-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt>
+// DISASM-NEXT: 1050: ff 25 d2 1f 00 00 jmpq *8146(%rip)
+// DISASM-NEXT: 1056: 68 00 00 00 00 pushq $0
+// DISASM-NEXT: 105b: e9 e0 ff ff ff jmp -32 <.plt+0x20>
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section (4) .rela.plt {
+// CHECK-NEXT: 0x3018 R_X86_64_JUMP_SLOT fct2 0x0
+// CHECK-NEXT: 0x3020 R_X86_64_JUMP_SLOT f2 0x0
+// CHECK-NEXT: 0x3028 R_X86_64_IRELATIVE - 0x1000
+
+ // Hidden expect IRELATIVE
+ .globl fct
+ .hidden fct
+ .type fct, STT_GNU_IFUNC
+fct:
+ ret
+
+ // Not hidden expect JUMP_SLOT
+ .globl fct2
+ .type fct2, STT_GNU_IFUNC
+fct2:
+ ret
+
+ .globl f1
+ .type f1, @function
+f1:
+ call fct
+ call fct2
+ call f2 at PLT
+ ret
+
+ .globl f2
+ .type f2, @function
+f2:
+ ret
Propchange: lld/trunk/test/ELF/gnu-ifunc-shared.s
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: lld/trunk/test/ELF/gnu-ifunc-shared.s
------------------------------------------------------------------------------
svn:keywords = Rev Date Author URL Id
Modified: lld/trunk/test/ELF/gnu-ifunc.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/gnu-ifunc.s?rev=289045&r1=289044&r2=289045&view=diff
==============================================================================
--- lld/trunk/test/ELF/gnu-ifunc.s (original)
+++ lld/trunk/test/ELF/gnu-ifunc.s Thu Dec 8 06:58:55 2016
@@ -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
More information about the llvm-commits
mailing list