[lld] 891a865 - [ELF] Add IpltSection

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 17 00:06:11 PST 2019


Author: Fangrui Song
Date: 2019-12-17T00:06:04-08:00
New Revision: 891a8655ab563055e21c1f8a3907f9c43fe5c583

URL: https://github.com/llvm/llvm-project/commit/891a8655ab563055e21c1f8a3907f9c43fe5c583
DIFF: https://github.com/llvm/llvm-project/commit/891a8655ab563055e21c1f8a3907f9c43fe5c583.diff

LOG: [ELF] Add IpltSection

PltSection is used by both PLT and IPLT. The PLT section may have a
header while the IPLT section does not. Split off IpltSection from
PltSection to be clearer.

Unlike other targets, PPC64 cannot use the same code sequence for PLT
and IPLT. This helps make a future PPC64 patch (D71509) more isolated.

On EM_386 and EM_X86_64, when PLT is empty while IPLT is not, currently
we are inconsistent whether the PLT header is conceptually attached to
in.plt or in.iplt .  Consistently attach the header to in.plt can make
the -z retpolineplt logic simpler. It also makes `jmp` point to an
aesthetically better place for non-retpolineplt cases.

Reviewed By: grimar, ruiu

Differential Revision: https://reviews.llvm.org/D71519

Added: 
    

