[lld] ea15b86 - Revert D114783 [ELF] Split scanRelocations into scanRelocations/postScanRelocations

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 14 14:33:55 PST 2021


Author: Fangrui Song
Date: 2021-12-14T14:33:50-08:00
New Revision: ea15b862d77ed0f163d97735f45b7683ad86ffc9

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

LOG: Revert D114783 [ELF] Split scanRelocations into scanRelocations/postScanRelocations

May cause a failure for non-preemptible `bcmp` in a glibc -static link.

Added: 
    

Modified: 
    lld/ELF/Arch/AArch64.cpp
    lld/ELF/MapFile.cpp
    lld/ELF/Relocations.cpp
    lld/ELF/Relocations.h
    lld/ELF/Symbols.cpp
    lld/ELF/Symbols.h
    lld/ELF/SyntheticSections.cpp
    lld/ELF/Writer.cpp
    lld/test/ELF/aarch64-ifunc-bti.s
    lld/test/ELF/aarch64-thunk-pi.s
    lld/test/ELF/arm-branch-undef-weak-plt-thunk.s
    lld/test/ELF/arm-gnu-ifunc.s
    lld/test/ELF/arm-thumb-interwork-thunk.s
    lld/test/ELF/bsymbolic.s
    lld/test/ELF/gnu-ifunc-i386.s
    lld/test/ELF/ppc32-canonical-plt.s
    lld/test/ELF/ppc32-ifunc-nonpreemptible-pic.s
    lld/test/ELF/ppc32-reloc-got.s
    lld/test/ELF/ppc64-ifunc.s
    lld/test/ELF/relocation-nocopy.s
    lld/test/ELF/riscv-reloc-got.s
    lld/test/ELF/symver.s
    lld/test/ELF/version-script-symver.s
    lld/test/ELF/wrap-no-real.s
    lld/test/ELF/wrap-plt.s
    lld/test/ELF/x86-64-gotpc-relax-und-dso.s
    lld/test/ELF/x86-64-plt.s
    lld/test/ELF/x86-x32-plt.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index ca3a6aa58dc5b..b57fd61b65cca 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -690,11 +690,11 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym,
   };
   const uint8_t nopData[] = { 0x1f, 0x20, 0x03, 0xd5 }; // nop
 
-  // needsCopy indicates a non-ifunc canonical PLT entry whose address may
+  // needsPltAddr indicates a non-ifunc canonical PLT entry whose address may
   // escape to shared objects. isInIplt indicates a non-preemptible ifunc. Its
   // address may escape if referenced by a direct relocation. The condition is
   // conservative.
-  bool hasBti = btiHeader && (sym.needsCopy || sym.isInIplt);
+  bool hasBti = btiHeader && (sym.needsPltAddr || sym.isInIplt);
   if (hasBti) {
     memcpy(buf, btiData, sizeof(btiData));
     buf += sizeof(btiData);

diff  --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp
index 2759835275388..b898dfda8a797 100644
--- a/lld/ELF/MapFile.cpp
+++ b/lld/ELF/MapFile.cpp
@@ -58,7 +58,7 @@ static std::vector<Defined *> getSymbols() {
     for (Symbol *b : file->getSymbols())
       if (auto *dr = dyn_cast<Defined>(b))
         if (!dr->isSection() && dr->section && dr->section->isLive() &&
-            (dr->file == file || dr->needsCopy || dr->section->bss))
+            (dr->file == file || dr->needsPltAddr || dr->section->bss))
           v.push_back(dr);
   return v;
 }

diff  --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index fe1e7bfdc350a..7a6fda1e41da4 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -307,8 +307,6 @@ static void replaceWithDefined(Symbol &sym, SectionBase *sec, uint64_t value,
   sym.verdefIndex = old.verdefIndex;
   sym.exportDynamic = true;
   sym.isUsedInRegularObj = true;
-  // A copy relocated alias may need a GOT entry.
-  sym.needsGot = old.needsGot;
 }
 
 // Reserve space in .bss or .bss.rel.ro for copy relocation.
