diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2016-11-27 07:39:45 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2016-11-27 07:39:45 +0000 |
commit | 7fe4ec9b3a3094b118853bf6c165fb13ca0bfb9f (patch) | |
tree | 6743b07d4e415a073a88aee1ebea6054f44efbcf | |
parent | 2f5cb60b07ea9f5eb0d09640621aad70f14bafce (diff) | |
download | bcm5719-llvm-7fe4ec9b3a3094b118853bf6c165fb13ca0bfb9f.tar.gz bcm5719-llvm-7fe4ec9b3a3094b118853bf6c165fb13ca0bfb9f.zip |
Don't put an orphan before the first . assignment.
This is an horrible special case, but seems to match bfd's behaviour
and is important for avoiding placing an orphan section before the
expected start of the file.
llvm-svn: 287994
-rw-r--r-- | lld/ELF/LinkerScript.cpp | 14 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/orphan-first-cmd.s | 17 |
2 files changed, 28 insertions, 3 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 5618abd8f4b..8c5b7da77cf 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -632,13 +632,21 @@ template <class ELFT> void LinkerScript<ELFT>::adjustSectionsAfterSorting() { // /* The RW PT_LOAD starts here*/ // rw_sec : { *(rw_sec) } // would mean that the RW PT_LOAD would become unaligned. -static bool shouldSkip(const BaseCommand &Cmd) { +static bool shouldSkip(int CmdIndex) { + auto CmdIter = ScriptConfig->Commands.begin() + CmdIndex; + const BaseCommand &Cmd = **CmdIter; if (isa<OutputSectionCommand>(Cmd)) return false; const auto *Assign = dyn_cast<SymbolAssignment>(&Cmd); if (!Assign) return true; - return Assign->Name != "."; + if (Assign->Name != ".") + return true; + // As a horrible special case, skip a . assignment if it is the first thing in + // the script. We do this because it is common to set a load address by + // starting the script with ". = 0xabcd" and the expectation is that every + // section is after that. + return CmdIndex == 0; } // Orphan sections are sections present in the input files which are not @@ -657,7 +665,7 @@ void LinkerScript<ELFT>::placeOrphanSections() { // correct result. auto CmdIter = Opt.Commands.begin() + CmdIndex; auto E = Opt.Commands.end(); - while (CmdIter != E && shouldSkip(**CmdIter)) { + while (CmdIter != E && shouldSkip(CmdIndex)) { ++CmdIter; ++CmdIndex; } diff --git a/lld/test/ELF/linkerscript/orphan-first-cmd.s b/lld/test/ELF/linkerscript/orphan-first-cmd.s new file mode 100644 index 00000000000..1bc063c9bca --- /dev/null +++ b/lld/test/ELF/linkerscript/orphan-first-cmd.s @@ -0,0 +1,17 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "SECTIONS { \ +# RUN: . = 0x1000; \ +# RUN: . = 0x2000; \ +# RUN: .bar : { . = . + 1; } \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t -T %t.script %t.o -shared +# RUN: llvm-readobj -s %t | FileCheck %s + +# CHECK: Name: .text +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_EXECINSTR +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x1000 |