Modified: 
    lld/ELF/Arch/AArch64.cpp
    lld/ELF/Arch/ARM.cpp
    lld/ELF/Arch/PPC.cpp
    lld/ELF/Arch/PPC64.cpp
    lld/ELF/Arch/RISCV.cpp
    lld/ELF/Arch/X86.cpp
    lld/ELF/Arch/X86_64.cpp
    lld/ELF/Relocations.cpp
    lld/ELF/Symbols.cpp
    lld/ELF/SyntheticSections.cpp
    lld/ELF/SyntheticSections.h
    lld/ELF/Target.h
    lld/ELF/Writer.cpp
    lld/test/ELF/gnu-ifunc-i386.s
    lld/test/ELF/gnu-ifunc-plt-i386.s
    lld/test/ELF/gnu-ifunc-plt.s
    lld/test/ELF/gnu-ifunc-shared.s
    lld/test/ELF/gnu-ifunc.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 6697ee394bad..8d04c002ec70 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -64,8 +64,9 @@ AArch64::AArch64() {
   symbolicRel = R_AARCH64_ABS64;
   tlsDescRel = R_AARCH64_TLSDESC;
   tlsGotRel = R_AARCH64_TLS_TPREL64;
-  pltEntrySize = 16;
   pltHeaderSize = 32;
+  pltEntrySize = 16;
+  ipltEntrySize = 16;
   defaultMaxPageSize = 65536;
 
   // Align to the 2 MiB page size (known as a superpage or huge page).
@@ -590,8 +591,10 @@ AArch64BtiPac::AArch64BtiPac() {
   btiEntry = btiHeader && !config->shared;
   pacEntry = (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_PAC);
 
-  if (btiEntry || pacEntry)
+  if (btiEntry || pacEntry) {
     pltEntrySize = 24;
+    ipltEntrySize = 24;
+  }
 }
 
 void AArch64BtiPac::writePltHeader(uint8_t *buf) const {

diff  --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index d4df0272e9b2..7172ee0051f6 100644
--- a/lld/ELF/Arch/ARM.cpp
+++ b/lld/ELF/Arch/ARM.cpp
@@ -59,8 +59,9 @@ ARM::ARM() {
   tlsModuleIndexRel = R_ARM_TLS_DTPMOD32;
   tlsOffsetRel = R_ARM_TLS_DTPOFF32;
   gotBaseSymInGotPlt = false;
-  pltEntrySize = 16;
   pltHeaderSize = 32;
+  pltEntrySize = 16;
+  ipltEntrySize = 16;
   trapInstr = {0xd4, 0xd4, 0xd4, 0xd4};
   needsThunks = true;
 }

diff  --git a/lld/ELF/Arch/PPC.cpp b/lld/ELF/Arch/PPC.cpp
index be8ca30a16da..9b2722debc08 100644
--- a/lld/ELF/Arch/PPC.cpp
+++ b/lld/ELF/Arch/PPC.cpp
@@ -144,6 +144,7 @@ PPC::PPC() {
   gotPltHeaderEntriesNum = 0;
   pltHeaderSize = 64; // size of PLTresolve in .glink
   pltEntrySize = 4;
+  ipltEntrySize = 4;
 
   needsThunks = true;
 

diff  --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp
index e9a1c535fa4d..9043226b33b5 100644
--- a/lld/ELF/Arch/PPC64.cpp
+++ b/lld/ELF/Arch/PPC64.cpp
@@ -296,11 +296,12 @@ PPC64::PPC64() {
   relativeRel = R_PPC64_RELATIVE;
   iRelativeRel = R_PPC64_IRELATIVE;
   symbolicRel = R_PPC64_ADDR64;
+  pltHeaderSize = 60;
   pltEntrySize = 4;
+  ipltEntrySize = 4;
   gotBaseSymInGotPlt = false;
   gotHeaderEntriesNum = 1;
   gotPltHeaderEntriesNum = 2;
-  pltHeaderSize = 60;
   needsThunks = true;
 
   tlsModuleIndexRel = R_PPC64_DTPMOD64;

diff  --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 4b5006e6fbc8..5877faae7e29 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -95,8 +95,9 @@ RISCV::RISCV() {
   // .got.plt[0] = _dl_runtime_resolve, .got.plt[1] = link_map
   gotPltHeaderEntriesNum = 2;
 
-  pltEntrySize = 16;
   pltHeaderSize = 32;
+  pltEntrySize = 16;
+  ipltEntrySize = 16;
 }
 
 static uint32_t getEFlags(InputFile *f) {

diff  --git a/lld/ELF/Arch/X86.cpp b/lld/ELF/Arch/X86.cpp
index 31b3b0a45f2c..8d54e7e6b3f3 100644
--- a/lld/ELF/Arch/X86.cpp
+++ b/lld/ELF/Arch/X86.cpp
@@ -57,8 +57,9 @@ X86::X86() {
   tlsGotRel = R_386_TLS_TPOFF;
   tlsModuleIndexRel = R_386_TLS_DTPMOD32;
   tlsOffsetRel = R_386_TLS_DTPOFF32;
-  pltEntrySize = 16;
   pltHeaderSize = 16;
+  pltEntrySize = 16;
+  ipltEntrySize = 16;
   trapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
 
   // Align to the non-PAE large page size (known as a superpage or huge page).
@@ -235,7 +236,7 @@ void X86::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
   }
 
   write32le(buf + 7, relOff);
-  write32le(buf + 12, -pltHeaderSize - pltEntrySize * index - 16);
+  write32le(buf + 12, in.plt->getVA() - pltEntryAddr - 16);
 }
 
 int64_t X86::getImplicitAddend(const uint8_t *buf, RelType type) const {
@@ -432,6 +433,7 @@ class RetpolineNoPic : public X86 {
 RetpolinePic::RetpolinePic() {
   pltHeaderSize = 48;
   pltEntrySize = 32;
+  ipltEntrySize = 32;
 }
 
 void RetpolinePic::writeGotPlt(uint8_t *buf, const Symbol &s) const {
@@ -474,7 +476,7 @@ void RetpolinePic::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
   memcpy(buf, insn, sizeof(insn));
 
   uint32_t ebx = in.gotPlt->getVA();
-  unsigned off = pltHeaderSize + pltEntrySize * index;
+  unsigned off = pltEntryAddr - in.plt->getVA();
   write32le(buf + 3, gotPltEntryAddr - ebx);
   write32le(buf + 8, -off - 12 + 32);
   write32le(buf + 13, -off - 17 + 18);
@@ -485,6 +487,7 @@ void RetpolinePic::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
 RetpolineNoPic::RetpolineNoPic() {
   pltHeaderSize = 48;
   pltEntrySize = 32;
+  ipltEntrySize = 32;
 }
 
 void RetpolineNoPic::writeGotPlt(uint8_t *buf, const Symbol &s) const {
@@ -532,7 +535,7 @@ void RetpolineNoPic::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
   };
   memcpy(buf, insn, sizeof(insn));
 
-  unsigned off = pltHeaderSize + pltEntrySize * index;
+  unsigned off = pltEntryAddr - in.plt->getVA();
   write32le(buf + 2, gotPltEntryAddr);
   write32le(buf + 7, -off - 11 + 32);
   write32le(buf + 12, -off - 16 + 17);

diff  --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp
index 459fd1100ab6..d2c48284b785 100644
--- a/lld/ELF/Arch/X86_64.cpp
+++ b/lld/ELF/Arch/X86_64.cpp
@@ -61,8 +61,9 @@ X86_64::X86_64() {
   tlsGotRel = R_X86_64_TPOFF64;
   tlsModuleIndexRel = R_X86_64_DTPMOD64;
   tlsOffsetRel = R_X86_64_DTPOFF64;
-  pltEntrySize = 16;
   pltHeaderSize = 16;
+  pltEntrySize = 16;
+  ipltEntrySize = 16;
   trapInstr = {0xcc, 0xcc, 0xcc, 0xcc}; // 0xcc = INT3
 
   // Align to the large page size (known as a superpage or huge page).
@@ -166,7 +167,7 @@ void X86_64::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
 
   write32le(buf + 2, gotPltEntryAddr - pltEntryAddr - 6);
   write32le(buf + 7, index);
-  write32le(buf + 12, -pltHeaderSize - pltEntrySize * index - 16);
+  write32le(buf + 12, in.plt->getVA() - pltEntryAddr - 16);
 }
 
 RelType X86_64::getDynRel(RelType type) const {
@@ -599,6 +600,7 @@ class RetpolineZNow : public X86_64 {
 Retpoline::Retpoline() {
   pltHeaderSize = 48;
   pltEntrySize = 32;
+  ipltEntrySize = 32;
 }
 
 void Retpoline::writeGotPlt(uint8_t *buf, const Symbol &s) const {
@@ -639,7 +641,7 @@ void Retpoline::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
   };
   memcpy(buf, insn, sizeof(insn));
 
-  uint64_t off = pltHeaderSize + pltEntrySize * index;
+  uint64_t off = pltEntryAddr - in.plt->getVA();
 
   write32le(buf + 3, gotPltEntryAddr - pltEntryAddr - 7);
   write32le(buf + 8, -off - 12 + 32);
@@ -651,6 +653,7 @@ void Retpoline::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
 RetpolineZNow::RetpolineZNow() {
   pltHeaderSize = 32;
   pltEntrySize = 16;
+  ipltEntrySize = 16;
 }
 
 void RetpolineZNow::writePltHeader(uint8_t *buf) const {
@@ -679,7 +682,7 @@ void RetpolineZNow::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
   memcpy(buf, insn, sizeof(insn));
 
   write32le(buf + 3, gotPltEntryAddr - pltEntryAddr - 7);
-  write32le(buf + 8, -pltHeaderSize - pltEntrySize * index - 12);
+  write32le(buf + 8, in.plt->getVA() - pltEntryAddr - 12);
 }
 
 static TargetInfo *getTargetInfo() {

diff  --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 31b2a148e4c1..78bafe53023e 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1011,7 +1011,7 @@ static void addRelativeReloc(InputSectionBase *isec, uint64_t offsetInSec,
                          expr, type);
 }
 
-template <class GotPltSection>
+template <class PltSection, class GotPltSection>
 static void addPltEntry(PltSection *plt, GotPltSection *gotPlt,
                         RelocationBaseSection *rel, RelType type, Symbol &sym) {
   plt->addEntry(sym);
@@ -1415,13 +1415,9 @@ static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i,
     } else if (!needsPlt(expr)) {
       // Make the ifunc's PLT entry canonical by changing the value of its
       // symbol to redirect all references to point to it.
-      unsigned entryOffset = sym.pltIndex * target->pltEntrySize;
-      if (config->zRetpolineplt)
-        entryOffset += target->pltHeaderSize;
-
       auto &d = cast<Defined>(sym);
       d.section = in.iplt;
-      d.value = entryOffset;
+      d.value = sym.pltIndex * target->ipltEntrySize;
       d.size = 0;
       // It's important to set the symbol type here so that dynamic loaders
       // don't try to call the PLT as if it were an ifunc resolver.

diff  --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index f81e73e5091b..365be6f7802f 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -163,9 +163,11 @@ uint64_t Symbol::getGotPltOffset() const {
 }
 
 uint64_t Symbol::getPltVA() const {
-  PltSection *plt = isInIplt ? in.iplt : in.plt;
-  uint64_t outVA =
-      plt->getVA() + plt->headerSize + pltIndex * target->pltEntrySize;
+  uint64_t outVA = isInIplt
+                       ? in.iplt->getVA() + pltIndex * target->ipltEntrySize
+                       : in.plt->getVA() + in.plt->headerSize +
+                             pltIndex * target->pltEntrySize;
+
   // While linking microMIPS code PLT code are always microMIPS
   // code. Set the less-significant bit to track that fact.
   // See detailed comment in the `getSymVA` function.

diff  --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 46529ebfbf61..4cb398bdc1ca 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -2445,14 +2445,13 @@ void HashTableSection::writeTo(uint8_t *buf) {
 
 // On PowerPC64 the lazy symbol resolvers go into the `global linkage table`
 // in the .glink section, rather then the typical .plt section.
-PltSection::PltSection(bool isIplt)
-    : SyntheticSection(
-          SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16,
-          (config->emachine == EM_PPC || config->emachine == EM_PPC64)
-              ? ".glink"
-              : ".plt"),
-      headerSize(!isIplt || config->zRetpolineplt ? target->pltHeaderSize : 0),
-      isIplt(isIplt) {
+PltSection::PltSection()
+    : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, ".plt"),
+      headerSize(target->pltHeaderSize) {
+  if (config->emachine == EM_PPC || config->emachine == EM_PPC64) {
+    name = ".glink";
+  }
+
   // The PLT needs to be writable on SPARC as the dynamic linker will
   // modify the instructions in the PLT entries.
   if (config->emachine == EM_SPARCV9)
@@ -2465,10 +2464,9 @@ void PltSection::writeTo(uint8_t *buf) {
     return;
   }
 
-  // At beginning of PLT or retpoline IPLT, we have code to call the dynamic
+  // At beginning of PLT, we have code to call the dynamic
   // linker to resolve dynsyms at runtime. Write such code.
-  if (headerSize)
-    target->writePltHeader(buf);
+  target->writePltHeader(buf);
   size_t off = headerSize;
 
   for (size_t i = 0, e = entries.size(); i != e; ++i) {
@@ -2489,12 +2487,15 @@ size_t PltSection::getSize() const {
   return headerSize + entries.size() * target->pltEntrySize;
 }
 
-// Some architectures such as additional symbols in the PLT section. For
-// example ARM uses mapping symbols to aid disassembly
+bool PltSection::isNeeded() const {
+  // For -z retpolineplt, .iplt needs the .plt header.
+  return !entries.empty() || (config->zRetpolineplt && in.iplt->isNeeded());
+}
+
+// Used by ARM to add mapping symbols in the PLT section, which aid
+// disassembly.
 void PltSection::addSymbols() {
-  // The PLT may have symbols defined for the Header, the IPLT has no header
-  if (!isIplt)
-    target->addPltHeaderSymbols(*this);
+  target->addPltHeaderSymbols(*this);
 
   size_t off = headerSize;
   for (size_t i = 0; i < entries.size(); ++i) {
@@ -2503,6 +2504,40 @@ void PltSection::addSymbols() {
   }
 }
 
+IpltSection::IpltSection()
+    : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, ".plt") {
+  if (config->emachine == EM_PPC || config->emachine == EM_PPC64) {
+    name = ".glink";
+  }
+}
+
+void IpltSection::writeTo(uint8_t *buf) {
+  uint32_t off = 0;
+  for (const Symbol *sym : entries) {
+    target->writeIplt(buf + off, sym->getGotPltVA(), getVA() + off,
+                      sym->pltIndex);
+    off += target->ipltEntrySize;
+  }
+}
+
+size_t IpltSection::getSize() const {
+  return entries.size() * target->ipltEntrySize;
+}
+
+void IpltSection::addEntry(Symbol &sym) {
+  sym.pltIndex = entries.size();
+  entries.push_back(&sym);
+}
+
+// ARM uses mapping symbols to aid disassembly.
+void IpltSection::addSymbols() {
+  size_t off = 0;
+  for (size_t i = 0, e = entries.size(); i != e; ++i) {
+    target->addPltSymbols(*this, off);
+    off += target->pltEntrySize;
+  }
+}
+
 // The string hash function for .gdb_index.
 static uint32_t computeGdbHash(StringRef s) {
   uint32_t h = 0;

diff  --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 601f66057b62..83446ce45e65 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -662,16 +662,15 @@ class HashTableSection final : public SyntheticSection {
   size_t size = 0;
 };
 
-// The PltSection is used for both the Plt and Iplt. The former usually has a
-// header as its first entry that is used at run-time to resolve lazy binding.
-// The latter is used for GNU Ifunc symbols, that will be subject to a
-// Target->IRelativeRel.
+// Used for PLT entries. It usually has a PLT header for lazy binding. Each PLT
+// entry is associated with a JUMP_SLOT relocation, which may be resolved lazily
+// at runtime.
 class PltSection : public SyntheticSection {
 public:
-  PltSection(bool isIplt);
+  PltSection();
   void writeTo(uint8_t *buf) override;
   size_t getSize() const override;
-  bool isNeeded() const override { return !entries.empty(); }
+  bool isNeeded() const override;
   void addSymbols();
   void addEntry(Symbol &sym);
 
@@ -679,7 +678,22 @@ class PltSection : public SyntheticSection {
 
 private:
   std::vector<const Symbol *> entries;
-  bool isIplt;
+};
+
+// Used for non-preemptible ifuncs. It does not have a header. Each entry is
+// associated with an IRELATIVE relocation, which will be resolved eagerly at
+// runtime. PltSection cannot can only contain entries associated with JUMP_SLOT
+// relocations, so IPLT entries are in a separate section.
+class IpltSection final : public SyntheticSection {
+  std::vector<const Symbol *> entries;
+
+public:
+  IpltSection();
+  void writeTo(uint8_t *buf) override;
+  size_t getSize() const override;
+  bool isNeeded() const override { return !entries.empty(); }
+  void addSymbols();
+  void addEntry(Symbol &sym);
 };
 
 class GdbIndexSection final : public SyntheticSection {
@@ -1162,7 +1176,7 @@ struct InStruct {
   SyntheticSection *partEnd;
   SyntheticSection *partIndex;
   PltSection *plt;
-  PltSection *iplt;
+  IpltSection *iplt;
   PPC32Got2Section *ppc32Got2;
   RelocationBaseSection *relaPlt;
   RelocationBaseSection *relaIplt;

diff  --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index 8abf58045497..2b0b09c11de2 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -43,6 +43,11 @@ class TargetInfo {
 
   virtual void writePlt(uint8_t *buf, uint64_t gotEntryAddr,
                         uint64_t pltEntryAddr, int32_t index) const {}
+  virtual void writeIplt(uint8_t *buf, uint64_t gotEntryAddr,
+                         uint64_t pltEntryAddr, int32_t index) const {
+    // All but PPC64 use the same format for .plt and .iplt entries.
+    writePlt(buf, gotEntryAddr, pltEntryAddr, index);
+  }
   virtual void addPltHeaderSymbols(InputSection &isec) const {}
   virtual void addPltSymbols(InputSection &isec, uint64_t off) const {}
 
@@ -101,6 +106,7 @@ class TargetInfo {
   RelType tlsOffsetRel;
   unsigned pltEntrySize;
   unsigned pltHeaderSize;
+  unsigned ipltEntrySize;
 
   // At least on x86_64 positions 1 and 2 are used by the first plt entry
   // to support lazy loading.

diff  --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 38009bdd9aa3..c0ad33473747 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -515,9 +515,9 @@ template <class ELFT> void createSyntheticSections() {
       /*sort=*/false);
   add(in.relaIplt);
 
-  in.plt = make<PltSection>(false);
+  in.plt = make<PltSection>();
   add(in.plt);
-  in.iplt = make<PltSection>(true);
+  in.iplt = make<IpltSection>();
   add(in.iplt);
 
   if (config->andFeatures)

diff  --git a/lld/test/ELF/gnu-ifunc-i386.s b/lld/test/ELF/gnu-ifunc-i386.s
index 6d35059221f9..8b823475e7cc 100644
--- a/lld/test/ELF/gnu-ifunc-i386.s
+++ b/lld/test/ELF/gnu-ifunc-i386.s
@@ -123,11 +123,11 @@
 // DISASM-NEXT: foo:
 // DISASM-NEXT:   401100:       jmpl *4202784
 // DISASM-NEXT:                 pushl $0
-// DISASM-NEXT:                 jmp -32 <_start+0xa>
+// DISASM-NEXT:                 jmp -16 <foo>
 // DISASM:      bar:
 // DISASM-NEXT:   401110:       jmpl *4202788
 // DISASM-NEXT:                 pushl $8
-// DISASM-NEXT:                 jmp -48 <_start+0xa>
+// DISASM-NEXT:                 jmp -32 <foo>
 
 .text
 .type foo STT_GNU_IFUNC

diff  --git a/lld/test/ELF/gnu-ifunc-plt-i386.s b/lld/test/ELF/gnu-ifunc-plt-i386.s
index 180ecc310b99..4c1982497f82 100644
--- a/lld/test/ELF/gnu-ifunc-plt-i386.s
+++ b/lld/test/ELF/gnu-ifunc-plt-i386.s
@@ -63,10 +63,10 @@
 // DISASM-NEXT:                  jmp     -48 <.plt>
 // DISASM-NEXT:                  jmpl    *4207276
 // DISASM-NEXT:                  pushl   $0
-// DISASM-NEXT:                  jmp     -32 <zed2 at plt>
+// DISASM-NEXT:                  jmp     -64 <.plt>
 // DISASM-NEXT:                  jmpl    *4207280
 // DISASM-NEXT:                  pushl   $8
-// DISASM-NEXT:                  jmp     -48 <zed2 at plt>
+// DISASM-NEXT:                  jmp     -80 <.plt>
 
 .text
 .type foo STT_GNU_IFUNC

diff  --git a/lld/test/ELF/gnu-ifunc-plt.s b/lld/test/ELF/gnu-ifunc-plt.s
index 0610d850759f..c359a1ddca73 100644
--- a/lld/test/ELF/gnu-ifunc-plt.s
+++ b/lld/test/ELF/gnu-ifunc-plt.s
@@ -64,10 +64,10 @@
 // DISASM-NEXT:   20131b:       jmp     -48 <.plt>
 // DISASM-NEXT:   201320:       jmpq    *8498(%rip)
 // DISASM-NEXT:   201326:       pushq   $0
-// DISASM-NEXT:   20132b:       jmp     -32 <zed2 at plt>
+// DISASM-NEXT:   20132b:       jmp     -64 <.plt>
 // DISASM-NEXT:   201330:       jmpq    *8490(%rip)
 // DISASM-NEXT:   201336:       pushq   $1
-// DISASM-NEXT:   20133b:       jmp     -48 <zed2 at plt>
+// DISASM-NEXT:   20133b:       jmp     -80 <.plt>
 
 .text
 .type foo STT_GNU_IFUNC

diff  --git a/lld/test/ELF/gnu-ifunc-shared.s b/lld/test/ELF/gnu-ifunc-shared.s
index d0e70100b6fd..b630776be7ac 100644
--- a/lld/test/ELF/gnu-ifunc-shared.s
+++ b/lld/test/ELF/gnu-ifunc-shared.s
@@ -41,7 +41,7 @@
 // DISASM-NEXT:     134b:       jmp     -48 <.plt>
 // DISASM-NEXT:     1350:       jmpq    *8466(%rip)
 // DISASM-NEXT:     1356:       pushq   $0
-// DISASM-NEXT:     135b:       jmp     -32 <f2 at plt>
+// DISASM-NEXT:     135b:       jmp     -64 <.plt>
 
 // CHECK: Relocations [
 // CHECK-NEXT:   Section (5) .rela.dyn {

diff  --git a/lld/test/ELF/gnu-ifunc.s b/lld/test/ELF/gnu-ifunc.s
index 97e8e9c5386d..e5b2af422492 100644
--- a/lld/test/ELF/gnu-ifunc.s
+++ b/lld/test/ELF/gnu-ifunc.s
@@ -107,10 +107,10 @@
 // DISASM-NEXT: .plt:
 // DISASM-NEXT:  2011b0: {{.*}} jmpq *4122(%rip)
 // DISASM-NEXT:  2011b6: {{.*}} pushq $0
-// DISASM-NEXT:  2011bb: {{.*}} jmp -32 <_start+0x16>
+// DISASM-NEXT:  2011bb: {{.*}} jmp -16 <.plt>
 // DISASM-NEXT:  2011c0: {{.*}} jmpq *4114(%rip)
 // DISASM-NEXT:  2011c6: {{.*}} pushq $1
-// DISASM-NEXT:  2011cb: {{.*}} jmp -48 <_start+0x16>
+// DISASM-NEXT:  2011cb: {{.*}} jmp -32 <.plt>
 
 .text
 .type foo STT_GNU_IFUNC


        


More information about the llvm-commits mailing list