[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

llvm-svn: 316984
This commit is contained in:
George Rimar 2017-10-31 10:31:58 +00:00
parent 06618bf71a
commit f9b04fd91f
3 changed files with 37 additions and 55 deletions

View File

@ -426,25 +426,6 @@ void LinkerScript::processSectionCommands() {
}
}
// 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(InputSectionBase *IS, StringRef Name) {
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(OutputSectionFactory &Factory) {
}
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();

View File

@ -250,7 +250,6 @@ public:
ExprValue getSymbolValue(StringRef Name, const Twine &Loc);
void fabricateDefaultCommands();
void addOrphanSections(OutputSectionFactory &Factory);
void removeEmptyCommands();
void adjustSectionsBeforeSorting();

View File

@ -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>::run() {
if (!Config->Relocatable)
addReservedSymbols();
// Create output sections.
if (Script->HasSectionsCommand) {
// If linker script contains SECTIONS commands, let it create sections.
Script->processSectionCommands();
// We want to process linker script commands. When SECTIONS command
// is given we 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();
}
// 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::function<void(InputSectionBase &)> Fn) {
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