[lld] r267555 - Store the binding in the Symbol.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 26 06:50:47 PDT 2016


Author: rafael
Date: Tue Apr 26 08:50:46 2016
New Revision: 267555

URL: http://llvm.org/viewvc/llvm-project?rev=267555&view=rev
Log:
Store the binding in the Symbol.

This remove a fixme, cleans up the weak undef interaction with archives and
lets us keep weak undefs still weak if they resolve to shared.

Added:
    lld/trunk/test/ELF/weak-undef-shared.s
Modified:
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/relocation-copy-alias.s

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=267555&r1=267554&r2=267555&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Tue Apr 26 08:50:46 2016
@@ -1363,12 +1363,13 @@ static bool sortMipsSymbols(const std::p
 }
 
 static uint8_t getSymbolBinding(SymbolBody *Body) {
-  uint8_t Visibility = Body->Backref->Visibility;
+  Symbol *S = Body->Backref;
+  uint8_t Visibility = S->Visibility;
   if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
     return STB_LOCAL;
-  if (Config->NoGnuUnique && Body->Binding == STB_GNU_UNIQUE)
+  if (Config->NoGnuUnique && S->Binding == STB_GNU_UNIQUE)
     return STB_GLOBAL;
-  return Body->Binding;
+  return S->Binding;
 }
 
 template <class ELFT> void SymbolTableSection<ELFT>::finalize() {
@@ -1442,7 +1443,7 @@ void SymbolTableSection<ELFT>::writeLoca
       }
       ESym->st_name = P.second;
       ESym->st_size = Body.template getSize<ELFT>();
-      ESym->setBindingAndType(Body.Binding, Body.Type);
+      ESym->setBindingAndType(STB_LOCAL, Body.Type);
       Buf += sizeof(*ESym);
     }
   }

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=267555&r1=267554&r2=267555&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Tue Apr 26 08:50:46 2016
@@ -244,6 +244,7 @@ template <class ELFT> void SymbolTable<E
   SymbolBody *Existing = Sym->Body;
 
   if (auto *L = dyn_cast<Lazy>(Existing)) {
+    Sym->Binding = New->Binding;
     if (New->isUndefined()) {
       addMemberFile(New, L);
       return;
@@ -270,8 +271,11 @@ template <class ELFT> void SymbolTable<E
       error(S);
     return;
   }
-  if (Comp < 0)
+  if (Comp < 0) {
     Sym->Body = New;
+    if (!New->isShared())
+      Sym->Binding = New->Binding;
+  }
 }
 
 static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
