[lld] r316984 - [ELF] - Simplify output section creation.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 31 03:31:58 PDT 2017
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
More information about the llvm-commits
mailing list