[lld] 712264b - [ELF] Merge parseSymbolVersion and computeIspreemptible

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 8 17:50:24 PST 2024


Author: Fangrui Song
Date: 2024-12-08T17:50:17-08:00
New Revision: 712264b83c736fac7a7f0d4296f84c1afbd93b1a

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

LOG: [ELF] Merge parseSymbolVersion and computeIspreemptible

ICF needs isPreemptible, which can be combined with parseSymbolVersion.

Added: 
    

Modified: 
    lld/ELF/Driver.cpp
    lld/ELF/ICF.cpp
    lld/ELF/SymbolTable.cpp
    lld/ELF/Symbols.cpp
    lld/ELF/Symbols.h
    lld/ELF/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index bc4b967ccbbbb4..1f90ecccb96f23 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2987,6 +2987,8 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
   if (!ctx.arg.relocatable) {
     llvm::TimeTraceScope timeScope("Process symbol versions");
     ctx.symtab->scanVersionScript();
+
+    parseVersionAndComputeIsPreemptible(ctx);
   }
 
   // Skip the normal linked output if some LTO options are specified.

diff  --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp
index 80ddc3c32cf5d1..1cdcf6be9d8a93 100644
--- a/lld/ELF/ICF.cpp
+++ b/lld/ELF/ICF.cpp
@@ -461,13 +461,6 @@ static void combineRelocHashes(unsigned cnt, InputSection *isec,
 
 // The main function of ICF.
 template <class ELFT> void ICF<ELFT>::run() {
-  // Compute isPreemptible early. We may add more symbols later, so this loop
-  // cannot be merged with the later computeIsPreemptible() pass which is used
-  // by scanRelocations().
-  if (ctx.arg.hasDynSymTab)
-    for (Symbol *sym : ctx.symtab->getSymbols())
-      sym->isPreemptible = computeIsPreemptible(ctx, *sym);
-
   // Two text sections may have identical content and relocations but 
diff erent
   // LSDA, e.g. the two functions may have catch blocks of 
diff erent types. If a
   // text section is referenced by a .eh_frame FDE with LSDA, it is not

diff  --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index 648da94989d7a4..d5b2200b502279 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -350,13 +350,6 @@ void SymbolTable::scanVersionScript() {
         assignAsterisk(pat, &v, true);
   }
 
-  // Symbol themselves might know their versions because symbols
-  // can contain versions in the form of <name>@<version>.
-  // Let them parse and update their names to exclude version suffix.
-  for (Symbol *sym : symVector)
-    if (sym->hasVersionSuffix)
-      sym->parseSymbolVersion(ctx);
-
   // isPreemptible is false at this point. To correctly compute the binding of a
   // Defined (which is used by includeInDynsym(ctx)), we need to know if it is
   // VER_NDX_LOCAL or not. Compute symbol versions before handling

diff  --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index dd530c59c3dc8e..b19381fe439c79 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -11,6 +11,7 @@
 #include "InputFiles.h"
 #include "InputSection.h"
 #include "OutputSections.h"
+#include "SymbolTable.h"
 #include "SyntheticSections.h"
 #include "Target.h"
 #include "Writer.h"
@@ -345,7 +346,7 @@ bool elf::computeIsPreemptible(Ctx &ctx, const Symbol &sym) {
 
   // Only symbols with default visibility that appear in dynsym can be
   // preempted. Symbols with protected visibility cannot be preempted.
-  if (!sym.includeInDynsym(ctx) || sym.visibility() != STV_DEFAULT)
+  if (sym.visibility() != STV_DEFAULT)
     return false;
 
   // At this point copy relocations have not been created yet, so any
@@ -370,6 +371,20 @@ bool elf::computeIsPreemptible(Ctx &ctx, const Symbol &sym) {
   return true;
 }
 
+void elf::parseVersionAndComputeIsPreemptible(Ctx &ctx) {
+  // Symbol themselves might know their versions because symbols
+  // can contain versions in the form of <name>@<version>.
+  // Let them parse and update their names to exclude version suffix.
+  bool hasDynSymTab = ctx.arg.hasDynSymTab;
+  for (Symbol *sym : ctx.symtab->getSymbols()) {
+    if (sym->hasVersionSuffix)
+      sym->parseSymbolVersion(ctx);
+    if (hasDynSymTab)
+      sym->isPreemptible =
+          sym->includeInDynsym(ctx) && computeIsPreemptible(ctx, *sym);
+  }
+}
+
 // Merge symbol properties.
 //
 // When we have many symbols of the same name, we choose one of them,

diff  --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index 85a52e98f87a1a..1a53f3a1e15261 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -527,6 +527,7 @@ void reportDuplicate(Ctx &, const Symbol &sym, const InputFile *newFile,
                      InputSectionBase *errSec, uint64_t errOffset);
 void maybeWarnUnorderableSymbol(Ctx &, const Symbol *sym);
 bool computeIsPreemptible(Ctx &, const Symbol &sym);
+void parseVersionAndComputeIsPreemptible(Ctx &);
 
 } // namespace lld::elf
 

diff  --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 8cd16704ba3ee3..ea9692a2f731b2 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -297,8 +297,11 @@ static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
       }
     }
 
-    if (ctx.arg.hasDynSymTab)
-      sym->isPreemptible = computeIsPreemptible(ctx, *sym);
+    if (ctx.arg.hasDynSymTab) {
+      sym->exportDynamic = sym->includeInDynsym(ctx);
+      sym->isPreemptible =
+          sym->exportDynamic && computeIsPreemptible(ctx, *sym);
+    }
   }
 }
 
@@ -1888,7 +1891,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
       if (ctx.in.symTab)
         ctx.in.symTab->addSymbol(sym);
 
-      if (sym->includeInDynsym(ctx)) {
+      if (sym->exportDynamic) {
         ctx.partitions[sym->partition - 1].dynSymTab->addSymbol(sym);
         if (auto *file = dyn_cast<SharedFile>(sym->file))
           if (file->isNeeded && !sym->isUndefined())


        


More information about the llvm-commits mailing list