[lld] r267639 - ELF: Re-implement -u directly and remove CanKeepUndefined flag.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 26 17:05:03 PDT 2016


Author: pcc
Date: Tue Apr 26 19:05:03 2016
New Revision: 267639

URL: http://llvm.org/viewvc/llvm-project?rev=267639&view=rev
Log:
ELF: Re-implement -u directly and remove CanKeepUndefined flag.

The semantics of the -u flag are to load the lazy symbol named by the flag. We
were previously relying on this behavior falling out of symbol resolution
against a synthetic undefined symbol, but that didn't quite give us the
correct behavior, so we needed a flag to mark symbols created with -u so
we could treat them specially in the writer. However, it's simpler and less
error prone to implement the required behavior directly and remove the flag.

This fixes an issue where symbols loaded with -u would receive hidden
visibility even when the definition in an object file had wider visibility.

Differential Revision: http://reviews.llvm.org/D19560

Modified:
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/SymbolTable.h
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/undefined-opt.s

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=267639&r1=267638&r2=267639&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Tue Apr 26 19:05:03 2016
@@ -483,9 +483,7 @@ template <class ELFT> void LinkerDriver:
   if (HasError)
     return; // There were duplicate symbols or incompatible files
 
-  for (StringRef S : Config->Undefined)
-    Symtab.addUndefinedOpt(S);
-
+  Symtab.scanUndefinedFlags();
   Symtab.scanShlibUndefined();
   Symtab.scanDynamicList();
   Symtab.scanVersionScript();

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=267639&r1=267638&r2=267639&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Tue Apr 26 19:05:03 2016
@@ -151,17 +151,7 @@ template <class ELFT> void SymbolTable<E
 template <class ELFT>
 SymbolBody *SymbolTable<ELFT>::addUndefined(StringRef Name) {
   auto *Sym = new (Alloc)
-      UndefinedElf<ELFT>(Name, STB_GLOBAL, STV_DEFAULT, /*Type*/ 0, false);
-  resolve(Sym);
-  return Sym;
-}
-
-// Add an undefined symbol. Unlike addUndefined, that symbol
-// doesn't have to be resolved, thus "opt" (optional).
-template <class ELFT>
-SymbolBody *SymbolTable<ELFT>::addUndefinedOpt(StringRef Name) {
-  auto *Sym = new (Alloc)
-      UndefinedElf<ELFT>(Name, STB_GLOBAL, STV_HIDDEN, /*Type*/ 0, true);
+      UndefinedElf<ELFT>(Name, STB_GLOBAL, STV_DEFAULT, /*Type*/ 0);
   resolve(Sym);
   return Sym;
 }
@@ -368,6 +358,16 @@ void SymbolTable<ELFT>::addMemberFile(Sy
     addFile(std::move(File));
 }
 
+// Process undefined (-u) flags by loading lazy symbols named by those flags.
+template <class ELFT>
+void SymbolTable<ELFT>::scanUndefinedFlags() {
+  for (StringRef S : Config->Undefined)
+    if (SymbolBody *Sym = find(S))
+      if (auto *L = dyn_cast<Lazy>(Sym))
+        if (std::unique_ptr<InputFile> File = L->getFile())
+          addFile(std::move(File));
+}
+
 // This function takes care of the case in which shared libraries depend on
 // the user program (not the other way, which is usual). Shared libraries
 // may have undefined symbols, expecting that the user program provides

Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=267639&r1=267638&r2=267639&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Tue Apr 26 19:05:03 2016
@@ -59,6 +59,7 @@ public:
   DefinedRegular<ELFT> *addIgnored(StringRef Name,
                                    uint8_t Visibility = llvm::ELF::STV_HIDDEN);
 
+  void scanUndefinedFlags();
   void scanShlibUndefined();
   void scanDynamicList();
   void scanVersionScript();

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=267639&r1=267638&r2=267639&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Tue Apr 26 19:05:03 2016
@@ -104,7 +104,6 @@ SymbolBody::SymbolBody(Kind K, StringRef
 }
 
 void SymbolBody::init() {
-  CanKeepUndefined = false;
   NeedsCopyOrPltAddr = false;
   CanOmitFromDynSym = false;
 }
