diff options
| author | James Henderson <jh7370@my.bristol.ac.uk> | 2018-07-03 09:23:25 +0000 |
|---|---|---|
| committer | James Henderson <jh7370@my.bristol.ac.uk> | 2018-07-03 09:23:25 +0000 |
| commit | b427d4eced315ffa2b6f5bd0f7ee24c9c869126a (patch) | |
| tree | 22b5411a2ccc68f84a137f2332a296cb58a7752e | |
| parent | 3897ded69101a87b6451d51bbb2e5b2e81387a53 (diff) | |
| download | bcm5719-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.cpp | 9 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/provide-empty-section.s | 30 |
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 |

