[lld] r284168 - ELF: Override DSO definitions when creating __start_* and __stop_* symbols.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 13 15:20:19 PDT 2016


Author: pcc
Date: Thu Oct 13 17:20:18 2016
New Revision: 284168

URL: http://llvm.org/viewvc/llvm-project?rev=284168&view=rev
Log:
ELF: Override DSO definitions when creating __start_* and __stop_* symbols.

Previously we would fail to synthesise a __start_ or __stop_ symbol if
there existed a definition in a DSO. Instead, we would try to link against
the DSO definition. This became possible after D23552 when linking against
lld-produced DSOs but could in principle also occur when linking against
DSOs produced by other linkers.

Not only does it seem more likely that a user would expect the resolved
definition to be local to the executable, but if a __start_ or __stop_
symbol was synthesised by the linker, it is effectively impossible to link
against correctly from a non-PIC executable in a read-only section. Neither
a PLT nor a copy relocation would give us the right semantics here. The only
way the link could succeed is if the executable provided its own synthetic
definition of the symbol.

The fix is to also synthesise the definition if the only definition comes
from a DSO. Since this is what the addOptionalSynthetic function does,
switch to using that function.

Fixes PR30680.

Differential Revision: https://reviews.llvm.org/D25544

Added:
    lld/trunk/test/ELF/Inputs/startstop-shared2.s
    lld/trunk/test/ELF/startstop-shared2.s
Modified:
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=284168&r1=284167&r2=284168&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Oct 13 17:20:18 2016
@@ -546,15 +546,15 @@ void PhdrEntry<ELFT>::add(OutputSectionB
 }
 
 template <class ELFT>
-static Symbol *addOptionalSynthetic(StringRef Name,
-                                    OutputSectionBase<ELFT> *Sec,
-                                    typename ELFT::uint Val) {
+static Symbol *
+addOptionalSynthetic(StringRef Name, OutputSectionBase<ELFT> *Sec,
+                     typename ELFT::uint Val, uint8_t StOther = STV_HIDDEN) {
   SymbolBody *S = Symtab<ELFT>::X->find(Name);
   if (!S)
     return nullptr;
   if (!S->isUndefined() && !S->isShared())
     return S->symbol();
-  return Symtab<ELFT>::X->addSynthetic(Name, Sec, Val, STV_HIDDEN);
+  return Symtab<ELFT>::X->addSynthetic(Name, Sec, Val, StOther);
 }
 
 template <class ELFT>
@@ -974,15 +974,9 @@ void Writer<ELFT>::addStartStopSymbols(O
   if (!isValidCIdentifier(S))
     return;
   StringSaver Saver(Alloc);
-  StringRef Start = Saver.save("__start_" + S);
-  StringRef Stop = Saver.save("__stop_" + S);
-  if (SymbolBody *B = Symtab<ELFT>::X->find(Start))
-    if (B->isUndefined())
-      Symtab<ELFT>::X->addSynthetic(Start, Sec, 0, B->getVisibility());
-  if (SymbolBody *B = Symtab<ELFT>::X->find(Stop))
-    if (B->isUndefined())
-      Symtab<ELFT>::X->addSynthetic(
-          Stop, Sec, DefinedSynthetic<ELFT>::SectionEnd, B->getVisibility());
+  addOptionalSynthetic(Saver.save("__start_" + S), Sec, 0, STV_DEFAULT);
+  addOptionalSynthetic(Saver.save("__stop_" + S), Sec,
+                       DefinedSynthetic<ELFT>::SectionEnd, STV_DEFAULT);
 }
 
 template <class ELFT>

Added: lld/trunk/test/ELF/Inputs/startstop-shared2.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/startstop-shared2.s?rev=284168&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/startstop-shared2.s (added)
+++ lld/trunk/test/ELF/Inputs/startstop-shared2.s Thu Oct 13 17:20:18 2016
@@ -0,0 +1,2 @@
+.globl __start_foo
+__start_foo:

Added: lld/trunk/test/ELF/startstop-shared2.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/startstop-shared2.s?rev=284168&view=auto
==============================================================================
--- lld/trunk/test/ELF/startstop-shared2.s (added)
+++ lld/trunk/test/ELF/startstop-shared2.s Thu Oct 13 17:20:18 2016
@@ -0,0 +1,14 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/startstop-shared2.s -o %t.o
+// RUN: ld.lld -o %t.so %t.o -shared
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o
+// RUN: ld.lld -o %t %t2.o %t.so
+// RUN: llvm-objdump -s -h %t | FileCheck %s
+
+// CHECK: foo           00000000 0000000000011008
+
+// CHECK: Contents of section .text:
+// CHECK-NEXT: 11000 08100100 00000000
+
+.quad __start_foo
+.section foo,"ax"




More information about the llvm-commits mailing list