Don't allocate a header bellow address 0.

With the current code if the script has a PHDRS we always obey and try
to allocate a header. This can cause Min - HeaderSize to underflow.

It looks like bfd actually prints an error for this case. With this
patch we do the same.

Found while looking at pr36515.

llvm-svn: 326441
This commit is contained in:
Rafael Espindola
2018-03-01 15:25:46 +00:00
parent 237e52674f
commit e75b42ee4e
2 changed files with 29 additions and 4 deletions

View File

@@ -897,6 +897,15 @@ static OutputSection *findFirstSection(PhdrEntry *Load) {
return nullptr;
}
static uint64_t computeBase(uint64_t Min, bool AllocateHeaders) {
// If there is no SECTIONS or if the linkerscript is explicit about program
// headers, do our best to allocate them.
if (!Script->HasSectionsCommand || AllocateHeaders)
return 0;
// Otherwise only allocate program headers if that would not add a page.
return alignDown(Min, Config->MaxPageSize);
}
// Try to find an address for the file and program headers output sections,
// which were unconditionally added to the first PT_LOAD segment earlier.
//
@@ -920,17 +929,22 @@ void LinkerScript::allocateHeaders(std::vector<PhdrEntry *> &Phdrs) {
return;
PhdrEntry *FirstPTLoad = *It;
bool HasExplicitHeaders =
llvm::any_of(PhdrsCommands, [](const PhdrsCommand &Cmd) {
return Cmd.HasPhdrs || Cmd.HasFilehdr;
});
uint64_t HeaderSize = getHeaderSize();
// When linker script with SECTIONS is being used, don't output headers
// unless there's a space for them.
uint64_t Base = HasSectionsCommand ? alignDown(Min, Config->MaxPageSize) : 0;
if (HeaderSize <= Min - Base || Script->hasPhdrsCommands()) {
if (HeaderSize <= Min - computeBase(Min, HasExplicitHeaders)) {
Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
Out::ElfHeader->Addr = Min;
Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size;
return;
}
// Error if we were explicitly asked to allocate headers.
if (HasExplicitHeaders)
error("could not allocate headers");
Out::ElfHeader->PtLoad = nullptr;
Out::ProgramHeaders->PtLoad = nullptr;
FirstPTLoad->FirstSec = findFirstSection(FirstPTLoad);

View File

@@ -0,0 +1,11 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
# RUN: echo "PHDRS { foobar PT_LOAD FILEHDR PHDRS; }" > %t.script
# RUN: echo "SECTIONS { .text : { *(.text) } : foobar }" >> %t.script
# RUN: not ld.lld --script %t.script %t.o -o %t 2>&1 | FileCheck %s
# CHECK: could not allocate headers
.global _start
_start:
retq