diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2018-03-01 15:25:46 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2018-03-01 15:25:46 +0000 |
commit | e75b42ee4ef0ed54d73a93c66f8bb9e9ed4e7006 (patch) | |
tree | 3604b9df58f5c36159645b17b844729c3f2a50cc | |
parent | 237e52674fb0f3959da2f3422905cdafc796ae45 (diff) | |
download | bcm5719-llvm-e75b42ee4ef0ed54d73a93c66f8bb9e9ed4e7006.tar.gz bcm5719-llvm-e75b42ee4ef0ed54d73a93c66f8bb9e9ed4e7006.zip |
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
-rw-r--r-- | lld/ELF/LinkerScript.cpp | 22 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/header-phdr2.s | 11 |
2 files changed, 29 insertions, 4 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 6aae9e6975d..f1a6d6381f1 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -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); diff --git a/lld/test/ELF/linkerscript/header-phdr2.s b/lld/test/ELF/linkerscript/header-phdr2.s new file mode 100644 index 00000000000..c595a6d3975 --- /dev/null +++ b/lld/test/ELF/linkerscript/header-phdr2.s @@ -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 |