[lld] r326441 - Don't allocate a header bellow address 0.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 1 07:25:46 PST 2018


Author: rafael
Date: Thu Mar  1 07:25:46 2018
New Revision: 326441

URL: http://llvm.org/viewvc/llvm-project?rev=326441&view=rev
Log:
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.

Added:
    lld/trunk/test/ELF/linkerscript/header-phdr2.s
Modified:
    lld/trunk/ELF/LinkerScript.cpp

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=326441&r1=326440&r2=326441&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Thu Mar  1 07:25:46 2018
@@ -897,6 +897,15 @@ static OutputSection *findFirstSection(P
   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::
     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);

Added: lld/trunk/test/ELF/linkerscript/header-phdr2.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/header-phdr2.s?rev=326441&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/header-phdr2.s (added)
+++ lld/trunk/test/ELF/linkerscript/header-phdr2.s Thu Mar  1 07:25:46 2018
@@ -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




More information about the llvm-commits mailing list