summaryrefslogtreecommitdiffstats
path: root/lld/ELF/LinkerScript.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2017-05-04 19:34:17 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2017-05-04 19:34:17 +0000
commit02ed7575e7c0dacb6eb36a5893817fcb967905b1 (patch)
tree99613754dc792144988cdb03a22335fb8f048973 /lld/ELF/LinkerScript.cpp
parentfc5b5cd29e9627d7887319ca62a79f1a71eac43b (diff)
downloadbcm5719-llvm-02ed7575e7c0dacb6eb36a5893817fcb967905b1.tar.gz
bcm5719-llvm-02ed7575e7c0dacb6eb36a5893817fcb967905b1.zip
Simplify the header allocation.
In the non linker script case we would try very early to find out if we could allocate the headers. Failing to do that would add extra alignment to the first ro section, since we would set PageAlign thinking it was the first section in the PT_LOAD. In the linker script case the header allocation must be done in the end, causing some duplication. We now tentatively add the headers to the first PT_LOAD and if it turns out they don't fit, remove them. With this we only need to allocate the headers in one place in the code. llvm-svn: 302186
Diffstat (limited to 'lld/ELF/LinkerScript.cpp')
-rw-r--r--lld/ELF/LinkerScript.cpp48
1 files changed, 44 insertions, 4 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 35b88254304..2620e699053 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -420,13 +420,11 @@ void LinkerScript::processCommands(OutputSectionFactory &Factory) {
CurOutSec = nullptr;
}
-void LinkerScript::fabricateDefaultCommands(bool AllocateHeader) {
+void LinkerScript::fabricateDefaultCommands() {
std::vector<BaseCommand *> Commands;
// Define start address
- uint64_t StartAddr = Config->ImageBase;
- if (AllocateHeader)
- StartAddr += elf::getHeaderSize();
+ uint64_t StartAddr = Config->ImageBase + elf::getHeaderSize();
// The Sections with -T<section> have been sorted in order of ascending
// address. We must lower StartAddr if the lowest -T<section address> as
@@ -892,6 +890,48 @@ void LinkerScript::synchronize() {
}
}
+static bool allocateHeaders(std::vector<PhdrEntry> &Phdrs,
+ ArrayRef<OutputSection *> OutputSections,
+ uint64_t Min) {
+ auto FirstPTLoad =
+ std::find_if(Phdrs.begin(), Phdrs.end(),
+ [](const PhdrEntry &E) { return E.p_type == PT_LOAD; });
+ if (FirstPTLoad == Phdrs.end())
+ return false;
+
+ uint64_t HeaderSize = getHeaderSize();
+ if (HeaderSize <= Min || Script->hasPhdrsCommands()) {
+ Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
+ Out::ElfHeader->Addr = Min;
+ Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size;
+ return true;
+ }
+
+ assert(FirstPTLoad->First == Out::ElfHeader);
+ OutputSection *ActualFirst = nullptr;
+ for (OutputSection *Sec : OutputSections) {
+ if (Sec->FirstInPtLoad == Out::ElfHeader) {
+ ActualFirst = Sec;
+ break;
+ }
+ }
+ if (ActualFirst) {
+ for (OutputSection *Sec : OutputSections)
+ if (Sec->FirstInPtLoad == Out::ElfHeader)
+ Sec->FirstInPtLoad = ActualFirst;
+ FirstPTLoad->First = ActualFirst;
+ } else {
+ Phdrs.erase(FirstPTLoad);
+ }
+
+ auto PhdrI = std::find_if(Phdrs.begin(), Phdrs.end(), [](const PhdrEntry &E) {
+ return E.p_type == PT_PHDR;
+ });
+ if (PhdrI != Phdrs.end())
+ Phdrs.erase(PhdrI);
+ return false;
+}
+
void LinkerScript::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
// Assign addresses as instructed by linker script SECTIONS sub-commands.
Dot = 0;
OpenPOWER on IntegriCloud