[lld] r277115 - Remove `Ignore` flag from SymbolAssignment class.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 28 22:48:40 PDT 2016


Author: ruiu
Date: Fri Jul 29 00:48:39 2016
New Revision: 277115

URL: http://llvm.org/viewvc/llvm-project?rev=277115&view=rev
Log:
Remove `Ignore` flag from SymbolAssignment class.

Previously, Ignore flag is set if we don't want to assign
a value to symbols. It happens if a symbol assingment is in
PROVIDE() and there's already a symbol with the same name.

The previous code had a subtle but that we assume that the
existing symbol is an absolute symbol even if it is not.
This patch fixes the issue by always overwriting an absolute
symbol.

Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/LinkerScript.h

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=277115&r1=277114&r2=277115&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Fri Jul 29 00:48:39 2016
@@ -195,17 +195,6 @@ LinkerScript<ELFT>::filter(std::vector<O
 }
 
 template <class ELFT>
-void LinkerScript<ELFT>::dispatchAssignment(SymbolAssignment *Cmd) {
-  uint64_t Val = Cmd->Expression(Dot);
-  if (Cmd->Name == ".") {
-    Dot = Val;
-  } else if (!Cmd->Ignore) {
-    auto *D = cast<DefinedRegular<ELFT>>(Symtab<ELFT>::X->find(Cmd->Name));
-    D->Value = Val;
-  }
-}
-
-template <class ELFT>
 void LinkerScript<ELFT>::assignAddresses(
     ArrayRef<OutputSectionBase<ELFT> *> Sections) {
   // Orphan sections are sections present in the input files which
@@ -226,7 +215,11 @@ void LinkerScript<ELFT>::assignAddresses
 
   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
     if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) {
-      dispatchAssignment(Cmd);
+      if (Cmd->Name == ".") {
+        Dot = Cmd->Expression(Dot);
+      } else if (Cmd->Sym) {
+        cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(Dot);
+      }
       continue;
     }
 
@@ -368,22 +361,25 @@ int LinkerScript<ELFT>::compareSections(
   return I < J ? -1 : 1;
 }
 
+// Add symbols defined by linker scripts.
 template <class ELFT> void LinkerScript<ELFT>::addScriptedSymbols() {
   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
     auto *Cmd = dyn_cast<SymbolAssignment>(Base.get());
     if (!Cmd || Cmd->Name == ".")
       continue;
 
+    // If a symbol was in PROVIDE(), define it only when it is an
+    // undefined symbol.
     SymbolBody *B = Symtab<ELFT>::X->find(Cmd->Name);
-    // The semantic of PROVIDE is that of introducing a symbol only if
-    // it's not defined and there's at least a reference to it.
-    if ((!B && !Cmd->Provide) || (B && B->isUndefined()))
-      Symtab<ELFT>::X->addAbsolute(Cmd->Name,
-                                   Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT);
-    else
-      // Symbol already exists in symbol table. If it is provided
-      // then we can't override its value.
-      Cmd->Ignore = Cmd->Provide;
+    if (Cmd->Provide && !(B && B->isUndefined()))
+      continue;
+
+    // Define an absolute symbol. The symbol value will be assigned later.
+    // (At this point, we don't know the final address yet.)
+    Symbol *Sym = Symtab<ELFT>::X->addUndefined(Cmd->Name);
+    replaceBody<DefinedRegular<ELFT>>(Sym, Cmd->Name, STV_DEFAULT);
+    Sym->Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
+    Cmd->Sym = Sym->body();
   }
 }
 

Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=277115&r1=277114&r2=277115&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Fri Jul 29 00:48:39 2016
@@ -20,6 +20,7 @@
 
 namespace lld {
 namespace elf {
+class SymbolBody;
 template <class ELFT> class InputSectionBase;
 template <class ELFT> class OutputSectionBase;
 template <class ELFT> class OutputSectionFactory;
@@ -56,9 +57,8 @@ struct SymbolAssignment : BaseCommand {
   StringRef Name;
   Expr Expression;
   bool Provide = false;
-  // Hidden and Ignore can be true, only if Provide is true
   bool Hidden = false;
-  bool Ignore = false;
+  SymbolBody *Sym = nullptr;
 };
 
 // Linker scripts allow additional constraints to be put on ouput sections.




More information about the llvm-commits mailing list