@@ -300,6 +304,7 @@ template <class ELFT> Symbol *SymbolTabl
   if (P.second) {
     Sym = new (Alloc) Symbol;
     Sym->Body = New;
+    Sym->Binding = New->isShared() ? STB_GLOBAL : New->Binding;
     Sym->Visibility = STV_DEFAULT;
     Sym->IsUsedInRegularObj = false;
     Sym->ExportDynamic = false;
@@ -353,7 +358,6 @@ void SymbolTable<ELFT>::addMemberFile(Sy
   // but we also need to preserve its binding and type.
   if (Undef->isWeak()) {
     // FIXME: Consider moving these members to Symbol.
-    L->Binding = Undef->Binding;
     L->Type = Undef->Type;
     return;
   }

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=267555&r1=267554&r2=267555&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Tue Apr 26 08:50:46 2016
@@ -44,6 +44,13 @@ std::string demangle(StringRef Name);
 struct Symbol {
   SymbolBody *Body;
 
+  // Symbol binding. This is on the Symbol to track changes during resolution.
+  // In particular:
+  // An undefined weak is still weak when it resolves to a shared library.
+  // An undefined weak will not fetch archive members, but we have to remember
+  // it is weak.
+  uint8_t Binding;
+
   // Symbol visibility. This is the computed minimum visibility of all
   // observed non-DSO symbols.
   unsigned Visibility : 2;
@@ -66,6 +73,8 @@ struct Symbol {
   unsigned VersionScriptGlobal : 1;
 
   bool includeInDynsym() const;
+
+  bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
 };
 
 // The base class for real symbol classes.

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=267555&r1=267554&r2=267555&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Apr 26 08:50:46 2016
@@ -424,7 +424,8 @@ static int32_t findMipsPairedAddend(cons
 // True if non-preemptable symbol always has the same value regardless of where
 // the DSO is loaded.
 template <class ELFT> static bool isAbsolute(const SymbolBody &Body) {
-  if (Body.isUndefined() && Body.isWeak())
+  Symbol *Sym = Body.Backref;
+  if (Body.isUndefined() && Sym->isWeak())
     return true; // always 0
   if (const auto *DR = dyn_cast<DefinedRegular<ELFT>>(&Body))
     return DR->Section == nullptr; // Absolute symbol.
@@ -521,7 +522,8 @@ void Writer<ELFT>::scanRelocs(InputSecti
     const RelTy &RI = *I;
     uint32_t SymIndex = RI.getSymbol(Config->Mips64EL);
     SymbolBody &OrigBody = File.getSymbolBody(SymIndex);
-    SymbolBody &Body = OrigBody.repl();
+    Symbol *Sym = OrigBody.Backref;
+    SymbolBody &Body = Sym ? *Sym->Body : OrigBody;
     uint32_t Type = RI.getType(Config->Mips64EL);
 
     // Ignore "hint" relocation because it is for optional code optimization.
@@ -533,7 +535,7 @@ void Writer<ELFT>::scanRelocs(InputSecti
       continue;
 
     // Set "used" bit for --as-needed.
-    if (OrigBody.isUndefined() && !OrigBody.isWeak())
+    if (OrigBody.isUndefined() && Sym && !Sym->isWeak())
       if (auto *S = dyn_cast<SharedSymbol<ELFT>>(&Body))
         S->File->IsUsed = true;
 
@@ -1342,7 +1344,7 @@ template <class ELFT> void Writer<ELFT>:
   std::vector<DefinedCommon *> CommonSymbols;
   for (Symbol *S : Symtab.getSymbols()) {
     SymbolBody *Body = S->Body;
-    if (Body->isUndefined() && !Body->isWeak()) {
+    if (Body->isUndefined() && !S->isWeak()) {
       auto *U = dyn_cast<UndefinedElf<ELFT>>(Body);
       if (!U || !U->canKeepUndefined())
         reportUndefined<ELFT>(Symtab, Body);

Modified: lld/trunk/test/ELF/relocation-copy-alias.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/relocation-copy-alias.s?rev=267555&r1=267554&r2=267555&view=diff
==============================================================================
--- lld/trunk/test/ELF/relocation-copy-alias.s (original)
+++ lld/trunk/test/ELF/relocation-copy-alias.s Tue Apr 26 08:50:46 2016
@@ -37,7 +37,7 @@ movl $5, b2
 // CHECK:      Name: b1
 // CHECK-NEXT: Value: [[B:.*]]
 // CHECK-NEXT: Size: 1
-// CHECK-NEXT: Binding: Weak (0x2)
+// CHECK-NEXT: Binding: Global
 // CHECK-NEXT: Type: Object (0x1)
 // CHECK-NEXT: Other: 0
 // CHECK-NEXT: Section: .bss
@@ -45,7 +45,7 @@ movl $5, b2
 // CHECK:      Name: b2
 // CHECK-NEXT: Value: [[B]]
 // CHECK-NEXT: Size: 1
-// CHECK-NEXT: Binding: Weak (0x2)
+// CHECK-NEXT: Binding: Global
 // CHECK-NEXT: Type: Object (0x1)
 // CHECK-NEXT: Other: 0
 // CHECK-NEXT: Section: .bss
@@ -53,7 +53,7 @@ movl $5, b2
 // CHECK:      Name: a2
 // CHECK-NEXT: Value: [[A]]
 // CHECK-NEXT: Size: 1
-// CHECK-NEXT: Binding: Weak (0x2)
+// CHECK-NEXT: Binding: Global
 // CHECK-NEXT: Type: Object (0x1)
 // CHECK-NEXT: Other: 0
 // CHECK-NEXT: Section: .bss

Added: lld/trunk/test/ELF/weak-undef-shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/weak-undef-shared.s?rev=267555&view=auto
==============================================================================
--- lld/trunk/test/ELF/weak-undef-shared.s (added)
+++ lld/trunk/test/ELF/weak-undef-shared.s Tue Apr 26 08:50:46 2016
@@ -0,0 +1,19 @@
+// REQUIRES: x86
+// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: llvm-mc %p/Inputs/shared.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
+// RUN: ld.lld %t2.o -o %t2.so -shared
+// RUN: ld.lld %t.o %t2.so -o %t.exe
+// RUN: llvm-readobj -t %t.exe | FileCheck %s
+
+// CHECK:      Name: bar
+// CHECK-NEXT: Value: 0x11020
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Weak
+// CHECK-NEXT: Type: Function
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: Undefined
+
+.global _start
+_start:
+        .weak bar
+        .quad bar




More information about the llvm-commits mailing list