[lld][linkerscript] Fix handling of DEFINED.
authorHafiz Abid Qadeer <abidh@codesourcery.com>
Thu, 16 Jul 2020 20:40:31 +0000 (21:40 +0100)
committerHafiz Abid Qadeer <abidh@codesourcery.com>
Tue, 28 Jul 2020 20:18:01 +0000 (21:18 +0100)
Current implementation did not check that symbols is actually defined. Only checked for presence.  GNU ld documentation says,

"Return 1 if symbol is in the linker global symbol table and is defined before the statement using DEFINED in the script, otherwise return 0."

https://sourceware.org/binutils/docs/ld/Builtin-Functions.html#Builtin-Functions

Reviewed By: MaskRay

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

lld/ELF/ScriptParser.cpp
lld/test/ELF/linkerscript/Inputs/define.s
lld/test/ELF/linkerscript/define.test

index 17ac7ff..eae1d17 100644 (file)
@@ -1311,7 +1311,10 @@ Expr ScriptParser::readPrimary() {
   }
   if (tok == "DEFINED") {
     StringRef name = readParenLiteral();
-    return [=] { return symtab->find(name) ? 1 : 0; };
+    return [=] {
+      Symbol *b = symtab->find(name);
+      return (b && b->isDefined()) ? 1 : 0;
+    };
   }
   if (tok == "LENGTH") {
     StringRef name = readParenLiteral();
index bc60a23..69f47a8 100644 (file)
@@ -6,3 +6,6 @@ defined = 0
 
 .section .bar,"a"
 .quad 1
+
+.section .test,"a"
+.quad 1
index 689476b..3ecaa11 100644 (file)
@@ -3,13 +3,17 @@
 # RUN: ld.lld -o %t --script %s %t.o
 # RUN: llvm-objdump --section-headers %t | FileCheck %s
 
+EXTERN(extern_defined)
 SECTIONS {
   . = DEFINED(defined) ? 0x11000 : .;
   .foo : { *(.foo*) }
   . = DEFINED(notdefined) ? 0x12000 : 0x13000;
   .bar : { *(.bar*) }
+  . = DEFINED(extern_defined) ? 0x14000 : 0x15000;
+  .test : { *(.test*) }
 }
 
 # CHECK: 1 .foo  00000008 0000000000011000 DATA
 # CHECK: 2 .bar  00000008 0000000000013000 DATA
-# CHECK: 3 .text 00000000 0000000000013008 TEXT
+# CHECK: 3 .test  00000008 0000000000015000 DATA
+# CHECK: 4 .text 00000000 0000000000015008 TEXT