[ELF] Process linker scripts deeper when declaring symbols.
authorIgor Kudrin <ikudrin@accesssoftek.com>
Wed, 28 Feb 2018 05:55:56 +0000 (05:55 +0000)
committerIgor Kudrin <ikudrin@accesssoftek.com>
Wed, 28 Feb 2018 05:55:56 +0000 (05:55 +0000)
We should process symbols inside output section declarations the same way as top-level ones.

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

llvm-svn: 326305

lld/ELF/LinkerScript.cpp
lld/test/ELF/linkerscript/symbols-synthetic.s
lld/test/ELF/linkerscript/version-script.s

index 85fef2d..b257c92 100644 (file)
@@ -165,27 +165,46 @@ void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
   Cmd->Sym = cast<Defined>(Sym);
 }
 
+// This function is called from LinkerScript::declareSymbols.
+// It creates a placeholder symbol if needed.
+static void declareSymbol(SymbolAssignment *Cmd) {
+  if (!shouldDefineSym(Cmd))
+    return;
+
+  // We can't calculate final value right now.
+  Symbol *Sym;
+  uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
+  std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, /*Type*/ 0, Visibility,
+                                              /*CanOmitFromDynSym*/ false,
+                                              /*File*/ nullptr);
+  replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility,
+                         STT_NOTYPE, 0, 0, nullptr);
+  Cmd->Sym = cast<Defined>(Sym);
+  Cmd->Provide = false;
+}
+
 // Symbols defined in script should not be inlined by LTO. At the same time
 // we don't know their final values until late stages of link. Here we scan
 // over symbol assignment commands and create placeholder symbols if needed.
 void LinkerScript::declareSymbols() {
   assert(!Ctx);
   for (BaseCommand *Base : SectionCommands) {
-    auto *Cmd = dyn_cast<SymbolAssignment>(Base);
-    if (!Cmd || !shouldDefineSym(Cmd))
+    if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
+      declareSymbol(Cmd);
       continue;
-
-    // We can't calculate final value right now.
-    Symbol *Sym;
-    uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
-    std::tie(Sym, std::ignore) =
-        Symtab->insert(Cmd->Name, /*Type*/ 0, Visibility,
-                       /*CanOmitFromDynSym*/ false,
-                       /*File*/ nullptr);
-    replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility,
-                           STT_NOTYPE, 0, 0, nullptr);
-    Cmd->Sym = cast<Defined>(Sym);
-    Cmd->Provide = false;
+    }
+    auto *Sec = dyn_cast<OutputSection>(Base);
+    if (!Sec)
+      continue;
+    // If the output section directive has constraints,
+    // we can't say for sure if it is going to be included or not.
+    // Skip such sections for now. Improve the checks if we ever
+    // need symbols from that sections to be declared early.
+    if (Sec->Constraint != ConstraintKind::NoConstraint)
+      continue;
+    for (BaseCommand *Base2 : Sec->SectionCommands)
+      if (auto *Cmd = dyn_cast<SymbolAssignment>(Base2))
+        declareSymbol(Cmd);
   }
 }
 
index 978ec9a..95cdae9 100644 (file)
@@ -61,7 +61,6 @@
 # SIMPLE-NEXT: 0000000000000120         .foo    00000000 _begin_sec
 # SIMPLE-NEXT: 0000000000000128         *ABS*   00000000 _end_sec_abs
 # SIMPLE-NEXT: 0000000000001048         .text   00000000 _start
-# SIMPLE-NEXT: 0000000000000ee4         *ABS*   00000000 size_foo_3
 # SIMPLE-NEXT: 0000000000000120         .foo    00000000 begin_foo
 # SIMPLE-NEXT: 0000000000000128         .foo    00000000 end_foo
 # SIMPLE-NEXT: 0000000000000008         *ABS*   00000000 size_foo_1
@@ -69,6 +68,7 @@
 # SIMPLE-NEXT: 0000000000001000         .foo    00000000 begin_bar
 # SIMPLE-NEXT: 0000000000001004         .foo    00000000 end_bar
 # SIMPLE-NEXT: 0000000000000ee4         *ABS*   00000000 size_foo_2
+# SIMPLE-NEXT: 0000000000000ee4         *ABS*   00000000 size_foo_3
 # SIMPLE-NEXT: 0000000000001004         .eh_frame_hdr     00000000 __eh_frame_hdr_start
 # SIMPLE-NEXT: 0000000000001010         *ABS*             00000000 __eh_frame_hdr_start2
 # SIMPLE-NEXT: 0000000000001018         .eh_frame_hdr     00000000 __eh_frame_hdr_end
index 5eb2465..df666e1 100644 (file)
@@ -5,6 +5,11 @@
 # RUN: ld.lld -T %t.script -shared --no-undefined-version %t.o -o %t.so
 # RUN: llvm-readobj -V %t.so | FileCheck %s
 
+# RUN: echo "SECTIONS { .text : { bar = foo; *(.text) } }" > %t.script
+# RUN: echo "VERSION { V { global: foo; bar; local: *; }; }" >> %t.script
+# RUN: ld.lld -T %t.script -shared --no-undefined-version %t.o -o %t.so
+# RUN: llvm-readobj -V %t.so | FileCheck %s
+
 ## Check that we are able to version symbols defined in script.
 # CHECK:      Symbols [
 # CHECK-NEXT:   Symbol {