[PATCH] D25544: ELF: Override DSO definitions when creating __start_* and __stop_* symbols.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 12 19:12:23 PDT 2016


pcc created this revision.
pcc added reviewers: ruiu, davide, grimar, rafael.
pcc added subscribers: krasin, llvm-commits.

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 https://reviews.llvm.org/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.


https://reviews.llvm.org/D25544

Files:
  lld/ELF/Writer.cpp
  lld/test/ELF/Inputs/startstop-shared2.s
  lld/test/ELF/startstop-shared2.s


Index: lld/test/ELF/startstop-shared2.s
===================================================================
--- /dev/null
+++ lld/test/ELF/startstop-shared2.s
@@ -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"
Index: lld/test/ELF/Inputs/startstop-shared2.s
===================================================================
--- /dev/null
+++ lld/test/ELF/Inputs/startstop-shared2.s
@@ -0,0 +1,2 @@
+.globl __start_foo
+__start_foo:
Index: lld/ELF/Writer.cpp
===================================================================
--- lld/ELF/Writer.cpp
+++ lld/ELF/Writer.cpp
@@ -546,15 +546,15 @@
 }
 
 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 @@
   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>


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D25544.74469.patch
Type: text/x-patch
Size: 2499 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161013/ce5fdaad/attachment.bin>


More information about the llvm-commits mailing list