[lld] r282596 - [ELF] Support -z max-page-size option

Petr Hosek via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 28 08:20:47 PDT 2016


Author: phosek
Date: Wed Sep 28 10:20:47 2016
New Revision: 282596

URL: http://llvm.org/viewvc/llvm-project?rev=282596&view=rev
Log:
[ELF] Support -z max-page-size option

This options issupported by both BFD ld and gold and allows
overriding the max page size whose default values are defined by
the target.

https://llvm.org/bugs/show_bug.cgi?id=30541

Differential Revision: https://reviews.llvm.org/D24891

Added:
    lld/trunk/test/ELF/linkerscript/page-size.s
Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=282596&r1=282595&r2=282596&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Wed Sep 28 10:20:47 2016
@@ -136,7 +136,8 @@ struct Configuration {
   uint16_t EMachine = llvm::ELF::EM_NONE;
   uint64_t EntryAddr = 0;
   uint64_t ImageBase;
-  uint64_t ZStackSize = -1;
+  uint64_t MaxPageSize;
+  uint64_t ZStackSize;
   unsigned LtoJobs;
   unsigned LtoO;
   unsigned Optimize;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=282596&r1=282595&r2=282596&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Wed Sep 28 10:20:47 2016
@@ -264,15 +264,20 @@ static bool hasZOption(opt::InputArgList
   return false;
 }
 
-static Optional<StringRef>
-getZOptionValue(opt::InputArgList &Args, StringRef Key) {
+static uint64_t
+getZOptionValue(opt::InputArgList &Args, StringRef Key, uint64_t Default) {
   for (auto *Arg : Args.filtered(OPT_z)) {
     StringRef Value = Arg->getValue();
     size_t Pos = Value.find("=");
-    if (Pos != StringRef::npos && Key == Value.substr(0, Pos))
-      return Value.substr(Pos + 1);
+    if (Pos != StringRef::npos && Key == Value.substr(0, Pos)) {
+      Value = Value.substr(Pos + 1);
+      uint64_t Result;
+      if (Value.getAsInteger(0, Result))
+        error("invalid " + Key + ": " + Value);
+      return Result;
+    }
   }
-  return None;
+  return Default;
 }
 
 void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
@@ -492,9 +497,7 @@ void LinkerDriver::readConfigs(opt::Inpu
   if (!Config->Relocatable)
     Config->Strip = getStripOption(Args);
 
-  if (Optional<StringRef> Value = getZOptionValue(Args, "stack-size"))
-    if (Value->getAsInteger(0, Config->ZStackSize))
-      error("invalid stack size: " + *Value);
+  Config->ZStackSize = getZOptionValue(Args, "stack-size", -1);
 
   // Config->Pic is true if we are generating position-independent code.
   Config->Pic = Config->Pie || Config->Shared;
@@ -657,6 +660,13 @@ template <class ELFT> void LinkerDriver:
     Config->ImageBase = Config->Pic ? 0 : Target->DefaultImageBase;
   }
 
+  // Initialize Config->MaxPageSize. The default value is defined by
+  // the target, but it can be overriden using the option.
+  Config->MaxPageSize =
+      getZOptionValue(Args, "max-page-size", Target->MaxPageSize);
+  if (!isPowerOf2_64(Config->MaxPageSize))
+    error("max-page-size: value isn't a power of 2");
+
   // Add all files to the symbol table. After this, the symbol table
   // contains all known names except a few linker-synthesized symbols.
   for (InputFile *F : Files)

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=282596&r1=282595&r2=282596&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Wed Sep 28 10:20:47 2016
@@ -1472,7 +1472,7 @@ uint64_t static getConstant(StringRef S)
   if (S == "COMMONPAGESIZE")
     return Target->PageSize;
   if (S == "MAXPAGESIZE")
-    return Target->MaxPageSize;
+    return Config->MaxPageSize;
   error("unknown constant: " + S);
   return 0;
 }

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=282596&r1=282595&r2=282596&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Sep 28 10:20:47 2016
@@ -1154,7 +1154,7 @@ template <class ELFT> void Writer<ELFT>:
   for (OutputSectionBase<ELFT> *Sec : OutputSections) {
     uintX_t Alignment = Sec->getAlignment();
     if (Sec->PageAlign)
-      Alignment = std::max<uintX_t>(Alignment, Target->MaxPageSize);
+      Alignment = std::max<uintX_t>(Alignment, Config->MaxPageSize);
 
     auto I = Config->SectionStartMap.find(Sec->getName());
     if (I != Config->SectionStartMap.end())
@@ -1182,14 +1182,14 @@ template <class ELFT, class uintX_t>
 static uintX_t getFileAlignment(uintX_t Off, OutputSectionBase<ELFT> *Sec) {
   uintX_t Alignment = Sec->getAlignment();
   if (Sec->PageAlign)
-    Alignment = std::max<uintX_t>(Alignment, Target->MaxPageSize);
+    Alignment = std::max<uintX_t>(Alignment, Config->MaxPageSize);
   Off = alignTo(Off, Alignment);
 
   // Relocatable output does not have program headers
   // and does not need any other offset adjusting.
   if (Config->Relocatable || !(Sec->getFlags() & SHF_ALLOC))
     return Off;
-  return alignTo(Off, Target->MaxPageSize, Sec->getVA());
+  return alignTo(Off, Config->MaxPageSize, Sec->getVA());
 }
 
 template <class ELFT, class uintX_t>
@@ -1241,7 +1241,7 @@ template <class ELFT> void Writer<ELFT>:
       H.p_vaddr = First->getVA();
     }
     if (H.p_type == PT_LOAD)
-      H.p_align = Target->MaxPageSize;
+      H.p_align = Config->MaxPageSize;
     else if (H.p_type == PT_GNU_RELRO)
       H.p_align = 1;
 

Added: lld/trunk/test/ELF/linkerscript/page-size.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/page-size.s?rev=282596&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/page-size.s (added)
+++ lld/trunk/test/ELF/linkerscript/page-size.s Wed Sep 28 10:20:47 2016
@@ -0,0 +1,68 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: ld.lld -z max-page-size=0x4000 %t -o %t2
+# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
+
+# CHECK:      ProgramHeaders [
+# CHECK:        ProgramHeader {
+# CHECK:          Type: PT_LOAD
+# CHECK-NEXT:     Offset: 0x0
+# CHECK-NEXT:     VirtualAddress: 0x10000
+# CHECK-NEXT:     PhysicalAddress: 0x10000
+# CHECK-NEXT:     FileSize: 344
+# CHECK-NEXT:     MemSize: 344
+# CHECK-NEXT:     Flags [
+# CHECK-NEXT:       PF_R
+# CHECK-NEXT:     ]
+# CHECK-NEXT:     Alignment: 16384
+# CHECK-NEXT:   }
+# CHECK-NEXT:   ProgramHeader {
+# CHECK-NEXT:     Type: PT_LOAD
+# CHECK-NEXT:     Offset: 0x4000
+# CHECK-NEXT:     VirtualAddress: 0x14000
+# CHECK-NEXT:     PhysicalAddress: 0x14000
+# CHECK-NEXT:     FileSize: 1
+# CHECK-NEXT:     MemSize: 1
+# CHECK-NEXT:     Flags [
+# CHECK-NEXT:       PF_R
+# CHECK-NEXT:       PF_X
+# CHECK-NEXT:     ]
+# CHECK-NEXT:     Alignment: 16384
+# CHECK-NEXT:   }
+# CHECK-NEXT:   ProgramHeader {
+# CHECK-NEXT:     Type: PT_LOAD
+# CHECK-NEXT:     Offset: 0x8000
+# CHECK-NEXT:     VirtualAddress: 0x18000
+# CHECK-NEXT:     PhysicalAddress: 0x18000
+# CHECK-NEXT:     FileSize: 8
+# CHECK-NEXT:     MemSize: 8
+# CHECK-NEXT:     Flags [
+# CHECK-NEXT:       PF_R
+# CHECK-NEXT:       PF_W
+# CHECK-NEXT:     ]
+# CHECK-NEXT:     Alignment: 16384
+# CHECK-NEXT:   }
+
+# RUN: echo "SECTIONS { \
+# RUN:         symbol = CONSTANT(MAXPAGESIZE); \
+# RUN:       }" > %t.script
+# RUN: ld.lld -z max-page-size=0x4000 -o %t1 --script %t.script %t
+# RUN: llvm-objdump -t %t1 | FileCheck -check-prefix CHECK-SCRIPT %s
+
+# CHECK-SCRIPT: 0000000000004000 *ABS* 00000000 symbol
+
+# RUN: not ld.lld -z max-page-size=0x1001 -o %t1 --script %t.script %t 2>&1 \
+# RUN:  | FileCheck -check-prefix=ERR1 %s
+# ERR1: max-page-size: value isn't a power of 2
+
+# RUN: not ld.lld -z max-page-size=-0x1000 -o %t1 --script %t.script %t 2>&1 \
+# RUN:  | FileCheck -check-prefix=ERR2 %s
+# ERR2: invalid max-page-size: -0x1000
+
+.global _start
+_start:
+  nop
+
+.section .a, "aw"
+.quad 0




More information about the llvm-commits mailing list