summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Henderson <jh7370@my.bristol.ac.uk>2018-07-03 09:23:25 +0000
committerJames Henderson <jh7370@my.bristol.ac.uk>2018-07-03 09:23:25 +0000
commitb427d4eced315ffa2b6f5bd0f7ee24c9c869126a (patch)
tree22b5411a2ccc68f84a137f2332a296cb58a7752e
parent3897ded69101a87b6451d51bbb2e5b2e81387a53 (diff)
downloadbcm5719-llvm-b427d4eced315ffa2b6f5bd0f7ee24c9c869126a.tar.gz
bcm5719-llvm-b427d4eced315ffa2b6f5bd0f7ee24c9c869126a.zip
[ELF] Don't create empty output section for unreferenced PROVIDEs
LLD removes empty output sections otherwise specified in the linker script. Prior to this change however, if section descriptions included ANY kind of symbol assignment, then the consequent output section would not be removed, even if the assignment was marked with PROVIDE and not actually triggered (i.e. the symbol was never referenced). This change modifies the isDiscarable function to ignore such directives when determining whether a section should be discarded, in keeping with bfd's behaviour. Symbol assignments that do result in a symbol definition will continue to result in a kept section (this is not actually the same as bfd's behaviour, but it is simpler, and probably makes more sense). Reviewed By: grimar Differential Revision: https://reviews.llvm.org/D48771 llvm-svn: 336184
-rw-r--r--lld/ELF/LinkerScript.cpp9
-rw-r--r--lld/test/ELF/linkerscript/provide-empty-section.s30
2 files changed, 38 insertions, 1 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 9cc836bd131..3e3fe31570d 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -834,9 +834,16 @@ static bool isDiscardable(OutputSection &Sec) {
if (Sec.ExpressionsUseSymbols)
return false;
- for (BaseCommand *Base : Sec.SectionCommands)
+ for (BaseCommand *Base : Sec.SectionCommands) {
+ if (auto Cmd = dyn_cast<SymbolAssignment>(Base))
+ // Don't create empty output sections just for unreferenced PROVIDE
+ // symbols.
+ if (Cmd->Name != "." && !Cmd->Sym)
+ continue;
+
if (!isa<InputSectionDescription>(*Base))
return false;
+ }
return true;
}
diff --git a/lld/test/ELF/linkerscript/provide-empty-section.s b/lld/test/ELF/linkerscript/provide-empty-section.s
new file mode 100644
index 00000000000..56cb6aca1e3
--- /dev/null
+++ b/lld/test/ELF/linkerscript/provide-empty-section.s
@@ -0,0 +1,30 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tundefined.o
+# RUN: echo "foo=42" | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %tdefined.o
+# RUN: echo "call foo" | llvm-mc -filetype=obj -triple=x86_64-unknown-linux - -o %treference.o
+
+# RUN: echo "SECTIONS { .bar : { PROVIDE(foo = .); } }" > %t.script
+
+# Case 1: Provided symbol is undefined and not referenced - empty section should be removed.
+# RUN: ld.lld %tundefined.o -T %t.script -o %t1.elf
+# RUN: llvm-readobj -sections %t1.elf | FileCheck %s --check-prefix=NOSECTION
+
+# Case 2: Provided symbol is undefined and referenced - empty section should not be removed.
+# RUN: ld.lld %tundefined.o %treference.o -T %t.script -o %t2.elf
+# RUN: llvm-readobj -sections %t2.elf | FileCheck %s --check-prefix=SECTION
+
+# Case 3: Provided symbol is defined and not referenced - empty section should be removed.
+# RUN: ld.lld %tdefined.o -T %t.script -o %t3.elf
+# RUN: llvm-readobj -sections %t3.elf | FileCheck %s --check-prefix=NOSECTION
+
+# Case 4: Provided symbol is defined and referenced - empty section should not be removed.
+# RUN: ld.lld %tdefined.o %treference.o -T %t.script -o %t4.elf
+# RUN: llvm-readobj -sections %t4.elf | FileCheck %s --check-prefix=SECTION
+
+.global _start
+_start:
+ ret
+
+# SECTION: .bar
+# NOSECTION-NOT: .bar
OpenPOWER on IntegriCloud