[lld] r288461 - Allow duplicated abs symbols with the same value.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 1 18:58:22 PST 2016


Author: rafael
Date: Thu Dec  1 20:58:21 2016
New Revision: 288461

URL: http://llvm.org/viewvc/llvm-project?rev=288461&view=rev
Log:
Allow duplicated abs symbols with the same value.

This is a fairly reasonable bfd extension since there is one obvious value.

dtrace depends on this feature as it creates multiple absolute
symbols with the same value.

Added:
    lld/trunk/test/ELF/abs-conflict.s
Modified:
    lld/trunk/ELF/SymbolTable.cpp

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=288461&r1=288460&r2=288461&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Thu Dec  1 20:58:21 2016
@@ -291,18 +291,24 @@ static int compareDefined(Symbol *S, boo
 // We have a new non-common defined symbol with the specified binding. Return 1
 // if the new symbol should win, -1 if the new symbol should lose, or 0 if there
 // is a conflict. If the new symbol wins, also update the binding.
-static int compareDefinedNonCommon(Symbol *S, bool WasInserted,
-                                   uint8_t Binding) {
+template <typename ELFT>
+static int compareDefinedNonCommon(Symbol *S, bool WasInserted, uint8_t Binding,
+                                   bool IsAbsolute, typename ELFT::uint Value) {
   if (int Cmp = compareDefined(S, WasInserted, Binding)) {
     if (Cmp > 0)
       S->Binding = Binding;
     return Cmp;
   }
-  if (isa<DefinedCommon>(S->body())) {
+  SymbolBody *B = S->body();
+  if (isa<DefinedCommon>(B)) {
     // Non-common symbols take precedence over common symbols.
     if (Config->WarnCommon)
       warn("common " + S->body()->getName() + " is overridden");
     return 1;
+  } else if (auto *R = dyn_cast<DefinedRegular<ELFT>>(B)) {
+    if (R->Section == nullptr && Binding == STB_GLOBAL && IsAbsolute &&
+        R->Value == Value)
+      return -1;
   }
   return 0;
 }
@@ -377,7 +383,8 @@ Symbol *SymbolTable<ELFT>::addRegular(St
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name, Type, StOther & 3,
                                     /*CanOmitFromDynSym*/ false, File);
-  int Cmp = compareDefinedNonCommon(S, WasInserted, Binding);
+  int Cmp = compareDefinedNonCommon<ELFT>(S, WasInserted, Binding,
+                                          Section == nullptr, Value);
   if (Cmp > 0)
     replaceBody<DefinedRegular<ELFT>>(S, Name, /*IsLocal=*/false, StOther, Type,
                                       Value, Size, Section, File);
@@ -394,7 +401,8 @@ Symbol *SymbolTable<ELFT>::addSynthetic(
   bool WasInserted;
   std::tie(S, WasInserted) = insert(N, STT_NOTYPE, /*Visibility*/ StOther & 0x3,
                                     /*CanOmitFromDynSym*/ false, nullptr);
-  int Cmp = compareDefinedNonCommon(S, WasInserted, STB_GLOBAL);
+  int Cmp = compareDefinedNonCommon<ELFT>(S, WasInserted, STB_GLOBAL,
+                                          /*IsAbsolute*/ false, /*Value*/ 0);
   if (Cmp > 0)
     replaceBody<DefinedSynthetic<ELFT>>(S, N, Value, Section);
   else if (Cmp == 0)
@@ -431,7 +439,8 @@ Symbol *SymbolTable<ELFT>::addBitcode(St
   bool WasInserted;
   std::tie(S, WasInserted) =
       insert(Name, Type, StOther & 3, CanOmitFromDynSym, F);
-  int Cmp = compareDefinedNonCommon(S, WasInserted, Binding);
+  int Cmp = compareDefinedNonCommon<ELFT>(S, WasInserted, Binding,
+                                          /*IsAbs*/ false, /*Value*/ 0);
   if (Cmp > 0)
     replaceBody<DefinedRegular<ELFT>>(S, Name, /*IsLocal=*/false, StOther, Type,
                                       0, 0, nullptr, F);

Added: lld/trunk/test/ELF/abs-conflict.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/abs-conflict.s?rev=288461&view=auto
==============================================================================
--- lld/trunk/test/ELF/abs-conflict.s (added)
+++ lld/trunk/test/ELF/abs-conflict.s Thu Dec  1 20:58:21 2016
@@ -0,0 +1,16 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: ld.lld %t.o %t.o -o %t.so -shared
+// RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s
+
+// CHECK:      Name: foo
+// CHECK-NEXT: Value: 0x123
+
+.global foo
+foo = 0x123
+
+// RUN: echo ".global foo; foo = 0x124" >  %t2.s
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t2.s -o %t2.o
+// RUN: not ld.lld %t.o %t2.o -o %t.so -shared 2>&1 | FileCheck --check-prefix=DUP %s
+
+// DUP: duplicate symbol 'foo'




More information about the llvm-commits mailing list