From 5fcc99c27dba457d15f9061b809fcc33d9218e4e Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 27 Nov 2016 09:44:45 +0000 Subject: 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 --- lld/ELF/LinkerScript.cpp | 35 +++++++++++++++++++--------- 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 void LinkerScript::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(Cmd)) return false; const auto *Assign = dyn_cast(&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::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 &Cmd) { + if (isa(*Cmd)) + return true; + const auto *Assign = dyn_cast(Cmd.get()); + if (!Assign) + return false; + return Assign->Name == "."; + }); + if (FirstSectionOrDotAssignment != Opt.Commands.end()) { + CmdIndex = FirstSectionOrDotAssignment - Opt.Commands.begin(); + if (isa(**FirstSectionOrDotAssignment)) + ++CmdIndex; + } + for (OutputSectionBase *Sec : *OutputSections) { StringRef Name = Sec->getName(); @@ -665,7 +678,7 @@ void LinkerScript::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; } \ -- cgit v1.2.3