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
This commit is contained in:
Rafael Espindola
2017-05-04 19:34:17 +00:00
parent fc5b5cd29e
commit 02ed7575e7
4 changed files with 52 additions and 70 deletions

View File

@@ -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;