[PATCH] D63564: Add undefined symbols from linker script to output file

Ilie Halip via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 19 09:55:58 PDT 2019


ihalip created this revision.
ihalip added a project: lld.
Herald added subscribers: llvm-commits, MaskRay, arichardson, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.

According to GNU ld documentation, using the EXTERN(symbol) in a linker script has the same effect as the -u/--undefined command-line parameter.

When using such a linker script with lld, the linker doesn't add these symbols to the output file. A simple example:
$ touch a.c
$ clang -c a.c -o a.o
$ echo "EXTERN(test)" > a.lds
$ ld.lld -T a.lds a.o -o a.out
$ objdump -t a.out | grep test
$

These are not added because these symbols are not added to lld's symbol table. Driver.cpp has this code:

  for (StringRef Arg : Config->Undefined)
    if (Symbol *Sym = Symtab->find(Arg))
      handleUndefined(Sym);

Here, Symtab is empty, which is why lld silently discards the symbols declared in the script.

I can see two possible fixes for this issue:

1. The one I'm proposing in this review: add the symbols to Symtab as they are read by the script parser
2. Add them to Symtab close to that piece of code in Driver.cpp.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D63564

Files:
  lld/ELF/ScriptParser.cpp
  lld/test/ELF/linkerscript/extern.s


Index: lld/test/ELF/linkerscript/extern.s
===================================================================
--- /dev/null
+++ lld/test/ELF/linkerscript/extern.s
@@ -0,0 +1,33 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: echo "EXTERN( test )" > %t.script
+# RUN: echo "EXTERN( "test" )" >> %t.script
+# RUN: echo "EXTERN( "test2" )" >> %t.script
+# RUN: ld.lld %t -o %t2 -T %t.script
+# RUN: llvm-readobj -t %t2 | FileCheck %s
+
+.globl _start
+_start:
+  ret
+
+## Test that the script adds the specified symbols, and that they
+## are marked as undefined.
+
+# CHECK:      Symbol {
+# CHECK:        Name: test (1)
+# CHECK-NEXT:    Value: 0x0
+# CHECK-NEXT:    Size: 0
+# CHECK-NEXT:    Binding: Global (0x1)
+# CHECK-NEXT:    Type: None (0x0)
+# CHECK-NEXT:    Other: 0
+# CHECK-NEXT:    Section: Undefined (0x0)
+# CHECK-NEXT:  }
+# CHECK-NEXT:  Symbol {
+# CHECK-NEXT:    Name: test2 (6)
+# CHECK-NEXT:    Value: 0x0
+# CHECK-NEXT:    Size: 0
+# CHECK-NEXT:    Binding: Global (0x1)
+# CHECK-NEXT:    Type: None (0x0)
+# CHECK-NEXT:    Other: 0
+# CHECK-NEXT:    Section: Undefined (0x0)
+# CHECK-NEXT:  }
Index: lld/ELF/ScriptParser.cpp
===================================================================
--- lld/ELF/ScriptParser.cpp
+++ lld/ELF/ScriptParser.cpp
@@ -328,8 +328,12 @@
 
 void ScriptParser::readExtern() {
   expect("(");
-  while (!errorCount() && !consume(")"))
-    Config->Undefined.push_back(unquote(next()));
+  while (!errorCount() && !consume(")")) {
+    StringRef Name = unquote(next());
+    Symtab->addSymbol(
+      Undefined{nullptr, Name, STB_GLOBAL, STV_DEFAULT, 0});
+    Config->Undefined.push_back(Name);
+  }
 }
 
 void ScriptParser::readGroup() {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D63564.205624.patch
Type: text/x-patch
Size: 1741 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190619/f8e8aa95/attachment.bin>


More information about the llvm-commits mailing list