From c60b4510ea6db9726fd4870381ca8486d862e9b8 Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Wed, 3 May 2017 08:44:50 +0000 Subject: [ELF] Fix problems with fabricateDefaultCommands() and --section-start The --section-start =
needs to be translated into equivalent linker script commands. There are a couple of problems with the existing implementation: - The --section-start with the lowest address is assumed to be at the start of the map. This assumption is incorrect, we have to iterate through the SectionStartMap to find the lowest address. - The addresses in --section-start were being over-aligned when the sections were marked as PageAlign. This is inconsistent with the use of SectionStartMap in fixHeaders(), and can cause problems when the PageAlign causes an "unable to move location counter backward" error when the --section-start with PageAlign is aligned to an address higher than the next --section-start. The ld.bfd and ld.gold seem to be more consistent with this approach but this is not a well specified area. This change fixes the problems above and also corrects a typo in which fabricateDefaultCommands() is called with the wrong parameter, it should be called with AllocateHeader not Config->MaxPageSize. Differential Revision: https://reviews.llvm.org/D32749 llvm-svn: 302007 --- lld/ELF/LinkerScript.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'lld/ELF/LinkerScript.cpp') diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 22a5b639469..3f872c65897 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -428,13 +428,12 @@ void LinkerScript::fabricateDefaultCommands(bool AllocateHeader) { if (AllocateHeader) StartAddr += elf::getHeaderSize(); - // The Sections with -T
are sorted in order of ascending address - // we must use this if it is lower than StartAddr as calls to setDot() must - // be monotonically increasing - if (!Config->SectionStartMap.empty()) { - uint64_t LowestSecStart = Config->SectionStartMap.begin()->second; - StartAddr = std::min(StartAddr, LowestSecStart); - } + // The Sections with -T
have been sorted in order of ascending + // address. We must lower StartAddr if the lowest -T
as + // calls to setDot() must be monotonically increasing. + for (auto& KV : Config->SectionStartMap) + StartAddr = std::min(StartAddr, KV.second); + Commands.push_back( make(".", [=] { return StartAddr; }, "")); @@ -444,17 +443,19 @@ void LinkerScript::fabricateDefaultCommands(bool AllocateHeader) { if (!(Sec->Flags & SHF_ALLOC)) continue; + auto *OSCmd = make(Sec->Name); + OSCmd->Sec = Sec; + + // Prefer user supplied address over additional alignment constraint auto I = Config->SectionStartMap.find(Sec->Name); if (I != Config->SectionStartMap.end()) Commands.push_back( make(".", [=] { return I->second; }, "")); - - auto *OSCmd = make(Sec->Name); - OSCmd->Sec = Sec; - if (Sec->PageAlign) + else if (Sec->PageAlign) OSCmd->AddrExpr = [=] { return alignTo(Script->getDot(), Config->MaxPageSize); }; + Commands.push_back(OSCmd); if (Sec->Sections.size()) { auto *ISD = make(""); -- cgit v1.2.3