Index: lld/trunk/ELF/LinkerScript.h =================================================================== --- lld/trunk/ELF/LinkerScript.h +++ lld/trunk/ELF/LinkerScript.h @@ -250,7 +250,6 @@ ExprValue getSymbolValue(StringRef Name, const Twine &Loc); - void fabricateDefaultCommands(); void addOrphanSections(OutputSectionFactory &Factory); void removeEmptyCommands(); void adjustSectionsBeforeSorting(); Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -426,25 +426,6 @@ } } -// If no SECTIONS command was given, we create simple SectionCommands -// as if a minimum SECTIONS command were given. This function does that. -void LinkerScript::fabricateDefaultCommands() { - // Define start address - uint64_t StartAddr = UINT64_MAX; - - // 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); - - auto Expr = [=] { - return std::min(StartAddr, Target->getImageBase() + elf::getHeaderSize()); - }; - SectionCommands.insert(SectionCommands.begin(), - make(".", Expr, "")); -} - static OutputSection *findByName(ArrayRef Vec, StringRef Name) { for (BaseCommand *Base : Vec) @@ -465,6 +446,7 @@ void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) { unsigned End = SectionCommands.size(); + std::vector V; for (InputSectionBase *S : InputSections) { if (!S->Live || S->Parent) continue; @@ -479,9 +461,18 @@ } if (OutputSection *OS = Factory.addInputSec(S, Name)) - SectionCommands.push_back(OS); + V.push_back(OS); assert(S->getOutputSection()->SectionIndex == INT_MAX); } + + // If no SECTIONS command was given, we should insert sections commands + // before others, so that we can handle scripts which refers them, + // for example: "foo = ABSOLUTE(ADDR(.text)));". + // When SECTIONS command is present we just add all orphans to the end. + if (HasSectionsCommand) + SectionCommands.insert(SectionCommands.end(), V.begin(), V.end()); + else + SectionCommands.insert(SectionCommands.begin(), V.begin(), V.end()); } uint64_t LinkerScript::advance(uint64_t Size, unsigned Alignment) { @@ -802,11 +793,26 @@ } } -// Assign addresses as instructed by linker script SECTIONS sub-commands. +static uint64_t getInitialDot() { + // By default linker scripts use an initial value of 0 for '.', + // but prefer -image-base if set. + if (Script->HasSectionsCommand) + return Config->ImageBase ? *Config->ImageBase : 0; + + uint64_t StartAddr = UINT64_MAX; + // 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); + return std::min(StartAddr, Target->getImageBase() + elf::getHeaderSize()); +} + +// Here we assign addresses as instructed by linker script SECTIONS +// sub-commands. Doing that allows us to use final VA values, so here +// we also handle rest commands like symbol assignments and ASSERTs. void LinkerScript::assignAddresses() { - // By default linker scripts use an initial value of 0 for '.', but prefer - // -image-base if set. - Dot = Config->ImageBase ? *Config->ImageBase : 0; + Dot = getInitialDot(); auto Deleter = make_unique(); Ctx = Deleter.get(); Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -49,7 +49,6 @@ void copyLocalSymbols(); void addSectionSymbols(); void addReservedSymbols(); - void createSections(); void forEachRelSec(std::function Fn); void sortSections(); void sortInputSections(); @@ -169,22 +168,14 @@ if (!Config->Relocatable) addReservedSymbols(); - // Create output sections. - if (Script->HasSectionsCommand) { - // If linker script contains SECTIONS commands, let it create sections. - Script->processSectionCommands(); - - // Linker scripts may have left some input sections unassigned. - // Assign such sections using the default rule. - Script->addOrphanSections(Factory); - } else { - // If linker script does not contain SECTIONS commands, create - // output sections by default rules. We still need to give the - // linker script a chance to run, because it might contain - // non-SECTIONS commands such as ASSERT. - Script->processSectionCommands(); - createSections(); - } + // We want to process linker script commands. When SECTIONS command + // is given we let it create sections. + Script->processSectionCommands(); + + // Linker scripts controls how input sections are assigned to output sections. + // Input sections that were not handled by scripts are called "orphans", and + // they are assigned to output sections by the default rule. Process that. + Script->addOrphanSections(Factory); if (Config->Discard != DiscardPolicy::All) copyLocalSymbols(); @@ -852,20 +843,6 @@ Fn(*ES); } -template void Writer::createSections() { - std::vector Vec; - for (InputSectionBase *IS : InputSections) - if (IS && IS->Live) - if (OutputSection *Sec = - Factory.addInputSec(IS, getOutputSectionName(IS->Name))) - Vec.push_back(Sec); - - Script->SectionCommands.insert(Script->SectionCommands.begin(), Vec.begin(), - Vec.end()); - - Script->fabricateDefaultCommands(); -} - // This function generates assignments for predefined symbols (e.g. _end or // _etext) and inserts them into the commands sequence to be processed at the // appropriate time. This ensures that the value is going to be correct by the