summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2018-03-01 15:25:46 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2018-03-01 15:25:46 +0000
commite75b42ee4ef0ed54d73a93c66f8bb9e9ed4e7006 (patch)
tree3604b9df58f5c36159645b17b844729c3f2a50cc
parent237e52674fb0f3959da2f3422905cdafc796ae45 (diff)
downloadbcm5719-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.cpp22
-rw-r--r--lld/test/ELF/linkerscript/header-phdr2.s11
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
OpenPOWER on IntegriCloud