diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2017-02-06 22:21:46 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2017-02-06 22:21:46 +0000 |
| commit | 06f4743a48f8908d094bbb51eec6ce14df6f84c6 (patch) | |
| tree | 1dd4347d34762c6b9f04825397e8d2ca5e86bda1 | |
| parent | 383c5c228f012d989f65d924b30f9133b11de452 (diff) | |
| download | bcm5719-llvm-06f4743a48f8908d094bbb51eec6ce14df6f84c6.tar.gz bcm5719-llvm-06f4743a48f8908d094bbb51eec6ce14df6f84c6.zip | |
Handle symbol assignments before the first section switch.
We now create a dummy section with index 1 before processing the
linker script.
Thanks to George Rimar for finding the bug and providing the initial
testcase.
llvm-svn: 294252
| -rw-r--r-- | lld/ELF/LinkerScript.cpp | 24 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/non-absolute2.s | 12 |
2 files changed, 28 insertions, 8 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 3a9dc9fde33..2e707e7a213 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -776,6 +776,19 @@ void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry> &Phdrs) { // Assign addresses as instructed by linker script SECTIONS sub-commands. Dot = 0; + // A symbol can be assigned before any section is mentioned in the linker + // script. In an DSO, the symbol values are addresses, so the only important + // section values are: + // * SHN_UNDEF + // * SHN_ABS + // * Any value meaning a regular section. + // To handle that, create a dummy aether section that fills the void before + // the linker scripts switches to another section. It has an index of one + // which will map to whatever the first actual section is. + auto *Aether = make<OutputSectionBase>("", 0, SHF_ALLOC); + Aether->SectionIndex = 1; + switchTo(Aether); + for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) { if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get())) { if (Cmd->Name == ".") { @@ -973,14 +986,9 @@ template <class ELFT> bool LinkerScript<ELFT>::isAbsolute(StringRef S) { // to find suitable section for it as well. template <class ELFT> const OutputSectionBase *LinkerScript<ELFT>::getSymbolSection(StringRef S) { - SymbolBody *Sym = Symtab<ELFT>::X->find(S); - if (!Sym) { - if (OutputSections->empty()) - return nullptr; - return CurOutSec ? CurOutSec : (*OutputSections)[0]; - } - - return SymbolTableSection<ELFT>::getOutputSection(Sym); + if (SymbolBody *Sym = Symtab<ELFT>::X->find(S)) + return SymbolTableSection<ELFT>::getOutputSection(Sym); + return CurOutSec; } // Returns indices of ELF headers containing specific section, identified diff --git a/lld/test/ELF/linkerscript/non-absolute2.s b/lld/test/ELF/linkerscript/non-absolute2.s new file mode 100644 index 00000000000..97c34d31a91 --- /dev/null +++ b/lld/test/ELF/linkerscript/non-absolute2.s @@ -0,0 +1,12 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o +# RUN: echo "SECTIONS { A = . + 0x1; . += 0x1000; }" > %t.script +# RUN: ld.lld -shared %t1.o --script %t.script -o %t +# RUN: llvm-objdump -section-headers -t %t | FileCheck %s + +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size Address +# CHECK-NEXT: 0 00000000 0000000000000000 +# CHECK-NEXT: 1 .text 00000000 0000000000001000 + +# CHECK: 0000000000000001 .text 00000000 A |

