diff options
| author | Peter Smith <peter.smith@linaro.org> | 2017-04-19 12:46:32 +0000 |
|---|---|---|
| committer | Peter Smith <peter.smith@linaro.org> | 2017-04-19 12:46:32 +0000 |
| commit | cbfe9e946fd04d57145f35e2289c595a4a498f0b (patch) | |
| tree | e83e6cdbb3cd06983628310700024b3c35a6cd3f /lld/ELF/LinkerScript.cpp | |
| parent | cb89513bc74257178e8adb09029b64ab8b52bed5 (diff) | |
| download | bcm5719-llvm-cbfe9e946fd04d57145f35e2289c595a4a498f0b.tar.gz bcm5719-llvm-cbfe9e946fd04d57145f35e2289c595a4a498f0b.zip | |
[ELF] Always use Script::assignAddresses()
This change fabricates linker script commands for the case where there is
no linker script SECTIONS to control address assignment. This permits us
to have a single Script->assignAddresses() function.
There is a small change in user-visible-behavior with respect to the
handling of .tbss SHT_NOBITS, SHF_TLS as the Script->assignAddresses()
requires setDot() to be called with monotically increasing addresses.
The tls-offset.s test has been updated so that the script and non-script
results match.
This change should make the non-script behavior of lld closer to an
equivalent linker script.
Differential Revision: https://reviews.llvm.org/D31888
llvm-svn: 300687
Diffstat (limited to 'lld/ELF/LinkerScript.cpp')
| -rw-r--r-- | lld/ELF/LinkerScript.cpp | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index ab2ca22e9e1..63eb90456e1 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -413,6 +413,56 @@ void LinkerScript::processCommands(OutputSectionFactory &Factory) { CurOutSec = nullptr; } +void LinkerScript::fabricateDefaultCommands(bool AllocateHeader) { + std::vector<BaseCommand *> Commands; + + // Define start address + uint64_t StartAddr = Config->ImageBase; + if (AllocateHeader) + StartAddr += elf::getHeaderSize(); + + // The Sections with -T<section> 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); + } + Commands.push_back( + make<SymbolAssignment>(".", [=] { return StartAddr; }, "")); + + // For each OutputSection that needs a VA fabricate an OutputSectionCommand + // with an InputSectionDescription describing the InputSections + for (OutputSection *Sec : *OutputSections) { + if (!(Sec->Flags & SHF_ALLOC)) + continue; + + auto I = Config->SectionStartMap.find(Sec->Name); + if (I != Config->SectionStartMap.end()) + Commands.push_back( + make<SymbolAssignment>(".", [=] { return I->second; }, "")); + + auto *OSCmd = make<OutputSectionCommand>(Sec->Name); + OSCmd->Sec = Sec; + if (Sec->PageAlign) + OSCmd->AddrExpr = [=] { + return alignTo(Script->getDot(), Config->MaxPageSize); + }; + Commands.push_back(OSCmd); + if (Sec->Sections.size()) { + auto *ISD = make<InputSectionDescription>(""); + OSCmd->Commands.push_back(ISD); + for (InputSection *ISec : Sec->Sections) { + ISD->Sections.push_back(ISec); + ISec->Assigned = true; + } + } + } + // SECTIONS commands run before other non SECTIONS commands + Commands.insert(Commands.end(), Opt.Commands.begin(), Opt.Commands.end()); + Opt.Commands = std::move(Commands); +} + // Add sections that didn't match any sections command. void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) { for (InputSectionBase *S : InputSections) |