@@ -245,11 +244,8 @@ UndefinedElf<ELFT>::UndefinedElf(StringR
 
 template <typename ELFT>
 UndefinedElf<ELFT>::UndefinedElf(StringRef Name, uint8_t Binding,
-                                 uint8_t StOther, uint8_t Type,
-                                 bool CanKeepUndefined)
-    : SymbolBody(SymbolBody::UndefinedElfKind, Name, Binding, StOther, Type) {
-  this->CanKeepUndefined = CanKeepUndefined;
-}
+                                 uint8_t StOther, uint8_t Type)
+    : SymbolBody(SymbolBody::UndefinedElfKind, Name, Binding, StOther, Type) {}
 
 template <typename ELFT>
 UndefinedElf<ELFT>::UndefinedElf(const Elf_Sym &Sym)

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=267639&r1=267638&r2=267639&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Tue Apr 26 19:05:03 2016
@@ -177,8 +177,6 @@ public:
   // symbol or if the symbol should point to its plt entry.
   unsigned NeedsCopyOrPltAddr : 1;
 
-  unsigned CanKeepUndefined : 1;
-
   // The following fields have the same meaning as the ELF symbol attributes.
   uint8_t Type;    // symbol type
   uint8_t Binding; // symbol binding
@@ -325,10 +323,7 @@ template <class ELFT> class UndefinedElf
 public:
   UndefinedElf(StringRef N, const Elf_Sym &Sym);
   UndefinedElf(const Elf_Sym &Sym);
-  UndefinedElf(StringRef Name, uint8_t Binding, uint8_t StOther, uint8_t Type,
-               bool CanKeepUndefined);
-
-  bool canKeepUndefined() const { return CanKeepUndefined; }
+  UndefinedElf(StringRef Name, uint8_t Binding, uint8_t StOther, uint8_t Type);
 
   uintX_t Size;
 

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=267639&r1=267638&r2=267639&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Apr 26 19:05:03 2016
@@ -1339,11 +1339,8 @@ template <class ELFT> void Writer<ELFT>:
       if (auto *SS = dyn_cast<SharedSymbol<ELFT>>(Body))
         SS->File->IsUsed = true;
 
-    if (Body->isUndefined() && !S->isWeak()) {
-      auto *U = dyn_cast<UndefinedElf<ELFT>>(Body);
-      if (!U || !U->canKeepUndefined())
-        reportUndefined<ELFT>(Symtab, Body);
-    }
+    if (Body->isUndefined() && !S->isWeak())
+      reportUndefined<ELFT>(Symtab, Body);
 
     if (auto *C = dyn_cast<DefinedCommon>(Body))
       CommonSymbols.push_back(C);

Modified: lld/trunk/test/ELF/undefined-opt.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/undefined-opt.s?rev=267639&r1=267638&r2=267639&view=diff
==============================================================================
--- lld/trunk/test/ELF/undefined-opt.s (original)
+++ lld/trunk/test/ELF/undefined-opt.s Tue Apr 26 19:05:03 2016
@@ -51,5 +51,16 @@
 # UNK-UNDEFINED-SO-NOT:     Name: unknown
 # UNK-UNDEFINED-SO: ]
 
+# Added undefined symbols should appear in the dynamic table if necessary.
+# RUN: ld.lld -shared -o %t5 %t.o -u export
+# RUN: llvm-readobj --dyn-symbols %t5 | \
+# RUN:     FileCheck --check-prefix=EXPORT-SO %s
+# EXPORT-SO: DynamicSymbols [
+# EXPORT-SO:   Name: export
+# EXPORT-SO: ]
+
 .globl _start;
 _start:
+
+.globl export
+export:




More information about the llvm-commits mailing list