[lld] 03be619 - [ELF] Move ElfSym into Ctx. NFC

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 3 11:20:37 PDT 2024


Author: Fangrui Song
Date: 2024-08-03T11:20:32-07:00
New Revision: 03be619d9434de0a9616660a2119675635239a5b

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

LOG: [ELF] Move ElfSym into Ctx. NFC

Ctx was introduced in March 2022 as a more suitable place for such
singletons. ctx's hidden visibility optimizes generated instructions.

This change fixes a pitfall: certain ElfSym members (e.g.
globalOffsetTable, tlsModuleBase) were not zeroed and might be stale
when lld::elf::link was invoked the second time.

Added: 
    

Modified: 
    lld/ELF/Arch/Mips.cpp
    lld/ELF/Arch/RISCV.cpp
    lld/ELF/Config.h
    lld/ELF/Driver.cpp
    lld/ELF/InputSection.cpp
    lld/ELF/Symbols.cpp
    lld/ELF/Symbols.h
    lld/ELF/SyntheticSections.cpp
    lld/ELF/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/Mips.cpp b/lld/ELF/Arch/Mips.cpp
index e36e9d59a7401..7c7137117d78e 100644
--- a/lld/ELF/Arch/Mips.cpp
+++ b/lld/ELF/Arch/Mips.cpp
@@ -121,9 +121,9 @@ RelExpr MIPS<ELFT>::getRelExpr(RelType type, const Symbol &s,
     // offset between start of function and 'gp' value which by default
     // equal to the start of .got section. In that case we consider these
     // relocations as relative.
-    if (&s == ElfSym::mipsGpDisp)
+    if (&s == ctx.sym.mipsGpDisp)
       return R_MIPS_GOT_GP_PC;
-    if (&s == ElfSym::mipsLocalGp)
+    if (&s == ctx.sym.mipsLocalGp)
       return R_MIPS_GOT_GP;
     [[fallthrough]];
   case R_MIPS_32:

diff  --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 56759c28dcf41..8c2db2145f305 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -466,7 +466,7 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
 
   case INTERNAL_R_RISCV_GPREL_I:
   case INTERNAL_R_RISCV_GPREL_S: {
-    Defined *gp = ElfSym::riscvGlobalPointer;
+    Defined *gp = ctx.sym.riscvGlobalPointer;
     int64_t displace = SignExtend64(val - gp->getVA(), bits);
     checkInt(loc, displace, 12, rel);
     uint32_t insn = (read32le(loc) & ~(31 << 15)) | (X_GP << 15);
@@ -789,7 +789,7 @@ static void relaxTlsLe(const InputSection &sec, size_t i, uint64_t loc,
 
 static void relaxHi20Lo12(const InputSection &sec, size_t i, uint64_t loc,
                           Relocation &r, uint32_t &remove) {
-  const Defined *gp = ElfSym::riscvGlobalPointer;
+  const Defined *gp = ctx.sym.riscvGlobalPointer;
   if (!gp)
     return;
 

diff  --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 162631aaba42a..78bfea561445f 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -42,6 +42,7 @@ class ELFFileBase;
 class SharedFile;
 class InputSectionBase;
 class EhInputSection;
+class Defined;
 class Symbol;
 class BitcodeCompiler;
 class OutputSection;
@@ -494,6 +495,46 @@ struct Ctx {
   };
   OutSections out;
 
+  // Some linker-generated symbols need to be created as
+  // Defined symbols.
+  struct ElfSym {
+    // __bss_start
+    Defined *bss;
+
+    // etext and _etext
+    Defined *etext1;
+    Defined *etext2;
+
+    // edata and _edata
+    Defined *edata1;
+    Defined *edata2;
+
+    // end and _end
+    Defined *end1;
+    Defined *end2;
+
+    // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
+    // be at some offset from the base of the .got section, usually 0 or
+    // the end of the .got.
+    Defined *globalOffsetTable;
+
+    // _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS.
+    Defined *mipsGp;
+    Defined *mipsGpDisp;
+    Defined *mipsLocalGp;
+
+    // __global_pointer$ for RISC-V.
+    Defined *riscvGlobalPointer;
+
+    // __rel{,a}_iplt_{start,end} symbols.
+    Defined *relaIpltStart;
+    Defined *relaIpltEnd;
+
+    // _TLS_MODULE_BASE_ on targets that support TLSDESC.
+    Defined *tlsModuleBase;
+  };
+  ElfSym sym;
+
   SmallVector<std::unique_ptr<MemoryBuffer>> memoryBuffers;
   SmallVector<ELFFileBase *, 0> objectFiles;
   SmallVector<SharedFile *, 0> sharedFiles;

diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 7b5b86363ac9c..9f03aaec864ca 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -98,6 +98,8 @@ void Ctx::reset() {
   tlsPhdr = nullptr;
   out = OutSections{};
 
+  sym = ElfSym{};
+
   memoryBuffers.clear();
   objectFiles.clear();
   sharedFiles.clear();

diff  --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 7f8dded51fdab..da4c90516ec30 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -665,7 +665,7 @@ static Relocation *getRISCVPCRelHi20(const Symbol *sym, uint64_t addend) {
 // target-specific adjustment to produce a thread-pointer-relative offset.
 static int64_t getTlsTpOffset(const Symbol &s) {
   // On targets that support TLSDESC, _TLS_MODULE_BASE_ at tpoff = 0.
-  if (&s == ElfSym::tlsModuleBase)
+  if (&s == ctx.sym.tlsModuleBase)
     return 0;
 
   // There are 2 TLS layouts. Among targets we support, x86 uses TLS Variant 2

diff  --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 9cab824c37c3c..4e1ae819b86fa 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -58,22 +58,6 @@ std::string lld::toString(const elf::Symbol &sym) {
   return ret;
 }
 
-Defined *ElfSym::bss;
-Defined *ElfSym::etext1;
-Defined *ElfSym::etext2;
-Defined *ElfSym::edata1;
-Defined *ElfSym::edata2;
-Defined *ElfSym::end1;
-Defined *ElfSym::end2;
-Defined *ElfSym::globalOffsetTable;
-Defined *ElfSym::mipsGp;
-Defined *ElfSym::mipsGpDisp;
-Defined *ElfSym::mipsLocalGp;
-Defined *ElfSym::riscvGlobalPointer;
-Defined *ElfSym::relaIpltStart;
-Defined *ElfSym::relaIpltEnd;
-Defined *ElfSym::tlsModuleBase;
-
 static uint64_t getSymVA(const Symbol &sym, int64_t addend) {
   switch (sym.kind()) {
   case Symbol::DefinedKind: {

diff  --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index ff825615658eb..05aed16bfb0dc 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -501,45 +501,6 @@ class LazySymbol : public Symbol {
   static bool classof(const Symbol *s) { return s->kind() == LazyKind; }
 };
 
-// Some linker-generated symbols need to be created as
-// Defined symbols.
-struct ElfSym {
-  // __bss_start
-  static Defined *bss;
-
-  // etext and _etext
-  static Defined *etext1;
-  static Defined *etext2;
-
-  // edata and _edata
-  static Defined *edata1;
-  static Defined *edata2;
-
-  // end and _end
-  static Defined *end1;
-  static Defined *end2;
-
-  // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
-  // be at some offset from the base of the .got section, usually 0 or
-  // the end of the .got.
-  static Defined *globalOffsetTable;
-
-  // _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS.
-  static Defined *mipsGp;
-  static Defined *mipsGpDisp;
-  static Defined *mipsLocalGp;
-
-  // __global_pointer$ for RISC-V.
-  static Defined *riscvGlobalPointer;
-
-  // __rel{,a}_iplt_{start,end} symbols.
-  static Defined *relaIpltStart;
-  static Defined *relaIpltEnd;
-
-  // _TLS_MODULE_BASE_ on targets that support TLSDESC.
-  static Defined *tlsModuleBase;
-};
-
 // A buffer class that is large enough to hold any Symbol-derived
 // object. We allocate memory using this class and instantiate a symbol
 // using the placement new.

diff  --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 81068e65bcfea..c27ab2b67dc2b 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -702,7 +702,7 @@ uint64_t GotSection::getGlobalDynOffset(const Symbol &b) const {
 
 void GotSection::finalizeContents() {
   if (config->emachine == EM_PPC64 &&
-      numEntries <= target->gotHeaderEntriesNum && !ElfSym::globalOffsetTable)
+      numEntries <= target->gotHeaderEntriesNum && !ctx.sym.globalOffsetTable)
     size = 0;
   else
     size = numEntries * config->wordsize;
@@ -1090,7 +1090,7 @@ uint64_t MipsGotSection::getGp(const InputFile *f) const {
   // returns "common" _gp value. For secondary GOTs calculate
   // individual _gp values.
   if (!f || f->mipsGotIndex == uint32_t(-1) || f->mipsGotIndex == 0)
-    return ElfSym::mipsGp->getVA(0);
+    return ctx.sym.mipsGp->getVA(0);
   return getVA() + gots[f->mipsGotIndex].startIndex * config->wordsize + 0x7ff0;
 }
 
@@ -4860,7 +4860,7 @@ template <class ELFT> void elf::createSyntheticSections() {
 
   // _GLOBAL_OFFSET_TABLE_ is defined relative to either .got.plt or .got. Treat
   // it as a relocation and ensure the referenced section is created.
-  if (ElfSym::globalOffsetTable && config->emachine != EM_MIPS) {
+  if (ctx.sym.globalOffsetTable && config->emachine != EM_MIPS) {
     if (target->gotBaseSymInGotPlt)
       in.gotPlt->hasGotPltOffRel = true;
     else

diff  --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index bb4b958d87c42..648828e459824 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -167,19 +167,19 @@ void elf::addReservedSymbols() {
     // to GOT. Default offset is 0x7ff0.
     // See "Global Data Symbols" in Chapter 6 in the following document:
     // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
-    ElfSym::mipsGp = addAbsolute("_gp");
+    ctx.sym.mipsGp = addAbsolute("_gp");
 
     // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
     // start of function and 'gp' pointer into GOT.
     if (symtab.find("_gp_disp"))
-      ElfSym::mipsGpDisp = addAbsolute("_gp_disp");
+      ctx.sym.mipsGpDisp = addAbsolute("_gp_disp");
 
     // The __gnu_local_gp is a magic symbol equal to the current value of 'gp'
     // pointer. This symbol is used in the code generated by .cpload pseudo-op
     // in case of using -mno-shared option.
     // https://sourceware.org/ml/binutils/2004-12/msg00094.html
     if (symtab.find("__gnu_local_gp"))
-      ElfSym::mipsLocalGp = addAbsolute("__gnu_local_gp");
+      ctx.sym.mipsLocalGp = addAbsolute("__gnu_local_gp");
   } else if (config->emachine == EM_PPC) {
     // glibc *crt1.o has a undefined reference to _SDA_BASE_. Since we don't
     // support Small Data Area, define it arbitrarily as 0.
@@ -212,7 +212,7 @@ void elf::addReservedSymbols() {
 
     s->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL, STV_HIDDEN,
                        STT_NOTYPE, gotOff, /*size=*/0, ctx.out.elfHeader});
-    ElfSym::globalOffsetTable = cast<Defined>(s);
+    ctx.sym.globalOffsetTable = cast<Defined>(s);
   }
 
   // __ehdr_start is the location of ELF file headers. Note that we define
@@ -238,13 +238,13 @@ void elf::addReservedSymbols() {
     return addOptionalRegular(s, ctx.out.elfHeader, pos, STV_DEFAULT);
   };
 
-  ElfSym::bss = add("__bss_start", 0);
-  ElfSym::end1 = add("end", -1);
-  ElfSym::end2 = add("_end", -1);
-  ElfSym::etext1 = add("etext", -1);
-  ElfSym::etext2 = add("_etext", -1);
-  ElfSym::edata1 = add("edata", -1);
-  ElfSym::edata2 = add("_edata", -1);
+  ctx.sym.bss = add("__bss_start", 0);
+  ctx.sym.end1 = add("end", -1);
+  ctx.sym.end2 = add("_end", -1);
+  ctx.sym.etext1 = add("etext", -1);
+  ctx.sym.etext2 = add("_etext", -1);
+  ctx.sym.edata1 = add("edata", -1);
+  ctx.sym.edata2 = add("_edata", -1);
 }
 
 static void demoteDefined(Defined &sym, DenseMap<SectionBase *, size_t> &map) {
@@ -799,10 +799,10 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
   // We'll override ctx.out.elfHeader with relaDyn later when we are sure that
   // .rela.dyn will be present in the output.
   std::string name = config->isRela ? "__rela_iplt_start" : "__rel_iplt_start";
-  ElfSym::relaIpltStart =
+  ctx.sym.relaIpltStart =
       addOptionalRegular(name, ctx.out.elfHeader, 0, STV_HIDDEN);
   name.replace(name.size() - 5, 5, "end");
-  ElfSym::relaIpltEnd =
+  ctx.sym.relaIpltEnd =
       addOptionalRegular(name, ctx.out.elfHeader, 0, STV_HIDDEN);
 }
 
@@ -812,21 +812,21 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
 // time any references to these symbols are processed and is equivalent to
 // defining these symbols explicitly in the linker script.
 template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
-  if (ElfSym::globalOffsetTable) {
+  if (ctx.sym.globalOffsetTable) {
     // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention usually
     // to the start of the .got or .got.plt section.
     InputSection *sec = in.gotPlt.get();
     if (!target->gotBaseSymInGotPlt)
       sec = in.mipsGot ? cast<InputSection>(in.mipsGot.get())
                        : cast<InputSection>(in.got.get());
-    ElfSym::globalOffsetTable->section = sec;
+    ctx.sym.globalOffsetTable->section = sec;
   }
 
   // .rela_iplt_{start,end} mark the start and the end of .rel[a].dyn.
-  if (ElfSym::relaIpltStart && mainPart->relaDyn->isNeeded()) {
-    ElfSym::relaIpltStart->section = mainPart->relaDyn.get();
-    ElfSym::relaIpltEnd->section = mainPart->relaDyn.get();
-    ElfSym::relaIpltEnd->value = mainPart->relaDyn->getSize();
+  if (ctx.sym.relaIpltStart && mainPart->relaDyn->isNeeded()) {
+    ctx.sym.relaIpltStart->section = mainPart->relaDyn.get();
+    ctx.sym.relaIpltEnd->section = mainPart->relaDyn.get();
+    ctx.sym.relaIpltEnd->value = mainPart->relaDyn->getSize();
   }
 
   PhdrEntry *last = nullptr;
@@ -847,10 +847,10 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
   if (lastRO) {
     // _etext is the first location after the last read-only loadable segment
     // that does not contain large sections.
-    if (ElfSym::etext1)
-      ElfSym::etext1->section = lastRO;
-    if (ElfSym::etext2)
-      ElfSym::etext2->section = lastRO;
+    if (ctx.sym.etext1)
+      ctx.sym.etext1->section = lastRO;
+    if (ctx.sym.etext2)
+      ctx.sym.etext2->section = lastRO;
   }
 
   if (last) {
@@ -864,34 +864,34 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
         break;
     }
 
-    if (ElfSym::edata1)
-      ElfSym::edata1->section = edata;
-    if (ElfSym::edata2)
-      ElfSym::edata2->section = edata;
+    if (ctx.sym.edata1)
+      ctx.sym.edata1->section = edata;
+    if (ctx.sym.edata2)
+      ctx.sym.edata2->section = edata;
 
     // _end is the first location after the uninitialized data region.
-    if (ElfSym::end1)
-      ElfSym::end1->section = last->lastSec;
-    if (ElfSym::end2)
-      ElfSym::end2->section = last->lastSec;
+    if (ctx.sym.end1)
+      ctx.sym.end1->section = last->lastSec;
+    if (ctx.sym.end2)
+      ctx.sym.end2->section = last->lastSec;
   }
 
-  if (ElfSym::bss) {
+  if (ctx.sym.bss) {
     // On RISC-V, set __bss_start to the start of .sbss if present.
     OutputSection *sbss =
         config->emachine == EM_RISCV ? findSection(".sbss") : nullptr;
-    ElfSym::bss->section = sbss ? sbss : findSection(".bss");
+    ctx.sym.bss->section = sbss ? sbss : findSection(".bss");
   }
 
   // Setup MIPS _gp_disp/__gnu_local_gp symbols which should
   // be equal to the _gp symbol's value.
-  if (ElfSym::mipsGp) {
+  if (ctx.sym.mipsGp) {
     // Find GP-relative section with the lowest address
     // and use this address to calculate default _gp value.
     for (OutputSection *os : outputSections) {
       if (os->flags & SHF_MIPS_GPREL) {
-        ElfSym::mipsGp->section = os;
-        ElfSym::mipsGp->value = 0x7ff0;
+        ctx.sym.mipsGp->section = os;
+        ctx.sym.mipsGp->value = 0x7ff0;
         break;
       }
     }
@@ -1725,7 +1725,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
     // value/section does not matter but it has to be relative, so set its
     // st_shndx arbitrarily to 1 (ctx.out.elfHeader).
     if (config->emachine == EM_RISCV) {
-      ElfSym::riscvGlobalPointer = nullptr;
       if (!config->shared) {
         OutputSection *sec = findSection(".sdata");
         addOptionalRegular("__global_pointer$", sec ? sec : ctx.out.elfHeader,
@@ -1735,7 +1734,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
         if (config->relaxGP) {
           Symbol *s = symtab.find("__global_pointer$");
           if (s && s->isDefined())
-            ElfSym::riscvGlobalPointer = cast<Defined>(s);
+            ctx.sym.riscvGlobalPointer = cast<Defined>(s);
         }
       }
     }
@@ -1757,7 +1756,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
         s->resolve(Defined{ctx.internalFile, StringRef(), STB_GLOBAL,
                            STV_HIDDEN, STT_TLS, /*value=*/0, 0,
                            /*section=*/nullptr});
-        ElfSym::tlsModuleBase = cast<Defined>(s);
+        ctx.sym.tlsModuleBase = cast<Defined>(s);
       }
     }
 


        


More information about the llvm-commits mailing list