diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2016-11-27 09:44:45 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2016-11-27 09:44:45 +0000 |
commit | 5fcc99c27dba457d15f9061b809fcc33d9218e4e (patch) | |
tree | 0fc8c3fa0d66a78412cd14abcda2b62d52953a5f | |
parent | c3b3926f8b1325a7e6e05b9f8bb0c783d3ab2db4 (diff) | |
download | bcm5719-llvm-5fcc99c27dba457d15f9061b809fcc33d9218e4e.tar.gz bcm5719-llvm-5fcc99c27dba457d15f9061b809fcc33d9218e4e.zip |
Also skip regular symbol assignment at the start of a script.
Unfortunatelly some scripts look like
kernphys = ...
. = ....
and the expectation in that every orphan section is after the
assignment.
llvm-svn: 287996
-rw-r--r-- | lld/ELF/LinkerScript.cpp | 35 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/orphan-first-cmd.s | 1 |
2 files changed, 25 insertions, 11 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 8c5b7da77cf..feafd370fd8 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -632,21 +632,13 @@ 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(int CmdIndex) { - auto CmdIter = ScriptConfig->Commands.begin() + CmdIndex; - const BaseCommand &Cmd = **CmdIter; +static bool shouldSkip(const BaseCommand &Cmd) { if (isa<OutputSectionCommand>(Cmd)) return false; const auto *Assign = dyn_cast<SymbolAssignment>(&Cmd); if (!Assign) return true; - 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; + return Assign->Name != "."; } // Orphan sections are sections present in the input files which are not @@ -658,6 +650,27 @@ void LinkerScript<ELFT>::placeOrphanSections() { // This loops creates or moves commands as needed so that they are in the // correct order. int CmdIndex = 0; + + // As a horrible special case, skip the first . assignment if it is before any + // section. 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. + auto FirstSectionOrDotAssignment = + std::find_if(Opt.Commands.begin(), Opt.Commands.end(), + [](const std::unique_ptr<BaseCommand> &Cmd) { + if (isa<OutputSectionCommand>(*Cmd)) + return true; + const auto *Assign = dyn_cast<SymbolAssignment>(Cmd.get()); + if (!Assign) + return false; + return Assign->Name == "."; + }); + if (FirstSectionOrDotAssignment != Opt.Commands.end()) { + CmdIndex = FirstSectionOrDotAssignment - Opt.Commands.begin(); + if (isa<SymbolAssignment>(**FirstSectionOrDotAssignment)) + ++CmdIndex; + } + for (OutputSectionBase *Sec : *OutputSections) { StringRef Name = Sec->getName(); @@ -665,7 +678,7 @@ void LinkerScript<ELFT>::placeOrphanSections() { // correct result. auto CmdIter = Opt.Commands.begin() + CmdIndex; auto E = Opt.Commands.end(); - while (CmdIter != E && shouldSkip(CmdIndex)) { + while (CmdIter != E && shouldSkip(**CmdIter)) { ++CmdIter; ++CmdIndex; } diff --git a/lld/test/ELF/linkerscript/orphan-first-cmd.s b/lld/test/ELF/linkerscript/orphan-first-cmd.s index 1bc063c9bca..3fb3b31b9a4 100644 --- a/lld/test/ELF/linkerscript/orphan-first-cmd.s +++ b/lld/test/ELF/linkerscript/orphan-first-cmd.s @@ -1,6 +1,7 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: echo "SECTIONS { \ +# RUN: foo = 123; \ # RUN: . = 0x1000; \ # RUN: . = 0x2000; \ # RUN: .bar : { . = . + 1; } \ |