[PATCH] D43069: [ELF] - Report error if removed empty output section used undefined symbols.

George Rimar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 8 05:45:21 PST 2018


grimar created this revision.
grimar added reviewers: ruiu, rafael.
Herald added a subscriber: emaste.

This is demo patch do demonstrate approach for fixing PR36297.
It contains testcase for address expression only, if approach is OK,
I'll add testcase.

Issue itself is that if we have `SECTIONS { .bar (a+b) : { *(.stub) } };`
script and no section `.stub`, when LLD will remove `.bar`, but
produce output with undefined symbols `a` and `b`.

I found it when investigated following script:
`.build-id (INFO) : { *(.note.gnu.build-id) }`

Since we do not yet support `(INFO)`,
we produced broken output with undefined symbol INFO instead 
of doing right things.


https://reviews.llvm.org/D43069

Files:
  ELF/LinkerScript.cpp
  test/ELF/linkerscript/address-expr-symbols.s


Index: test/ELF/linkerscript/address-expr-symbols.s
===================================================================
--- test/ELF/linkerscript/address-expr-symbols.s
+++ test/ELF/linkerscript/address-expr-symbols.s
@@ -0,0 +1,7 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "SECTIONS { .bar (a+b) : { *(.stub) } };" > %t.script
+# RUN: not ld.lld -o %t --script %t.script %t.o 2>&1 | FileCheck %s
+
+# CHECK-DAG: symbol not found: b
+# CHECK-DAG: symbol not found: a
Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -757,11 +757,27 @@
   // clutter the output.
   // We instead remove trivially empty sections. The bfd linker seems even
   // more aggressive at removing them.
-  llvm::erase_if(SectionCommands, [&](BaseCommand *Base) {
-    if (auto *Sec = dyn_cast<OutputSection>(Base))
-      return !Sec->Live;
-    return false;
-  });
+  for (BaseCommand *& Cmd : SectionCommands) {
+    auto *Sec = dyn_cast<OutputSection>(Cmd);
+    if (!Sec || Sec->Live)
+      continue;
+
+    // If section had address or align expressions we want to check them were
+    // calculatable before we remove the section. Otherwise if any expression
+    // contains undefined symbol, we would not report the proper error.
+    auto RunExpr = [](Expr &E) {
+      if (E)
+        E();
+    };
+    RunExpr(Sec->AddrExpr);
+    RunExpr(Sec->AlignExpr);
+    RunExpr(Sec->LMAExpr);
+    RunExpr(Sec->SubalignExpr);
+
+    Cmd = nullptr;
+  }
+
+  llvm::erase_if(SectionCommands, [&](BaseCommand *Base) { return !Base; });
 }
 
 static bool isAllSectionDescription(const OutputSection &Cmd) {


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


More information about the llvm-commits mailing list