[lld] r316984 - [ELF] - Simplify output section creation.
Rafael Avila de Espindola via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 7 10:33:54 PST 2017
Very nice find!
Thanks,
Rafael
George Rimar via llvm-commits <llvm-commits at lists.llvm.org> writes:
> Author: grimar
> Date: Tue Oct 31 03:31:58 2017
> New Revision: 316984
>
> URL: http://llvm.org/viewvc/llvm-project?rev=316984&view=rev
> Log:
> [ELF] - Simplify output section creation.
>
> When there is no SECTION commands given, all sections are
> technically orphans, but now we handle script orphans sections
> and regular "orphans" sections for non-scripted case differently,
> though we can handle them at one place.
>
> Patch do that change.
>
> Differential revision: https://reviews.llvm.org/D39045
>
> Modified:
> lld/trunk/ELF/LinkerScript.cpp
> lld/trunk/ELF/LinkerScript.h
> lld/trunk/ELF/Writer.cpp
>
> Modified: lld/trunk/ELF/LinkerScript.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=316984&r1=316983&r2=316984&view=diff
> ==============================================================================
> --- lld/trunk/ELF/LinkerScript.cpp (original)
> +++ lld/trunk/ELF/LinkerScript.cpp Tue Oct 31 03:31:58 2017
> @@ -426,25 +426,6 @@ void LinkerScript::processSectionCommand
> }
> }
>
> -// 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<section> have been sorted in order of ascending
> - // address. We must lower StartAddr if the lowest -T<section address> 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<SymbolAssignment>(".", Expr, ""));
> -}
> -
> static OutputSection *findByName(ArrayRef<BaseCommand *> Vec,
> StringRef Name) {
> for (BaseCommand *Base : Vec)
> @@ -465,6 +446,7 @@ static void reportOrphan(InputSectionBas
> void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
> unsigned End = SectionCommands.size();
>
> + std::vector<OutputSection *> V;
> for (InputSectionBase *S : InputSections) {
> if (!S->Live || S->Parent)
> continue;
> @@ -479,9 +461,18 @@ void LinkerScript::addOrphanSections(Out
> }
>
> 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 @@ LinkerScript::AddressState::AddressState
> }
> }
>
> -// 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<section> have been sorted in order of ascending
> + // address. We must lower StartAddr if the lowest -T<section address> 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<AddressState>();
> Ctx = Deleter.get();
>
> Modified: lld/trunk/ELF/LinkerScript.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=316984&r1=316983&r2=316984&view=diff
> ==============================================================================
> --- lld/trunk/ELF/LinkerScript.h (original)
> +++ lld/trunk/ELF/LinkerScript.h Tue Oct 31 03:31:58 2017
> @@ -250,7 +250,6 @@ public:
>
> ExprValue getSymbolValue(StringRef Name, const Twine &Loc);
>
> - void fabricateDefaultCommands();
> void addOrphanSections(OutputSectionFactory &Factory);
> void removeEmptyCommands();
> void adjustSectionsBeforeSorting();
>
> Modified: lld/trunk/ELF/Writer.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=316984&r1=316983&r2=316984&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Writer.cpp (original)
> +++ lld/trunk/ELF/Writer.cpp Tue Oct 31 03:31:58 2017
> @@ -49,7 +49,6 @@ private:
> void copyLocalSymbols();
> void addSectionSymbols();
> void addReservedSymbols();
> - void createSections();
> void forEachRelSec(std::function<void(InputSectionBase &)> Fn);
> void sortSections();
> void sortInputSections();
> @@ -169,22 +168,14 @@ template <class ELFT> void Writer<ELFT>:
> 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 @@ void Writer<ELFT>::forEachRelSec(std::fu
> Fn(*ES);
> }
>
> -template <class ELFT> void Writer<ELFT>::createSections() {
> - std::vector<OutputSection *> 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
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list