@@ -353,7 +351,7 @@ static void replaceWithDefined(Symbol &sym, SectionBase *sec, uint64_t value,
 // to the variable in .bss. This kind of issue is sometimes very hard to
 // debug. What's a solution? Instead of exporting a variable V from a DSO,
 // define an accessor getV().
-template <class ELFT> static void addCopyRelSymbolImpl(SharedSymbol &ss) {
+template <class ELFT> static void addCopyRelSymbol(SharedSymbol &ss) {
   // Copy relocation against zero-sized symbol doesn't make sense.
   uint64_t symSize = ss.getSize();
   if (symSize == 0 || ss.alignment == 0)
@@ -384,26 +382,6 @@ template <class ELFT> static void addCopyRelSymbolImpl(SharedSymbol &ss) {
   mainPart->relaDyn->addSymbolReloc(target->copyRel, sec, 0, ss);
 }
 
-static void addCopyRelSymbol(SharedSymbol &ss) {
-  const SharedFile &file = ss.getFile();
-  switch (file.ekind) {
-  case ELF32LEKind:
-    addCopyRelSymbolImpl<ELF32LE>(ss);
-    break;
-  case ELF32BEKind:
-    addCopyRelSymbolImpl<ELF32BE>(ss);
-    break;
-  case ELF64LEKind:
-    addCopyRelSymbolImpl<ELF64LE>(ss);
-    break;
-  case ELF64BEKind:
-    addCopyRelSymbolImpl<ELF64BE>(ss);
-    break;
-  default:
-    llvm_unreachable("");
-  }
-}
-
 // MIPS has an odd notion of "paired" relocations to calculate addends.
 // For example, if a relocation is of R_MIPS_HI16, there must be a
 // R_MIPS_LO16 relocation after that, and an addend is calculated using
@@ -1067,7 +1045,7 @@ static void processRelocAux(InputSectionBase &sec, RelExpr expr, RelType type,
                 " against symbol '" + toString(*ss) +
                 "'; recompile with -fPIC or remove '-z nocopyreloc'" +
                 getLocation(sec, sym, offset));
-        sym.needsCopy = true;
+        addCopyRelSymbol<ELFT>(*ss);
       }
       sec.relocations.push_back({expr, type, offset, addend, &sym});
       return;
@@ -1105,8 +1083,20 @@ static void processRelocAux(InputSectionBase &sec, RelExpr expr, RelType type,
         errorOrWarn("symbol '" + toString(sym) +
                     "' cannot be preempted; recompile with -fPIE" +
                     getLocation(sec, sym, offset));
-      sym.needsCopy = true;
-      sym.needsPlt = true;
+      if (!sym.isInPlt())
+        addPltEntry(in.plt, in.gotPlt, in.relaPlt, target->pltRel, sym);
+      if (!sym.isDefined()) {
+        replaceWithDefined(
+            sym, in.plt,
+            target->pltHeaderSize + target->pltEntrySize * sym.pltIndex, 0);
+        if (config->emachine == EM_PPC) {
+          // PPC32 canonical PLT entries are at the beginning of .glink
+          cast<Defined>(sym).value = in.plt->headerSize;
+          in.plt->headerSize += 16;
+          cast<PPC32GlinkSection>(in.plt)->canonical_plts.push_back(&sym);
+        }
+      }
+      sym.needsPltAddr = true;
       sec.relocations.push_back({expr, type, offset, addend, &sym});
       return;
     }
@@ -1435,23 +1425,116 @@ static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i,
     return;
   }
 
-  if (needsGot(expr)) {
-    if (config->emachine == EM_MIPS) {
-      // MIPS ABI has special rules to process GOT entries and doesn't
-      // require relocation entries for them. A special case is TLS
-      // relocations. In that case dynamic loader applies dynamic
-      // relocations to initialize TLS GOT entries.
-      // See "Global Offset Table" in Chapter 5 in the following document
-      // for detailed description:
-      // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
-      in.mipsGot->addEntry(*sec.file, sym, addend, expr);
-    } else {
-      sym.needsGot = true;
+  // Non-preemptible ifuncs require special handling. First, handle the usual
+  // case where the symbol isn't one of these.
+  if (!sym.isGnuIFunc() || sym.isPreemptible) {
+    // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
+    if (needsPlt(expr) && !sym.isInPlt())
+      addPltEntry(in.plt, in.gotPlt, in.relaPlt, target->pltRel, sym);
+
+    // Create a GOT slot if a relocation needs GOT.
+    if (needsGot(expr)) {
+      if (config->emachine == EM_MIPS) {
+        // MIPS ABI has special rules to process GOT entries and doesn't
+        // require relocation entries for them. A special case is TLS
+        // relocations. In that case dynamic loader applies dynamic
+        // relocations to initialize TLS GOT entries.
+        // See "Global Offset Table" in Chapter 5 in the following document
+        // for detailed description:
+        // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
+        in.mipsGot->addEntry(*sec.file, sym, addend, expr);
+      } else if (!sym.isInGot()) {
+        addGotEntry(sym);
+      }
     }
-  } else if (needsPlt(expr)) {
-    sym.needsPlt = true;
   } else {
-    sym.hasDirectReloc = true;
+    // Handle a reference to a non-preemptible ifunc. These are special in a
+    // few ways:
+    //
+    // - Unlike most non-preemptible symbols, non-preemptible ifuncs do not have
+    //   a fixed value. But assuming that all references to the ifunc are
+    //   GOT-generating or PLT-generating, the handling of an ifunc is
+    //   relatively straightforward. We create a PLT entry in Iplt, which is
+    //   usually at the end of .plt, which makes an indirect call using a
+    //   matching GOT entry in igotPlt, which is usually at the end of .got.plt.
+    //   The GOT entry is relocated using an IRELATIVE relocation in relaIplt,
+    //   which is usually at the end of .rela.plt. Unlike most relocations in
+    //   .rela.plt, which may be evaluated lazily without -z now, dynamic
+    //   loaders evaluate IRELATIVE relocs eagerly, which means that for
+    //   IRELATIVE relocs only, GOT-generating relocations can point directly to
+    //   .got.plt without requiring a separate GOT entry.
+    //
+    // - Despite the fact that an ifunc does not have a fixed value, compilers
+    //   that are not passed -fPIC will assume that they do, and will emit
+    //   direct (non-GOT-generating, non-PLT-generating) relocations to the
+    //   symbol. This means that if a direct relocation to the symbol is
+    //   seen, the linker must set a value for the symbol, and this value must
+    //   be consistent no matter what type of reference is made to the symbol.
+    //   This can be done by creating a PLT entry for the symbol in the way
+    //   described above and making it canonical, that is, making all references
+    //   point to the PLT entry instead of the resolver. In lld we also store
+    //   the address of the PLT entry in the dynamic symbol table, which means
+    //   that the symbol will also have the same value in other modules.
+    //   Because the value loaded from the GOT needs to be consistent with
+    //   the value computed using a direct relocation, a non-preemptible ifunc
+    //   may end up with two GOT entries, one in .got.plt that points to the
+    //   address returned by the resolver and is used only by the PLT entry,
+    //   and another in .got that points to the PLT entry and is used by
+    //   GOT-generating relocations.
+    //
+    // - The fact that these symbols do not have a fixed value makes them an
+    //   exception to the general rule that a statically linked executable does
+    //   not require any form of dynamic relocation. To handle these relocations
+    //   correctly, the IRELATIVE relocations are stored in an array which a
+    //   statically linked executable's startup code must enumerate using the
+    //   linker-defined symbols __rela?_iplt_{start,end}.
+    if (!sym.isInPlt()) {
+      // Create PLT and GOTPLT slots for the symbol.
+      sym.isInIplt = true;
+
+      // Create a copy of the symbol to use as the target of the IRELATIVE
+      // relocation in the igotPlt. This is in case we make the PLT canonical
+      // later, which would overwrite the original symbol.
+      //
+      // FIXME: Creating a copy of the symbol here is a bit of a hack. All
+      // that's really needed to create the IRELATIVE is the section and value,
+      // so ideally we should just need to copy those.
+      auto *directSym = make<Defined>(cast<Defined>(sym));
+      addPltEntry(in.iplt, in.igotPlt, in.relaIplt, target->iRelativeRel,
+                  *directSym);
+      sym.pltIndex = directSym->pltIndex;
+    }
+    if (needsGot(expr)) {
+      // Redirect GOT accesses to point to the Igot.
+      //
+      // This field is also used to keep track of whether we ever needed a GOT
+      // entry. If we did and we make the PLT canonical later, we'll need to
+      // create a GOT entry pointing to the PLT entry for Sym.
+      sym.gotInIgot = true;
+    } 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.
+      auto &d = cast<Defined>(sym);
+      d.section = in.iplt;
+      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.
+      d.type = STT_FUNC;
+
+      if (sym.gotInIgot) {
+        // We previously encountered a GOT generating reference that we
+        // redirected to the Igot. Now that the PLT entry is canonical we must
+        // clear the redirection to the Igot and add a GOT entry. As we've
+        // changed the symbol type to STT_FUNC future GOT generating references
+        // will naturally use this GOT entry.
+        //
+        // We don't need to worry about creating a MIPS GOT here because ifuncs
+        // aren't a thing on MIPS.
+        sym.gotInIgot = false;
+        addGotEntry(sym);
+      }
+    }
   }
 
   processRelocAux<ELFT>(sec, expr, type, offset, sym, addend);
@@ -1532,121 +1615,6 @@ template <class ELFT> void elf::scanRelocations(InputSectionBase &s) {
     scanRelocs<ELFT>(s, rels.relas);
 }
 
-static bool handleNonPreemptibleIfunc(Symbol &sym) {
-  // Handle a reference to a non-preemptible ifunc. These are special in a
-  // few ways:
-  //
-  // - Unlike most non-preemptible symbols, non-preemptible ifuncs do not have
-  //   a fixed value. But assuming that all references to the ifunc are
-  //   GOT-generating or PLT-generating, the handling of an ifunc is
-  //   relatively straightforward. We create a PLT entry in Iplt, which is
-  //   usually at the end of .plt, which makes an indirect call using a
-  //   matching GOT entry in igotPlt, which is usually at the end of .got.plt.
-  //   The GOT entry is relocated using an IRELATIVE relocation in relaIplt,
-  //   which is usually at the end of .rela.plt. Unlike most relocations in
-  //   .rela.plt, which may be evaluated lazily without -z now, dynamic
-  //   loaders evaluate IRELATIVE relocs eagerly, which means that for
-  //   IRELATIVE relocs only, GOT-generating relocations can point directly to
-  //   .got.plt without requiring a separate GOT entry.
-  //
-  // - Despite the fact that an ifunc does not have a fixed value, compilers
-  //   that are not passed -fPIC will assume that they do, and will emit
-  //   direct (non-GOT-generating, non-PLT-generating) relocations to the
-  //   symbol. This means that if a direct relocation to the symbol is
-  //   seen, the linker must set a value for the symbol, and this value must
-  //   be consistent no matter what type of reference is made to the symbol.
-  //   This can be done by creating a PLT entry for the symbol in the way
-  //   described above and making it canonical, that is, making all references
-  //   point to the PLT entry instead of the resolver. In lld we also store
-  //   the address of the PLT entry in the dynamic symbol table, which means
-  //   that the symbol will also have the same value in other modules.
-  //   Because the value loaded from the GOT needs to be consistent with
-  //   the value computed using a direct relocation, a non-preemptible ifunc
-  //   may end up with two GOT entries, one in .got.plt that points to the
-  //   address returned by the resolver and is used only by the PLT entry,
-  //   and another in .got that points to the PLT entry and is used by
-  //   GOT-generating relocations.
-  //
-  // - The fact that these symbols do not have a fixed value makes them an
-  //   exception to the general rule that a statically linked executable does
-  //   not require any form of dynamic relocation. To handle these relocations
-  //   correctly, the IRELATIVE relocations are stored in an array which a
-  //   statically linked executable's startup code must enumerate using the
-  //   linker-defined symbols __rela?_iplt_{start,end}.
-  if (!sym.isGnuIFunc() || sym.isPreemptible || config->zIfuncNoplt)
-    return false;
-
-  sym.isInIplt = true;
-
-  // Create an Iplt and the associated IRELATIVE relocation pointing to the
-  // original section/value pairs. For non-GOT non-PLT relocation case below, we
-  // may alter section/value, so create a copy of the symbol to make
-  // section/value fixed.
-  auto *directSym = make<Defined>(cast<Defined>(sym));
-  addPltEntry(in.iplt, in.igotPlt, in.relaIplt, target->iRelativeRel,
-              *directSym);
-  sym.pltIndex = directSym->pltIndex;
-
-  if (sym.hasDirectReloc) {
-    // Change the value to the IPLT and redirect all references to it.
-    auto &d = cast<Defined>(sym);
-    d.section = in.iplt;
-    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.
-    d.type = STT_FUNC;
-
-    if (sym.needsGot)
-      addGotEntry(sym);
-  } else if (sym.needsGot) {
-    // Redirect GOT accesses to point to the Igot.
-    sym.gotInIgot = true;
-  }
-  return true;
-}
-
-void elf::postScanRelocations() {
-  auto fn = [](Symbol &sym) {
-    if (handleNonPreemptibleIfunc(sym))
-      return;
-    if (sym.needsGot)
-      addGotEntry(sym);
-    if (sym.needsPlt)
-      addPltEntry(in.plt, in.gotPlt, in.relaPlt, target->pltRel, sym);
-    if (sym.needsCopy) {
-      if (sym.isObject()) {
-        addCopyRelSymbol(cast<SharedSymbol>(sym));
-        // needsCopy is cleared for sym and its aliases so that in later
-        // iterations aliases won't cause redundant copies.
-        assert(!sym.needsCopy);
-      } else {
-        assert(sym.isFunc() && sym.needsPlt);
-        if (!sym.isDefined()) {
-          replaceWithDefined(
-              sym, in.plt,
-              target->pltHeaderSize + target->pltEntrySize * sym.pltIndex, 0);
-          sym.needsCopy = true;
-          if (config->emachine == EM_PPC) {
-            // PPC32 canonical PLT entries are at the beginning of .glink
-            cast<Defined>(sym).value = in.plt->headerSize;
-            in.plt->headerSize += 16;
-            cast<PPC32GlinkSection>(in.plt)->canonical_plts.push_back(&sym);
-          }
-        }
-      }
-    }
-  };
-  for (Symbol *sym : symtab->symbols())
-    fn(*sym);
-
-  // Local symbols may need the aforementioned non-preemptible ifunc and GOT
-  // handling. They don't need regular PLT.
-  for (InputFile *file : objectFiles)
-    for (Symbol *sym : cast<ELFFileBase>(file)->getLocalSymbols())
-      fn(*sym);
-}
-
 static bool mergeCmp(const InputSection *a, const InputSection *b) {
   // std::merge requires a strict weak ordering.
   if (a->outSecOff < b->outSecOff)

diff  --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h
index c652c0a5f70fc..86e6cf4bc1f5a 100644
--- a/lld/ELF/Relocations.h
+++ b/lld/ELF/Relocations.h
@@ -126,7 +126,6 @@ struct JumpInstrMod {
 // Call reportUndefinedSymbols() after calling scanRelocations() to emit
 // the diagnostics.
 template <class ELFT> void scanRelocations(InputSectionBase &);
-void postScanRelocations();
 
 template <class ELFT> void reportUndefinedSymbols();
 

diff  --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 01a3598f8d60b..c1bfb6653c88f 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -120,7 +120,7 @@ static uint64_t getSymVA(const Symbol &sym, int64_t addend) {
     // field etc) do the same trick as compiler uses to mark microMIPS
     // for CPU - set the less-significant bit.
     if (config->emachine == EM_MIPS && isMicroMips() &&
-        ((sym.stOther & STO_MIPS_MICROMIPS) || sym.needsCopy))
+        ((sym.stOther & STO_MIPS_MICROMIPS) || sym.needsPltAddr))
       va |= 1;
 
     if (d.isTls() && !config->relocatable) {

diff  --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index e7b4ca0a2be73..cc48ef0ab3b7a 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -245,12 +245,16 @@ class Symbol {
         type(type), stOther(stOther), symbolKind(k), visibility(stOther & 3),
         isUsedInRegularObj(!file || file->kind() == InputFile::ObjKind),
         exportDynamic(isExportDynamic(k, visibility)), inDynamicList(false),
-        canInline(false), referenced(false), traced(false), isInIplt(false),
-        gotInIgot(false), isPreemptible(false), used(!config->gcSections),
-        needsTocRestore(false), scriptDefined(false), needsCopy(false),
-        needsGot(false), needsPlt(false), hasDirectReloc(false) {}
+        canInline(false), referenced(false), traced(false), needsPltAddr(false),
+        isInIplt(false), gotInIgot(false), isPreemptible(false),
+        used(!config->gcSections), needsTocRestore(false),
+        scriptDefined(false) {}
 
 public:
+  // True the symbol should point to its PLT entry.
+  // For SharedSymbol only.
+  uint8_t needsPltAddr : 1;
+
   // True if this symbol is in the Iplt sub-section of the Plt and the Igot
   // sub-section of the .got.plt or .got.
   uint8_t isInIplt : 1;
@@ -275,16 +279,6 @@ class Symbol {
   // True if this symbol is defined by a linker script.
   uint8_t scriptDefined : 1;
 
-  // True if this symbol needs a canonical PLT entry, or (during
-  // postScanRelocations) a copy relocation.
-  uint8_t needsCopy : 1;
-
-  // Temporary flags used to communicate which symbol entries need PLT and GOT
-  // entries during postScanRelocations();
-  uint8_t needsGot : 1;
-  uint8_t needsPlt : 1;
-  uint8_t hasDirectReloc : 1;
-
   // The partition whose dynamic symbol table contains this symbol's definition.
   uint8_t partition = 1;
 

diff  --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 5982f90544257..bcb521a47a4ae 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -2175,8 +2175,7 @@ static BssSection *getCommonSec(Symbol *sym) {
 static uint32_t getSymSectionIndex(Symbol *sym) {
   if (getCommonSec(sym))
     return SHN_COMMON;
-  assert(!(sym->needsCopy && sym->isObject()));
-  if (!isa<Defined>(sym) || sym->needsCopy)
+  if (!isa<Defined>(sym) || sym->needsPltAddr)
     return SHN_UNDEF;
   if (const OutputSection *os = sym->getOutputSection())
     return os->sectionIndex >= SHN_LORESERVE ? (uint32_t)SHN_XINDEX
@@ -2251,7 +2250,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *buf) {
 
     for (SymbolTableEntry &ent : symbols) {
       Symbol *sym = ent.sym;
-      if (sym->isInPlt() && sym->needsCopy)
+      if (sym->isInPlt() && sym->needsPltAddr)
         eSym->st_other |= STO_MIPS_PLT;
       if (isMicroMips()) {
         // We already set the less-significant bit for symbols
@@ -2262,7 +2261,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *buf) {
         // like `objdump` will be able to deal with a correct
         // symbol position.
         if (sym->isDefined() &&
-            ((sym->stOther & STO_MIPS_MICROMIPS) || sym->needsCopy)) {
+            ((sym->stOther & STO_MIPS_MICROMIPS) || sym->needsPltAddr)) {
           if (!strTabSec.isDynamic())
             eSym->st_value &= ~1;
           eSym->st_other |= STO_MIPS_MICROMIPS;

diff  --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index b5ec50a4092af..07c5e23033743 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1947,7 +1947,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
     if (!config->relocatable) {
       forEachRelSec(scanRelocations<ELFT>);
       reportUndefinedSymbols<ELFT>();
-      postScanRelocations();
     }
   }
 

diff  --git a/lld/test/ELF/aarch64-ifunc-bti.s b/lld/test/ELF/aarch64-ifunc-bti.s
index 4a5607d323325..732983645d27f 100644
--- a/lld/test/ELF/aarch64-ifunc-bti.s
+++ b/lld/test/ELF/aarch64-ifunc-bti.s
@@ -35,13 +35,16 @@
 # CHECK-EMPTY:
 ## The address of ifunc1 at plt does not escape so it does not need `bti c`,
 ## but having bti is not wrong.
-# CHECK-NEXT: 00000000000103e0 <ifunc2>:
+# CHECK-NEXT: 00000000000103e0 <.iplt>:
 # CHECK-NEXT:    103e0:         bti     c
 # CHECK-NEXT:                   adrp    x16, 0x30000
 # CHECK-NEXT:                   ldr     x17, [x16, #1360]
 # CHECK-NEXT:                   add     x16, x16, #1360
 # CHECK-NEXT:                   br      x17
 # CHECK-NEXT:                   nop
+# CHECK-EMPTY:
+## The address of ifunc2 (STT_FUNC) escapes, so it must have `bti c`.
+# CHECK-NEXT: 00000000000103f8 <ifunc2>:
 # CHECK-NEXT:    103f8:         bti     c
 # CHECK-NEXT:                   adrp    x16, 0x30000
 # CHECK-NEXT:                   ldr     x17, [x16, #1368]
@@ -49,11 +52,10 @@
 # CHECK-NEXT:                   br      x17
 # CHECK-NEXT:                   nop
 
-## The address of ifunc2 (STT_FUNC) escapes, so it must have `bti c`.
-# SHARED:      <ifunc2>:
+# SHARED:      <.iplt>:
 # SHARED-NEXT:    bti     c
 
-# SHARED:         nop
+# SHARED:      <ifunc2>:
 # SHARED-NEXT:    bti     c
 
 .section ".note.gnu.property", "a"

diff  --git a/lld/test/ELF/aarch64-thunk-pi.s b/lld/test/ELF/aarch64-thunk-pi.s
index 23c9a25b198a1..1f11f127109f9 100644
--- a/lld/test/ELF/aarch64-thunk-pi.s
+++ b/lld/test/ELF/aarch64-thunk-pi.s
@@ -36,7 +36,7 @@ low_target2:
 // adrp calculation is (PC + signed immediate) & (!0xfff)
 // CHECK: <__AArch64ADRPThunk_high_target>:
 // CHECK-NEXT:       14:       adrp    x16, 0x10000000
-// CHECK-NEXT:                 add     x16, x16, #0x50
+// CHECK-NEXT:                 add     x16, x16, #0x40
 // CHECK-NEXT:                 br      x16
 // CHECK: <__AArch64ADRPThunk_high_target2>:
 // CHECK-NEXT:       20:       adrp    x16, 0x10000000
@@ -57,7 +57,7 @@ high_target:
  bl low_target
  ret
 // CHECK: <high_target>:
-// CHECK-NEXT: 10000000:       bl 0x10000040 <low_target at plt>
+// CHECK-NEXT: 10000000:       bl 0x10000050 <low_target at plt>
 // CHECK-NEXT:                 ret
 
  .hidden high_target2
@@ -90,13 +90,13 @@ high_target2:
 // CHECK-NEXT:                 nop
 // CHECK-NEXT:                 nop
 // CHECK-EMPTY:
-// CHECK-NEXT:   <low_target at plt>:
+// CHECK-NEXT:   <high_target at plt>:
 // CHECK-NEXT: 10000040:       adrp    x16, 0x10000000
 // CHECK-NEXT:                 ldr     x17, [x16, #0x200]
 // CHECK-NEXT:                 add     x16, x16, #0x200
 // CHECK-NEXT:                 br      x17
 // CHECK-EMPTY:
-// CHECK-NEXT:   <high_target at plt>:
+// CHECK-NEXT:   <low_target at plt>:
 // CHECK-NEXT: 10000050:       adrp    x16, 0x10000000
 // CHECK-NEXT:                 ldr     x17, [x16, #0x208]
 // CHECK-NEXT:                 add     x16, x16, #0x208

diff  --git a/lld/test/ELF/arm-branch-undef-weak-plt-thunk.s b/lld/test/ELF/arm-branch-undef-weak-plt-thunk.s
index f75fb6c178545..ca71f45b4a2b7 100644
--- a/lld/test/ELF/arm-branch-undef-weak-plt-thunk.s
+++ b/lld/test/ELF/arm-branch-undef-weak-plt-thunk.s
@@ -27,10 +27,10 @@ _start:
 // CHECK-NEXT:    201e4:       00 00 00 ea     b       0x201ec <__ARMv7ABSLongThunk_undefined_weak_we_expect_a_plt_entry_for>
 // CHECK-NEXT:    201e8:       02 00 00 eb     bl      0x201f8 <__ARMv7ABSLongThunk_bar2>
 // CHECK: <__ARMv7ABSLongThunk_undefined_weak_we_expect_a_plt_entry_for>:
-// CHECK-NEXT:    201ec:        40 c2 00 e3     movw    r12, #576
+// CHECK-NEXT:    201ec:        30 c2 00 e3     movw    r12, #560
 // CHECK-NEXT:    201f0:        02 c2 40 e3     movt    r12, #514
 // CHECK-NEXT:    201f4:        1c ff 2f e1     bx      r12
 // CHECK: <__ARMv7ABSLongThunk_bar2>:
-// CHECK-NEXT:    201f8:        30 c2 00 e3     movw    r12, #560
+// CHECK-NEXT:    201f8:        40 c2 00 e3     movw    r12, #576
 // CHECK-NEXT:    201fc:        02 c2 40 e3     movt    r12, #514
 // CHECK-NEXT:    20200:        1c ff 2f e1     bx      r12

diff  --git a/lld/test/ELF/arm-gnu-ifunc.s b/lld/test/ELF/arm-gnu-ifunc.s
index 187ddd24d8a3b..bbd932ad7b442 100644
--- a/lld/test/ELF/arm-gnu-ifunc.s
+++ b/lld/test/ELF/arm-gnu-ifunc.s
@@ -118,8 +118,8 @@ _start:
 // DISASM: <bar>:
 // DISASM-NEXT:    20108:      bx      lr
 // DISASM: <_start>:
-// DISASM-NEXT:    2010c:      bl      0x20140
-// DISASM-NEXT:    20110:      bl      0x20130
+// DISASM-NEXT:    2010c:      bl      0x20130
+// DISASM-NEXT:    20110:      bl      0x20140
 // 1 * 65536 + 244 = 0x100f4 __rel_iplt_start
 // DISASM-NEXT:    20114:      movw    r0, #244
 // DISASM-NEXT:    20118:      movt    r0, #1

diff  --git a/lld/test/ELF/arm-thumb-interwork-thunk.s b/lld/test/ELF/arm-thumb-interwork-thunk.s
index ccc65e5b3789f..485e0f324b1a3 100644
--- a/lld/test/ELF/arm-thumb-interwork-thunk.s
+++ b/lld/test/ELF/arm-thumb-interwork-thunk.s
@@ -139,15 +139,15 @@ arm_caller:
 // CHECK-ARM-PLT: Disassembly of section .arm_caller:
 // CHECK-ARM-PLT-EMPTY:
 // CHECK-ARM-PLT-NEXT: <arm_caller>:
-// CHECK-ARM-PLT-NEXT: 1300:        bl      0x1630
-// CHECK-ARM-PLT-NEXT: 1304:        bl      0x1630
-// CHECK-ARM-PLT-NEXT: 1308:        b       0x1630
-// CHECK-ARM-PLT-NEXT: 130c:        b       0x1630
+// CHECK-ARM-PLT-NEXT: 1300:        bl      0x1650
+// CHECK-ARM-PLT-NEXT: 1304:        bl      0x1650
+// CHECK-ARM-PLT-NEXT: 1308:        b       0x1650
+// CHECK-ARM-PLT-NEXT: 130c:        b       0x1650
 // CHECK-ARM-PLT-NEXT: 1310:        b       0x1660
 // CHECK-ARM-PLT-NEXT: 1314:        b       0x1670
-// CHECK-ARM-PLT-NEXT: 1318:        b       0x1640
-// CHECK-ARM-PLT-NEXT: 131c:        beq     0x1680
-// CHECK-ARM-PLT-NEXT: 1320:        bne     0x1690
+// CHECK-ARM-PLT-NEXT: 1318:        b       0x1680
+// CHECK-ARM-PLT-NEXT: 131c:        beq     0x1690
+// CHECK-ARM-PLT-NEXT: 1320:        bne     0x16a0
 // CHECK-ARM-PLT-NEXT: 1324:        bx      lr
 
  .section .thumb_caller, "ax", %progbits
@@ -229,8 +229,8 @@ thumb_caller:
 // CHECK-ARM-PLT: Disassembly of section .thumb_caller:
 // CHECK-ARM-PLT-EMPTY:
 // CHECK-ARM-PLT-NEXT: <thumb_caller>:
-// CHECK-ARM-PLT-NEXT: 1400: blx     0x1640
-// CHECK-ARM-PLT-NEXT: 1404: blx     0x1640
+// CHECK-ARM-PLT-NEXT: 1400: blx     0x1680
+// CHECK-ARM-PLT-NEXT: 1404: blx     0x1680
 // CHECK-ARM-PLT-NEXT: 1408: b.w     0x1420 <__ThumbV7PILongThunk_arm_callee1>
 // CHECK-ARM-PLT-NEXT: 140c: b.w     0x142c <__ThumbV7PILongThunk_arm_callee2>
 // CHECK-ARM-PLT-NEXT: 1410: b.w     0x1438 <__ThumbV7PILongThunk_arm_callee3>
@@ -365,11 +365,11 @@ _start:
 // CHECK-ARM-PLT-NEXT: 000016ac <$d>:
 // CHECK-ARM-PLT-NEXT:     16ac:     d4 d4 d4 d4     .word   0xd4d4d4d4
 
-// CHECK-DSO-REL:      0x18C0 R_ARM_JUMP_SLOT thumb_callee1
-// CHECK-DSO-REL-NEXT: 0x18C4 R_ARM_JUMP_SLOT arm_callee1
-// CHECK-DSO-REL-NEXT: 0x18C8 R_ARM_JUMP_SLOT arm_caller
+// CHECK-DSO-REL:      0x18C0 R_ARM_JUMP_SLOT arm_caller
+// CHECK-DSO-REL-NEXT: 0x18C4 R_ARM_JUMP_SLOT thumb_caller
+// CHECK-DSO-REL-NEXT: 0x18C8 R_ARM_JUMP_SLOT thumb_callee1
 // CHECK-DSO-REL-NEXT: 0x18CC R_ARM_JUMP_SLOT thumb_callee2
 // CHECK-DSO-REL-NEXT: 0x18D0 R_ARM_JUMP_SLOT thumb_callee3
-// CHECK-DSO-REL-NEXT: 0x18D4 R_ARM_JUMP_SLOT arm_callee2
-// CHECK-DSO-REL-NEXT: 0x18D8 R_ARM_JUMP_SLOT arm_callee3
-// CHECK-DSO-REL-NEXT: 0x18DC R_ARM_JUMP_SLOT thumb_caller
+// CHECK-DSO-REL-NEXT: 0x18D4 R_ARM_JUMP_SLOT arm_callee1
+// CHECK-DSO-REL-NEXT: 0x18D8 R_ARM_JUMP_SLOT arm_callee2
+// CHECK-DSO-REL-NEXT: 0x18DC R_ARM_JUMP_SLOT arm_callee3

diff  --git a/lld/test/ELF/bsymbolic.s b/lld/test/ELF/bsymbolic.s
index 6a69a4ad1a2f4..ff182b110d066 100644
--- a/lld/test/ELF/bsymbolic.s
+++ b/lld/test/ELF/bsymbolic.s
@@ -41,9 +41,9 @@
 # REL_DEF-NEXT: }
 # REL_DEF-NEXT: .rela.plt {
 # REL_DEF-NEXT:   R_X86_64_JUMP_SLOT default
-# REL_DEF-NEXT:   R_X86_64_JUMP_SLOT notype_default
 # REL_DEF-NEXT:   R_X86_64_JUMP_SLOT weak_default
 # REL_DEF-NEXT:   R_X86_64_JUMP_SLOT ext_default
+# REL_DEF-NEXT:   R_X86_64_JUMP_SLOT notype_default
 # REL_DEF-NEXT:   R_X86_64_JUMP_SLOT undef
 # REL_DEF-NEXT: }
 
@@ -62,8 +62,8 @@
 # REL_GFUN-NEXT:   R_X86_64_64 data_default
 # REL_GFUN-NEXT: }
 # REL_GFUN-NEXT: .rela.plt {
-# REL_GFUN-NEXT:   R_X86_64_JUMP_SLOT notype_default
 # REL_GFUN-NEXT:   R_X86_64_JUMP_SLOT weak_default
+# REL_GFUN-NEXT:   R_X86_64_JUMP_SLOT notype_default
 # REL_GFUN-NEXT:   R_X86_64_JUMP_SLOT undef
 # REL_GFUN-NEXT: }
 

diff  --git a/lld/test/ELF/gnu-ifunc-i386.s b/lld/test/ELF/gnu-ifunc-i386.s
index a646492b5ea24..f19f40b8c6417 100644
--- a/lld/test/ELF/gnu-ifunc-i386.s
+++ b/lld/test/ELF/gnu-ifunc-i386.s
@@ -62,7 +62,7 @@
 // CHECK-NEXT: }
 // CHECK-NEXT: Symbol {
 // CHECK-NEXT:   Name: bar
-// CHECK-NEXT:   Value: 0x401100
+// CHECK-NEXT:   Value: 0x401110
 // CHECK-NEXT:   Size: 0
 // CHECK-NEXT:   Binding: Global
 // CHECK-NEXT:   Type: Function
@@ -80,7 +80,7 @@
 // CHECK-NEXT: }
 // CHECK-NEXT: Symbol {
 // CHECK-NEXT:   Name: foo
-// CHECK-NEXT:   Value: 0x401110
+// CHECK-NEXT:   Value: 0x401100
 // CHECK-NEXT:   Size: 0
 // CHECK-NEXT:   Binding: Global
 // CHECK-NEXT:   Type: Function
@@ -114,18 +114,18 @@
 // DISASM:      <foo_resolver>:
 // DISASM-NEXT:   4010e5:       retl
 // DISASM:      <_start>:
-// DISASM-NEXT:   4010e6:       calll 0x401110 <foo>
-// DISASM-NEXT:                 calll 0x401100 <bar>
+// DISASM-NEXT:   4010e6:       calll 0x401100 <foo>
+// DISASM-NEXT:                 calll 0x401110 <bar>
 // DISASM-NEXT:                 movl $4194516, %edx
 // DISASM-NEXT:                 movl $4194532, %edx
 // DISASM-EMPTY:
 // DISASM-NEXT: Disassembly of section .iplt:
 // DISASM-EMPTY:
-// DISASM-NEXT: <bar>:
+// DISASM-NEXT: <foo>:
 // DISASM-NEXT:   401100:       jmpl *4202784
 // DISASM-NEXT:                 pushl $0
 // DISASM-NEXT:                 jmp 0x0
-// DISASM:      <foo>:
+// DISASM:      <bar>:
 // DISASM-NEXT:   401110:       jmpl *4202788
 // DISASM-NEXT:                 pushl $8
 // DISASM-NEXT:                 jmp 0x0

diff  --git a/lld/test/ELF/ppc32-canonical-plt.s b/lld/test/ELF/ppc32-canonical-plt.s
index 8fd9e1bdb1f6e..f29e66ea0c28a 100644
--- a/lld/test/ELF/ppc32-canonical-plt.s
+++ b/lld/test/ELF/ppc32-canonical-plt.s
@@ -24,28 +24,28 @@
 
 ## st_value points to the canonical PLT entry in .glink
 # SYM: Symbol table '.dynsym'
-# SYM: 1001022c 0 FUNC GLOBAL DEFAULT UND func
-# SYM: 1001023c 0 FUNC GLOBAL DEFAULT UND func2
+# SYM: 1001023c 0 FUNC GLOBAL DEFAULT UND func
+# SYM: 1001022c 0 FUNC GLOBAL DEFAULT UND func2
 # SYM: 1001024c 0 FUNC GLOBAL DEFAULT UND ifunc
 # SYM: Symbol table '.symtab'
-# SYM: 1001022c 0 FUNC GLOBAL DEFAULT UND func
-# SYM: 1001023c 0 FUNC GLOBAL DEFAULT UND func2
+# SYM: 1001023c 0 FUNC GLOBAL DEFAULT UND func
+# SYM: 1001022c 0 FUNC GLOBAL DEFAULT UND func2
 # SYM: 1001024c 0 FUNC GLOBAL DEFAULT UND ifunc
 
 # HEX: 0x10030318 1001025c 10010260 10010264
 
-## Canonical PLT entry of func.
-## 0x10030318 = 65536*4099+792
+## Canonical PLT entry of func2.
+## 0x1003031C = 65536*4099+796
 # CHECK:      1001022c <.glink>:
 # CHECK-NEXT:           lis 11, 4099
-# CHECK-NEXT:           lwz 11, 792(11)
+# CHECK-NEXT:           lwz 11, 796(11)
 # CHECK-NEXT:           mtctr 11
 # CHECK-NEXT:           bctr
 
-## Canonical PLT entry of func2.
-## 0x1003031C = 65536*4099+796
+## Canonical PLT entry of func.
+## 0x10030318 = 65536*4099+792
 # CHECK-NEXT: 1001023c: lis 11, 4099
-# CHECK-NEXT:           lwz 11, 796(11)
+# CHECK-NEXT:           lwz 11, 792(11)
 # CHECK-NEXT:           mtctr 11
 # CHECK-NEXT:           bctr
 

diff  --git a/lld/test/ELF/ppc32-ifunc-nonpreemptible-pic.s b/lld/test/ELF/ppc32-ifunc-nonpreemptible-pic.s
index cbf9535d68a84..a4b7c8bf97b84 100644
--- a/lld/test/ELF/ppc32-ifunc-nonpreemptible-pic.s
+++ b/lld/test/ELF/ppc32-ifunc-nonpreemptible-pic.s
@@ -7,13 +7,12 @@
 # RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
 
 # RELOC:      .rela.dyn {
-# RELOC-NEXT:   0x3024C R_PPC_RELATIVE - 0x101A0
-# RELOC-NEXT:   0x30250 R_PPC_IRELATIVE - 0x10188
+# RELOC-NEXT:   0x30254 R_PPC_RELATIVE - 0x101A8
+# RELOC-NEXT:   0x30258 R_PPC_IRELATIVE - 0x10188
 # RELOC-NEXT: }
 
-# SYM: 000101a0 0 FUNC GLOBAL DEFAULT {{.*}} func
-# HEX:      Hex dump of section '.got2':
-# HEX-NEXT: 0x0003024c 00000000 ....
+# SYM: 000101a8 0 FUNC GLOBAL DEFAULT {{.*}} func
+# HEX: 0x00030254 00000000
 
 .section .got2,"aw"
 .long func
@@ -22,7 +21,9 @@
 # CHECK:      <.text>:
 # CHECK-NEXT: 10188: blr
 # CHECK:      <_start>:
-# CHECK-NEXT:   bl 0x10190
+# CHECK-NEXT:   bl 0x10198
+# CHECK-NEXT:   lis 9, 1
+# CHECK-NEXT:   addi 9, 9, 424
 # CHECK-EMPTY:
 # CHECK-NEXT: <00008000.got2.plt_pic32.func>:
 ## 0x10020114 = 65536*4098+276
@@ -40,3 +41,6 @@ func:
 .globl _start
 _start:
   bl func+0x8000 at plt
+
+  lis 9, func at ha
+  la 9, func at l(9)

diff  --git a/lld/test/ELF/ppc32-reloc-got.s b/lld/test/ELF/ppc32-reloc-got.s
index 1c7fdfda17c2f..48424abcbe58b 100644
--- a/lld/test/ELF/ppc32-reloc-got.s
+++ b/lld/test/ELF/ppc32-reloc-got.s
@@ -12,21 +12,19 @@
 ## Check we can handle R_PPC_GOT16, which may be generated by -fpic code.
 
 # RELOC:      .rela.dyn {
-# RELOC-NEXT:   0x10020218 R_PPC_GLOB_DAT b 0x0
+# RELOC-NEXT:   0x1002021C R_PPC_GLOB_DAT b 0x0
 # RELOC-NEXT: }
 
-# NM: 1002020c d _GLOBAL_OFFSET_TABLE_
 # NM: 10030220 d a
 
 ## The GOT slot of a can be filled at link time.
-# HEX:      section '.got':
-# HEX:      0x1002020c [[#%x,]] 00000000 00000000 00000000
-# HEX-NEXT: 0x1002021c 10030220
-
-## a: &.got[4] - _GLOBAL_OFFSET_TABLE_ = 0x1002021c - 0x1002020c = 16
-## b: &.got[3] - _GLOBAL_OFFSET_TABLE_ = 0x10020218 - 0x1002020c = 12
-# CHECK: lwz 3, 16(30)
-# CHECK: lwz 4, 12(30)
+# HEX: section '.got':
+# HEX: 0x1002020c {{[0-9a-f]+}} 00000000 00000000 10030220
+
+## a: &.got[3] - _GLOBAL_OFFSET_TABLE_ = 12
+## b: &.got[4] - _GLOBAL_OFFSET_TABLE_ = 16
+# CHECK: lwz 3, 12(30)
+# CHECK: lwz 4, 16(30)
 
 lwz 3,a at got(30)
 lwz 4,b at got(30)

diff  --git a/lld/test/ELF/ppc64-ifunc.s b/lld/test/ELF/ppc64-ifunc.s
index d3f26937fb275..a959f817c1dc6 100644
--- a/lld/test/ELF/ppc64-ifunc.s
+++ b/lld/test/ELF/ppc64-ifunc.s
@@ -16,9 +16,9 @@
 
 # SYM: Value            Size Type   Bind   Vis     Ndx
 # SYM: 0000000010028298    0 NOTYPE LOCAL  HIDDEN    4 .TOC.
-# SYM: 0000000010010268    0 FUNC   GLOBAL DEFAULT   3 ifunc1
+# SYM: 0000000010010288    0 FUNC   GLOBAL DEFAULT   3 ifunc1
 # SYM: 0000000010010210    0 IFUNC  GLOBAL DEFAULT   2 ifunc2
-# SYM: 0000000010010288    0 FUNC   GLOBAL DEFAULT   3 ifunc3
+# SYM: 0000000010010278    0 FUNC   GLOBAL DEFAULT   3 ifunc3
 
 # SECTIONS: .plt NOBITS 00000000100302a0 0002a0 000018 00 WA 0 0 8
 
@@ -32,23 +32,23 @@
 # CHECK-NEXT: 10010224:       bl 0x10010254
 # CHECK-NEXT:                 ld 2, 24(1)
 # CHECK-NEXT:                 addis 3, 2, -2
-# CHECK-NEXT:                 addi 3, 3, 32720
-# CHECK-NEXT:                 addis 3, 2, -2
 # CHECK-NEXT:                 addi 3, 3, 32752
+# CHECK-NEXT:                 addis 3, 2, -2
+# CHECK-NEXT:                 addi 3, 3, 32736
 
-# .plt[1] - .TOC. = 0x100302a0+8 - 0x10028298 = (1<<16) - 32752
+# .plt[0] - .TOC. = 0x100302a0 - 0x10028298 = (1<<16) - 32760
 # CHECK: <__plt_ifunc2>:
 # CHECK-NEXT:     std 2, 24(1)
 # CHECK-NEXT:     addis 12, 2, 1
-# CHECK-NEXT:     ld 12, -32752(12)
+# CHECK-NEXT:     ld 12, -32760(12)
 # CHECK-NEXT:     mtctr 12
 # CHECK-NEXT:     bctr
 
-# .plt[2] - .TOC. = 0x100302a0+16 - 0x10028298 = (1<<16) - 32744
+# .plt[1] - .TOC. = 0x100302a0+8 - 0x10028298 = (1<<16) - 32752
 # CHECK: <__plt_ifunc3>:
 # CHECK-NEXT:     std 2, 24(1)
 # CHECK-NEXT:     addis 12, 2, 1
-# CHECK-NEXT:     ld 12, -32744(12)
+# CHECK-NEXT:     ld 12, -32752(12)
 # CHECK-NEXT:     mtctr 12
 # CHECK-NEXT:     bctr
 # CHECK-EMPTY:
@@ -57,17 +57,19 @@
 ## ifunc2 and ifunc3 have the same code sequence as their PLT call stubs.
 # CHECK:      Disassembly of section .glink:
 # CHECK-EMPTY:
-# CHECK-NEXT: 0000000010010268 <ifunc1>:
+# CHECK-NEXT: 0000000010010268 <.glink>:
 # CHECK-NEXT:     addis 12, 2, 1
 # CHECK-NEXT:     ld 12, -32760(12)
 # CHECK-NEXT:     mtctr 12
 # CHECK-NEXT:     bctr
+# CHECK-EMPTY:
+# CHECK-NEXT: 0000000010010278 <ifunc3>:
 # CHECK-NEXT:     addis 12, 2, 1
 # CHECK-NEXT:     ld 12, -32752(12)
 # CHECK-NEXT:     mtctr 12
 # CHECK-NEXT:     bctr
 # CHECK-EMPTY:
-# CHECK-NEXT: 0000000010010288 <ifunc3>:
+# CHECK-NEXT: 0000000010010288 <ifunc1>:
 # CHECK-NEXT:     addis 12, 2, 1
 # CHECK-NEXT:     ld 12, -32744(12)
 # CHECK-NEXT:     mtctr 12

diff  --git a/lld/test/ELF/relocation-nocopy.s b/lld/test/ELF/relocation-nocopy.s
index bcd23a82c8272..70e99334796d1 100644
--- a/lld/test/ELF/relocation-nocopy.s
+++ b/lld/test/ELF/relocation-nocopy.s
@@ -7,9 +7,6 @@
 // CHECK: unresolvable relocation R_X86_64_32S against symbol 'x'
 // CHECK: unresolvable relocation R_X86_64_32S against symbol 'y'
 // CHECK: unresolvable relocation R_X86_64_32S against symbol 'z'
-// CHECK: unresolvable relocation R_X86_64_32 against symbol 'x'
-// CHECK: unresolvable relocation R_X86_64_32 against symbol 'y'
-// CHECK: unresolvable relocation R_X86_64_32 against symbol 'z'
 
 .text
 .global _start

diff  --git a/lld/test/ELF/riscv-reloc-got.s b/lld/test/ELF/riscv-reloc-got.s
index aecf42872f059..ce4d648d48d9a 100644
--- a/lld/test/ELF/riscv-reloc-got.s
+++ b/lld/test/ELF/riscv-reloc-got.s
@@ -25,39 +25,39 @@
 # SEC64: .got PROGBITS 0000000000012358 000358 000018
 
 # RELOC32:      .rela.dyn {
-# RELOC32-NEXT:   0x12210 R_RISCV_32 b 0x0
+# RELOC32-NEXT:   0x12214 R_RISCV_32 b 0x0
 # RELOC32-NEXT: }
 
 # RELOC64:      .rela.dyn {
-# RELOC64-NEXT:   0x12360 R_RISCV_64 b 0x0
+# RELOC64-NEXT:   0x12368 R_RISCV_64 b 0x0
 # RELOC64-NEXT: }
 
 # NM32: 00013218 d a
 # NM64: 0000000000013370 d a
 
 ## .got[0] = _DYNAMIC
-## .got[1] = 0 (relocated by R_RISCV_32/64 at runtime)
-## .got[2] = a (filled at link time)
+## .got[1] = a (filled at link time)
+## .got[2] = 0 (relocated by R_RISCV_64 at runtime)
 # HEX32: section '.got':
-# HEX32: 0x0001220c ac210100 00000000 18320100 
+# HEX32: 0x0001220c ac210100 18320100 00000000
 
 # HEX64: section '.got':
-# HEX64: 0x00012358 98220100 00000000 00000000 00000000
-# HEX64: 0x00012368 70330100 00000000
+# HEX64: 0x00012358 98220100 00000000 70330100 00000000
+# HEX64: 0x00012368 00000000 00000000
 
-## &.got[2]-. = 0x12214-0x1119c = 4096*1+120
+## &.got[1]-. = 0x12210-0x1119c = 4096*1+116
 # DIS32:      1119c: auipc a0, 1
-# DIS32-NEXT:        lw a0, 120(a0)
-## &.got[1]-. = 0x12210-0x111a4 = 4096*1+108
+# DIS32-NEXT:        lw a0, 116(a0)
+## &.got[2]-. = 0x12214-0x111a4 = 4096*1+112
 # DIS32:      111a4: auipc a0, 1
-# DIS32-NEXT:        lw a0, 108(a0)
+# DIS32-NEXT:        lw a0, 112(a0)
 
-## &.got[2]-. = 0x12368-0x11288 = 4096*1+224
+## &.got[1]-. = 0x12360-0x11288 = 4096*1+216
 # DIS64:      11288: auipc a0, 1
-# DIS64-NEXT:        ld a0, 224(a0)
-## &.got[1]-. = 0x12360-0x11290 = 4096*1+208
+# DIS64-NEXT:        ld a0, 216(a0)
+## &.got[2]-. = 0x12368-0x11290 = 4096*1+216
 # DIS64:      11290: auipc a0, 1
-# DIS64-NEXT:        ld a0, 208(a0)
+# DIS64-NEXT:        ld a0, 216(a0)
 
 la a0,a
 la a0,b

diff  --git a/lld/test/ELF/symver.s b/lld/test/ELF/symver.s
index d05fcc2a55d36..81f10f0017fc9 100644
--- a/lld/test/ELF/symver.s
+++ b/lld/test/ELF/symver.s
@@ -105,8 +105,8 @@
 # RUN: llvm-objdump -d --no-show-raw-insn %t.w1 | FileCheck %s --check-prefix=W1DIS
 
 # W1REL:      .rela.plt {
-# W1REL-NEXT:   R_X86_64_JUMP_SLOT foo@@v1 0x0
 # W1REL-NEXT:   R_X86_64_JUMP_SLOT __wrap_foo 0x0
+# W1REL-NEXT:   R_X86_64_JUMP_SLOT foo@@v1 0x0
 # W1REL-NEXT: }
 
 # W1DIS-LABEL: <.text>:
@@ -121,8 +121,8 @@
 # RUN: llvm-objdump -d --no-show-raw-insn %t.w2 | FileCheck %s --check-prefix=W2DIS
 
 # W2REL:      .rela.plt {
-# W2REL-NEXT:   R_X86_64_JUMP_SLOT foo at v1 0x0
 # W2REL-NEXT:   R_X86_64_JUMP_SLOT __wrap_foo 0x0
+# W2REL-NEXT:   R_X86_64_JUMP_SLOT foo at v1 0x0
 # W2REL-NEXT: }
 
 # W2DIS-LABEL: <.text>:

diff  --git a/lld/test/ELF/version-script-symver.s b/lld/test/ELF/version-script-symver.s
index ee87c3405ab63..a3a820f9edeaa 100644
--- a/lld/test/ELF/version-script-symver.s
+++ b/lld/test/ELF/version-script-symver.s
@@ -42,8 +42,8 @@
 # RUN: ld.lld --version-script %t4.script -shared %t.o %tref.o -o %t5.so
 # RUN: llvm-readelf -r %t5.so | FileCheck --check-prefix=RELOC %s
 
-# RELOC: R_X86_64_JUMP_SLOT {{.*}} foo4@@v2 + 0
 # RELOC: R_X86_64_JUMP_SLOT {{.*}} foo3 at v1 + 0
+# RELOC: R_X86_64_JUMP_SLOT {{.*}} foo4@@v2 + 0
 
 .globl foo1; foo1: ret
 .globl foo2; foo2: ret

diff  --git a/lld/test/ELF/wrap-no-real.s b/lld/test/ELF/wrap-no-real.s
index 125e2cfbcce75..75df54be61ba5 100644
--- a/lld/test/ELF/wrap-no-real.s
+++ b/lld/test/ELF/wrap-no-real.s
@@ -9,23 +9,23 @@
 // RUN: llvm-readelf -s -x .got %t | FileCheck --check-prefix=READELF --implicit-check-not=__real_ %s
 
 // CHECK: <_start>:
-// CHECK-NEXT: movq {{.*}}(%rip), %rax  # 0x2021b0
-// CHECK-NEXT: movq {{.*}}(%rip), %rbx  # 0x2021b0
-// CHECK-NEXT: movq {{.*}}(%rip), %rcx  # 0x2021a8
+// CHECK-NEXT: movq {{.*}}(%rip), %rax  # 0x2021a8
+// CHECK-NEXT: movq {{.*}}(%rip), %rbx  # 0x2021a8
+// CHECK-NEXT: movq {{.*}}(%rip), %rcx  # 0x2021b0
 
 // READELF:      0000000000011000  0 NOTYPE GLOBAL DEFAULT ABS foo
 // READELF:      0000000000011010  0 NOTYPE GLOBAL DEFAULT ABS __wrap_foo
 // READELF:      Hex dump of section '.got':
-// READELF-NEXT: 0x[[#%x,ADDR:]] 00100100 00000000 10100100 00000000
+// READELF-NEXT: 0x[[#%x,ADDR:]] 10100100 00000000 00100100 00000000
 
 // RUN: ld.lld -o %t2 %t1.o %t2.o %t3.so --wrap foo
 // RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=CHECK2 %s
 // RUN: llvm-readelf -s -x .got %t2 | FileCheck --check-prefix=READELF --implicit-check-not=__real_ %s
 
 // CHECK2: <_start>:
-// CHECK2-NEXT: movq {{.*}}(%rip), %rax  # 0x2022e8
-// CHECK2-NEXT: movq {{.*}}(%rip), %rbx  # 0x2022e8
-// CHECK2-NEXT: movq {{.*}}(%rip), %rcx  # 0x2022e0
+// CHECK2-NEXT: movq {{.*}}(%rip), %rax  # 0x2022e0
+// CHECK2-NEXT: movq {{.*}}(%rip), %rbx  # 0x2022e0
+// CHECK2-NEXT: movq {{.*}}(%rip), %rcx  # 0x2022e8
 
 .global _start
 _start:

diff  --git a/lld/test/ELF/wrap-plt.s b/lld/test/ELF/wrap-plt.s
index f9a88ddd59471..57b417e7b2f0c 100644
--- a/lld/test/ELF/wrap-plt.s
+++ b/lld/test/ELF/wrap-plt.s
@@ -10,8 +10,8 @@
 
 // CHECK:      Relocations [
 // CHECK-NEXT:   Section ({{.*}}) .rela.plt {
-// CHECK-NEXT:     R_X86_64_JUMP_SLOT foo 0x0
 // CHECK-NEXT:     R_X86_64_JUMP_SLOT __wrap_foo 0x0
+// CHECK-NEXT:     R_X86_64_JUMP_SLOT foo 0x0
 // CHECK-NEXT:     R_X86_64_JUMP_SLOT _start 0x0
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]

diff  --git a/lld/test/ELF/x86-64-gotpc-relax-und-dso.s b/lld/test/ELF/x86-64-gotpc-relax-und-dso.s
index 709215fc1f7a0..ac7088d9f0c1c 100644
--- a/lld/test/ELF/x86-64-gotpc-relax-und-dso.s
+++ b/lld/test/ELF/x86-64-gotpc-relax-und-dso.s
@@ -23,22 +23,22 @@
 # DISASM:      <hid>:
 # DISASM-NEXT:     nop
 # DISASM:      <_start>:
-# DISASM-NEXT:    movq    4375(%rip), %rax
-# DISASM-NEXT:    movq    4368(%rip), %rax
-# DISASM-NEXT:    movq    4369(%rip), %rax
-# DISASM-NEXT:    movq    4362(%rip), %rax
+# DISASM-NEXT:    movq    4367(%rip), %rax
+# DISASM-NEXT:    movq    4360(%rip), %rax
+# DISASM-NEXT:    movq    4361(%rip), %rax
+# DISASM-NEXT:    movq    4354(%rip), %rax
 # DISASM-NEXT:    leaq    -36(%rip), %rax
 # DISASM-NEXT:    leaq    -43(%rip), %rax
-# DISASM-NEXT:    movq    4325(%rip), %rax
-# DISASM-NEXT:    movq    4318(%rip), %rax
-# DISASM-NEXT:    movq    4319(%rip), %rax
-# DISASM-NEXT:    movq    4312(%rip), %rax
-# DISASM-NEXT:    movq    4313(%rip), %rax
-# DISASM-NEXT:    movq    4306(%rip), %rax
+# DISASM-NEXT:    movq    4341(%rip), %rax
+# DISASM-NEXT:    movq    4334(%rip), %rax
+# DISASM-NEXT:    movq    4311(%rip), %rax
+# DISASM-NEXT:    movq    4304(%rip), %rax
+# DISASM-NEXT:    movq    4305(%rip), %rax
+# DISASM-NEXT:    movq    4298(%rip), %rax
 # DISASM-NEXT:    leaq    -92(%rip), %rax
 # DISASM-NEXT:    leaq    -99(%rip), %rax
-# DISASM-NEXT:    movq    4269(%rip), %rax
-# DISASM-NEXT:    movq    4262(%rip), %rax
+# DISASM-NEXT:    movq    4285(%rip), %rax
+# DISASM-NEXT:    movq    4278(%rip), %rax
 
 .text
 .globl foo

diff  --git a/lld/test/ELF/x86-64-plt.s b/lld/test/ELF/x86-64-plt.s
index a3558999f7389..9309f5e0320b8 100644
--- a/lld/test/ELF/x86-64-plt.s
+++ b/lld/test/ELF/x86-64-plt.s
@@ -14,15 +14,15 @@
 # CHECK1:      .plt      PROGBITS 00000000002012e0 0002e0 000030 00 AX   0   0 16
 # CHECK1:      .got.plt  PROGBITS 00000000002033e0 0003e0 000028 00 WA   0   0  8
 # CHECK1:      Relocation section '.rela.plt' at offset {{.*}} contains 2 entries:
-# CHECK1:      00000000002033f8 {{.*}} R_X86_64_JUMP_SLOT 0000000000000000 weak + 0
-# CHECK1-NEXT: 0000000000203400 {{.*}} R_X86_64_JUMP_SLOT 0000000000000000 bar + 0
+# CHECK1:      00000000002033f8 {{.*}} R_X86_64_JUMP_SLOT 0000000000000000 bar + 0
+# CHECK1-NEXT: 0000000000203400 {{.*}} R_X86_64_JUMP_SLOT 0000000000000000 weak + 0
 
 # CHECK2:      Name      Type     Address          Off    Size   ES Flg Lk Inf Al
 # CHECK2:      .plt      PROGBITS 0000000000001310 000310 000030 00 AX   0   0 16
 # CHECK2:      .got.plt  PROGBITS 0000000000003400 000400 000028 00 WA   0   0  8
 # CHECK2:      Relocation section '.rela.plt' at offset {{.*}} contains 2 entries:
-# CHECK2:      0000000000003418 {{.*}} R_X86_64_JUMP_SLOT 0000000000000000 weak + 0
-# CHECK2-NEXT: 0000000000003420 {{.*}} R_X86_64_JUMP_SLOT 0000000000000000 bar + 0
+# CHECK2:      0000000000003418 {{.*}} R_X86_64_JUMP_SLOT 0000000000000000 bar + 0
+# CHECK2-NEXT: 0000000000003420 {{.*}} R_X86_64_JUMP_SLOT 0000000000000000 weak + 0
 
 # DISASM:       <_start>:
 # DISASM-NEXT:    callq {{.*}} <local>
@@ -37,12 +37,12 @@
 # DISASM1-NEXT:             jmpq *8452(%rip)  # 0x2033f0
 # DISASM1-NEXT:             nopl (%rax)
 # DISASM1-EMPTY:
-# DISASM1-NEXT: <weak at plt>:
+# DISASM1-NEXT: <bar at plt>:
 # DISASM1-NEXT: 2012f0:     jmpq *8450(%rip)  # 0x2033f8
 # DISASM1-NEXT:             pushq $0
 # DISASM1-NEXT:             jmp 0x2012e0 <.plt>
 # DISASM1-EMPTY:
-# DISASM1-NEXT: <bar at plt>:
+# DISASM1-NEXT: <weak at plt>:
 # DISASM1-NEXT: 201300:     jmpq *8442(%rip)  # 0x203400
 # DISASM1-NEXT:             pushq $1
 # DISASM1-NEXT:             jmp 0x2012e0 <.plt>
@@ -55,12 +55,12 @@
 # DISASM2-NEXT:             jmpq *8436(%rip)  # 0x3410
 # DISASM2-NEXT:             nopl (%rax)
 # DISASM2-EMPTY:
-# DISASM2-NEXT: <weak at plt>:
+# DISASM2-NEXT: <bar at plt>:
 # DISASM2-NEXT:   1320:     jmpq *8434(%rip)  # 0x3418
 # DISASM2-NEXT:             pushq $0
 # DISASM2-NEXT:             jmp 0x1310 <.plt>
 # DISASM2-EMPTY:
-# DISASM2-NEXT: <bar at plt>:
+# DISASM2-NEXT: <weak at plt>:
 # DISASM2-NEXT:   1330:     jmpq *8426(%rip)  # 0x3420
 # DISASM2-NEXT:             pushq $1
 # DISASM2-NEXT:             jmp 0x1310 <.plt>

diff  --git a/lld/test/ELF/x86-x32-plt.s b/lld/test/ELF/x86-x32-plt.s
index 1b8aad30ce6f3..8c6569fffa41c 100644
--- a/lld/test/ELF/x86-x32-plt.s
+++ b/lld/test/ELF/x86-x32-plt.s
@@ -11,8 +11,8 @@
 # CHECK:      .plt      PROGBITS 002011e0 0001e0 000030 00 AX   0   0 16
 # CHECK:      .got.plt  PROGBITS 00203278 000278 000028 00 WA   0   0  8
 # CHECK:      Relocation section '.rela.plt' at offset {{.*}} contains 2 entries:
-# CHECK:      00203290 {{.*}} R_X86_64_JUMP_SLOT 00000000 weak + 0
-# CHECK-NEXT: 00203298 {{.*}} R_X86_64_JUMP_SLOT 00000000 bar + 0
+# CHECK:      00203290 {{.*}} R_X86_64_JUMP_SLOT 00000000 bar + 0
+# CHECK-NEXT: 00203298 {{.*}} R_X86_64_JUMP_SLOT 00000000 weak + 0
 
 # DISASM:       <_start>:
 # DISASM-NEXT:    callq {{.*}} <local>
@@ -27,12 +27,12 @@
 # DISASM-NEXT:             jmpq *8348(%rip)  # 0x203288
 # DISASM-NEXT:             nopl (%rax)
 # DISASM-EMPTY:
-# DISASM-NEXT: <weak at plt>:
+# DISASM-NEXT: <bar at plt>:
 # DISASM-NEXT: 2011f0:     jmpq *8346(%rip)  # 0x203290
 # DISASM-NEXT:             pushq $0
 # DISASM-NEXT:             jmp 0x2011e0 <.plt>
 # DISASM-EMPTY:
-# DISASM-NEXT: <bar at plt>:
+# DISASM-NEXT: <weak at plt>:
 # DISASM-NEXT: 201200:     jmpq *8338(%rip)  # 0x203298
 # DISASM-NEXT:             pushq $1
 # DISASM-NEXT:             jmp 0x2011e0 <.plt>


        


More information about the llvm-commits mailing list