[lld] r256144 - [ELF] - Implemented R_*_IRELATIVE relocations for x86, x64 targets.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 21 02:12:07 PST 2015
Author: grimar
Date: Mon Dec 21 04:12:06 2015
New Revision: 256144
URL: http://llvm.org/viewvc/llvm-project?rev=256144&view=rev
Log:
[ELF] - Implemented R_*_IRELATIVE relocations for x86, x64 targets.
This relocation is similar to R_*_RELATIVE except that the value used in this relocation is the program address returned by the function, which takes no arguments, at the address of
the result of the corresponding R_*_RELATIVE relocation as specified in the processor-specific ABI. The purpose of this relocation to avoid name lookup for locally defined STT_GNU_IFUNC symbols at load-time.
More info can be found in ifunc.txt from https://sites.google.com/site/x32abi/documents.
Differential revision: http://reviews.llvm.org/D15235
Added:
lld/trunk/test/ELF/gnu-ifunc-i386.s
lld/trunk/test/ELF/gnu-ifunc-nosym-i386.s
lld/trunk/test/ELF/gnu-ifunc-nosym.s
lld/trunk/test/ELF/gnu-ifunc.s
Modified:
lld/trunk/ELF/OutputSections.cpp
lld/trunk/ELF/OutputSections.h
lld/trunk/ELF/Symbols.h
lld/trunk/ELF/Target.cpp
lld/trunk/ELF/Target.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=256144&r1=256143&r2=256144&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Mon Dec 21 04:12:06 2015
@@ -269,7 +269,9 @@ template <class ELFT> void RelocationSec
unsigned Sym = CanBePreempted ? Body->DynamicSymbolTableIndex : 0;
unsigned Reloc;
- if (!CanBePreempted || IsDynRelative)
+ if (!CanBePreempted && Body && isGnuIFunc<ELFT>(*Body))
+ Reloc = Target->getIRelativeReloc();
+ else if (!CanBePreempted || IsDynRelative)
Reloc = Target->getRelativeReloc();
else if (LazyReloc)
Reloc = Target->getPltReloc();
@@ -320,7 +322,8 @@ template <class ELFT> unsigned Relocatio
}
template <class ELFT> void RelocationSection<ELFT>::finalize() {
- this->Header.sh_link = Out<ELFT>::DynSymTab->SectionIndex;
+ this->Header.sh_link = Static ? Out<ELFT>::SymTab->SectionIndex
+ : Out<ELFT>::DynSymTab->SectionIndex;
this->Header.sh_size = Relocs.size() * this->Header.sh_entsize;
}
Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=256144&r1=256143&r2=256144&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Mon Dec 21 04:12:06 2015
@@ -232,6 +232,8 @@ public:
bool hasRelocs() const { return !Relocs.empty(); }
bool isRela() const { return IsRela; }
+ bool Static = false;
+
private:
bool applyTlsDynamicReloc(SymbolBody *Body, uint32_t Type, Elf_Rel *P,
Elf_Rel *N);
Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=256144&r1=256143&r2=256144&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Mon Dec 21 04:12:06 2015
@@ -183,6 +183,11 @@ public:
// The content for _gp symbol for MIPS target.
static Elf_Sym MipsGp;
+ // __rel_iplt_start/__rel_iplt_end for signaling
+ // where R_[*]_IRELATIVE relocations do live.
+ static Elf_Sym RelaIpltStart;
+ static Elf_Sym RelaIpltEnd;
+
DefinedAbsolute(StringRef N, const Elf_Sym &Sym)
: Defined<ELFT>(Base::DefinedAbsoluteKind, N, Sym) {}
@@ -200,6 +205,12 @@ typename DefinedAbsolute<ELFT>::Elf_Sym
template <class ELFT>
typename DefinedAbsolute<ELFT>::Elf_Sym DefinedAbsolute<ELFT>::MipsGp;
+template <class ELFT>
+typename DefinedAbsolute<ELFT>::Elf_Sym DefinedAbsolute<ELFT>::RelaIpltStart;
+
+template <class ELFT>
+typename DefinedAbsolute<ELFT>::Elf_Sym DefinedAbsolute<ELFT>::RelaIpltEnd;
+
template <class ELFT> class DefinedCommon : public Defined<ELFT> {
typedef ELFSymbolBody<ELFT> Base;
typedef typename Base::Elf_Sym Elf_Sym;
Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=256144&r1=256143&r2=256144&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Mon Dec 21 04:12:06 2015
@@ -70,6 +70,17 @@ template <unsigned N> static void checkA
error("Improper alignment for relocation " + S);
}
+template <class ELFT> bool isGnuIFunc(const SymbolBody &S) {
+ if (auto *SS = dyn_cast<Defined<ELFT>>(&S))
+ return SS->Sym.getType() == STT_GNU_IFUNC;
+ return false;
+}
+
+template bool isGnuIFunc<ELF32LE>(const SymbolBody &S);
+template bool isGnuIFunc<ELF32BE>(const SymbolBody &S);
+template bool isGnuIFunc<ELF64LE>(const SymbolBody &S);
+template bool isGnuIFunc<ELF64BE>(const SymbolBody &S);
+
namespace {
class X86TargetInfo final : public TargetInfo {
public:
@@ -258,6 +269,7 @@ X86TargetInfo::X86TargetInfo() {
PCRelReloc = R_386_PC32;
GotReloc = R_386_GLOB_DAT;
PltReloc = R_386_JUMP_SLOT;
+ IRelativeReloc = R_386_IRELATIVE;
RelativeReloc = R_386_RELATIVE;
TlsGotReloc = R_386_TLS_TPOFF;
TlsGlobalDynamicReloc = R_386_TLS_GD;
@@ -357,7 +369,8 @@ bool X86TargetInfo::relocNeedsGot(uint32
}
bool X86TargetInfo::relocNeedsPlt(uint32_t Type, const SymbolBody &S) const {
- return (Type == R_386_PLT32 && canBePreempted(&S, true)) ||
+ return isGnuIFunc<ELF32LE>(S) ||
+ (Type == R_386_PLT32 && canBePreempted(&S, true)) ||
(Type == R_386_PC32 && S.isShared());
}
@@ -557,6 +570,7 @@ X86_64TargetInfo::X86_64TargetInfo() {
GotReloc = R_X86_64_GLOB_DAT;
PltReloc = R_X86_64_JUMP_SLOT;
RelativeReloc = R_X86_64_RELATIVE;
+ IRelativeReloc = R_X86_64_IRELATIVE;
TlsGotReloc = R_X86_64_TPOFF64;
TlsLocalDynamicReloc = R_X86_64_TLSLD;
TlsGlobalDynamicReloc = R_X86_64_TLSGD;
@@ -633,6 +647,8 @@ unsigned X86_64TargetInfo::getPltRefRelo
bool X86_64TargetInfo::relocNeedsPlt(uint32_t Type, const SymbolBody &S) const {
if (needsCopyRel(Type, S))
return false;
+ if (isGnuIFunc<ELF64LE>(S))
+ return true;
switch (Type) {
default:
Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=256144&r1=256143&r2=256144&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Mon Dec 21 04:12:06 2015
@@ -27,6 +27,7 @@ public:
unsigned getGotReloc() const { return GotReloc; }
unsigned getPltReloc() const { return PltReloc; }
unsigned getRelativeReloc() const { return RelativeReloc; }
+ unsigned getIRelativeReloc() const { return IRelativeReloc; }
bool isTlsLocalDynamicReloc(unsigned Type) const {
return Type == TlsLocalDynamicReloc;
}
@@ -88,6 +89,7 @@ protected:
unsigned GotReloc;
unsigned PltReloc;
unsigned RelativeReloc;
+ unsigned IRelativeReloc;
unsigned TlsGotReloc = 0;
unsigned TlsLocalDynamicReloc = 0;
unsigned TlsGlobalDynamicReloc = 0;
@@ -105,6 +107,8 @@ uint64_t getPPC64TocBase();
template <class ELFT>
typename llvm::object::ELFFile<ELFT>::uintX_t getMipsGpAddr();
+template <class ELFT> bool isGnuIFunc(const SymbolBody &S);
+
extern std::unique_ptr<TargetInfo> Target;
TargetInfo *createTarget();
}
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=256144&r1=256143&r2=256144&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Dec 21 04:12:06 2015
@@ -277,6 +277,15 @@ void Writer<ELFT>::scanRelocs(
}
}
+ // An STT_GNU_IFUNC symbol always uses a PLT entry, and all references
+ // to the symbol go through the PLT. This is true even for a local
+ // symbol, although local symbols normally do not require PLT entries.
+ if (Body && isGnuIFunc<ELFT>(*Body)) {
+ Body->setUsedInDynamicReloc();
+ Out<ELFT>::RelaPlt->addReloc({&C, &RI});
+ continue;
+ }
+
if (Config->EMachine == EM_MIPS && NeedsGot) {
// MIPS ABI has special rules to process GOT entries
// and doesn't require relocation entries for them.
@@ -578,6 +587,27 @@ static bool compareSections(OutputSectio
return std::distance(ItA, ItB) > 0;
}
+// A statically linked executable will have rel[a].plt section
+// to hold R_[*]_IRELATIVE relocations.
+// The multi-arch libc will use these symbols to locate
+// these relocations at program startup time.
+// If RelaPlt is empty then there is no reason to create this symbols.
+template <class ELFT>
+static void addIRelocMarkers(SymbolTable<ELFT> &Symtab, bool IsDynamic) {
+ if (IsDynamic || !Out<ELFT>::RelaPlt || !Out<ELFT>::RelaPlt->hasRelocs())
+ return;
+ bool IsRela = shouldUseRela<ELFT>();
+ auto AddMarker = [&](StringRef Name, typename Writer<ELFT>::Elf_Sym &Sym) {
+ if (SymbolBody *B = Symtab.find(Name))
+ if (B->isUndefined())
+ Symtab.addAbsolute(Name, Sym);
+ };
+ AddMarker(IsRela ? "__rela_iplt_start" : "__rel_iplt_start",
+ DefinedAbsolute<ELFT>::RelaIpltStart);
+ AddMarker(IsRela ? "__rela_iplt_end" : "__rel_iplt_end",
+ DefinedAbsolute<ELFT>::RelaIpltEnd);
+}
+
// Create output section objects and add them to OutputSections.
template <class ELFT> void Writer<ELFT>::createSections() {
// .interp needs to be on the first page in the output file.
@@ -720,6 +750,8 @@ template <class ELFT> void Writer<ELFT>:
}
}
+ addIRelocMarkers<ELFT>(Symtab, isOutputDynamic());
+
std::vector<DefinedCommon<ELFT> *> CommonSymbols;
std::vector<SharedSymbol<ELFT> *> SharedCopySymbols;
for (auto &P : Symtab.getSymbols()) {
@@ -762,8 +794,6 @@ template <class ELFT> void Writer<ELFT>:
OutputSections.push_back(Out<ELFT>::DynStrTab);
if (Out<ELFT>::RelaDyn->hasRelocs())
OutputSections.push_back(Out<ELFT>::RelaDyn);
- if (Out<ELFT>::RelaPlt && Out<ELFT>::RelaPlt->hasRelocs())
- OutputSections.push_back(Out<ELFT>::RelaPlt);
// This is a MIPS specific section to hold a space within the data segment
// of executable file which is pointed to by the DT_MIPS_RLD_MAP entry.
// See "Dynamic section" in Chapter 5 in the following document:
@@ -777,6 +807,13 @@ template <class ELFT> void Writer<ELFT>:
}
}
+ // We always need to add rel[a].plt to output if it has entries.
+ // Even during static linking it can contain R_[*]_IRELATIVE relocations.
+ if (Out<ELFT>::RelaPlt && Out<ELFT>::RelaPlt->hasRelocs()) {
+ OutputSections.push_back(Out<ELFT>::RelaPlt);
+ Out<ELFT>::RelaPlt->Static = !isOutputDynamic();
+ }
+
bool needsGot = !Out<ELFT>::Got->empty();
// We add the .got section to the result for dynamic MIPS target because
// its address and properties are mentioned in the .dynamic section.
@@ -997,6 +1034,15 @@ template <class ELFT> void Writer<ELFT>:
// point to the end of the data segment.
DefinedAbsolute<ELFT>::End.st_value = VA;
+ // Update __rel_iplt_start/__rel_iplt_end to wrap the
+ // rela.plt section.
+ if (Out<ELFT>::RelaPlt) {
+ uintX_t Start = Out<ELFT>::RelaPlt->getVA();
+ DefinedAbsolute<ELFT>::RelaIpltStart.st_value = Start;
+ DefinedAbsolute<ELFT>::RelaIpltEnd.st_value =
+ Start + Out<ELFT>::RelaPlt->getSize();
+ }
+
// Update MIPS _gp absolute symbol so that it points to the static data.
if (Config->EMachine == EM_MIPS)
DefinedAbsolute<ELFT>::MipsGp.st_value = getMipsGpAddr<ELFT>();
Added: lld/trunk/test/ELF/gnu-ifunc-i386.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/gnu-ifunc-i386.s?rev=256144&view=auto
==============================================================================
--- lld/trunk/test/ELF/gnu-ifunc-i386.s (added)
+++ lld/trunk/test/ELF/gnu-ifunc-i386.s Mon Dec 21 04:12:06 2015
@@ -0,0 +1,130 @@
+// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
+// RUN: ld.lld -static %t.o -o %tout
+// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
+// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s --check-prefix=CHECK
+// REQUIRES: x86
+
+// 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: [[RELA:.*]]
+// CHECK-NEXT: Offset: 0xD4
+// CHECK-NEXT: Size: 16
+// CHECK-NEXT: Link: 5
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 4
+// CHECK-NEXT: EntrySize: 8
+// CHECK-NEXT: }
+// CHECK: Relocations [
+// CHECK-NEXT: Section ({{.*}}) .rel.plt {
+// CHECK-NEXT: 0x1200C R_386_IRELATIVE
+// CHECK-NEXT: 0x12010 R_386_IRELATIVE
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+
+// CHECK: Symbols [
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name:
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: __rel_iplt_end
+// CHECK-NEXT: Value: 0x100E4
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Absolute
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: __rel_iplt_start
+// CHECK-NEXT: Value: [[RELA]]
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Absolute
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: _start
+// CHECK-NEXT: Value: 0x11002
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: bar
+// CHECK-NEXT: Value: 0x11001
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: GNU_IFunc
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: foo
+// CHECK-NEXT: Value: 0x11000
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: GNU_IFunc
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text
+// CHECK-NEXT: }
+// CHECK-NEXT:]
+
+// DISASM: Disassembly of section .text:
+// DISASM-NEXT: foo:
+// 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: 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>
+
+.text
+.type foo STT_GNU_IFUNC
+.globl foo
+.type foo, @function
+foo:
+ ret
+
+.type bar STT_GNU_IFUNC
+.globl bar
+.type bar, @function
+bar:
+ ret
+
+.globl _start
+_start:
+ call foo
+ call bar
+ movl $__rel_iplt_start,%edx
+ movl $__rel_iplt_end,%edx
Added: lld/trunk/test/ELF/gnu-ifunc-nosym-i386.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/gnu-ifunc-nosym-i386.s?rev=256144&view=auto
==============================================================================
--- lld/trunk/test/ELF/gnu-ifunc-nosym-i386.s (added)
+++ lld/trunk/test/ELF/gnu-ifunc-nosym-i386.s Mon Dec 21 04:12:06 2015
@@ -0,0 +1,29 @@
+// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
+// RUN: ld.lld -static %t.o -o %tout
+// RUN: llvm-readobj -symbols %tout | FileCheck %s
+// REQUIRES: x86
+
+// Check that no __rel_iplt_end/__rel_iplt_start
+// appear in symtab if there is no references to them.
+// CHECK: Symbols [
+// CHECK-NEXT-NOT: __rel_iplt_end
+// CHECK-NEXT-NOT: __rel_iplt_start
+// CHECK: ]
+
+.text
+.type foo STT_GNU_IFUNC
+.globl foo
+.type foo, @function
+foo:
+ ret
+
+.type bar STT_GNU_IFUNC
+.globl bar
+.type bar, @function
+bar:
+ ret
+
+.globl _start
+_start:
+ call foo
+ call bar
Added: lld/trunk/test/ELF/gnu-ifunc-nosym.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/gnu-ifunc-nosym.s?rev=256144&view=auto
==============================================================================
--- lld/trunk/test/ELF/gnu-ifunc-nosym.s (added)
+++ lld/trunk/test/ELF/gnu-ifunc-nosym.s Mon Dec 21 04:12:06 2015
@@ -0,0 +1,29 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld -static %t.o -o %tout
+// RUN: llvm-readobj -symbols %tout | FileCheck %s
+// REQUIRES: x86
+
+// Check that no __rela_iplt_end/__rela_iplt_start
+// appear in symtab if there is no references to them.
+// CHECK: Symbols [
+// CHECK-NEXT-NOT: __rela_iplt_end
+// CHECK-NEXT-NOT: __rela_iplt_start
+// CHECK: ]
+
+.text
+.type foo STT_GNU_IFUNC
+.globl foo
+.type foo, @function
+foo:
+ ret
+
+.type bar STT_GNU_IFUNC
+.globl bar
+.type bar, @function
+bar:
+ ret
+
+.globl _start
+_start:
+ call foo
+ call bar
Added: lld/trunk/test/ELF/gnu-ifunc.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/gnu-ifunc.s?rev=256144&view=auto
==============================================================================
--- lld/trunk/test/ELF/gnu-ifunc.s (added)
+++ lld/trunk/test/ELF/gnu-ifunc.s Mon Dec 21 04:12:06 2015
@@ -0,0 +1,126 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld -static %t.o -o %tout
+// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
+// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s --check-prefix=CHECK
+// REQUIRES: x86
+
+// CHECK: Sections [
+// CHECK: Section {
+// CHECK: Index: 1
+// CHECK-NEXT: Name: .rela.plt
+// CHECK-NEXT: Type: SHT_RELA
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: [[RELA:.*]]
+// CHECK-NEXT: Offset: 0x158
+// CHECK-NEXT: Size: 48
+// CHECK-NEXT: Link: 5
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 8
+// CHECK-NEXT: EntrySize: 24
+// CHECK-NEXT: }
+// CHECK: Relocations [
+// CHECK-NEXT: Section ({{.*}}) .rela.plt {
+// CHECK-NEXT: 0x12018 R_X86_64_IRELATIVE
+// CHECK-NEXT: 0x12020 R_X86_64_IRELATIVE
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+// CHECK: Symbols [
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name:
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: __rela_iplt_end
+// CHECK-NEXT: Value: 0x10188
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Absolute
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: __rela_iplt_start
+// CHECK-NEXT: Value: [[RELA]]
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Absolute
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: _start
+// CHECK-NEXT: Value: 0x11002
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: None
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: bar
+// CHECK-NEXT: Value: 0x11001
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: GNU_IFunc
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: foo
+// CHECK-NEXT: Value: 0x11000
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: GNU_IFunc
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+
+// DISASM: Disassembly of section .text:
+// DISASM-NEXT: foo:
+// DISASM-NEXT: 11000: c3 retq
+// DISASM: bar:
+// DISASM-NEXT: 11001: c3 retq
+// DISASM: _start:
+// DISASM-NEXT: 11002: e8 29 00 00 00 callq 41
+// DISASM-NEXT: 11007: e8 34 00 00 00 callq 52
+// DISASM-NEXT: 1100c: ba 58 01 01 00 movl $65880, %edx
+// DISASM-NEXT: 11011: ba 88 01 01 00 movl $65928, %edx
+// DISASM-NEXT: Disassembly of section .plt:
+// DISASM-NEXT: .plt:
+// DISASM-NEXT: 11020: ff 35 e2 0f 00 00 pushq 4066(%rip)
+// DISASM-NEXT: 11026: ff 25 e4 0f 00 00 jmpq *4068(%rip)
+// DISASM-NEXT: 1102c: 0f 1f 40 00 nopl (%rax)
+// DISASM-NEXT: 11030: ff 25 e2 0f 00 00 jmpq *4066(%rip)
+// DISASM-NEXT: 11036: 68 00 00 00 00 pushq $0
+// DISASM-NEXT: 1103b: e9 e0 ff ff ff jmp -32
+// DISASM-NEXT: 11040: ff 25 da 0f 00 00 jmpq *4058(%rip)
+// DISASM-NEXT: 11046: 68 01 00 00 00 pushq $1
+// DISASM-NEXT: 1104b: e9 d0 ff ff ff jmp -48
+
+.text
+.type foo STT_GNU_IFUNC
+.globl foo
+.type foo, @function
+foo:
+ ret
+
+.type bar STT_GNU_IFUNC
+.globl bar
+.type bar, @function
+bar:
+ ret
+
+.globl _start
+_start:
+ call foo
+ call bar
+ movl $__rela_iplt_start,%edx
+ movl $__rela_iplt_end,%edx
More information about the llvm-commits
mailing list