[lld] r360593 - [ELF] Full support for -n (--nmagic) and -N (--omagic) via common page

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Mon May 13 09:01:26 PDT 2019


Author: psmith
Date: Mon May 13 09:01:26 2019
New Revision: 360593

URL: http://llvm.org/viewvc/llvm-project?rev=360593&view=rev
Log:
[ELF] Full support for -n (--nmagic) and -N (--omagic) via common page

The -n (--nmagic) disables page alignment, and acts as a -Bstatic
The -N (--omagic) does what -n does but also marks the executable segment as
writeable. As page alignment is disabled headers are not allocated unless
explicit in the linker script.

To disable page alignment in LLD we choose to set the page sizes to 1 so
that any alignment based on the page size does nothing. To set the
Target->PageSize to 1 we implement -z common-page-size, which has the side
effect of allowing the user to set the value as well.

Setting the page alignments to 1 does mean that any use of
CONSTANT(MAXPAGESIZE) or CONSTANT(COMMONPAGESIZE) in a linker script will
return 1, unlike in ld.bfd. However given that -n and -N disable paging
these probably shouldn't be used in a linker script where -n or -N is in
use.

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


Added:
    lld/trunk/test/ELF/common-page.s
    lld/trunk/test/ELF/linkerscript/nmagic-alignment.test
    lld/trunk/test/ELF/magic-page-combo-warn.s
Modified:
    lld/trunk/ELF/Arch/SPARCV9.cpp
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/Options.td
    lld/trunk/ELF/ScriptParser.cpp
    lld/trunk/ELF/Target.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/docs/ld.lld.1
    lld/trunk/test/ELF/relro-omagic.s
    lld/trunk/test/ELF/segments.s

Modified: lld/trunk/ELF/Arch/SPARCV9.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/SPARCV9.cpp?rev=360593&r1=360592&r2=360593&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/SPARCV9.cpp (original)
+++ lld/trunk/ELF/Arch/SPARCV9.cpp Mon May 13 09:01:26 2019
@@ -41,7 +41,7 @@ SPARCV9::SPARCV9() {
   PltEntrySize = 32;
   PltHeaderSize = 4 * PltEntrySize;
 
-  PageSize = 8192;
+  DefaultCommonPageSize = 8192;
   DefaultMaxPageSize = 0x100000;
   DefaultImageBase = 0x100000;
 }

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=360593&r1=360592&r2=360593&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Mon May 13 09:01:26 2019
@@ -159,6 +159,7 @@ struct Configuration {
   bool LTONewPassManager;
   bool MergeArmExidx;
   bool MipsN32Abi = false;
+  bool Nmagic;
   bool NoinhibitExec;
   bool Nostdlib;
   bool OFormatBinary;
@@ -219,6 +220,7 @@ struct Configuration {
   uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;
   uint16_t EMachine = llvm::ELF::EM_NONE;
   llvm::Optional<uint64_t> ImageBase;
+  uint64_t CommonPageSize;
   uint64_t MaxPageSize;
   uint64_t MipsGotSize;
   uint64_t ZStackSize;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=360593&r1=360592&r2=360593&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Mon May 13 09:01:26 2019
@@ -365,7 +365,8 @@ static bool isKnownZFlag(StringRef S) {
          S == "nokeep-text-section-prefix" || S == "norelro" || S == "notext" ||
          S == "now" || S == "origin" || S == "relro" || S == "retpolineplt" ||
          S == "rodynamic" || S == "text" || S == "wxneeded" ||
-         S.startswith("max-page-size=") || S.startswith("stack-size=");
+         S.startswith("common-page-size") || S.startswith("max-page-size=") ||
+         S.startswith("stack-size=");
 }
 
 // Report an error for an unknown -z option.
@@ -829,6 +830,7 @@ static void readConfigs(opt::InputArgLis
   Config->MipsGotSize = args::getInteger(Args, OPT_mips_got_size, 0xfff0);
   Config->MergeArmExidx =
       Args.hasFlag(OPT_merge_exidx_entries, OPT_no_merge_exidx_entries, true);
+  Config->Nmagic = Args.hasFlag(OPT_nmagic, OPT_no_nmagic, false);
   Config->NoinhibitExec = Args.hasArg(OPT_noinhibit_exec);
   Config->Nostdlib = Args.hasArg(OPT_nostdlib);
   Config->OFormatBinary = isOutputFormatBinary(Args);
@@ -957,11 +959,10 @@ static void readConfigs(opt::InputArgLis
   if (Args.hasArg(OPT_print_map))
     Config->MapFile = "-";
 
-  // --omagic is an option to create old-fashioned executables in which
-  // .text segments are writable. Today, the option is still in use to
-  // create special-purpose programs such as boot loaders. It doesn't
-  // make sense to create PT_GNU_RELRO for such executables.
-  if (Config->Omagic)
+  // Page alignment can be disabled by the -n (--nmagic) and -N (--omagic).
+  // As PT_GNU_RELRO relies on Paging, do not create it when we have disabled
+  // it.
+  if (Config->Nmagic || Config->Omagic)
     Config->ZRelro = false;
 
   std::tie(Config->BuildId, Config->BuildIdVector) = getBuildId(Args);
@@ -1114,6 +1115,8 @@ void LinkerDriver::createFiles(opt::Inpu
       Config->AsNeeded = false;
       break;
     case OPT_Bstatic:
+    case OPT_omagic:
+    case OPT_nmagic:
       Config->Static = true;
       break;
     case OPT_Bdynamic:
@@ -1199,6 +1202,29 @@ static uint64_t getMaxPageSize(opt::Inpu
                                        Target->DefaultMaxPageSize);
   if (!isPowerOf2_64(Val))
     error("max-page-size: value isn't a power of 2");
+  if (Config->Nmagic || Config->Omagic) {
+    if (Val != Target->DefaultMaxPageSize)
+      warn("-z max-page-size set, but paging disabled by omagic or nmagic");
+    return 1;
+  }
+  return Val;
+}
+
+// Parse -z common-page-size=<value>. The default value is defined by
+// each target.
+static uint64_t getCommonPageSize(opt::InputArgList &Args) {
+  uint64_t Val = args::getZOptionValue(Args, OPT_z, "common-page-size",
+                                       Target->DefaultCommonPageSize);
+  if (!isPowerOf2_64(Val))
+    error("common-page-size: value isn't a power of 2");
+  if (Config->Nmagic || Config->Omagic) {
+    if (Val != Target->DefaultCommonPageSize)
+      warn("-z common-page-size set, but paging disabled by omagic or nmagic");
+    return 1;
+  }
+  // CommonPageSize can't be larger than MaxPageSize.
+  if (Val > Config->MaxPageSize)
+    Val = Config->MaxPageSize;
   return Val;
 }
 
@@ -1623,7 +1649,18 @@ template <class ELFT> void LinkerDriver:
     llvm::erase_if(InputSections, [](InputSectionBase *S) { return S->Debug; });
 
   Config->EFlags = Target->calcEFlags();
+  // MaxPageSize (sometimes called abi page size) is the maximum page size that
+  // the output can be run on. For example if the OS can use 4k or 64k page
+  // sizes then MaxPageSize must be 64 for the output to be useable on both.
+  // All important alignment decisions must use this value.
   Config->MaxPageSize = getMaxPageSize(Args);
+  // CommonPageSize is the most common page size that the output will be run on.
+  // For example if an OS can use 4k or 64k page sizes and 4k is more common
+  // than 64k then CommonPageSize is set to 4k. CommonPageSize can be used for
+  // optimizations such as DATA_SEGMENT_ALIGN in linker scripts. LLD's use of it
+  // is limited to writing trap instructions on the last executable segment.
+  Config->CommonPageSize = getCommonPageSize(Args);
+
   Config->ImageBase = getImageBase(Args);
 
   if (Config->EMachine == EM_ARM) {

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=360593&r1=360592&r2=360593&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Mon May 13 09:01:26 2019
@@ -993,8 +993,10 @@ void LinkerScript::allocateHeaders(std::
       llvm::any_of(PhdrsCommands, [](const PhdrsCommand &Cmd) {
         return Cmd.HasPhdrs || Cmd.HasFilehdr;
       });
+  bool Paged = !Config->Omagic && !Config->Nmagic;
   uint64_t HeaderSize = getHeaderSize();
-  if (HeaderSize <= Min - computeBase(Min, HasExplicitHeaders)) {
+  if ((Paged || HasExplicitHeaders) &&
+      HeaderSize <= Min - computeBase(Min, HasExplicitHeaders)) {
     Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
     Out::ElfHeader->Addr = Min;
     Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size;

Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=360593&r1=360592&r2=360593&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Mon May 13 09:01:26 2019
@@ -218,6 +218,9 @@ defm merge_exidx_entries: B<"merge-exidx
     "Enable merging .ARM.exidx entries (default)",
     "Disable merging .ARM.exidx entries">;
 
+def nmagic: F<"nmagic">, MetaVarName<"<magic>">,
+  HelpText<"Do not page align sections, link against static libraries.">;
+
 def nostdlib: F<"nostdlib">,
   HelpText<"Only search directories specified on the command line">;
 
@@ -230,8 +233,11 @@ def no_dynamic_linker: F<"no-dynamic-lin
 def noinhibit_exec: F<"noinhibit-exec">,
   HelpText<"Retain the executable output file whenever it is still usable">;
 
+def no_nmagic: F<"no-nmagic">, MetaVarName<"<magic>">,
+  HelpText<"Page align sections (default)">;
+
 def no_omagic: F<"no-omagic">, MetaVarName<"<magic>">,
-  HelpText<"Do not set the text data sections to be writable">;
+  HelpText<"Do not set the text data sections to be writable, page align sections (default)">;
 
 def no_rosegment: F<"no-rosegment">,
   HelpText<"Do not put read-only non-executable sections in their own segment">;
@@ -246,7 +252,7 @@ def oformat: Separate<["--"], "oformat">
   HelpText<"Specify the binary format for the output object file">;
 
 def omagic: Flag<["--"], "omagic">, MetaVarName<"<magic>">,
-  HelpText<"Set the text and data sections to be readable and writable">;
+  HelpText<"Set the text and data sections to be readable and writable, do not page align sections, link against static libraries">;
 
 defm orphan_handling:
   Eq<"orphan-handling", "Control how orphan sections are handled when linker script used">;
@@ -414,6 +420,7 @@ def: Separate<["-"], "b">, Alias<format>
 def: JoinedOrSeparate<["-"], "l">, Alias<library>, HelpText<"Alias for --library">;
 def: JoinedOrSeparate<["-"], "L">, Alias<library_path>, HelpText<"Alias for --library-path">;
 def: F<"no-pic-executable">, Alias<no_pie>, HelpText<"Alias for --no-pie">;
+def: Flag<["-"], "n">, Alias<nmagic>, HelpText<"Alias for --nmagic">;
 def: Flag<["-"], "N">, Alias<omagic>, HelpText<"Alias for --omagic">;
 def: Joined<["--"], "output=">, Alias<o>, HelpText<"Alias for -o">;
 def: Separate<["--"], "output">, Alias<o>, HelpText<"Alias for -o">;

Modified: lld/trunk/ELF/ScriptParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ScriptParser.cpp?rev=360593&r1=360592&r2=360593&view=diff
==============================================================================
--- lld/trunk/ELF/ScriptParser.cpp (original)
+++ lld/trunk/ELF/ScriptParser.cpp Mon May 13 09:01:26 2019
@@ -1039,7 +1039,7 @@ Expr ScriptParser::getPageSize() {
   std::string Location = getCurrentLocation();
   return [=]() -> uint64_t {
     if (Target)
-      return Target->PageSize;
+      return Config->CommonPageSize;
     error(Location + ": unable to calculate page size");
     return 4096; // Return a dummy value.
   };

Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=360593&r1=360592&r2=360593&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Mon May 13 09:01:26 2019
@@ -81,7 +81,7 @@ public:
 
   virtual ~TargetInfo();
 
-  unsigned PageSize = 4096;
+  unsigned DefaultCommonPageSize = 4096;
   unsigned DefaultMaxPageSize = 4096;
 
   uint64_t getImageBase() const;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=360593&r1=360592&r2=360593&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon May 13 09:01:26 2019
@@ -2132,7 +2132,7 @@ template <class ELFT> void Writer<ELFT>:
     // segment is the last loadable segment, align the offset of the
     // following section to avoid loading non-segments parts of the file.
     if (LastRX && LastRX->LastSec == Sec)
-      Off = alignTo(Off, Target->PageSize);
+      Off = alignTo(Off, Config->CommonPageSize);
   }
 
   SectionHeaderOff = alignTo(Off, Config->Wordsize);
@@ -2184,7 +2184,7 @@ template <class ELFT> void Writer<ELFT>:
       // The glibc dynamic loader rounds the size down, so we need to round up
       // to protect the last page. This is a no-op on FreeBSD which always
       // rounds up.
-      P->p_memsz = alignTo(P->p_memsz, Target->PageSize);
+      P->p_memsz = alignTo(P->p_memsz, Config->CommonPageSize);
     }
 
     if (P->p_type == PT_TLS && P->p_memsz) {
@@ -2477,10 +2477,10 @@ template <class ELFT> void Writer<ELFT>:
   // Fill the last page.
   for (PhdrEntry *P : Phdrs)
     if (P->p_type == PT_LOAD && (P->p_flags & PF_X))
-      fillTrap(Out::BufferStart +
-                   alignDown(P->p_offset + P->p_filesz, Target->PageSize),
+      fillTrap(Out::BufferStart + alignDown(P->p_offset + P->p_filesz,
+                                            Config->CommonPageSize),
                Out::BufferStart +
-                   alignTo(P->p_offset + P->p_filesz, Target->PageSize));
+                   alignTo(P->p_offset + P->p_filesz, Config->CommonPageSize));
 
   // Round up the file size of the last segment to the page boundary iff it is
   // an executable segment to ensure that other tools don't accidentally
@@ -2491,7 +2491,8 @@ template <class ELFT> void Writer<ELFT>:
       Last = P;
 
   if (Last && (Last->p_flags & PF_X))
-    Last->p_memsz = Last->p_filesz = alignTo(Last->p_filesz, Target->PageSize);
+    Last->p_memsz = Last->p_filesz =
+        alignTo(Last->p_filesz, Config->CommonPageSize);
 }
 
 // Write section contents to a mmap'ed file.

Modified: lld/trunk/docs/ld.lld.1
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/docs/ld.lld.1?rev=360593&r1=360592&r2=360593&view=diff
==============================================================================
--- lld/trunk/docs/ld.lld.1 (original)
+++ lld/trunk/docs/ld.lld.1 Mon May 13 09:01:26 2019
@@ -254,6 +254,8 @@ Set target emulation.
 .It Fl -Map Ns = Ns Ar file , Fl M Ar file
 Print a link map to
 .Ar file .
+.It Fl -nmagic , Fl n
+Do not page align sections, link against static libraries.
 .It Fl -no-allow-shlib-undefined
 Do not allow unresolved references in shared libraries.
 This option is enabled by default when linking an executable.
@@ -277,6 +279,10 @@ Disable garbage collection of unused sec
 Disable STB_GNU_UNIQUE symbol binding.
 .It Fl -no-merge-exidx-entries
 Disable merging .ARM.exidx entries.
+.It F1 -no-nmagic
+Page align sections.
+.It F1 -no-omagic
+Do not set the text data sections to be writable, page align sections.
 .It Fl -no-rosegment
 Do not put read-only non-executable sections in their own segment.
 .It Fl -no-threads
@@ -325,7 +331,7 @@ is
 .Cm binary ,
 which produces output with no ELF header.
 .It Fl -omagic , Fl N
-Set the text and data sections to be readable and writable.
+Set the text and data sections to be readable and writable, do not page align sections, link against static libraries.
 .It Fl -opt-remarks-filename Ar file
 Write optimization remarks in YAML format to
 .Ar file .

Added: lld/trunk/test/ELF/common-page.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/common-page.s?rev=360593&view=auto
==============================================================================
--- lld/trunk/test/ELF/common-page.s (added)
+++ lld/trunk/test/ELF/common-page.s Mon May 13 09:01:26 2019
@@ -0,0 +1,223 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# exits with return code 42 on linux
+.globl _start
+_start:
+  nop
+
+# Increase max-page-size to 64k while using the default x86_64 common page size
+# of 4k. If the last loadable segment is executable then lld aligns the next
+# section using the common page size.
+
+# RUN: ld.lld -z max-page-size=0x10000 -z common-page-size=0x1000 %t -o %t2
+# RUN: llvm-readobj --sections -l %t2 | FileCheck --check-prefix=CHECK-MAX %s
+
+# CHECK-MAX:      Sections [
+# CHECK-MAX-NEXT:   Section {
+# CHECK-MAX-NEXT:     Index: 0
+# CHECK-MAX-NEXT:     Name:  (0)
+# CHECK-MAX-NEXT:     Type: SHT_NULL (0x0)
+# CHECK-MAX-NEXT:     Flags [ (0x0)
+# CHECK-MAX-NEXT:     ]
+# CHECK-MAX-NEXT:     Address: 0x0
+# CHECK-MAX-NEXT:     Offset: 0x0
+# CHECK-MAX-NEXT:     Size: 0
+# CHECK-MAX-NEXT:     Link: 0
+# CHECK-MAX-NEXT:     Info: 0
+# CHECK-MAX-NEXT:     AddressAlignment: 0
+# CHECK-MAX-NEXT:     EntrySize: 0
+# CHECK-MAX-NEXT:   }
+# CHECK-MAX-NEXT:   Section {
+# CHECK-MAX-NEXT:     Index: 1
+# CHECK-MAX-NEXT:     Name: .text (1)
+# CHECK-MAX-NEXT:     Type: SHT_PROGBITS (0x1)
+# CHECK-MAX-NEXT:     Flags [ (0x6)
+# CHECK-MAX-NEXT:       SHF_ALLOC (0x2)
+# CHECK-MAX-NEXT:       SHF_EXECINSTR (0x4)
+# CHECK-MAX-NEXT:     ]
+# CHECK-MAX-NEXT:     Address: 0x210000
+# CHECK-MAX-NEXT:     Offset: 0x10000
+# CHECK-MAX-NEXT:     Size: 1
+# CHECK-MAX-NEXT:     Link: 0
+# CHECK-MAX-NEXT:     Info: 0
+# CHECK-MAX-NEXT:     AddressAlignment: 4
+# CHECK-MAX-NEXT:     EntrySize: 0
+# CHECK-MAX-NEXT:   }
+# CHECK-MAX-NEXT:   Section {
+# CHECK-MAX-NEXT:     Index: 2
+# CHECK-MAX-NEXT:     Name: .comment (7)
+# CHECK-MAX-NEXT:     Type: SHT_PROGBITS (0x1)
+# CHECK-MAX-NEXT:     Flags [ (0x30)
+# CHECK-MAX-NEXT:       SHF_MERGE (0x10)
+# CHECK-MAX-NEXT:       SHF_STRINGS (0x20)
+# CHECK-MAX-NEXT:     ]
+# CHECK-MAX-NEXT:     Address: 0x0
+# CHECK-MAX-NEXT:     Offset: 0x11000
+# CHECK-MAX-NEXT:     Size: 8
+# CHECK-MAX-NEXT:     Link: 0
+# CHECK-MAX-NEXT:     Info: 0
+# CHECK-MAX-NEXT:     AddressAlignment: 1
+# CHECK-MAX-NEXT:     EntrySize: 1
+
+# CHECK-MAX: ProgramHeaders [
+# CHECK-MAX-NEXT:   ProgramHeader {
+# CHECK-MAX-NEXT:     Type: PT_PHDR (0x6)
+# CHECK-MAX-NEXT:     Offset: 0x40
+# CHECK-MAX-NEXT:     VirtualAddress: 0x200040
+# CHECK-MAX-NEXT:     PhysicalAddress: 0x200040
+# CHECK-MAX-NEXT:     FileSize: 224
+# CHECK-MAX-NEXT:     MemSize: 224
+# CHECK-MAX-NEXT:     Flags [ (0x4)
+# CHECK-MAX-NEXT:       PF_R (0x4)
+# CHECK-MAX-NEXT:     ]
+# CHECK-MAX-NEXT:     Alignment: 8
+# CHECK-MAX-NEXT:   }
+# CHECK-MAX-NEXT:   ProgramHeader {
+# CHECK-MAX-NEXT:     Type: PT_LOAD (0x1)
+# CHECK-MAX-NEXT:     Offset: 0x0
+# CHECK-MAX-NEXT:     VirtualAddress: 0x200000
+# CHECK-MAX-NEXT:     PhysicalAddress: 0x200000
+# CHECK-MAX-NEXT:     FileSize: 288
+# CHECK-MAX-NEXT:     MemSize: 288
+# CHECK-MAX-NEXT:     Flags [ (0x4)
+# CHECK-MAX-NEXT:       PF_R (0x4)
+# CHECK-MAX-NEXT:     ]
+# CHECK-MAX-NEXT:     Alignment: 65536
+# CHECK-MAX-NEXT:   }
+# CHECK-MAX-NEXT:   ProgramHeader {
+# CHECK-MAX-NEXT:     Type: PT_LOAD (0x1)
+# CHECK-MAX-NEXT:     Offset: 0x10000
+# CHECK-MAX-NEXT:     VirtualAddress: 0x210000
+# CHECK-MAX-NEXT:     PhysicalAddress: 0x210000
+# CHECK-MAX-NEXT:     FileSize: 4096
+# CHECK-MAX-NEXT:     MemSize: 4096
+# CHECK-MAX-NEXT:     Flags [ (0x5)
+# CHECK-MAX-NEXT:       PF_R (0x4)
+# CHECK-MAX-NEXT:       PF_X (0x1)
+# CHECK-MAX-NEXT:     ]
+# CHECK-MAX-NEXT:     Alignment: 65536
+# CHECK-MAX-NEXT:   }
+# CHECK-MAX-NEXT:   ProgramHeader {
+# CHECK-MAX-NEXT:     Type: PT_GNU_STACK (0x6474E551)
+# CHECK-MAX-NEXT:     Offset: 0x0
+# CHECK-MAX-NEXT:     VirtualAddress: 0x0
+# CHECK-MAX-NEXT:     PhysicalAddress: 0x0
+# CHECK-MAX-NEXT:     FileSize: 0
+# CHECK-MAX-NEXT:     MemSize: 0
+# CHECK-MAX-NEXT:     Flags [ (0x6)
+# CHECK-MAX-NEXT:       PF_R (0x4)
+# CHECK-MAX-NEXT:       PF_W (0x2)
+# CHECK-MAX-NEXT:     ]
+# CHECK-MAX-NEXT:     Alignment: 0
+
+# Increase common-page-size to max-page-size. Expect to see a larger offset
+# of the first Section after the executable loadable segment due to the higher
+# alignment requirement.
+
+# RUN: ld.lld -z max-page-size=0x10000 -z common-page-size=0x10000 %t -o %t3
+# RUN: llvm-readobj --sections -l %t3 | FileCheck --check-prefix=CHECK-COMMON %s
+
+# Check that we truncate common-page-size to max-page-size
+
+# RUN: ld.lld -z max-page-size=0x10000 -z common-page-size=0x100000 %t -o %t4
+# RUN: llvm-readobj --sections -l %t4 | FileCheck --check-prefix=CHECK-COMMON %s
+
+# CHECK-COMMON: Sections [
+# CHECK-COMMON-NEXT:   Section {
+# CHECK-COMMON-NEXT:     Index: 0
+# CHECK-COMMON-NEXT:     Name:  (0)
+# CHECK-COMMON-NEXT:     Type: SHT_NULL (0x0)
+# CHECK-COMMON-NEXT:     Flags [ (0x0)
+# CHECK-COMMON-NEXT:     ]
+# CHECK-COMMON-NEXT:     Address: 0x0
+# CHECK-COMMON-NEXT:     Offset: 0x0
+# CHECK-COMMON-NEXT:     Size: 0
+# CHECK-COMMON-NEXT:     Link: 0
+# CHECK-COMMON-NEXT:     Info: 0
+# CHECK-COMMON-NEXT:     AddressAlignment: 0
+# CHECK-COMMON-NEXT:     EntrySize: 0
+# CHECK-COMMON-NEXT:   }
+# CHECK-COMMON-NEXT:   Section {
+# CHECK-COMMON-NEXT:     Index: 1
+# CHECK-COMMON-NEXT:     Name: .text (1)
+# CHECK-COMMON-NEXT:     Type: SHT_PROGBITS (0x1)
+# CHECK-COMMON-NEXT:     Flags [ (0x6)
+# CHECK-COMMON-NEXT:       SHF_ALLOC (0x2)
+# CHECK-COMMON-NEXT:       SHF_EXECINSTR (0x4)
+# CHECK-COMMON-NEXT:     ]
+# CHECK-COMMON-NEXT:     Address: 0x210000
+# CHECK-COMMON-NEXT:     Offset: 0x10000
+# CHECK-COMMON-NEXT:     Size: 1
+# CHECK-COMMON-NEXT:     Link: 0
+# CHECK-COMMON-NEXT:     Info: 0
+# CHECK-COMMON-NEXT:     AddressAlignment: 4
+# CHECK-COMMON-NEXT:     EntrySize: 0
+# CHECK-COMMON-NEXT:   }
+# CHECK-COMMON-NEXT:   Section {
+# CHECK-COMMON-NEXT:     Index: 2
+# CHECK-COMMON-NEXT:     Name: .comment (7)
+# CHECK-COMMON-NEXT:     Type: SHT_PROGBITS (0x1)
+# CHECK-COMMON-NEXT:     Flags [ (0x30)
+# CHECK-COMMON-NEXT:       SHF_MERGE (0x10)
+# CHECK-COMMON-NEXT:       SHF_STRINGS (0x20)
+# CHECK-COMMON-NEXT:     ]
+# CHECK-COMMON-NEXT:     Address: 0x0
+# CHECK-COMMON-NEXT:     Offset: 0x20000
+# CHECK-COMMON-NEXT:     Size: 8
+# CHECK-COMMON-NEXT:     Link: 0
+# CHECK-COMMON-NEXT:     Info: 0
+# CHECK-COMMON-NEXT:     AddressAlignment: 1
+# CHECK-COMMON-NEXT:     EntrySize: 1
+
+# CHECK-COMMON: ProgramHeaders [
+# CHECK-COMMON-NEXT:   ProgramHeader {
+# CHECK-COMMON-NEXT:     Type: PT_PHDR (0x6)
+# CHECK-COMMON-NEXT:     Offset: 0x40
+# CHECK-COMMON-NEXT:     VirtualAddress: 0x200040
+# CHECK-COMMON-NEXT:     PhysicalAddress: 0x200040
+# CHECK-COMMON-NEXT:     FileSize: 224
+# CHECK-COMMON-NEXT:     MemSize: 224
+# CHECK-COMMON-NEXT:     Flags [ (0x4)
+# CHECK-COMMON-NEXT:       PF_R (0x4)
+# CHECK-COMMON-NEXT:     ]
+# CHECK-COMMON-NEXT:     Alignment: 8
+# CHECK-COMMON-NEXT:   }
+# CHECK-COMMON-NEXT:   ProgramHeader {
+# CHECK-COMMON-NEXT:     Type: PT_LOAD (0x1)
+# CHECK-COMMON-NEXT:     Offset: 0x0
+# CHECK-COMMON-NEXT:     VirtualAddress: 0x200000
+# CHECK-COMMON-NEXT:     PhysicalAddress: 0x200000
+# CHECK-COMMON-NEXT:     FileSize: 288
+# CHECK-COMMON-NEXT:     MemSize: 288
+# CHECK-COMMON-NEXT:     Flags [ (0x4)
+# CHECK-COMMON-NEXT:       PF_R (0x4)
+# CHECK-COMMON-NEXT:     ]
+# CHECK-COMMON-NEXT:     Alignment: 65536
+# CHECK-COMMON-NEXT:   }
+# CHECK-COMMON-NEXT:   ProgramHeader {
+# CHECK-COMMON-NEXT:     Type: PT_LOAD (0x1)
+# CHECK-COMMON-NEXT:     Offset: 0x10000
+# CHECK-COMMON-NEXT:     VirtualAddress: 0x210000
+# CHECK-COMMON-NEXT:     PhysicalAddress: 0x210000
+# CHECK-COMMON-NEXT:     FileSize: 65536
+# CHECK-COMMON-NEXT:     MemSize: 65536
+# CHECK-COMMON-NEXT:     Flags [ (0x5)
+# CHECK-COMMON-NEXT:       PF_R (0x4)
+# CHECK-COMMON-NEXT:       PF_X (0x1)
+# CHECK-COMMON-NEXT:     ]
+# CHECK-COMMON-NEXT:     Alignment: 65536
+# CHECK-COMMON-NEXT:   }
+# CHECK-COMMON-NEXT:   ProgramHeader {
+# CHECK-COMMON-NEXT:     Type: PT_GNU_STACK (0x6474E551)
+# CHECK-COMMON-NEXT:     Offset: 0x0
+# CHECK-COMMON-NEXT:     VirtualAddress: 0x0
+# CHECK-COMMON-NEXT:     PhysicalAddress: 0x0
+# CHECK-COMMON-NEXT:     FileSize: 0
+# CHECK-COMMON-NEXT:     MemSize: 0
+# CHECK-COMMON-NEXT:     Flags [ (0x6)
+# CHECK-COMMON-NEXT:       PF_R (0x4)
+# CHECK-COMMON-NEXT:       PF_W (0x2)
+# CHECK-COMMON-NEXT:     ]
+# CHECK-COMMON-NEXT:     Alignment: 0

Added: lld/trunk/test/ELF/linkerscript/nmagic-alignment.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/nmagic-alignment.test?rev=360593&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/nmagic-alignment.test (added)
+++ lld/trunk/test/ELF/linkerscript/nmagic-alignment.test Mon May 13 09:01:26 2019
@@ -0,0 +1,85 @@
+# REQUIRES: x86
+
+# Test that mimics a use case of -n to produce a kernel mapped shared-object
+# in a non paged context. We specifically want to test:
+# - We can allocate the headers into the first program header (via PHDRS)
+# typically -n does not allocate headers.
+# - The alignment of the .text section is not page aligned.
+
+# RUN: echo ".text; .globl foo; foo: nop" > %t.s
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t.s -o %t.o
+# RUN: ld.lld %t.o -o %t.so --shared --hash-style=sysv --script %s
+# RUN: llvm-readobj --program-headers %t.so | FileCheck %s
+# RUN: ld.lld %t.o -o %t2.so --shared --hash-style=sysv -n --script %s
+# RUN: llvm-readobj --program-headers %t2.so | FileCheck %s --check-prefix=CHECK-N
+
+SECTIONS {
+ . = 0x0 + SIZEOF_HEADERS;
+ .hash : { *(.hash) } :text
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ . = ALIGN(4);
+ .text : { *(.text*) }
+ .dynamic : { *(.dynamic) } :text :dynamic
+}
+
+PHDRS {
+ text PT_LOAD FLAGS(5) FILEHDR PHDRS;
+ dynamic PT_DYNAMIC FLAGS(4);
+}
+
+# CHECK: ProgramHeaders [
+# CHECK-NEXT:   ProgramHeader {
+# CHECK-NEXT:     Type: PT_LOAD
+# CHECK-NEXT:     Offset: 0x0
+# CHECK-NEXT:     VirtualAddress: 0x0
+# CHECK-NEXT:     PhysicalAddress: 0x0
+# CHECK-NEXT:     FileSize:
+# CHECK-NEXT:     MemSize:
+# CHECK-NEXT:     Flags [
+# CHECK-NEXT:       PF_R
+# CHECK-NEXT:       PF_X
+# CHECK-NEXT:     ]
+# CHECK-NEXT:     Alignment: 4096
+# CHECK-NEXT:   }
+# CHECK-NEXT:   ProgramHeader {
+# CHECK-NEXT:     Type: PT_DYNAMIC
+# CHECK-NEXT:     Offset: 0x108
+# CHECK-NEXT:     VirtualAddress: 0x108
+# CHECK-NEXT:     PhysicalAddress: 0x108
+# CHECK-NEXT:     FileSize:
+# CHECK-NEXT:     MemSize:
+# CHECK-NEXT:     Flags [
+# CHECK-NEXT:       PF_R
+# CHECK-NEXT:     ]
+# CHECK-NEXT:     Alignment: 8
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+# CHECK-N: ProgramHeaders [
+# CHECK-N-NEXT:   ProgramHeader {
+# CHECK-N-NEXT:     Type: PT_LOAD
+# CHECK-N-NEXT:     Offset: 0x0
+# CHECK-N-NEXT:     VirtualAddress: 0x0
+# CHECK-N-NEXT:     PhysicalAddress: 0x0
+# CHECK-N-NEXT:     FileSize: 360
+# CHECK-N-NEXT:     MemSize: 360
+# CHECK-N-NEXT:     Flags [
+# CHECK-N-NEXT:       PF_R
+# CHECK-N-NEXT:       PF_X
+# CHECK-N-NEXT:     ]
+# CHECK-N-NEXT:     Alignment: 8
+# CHECK-N-NEXT:   }
+# CHECK-N-NEXT:   ProgramHeader {
+# CHECK-N-NEXT:     Type: PT_DYNAMIC
+# CHECK-N-NEXT:     Offset: 0x108
+# CHECK-N-NEXT:     VirtualAddress: 0x108
+# CHECK-N-NEXT:     PhysicalAddress: 0x108
+# CHECK-N-NEXT:     FileSize:
+# CHECK-N-NEXT:     MemSize:
+# CHECK-N-NEXT:     Flags [
+# CHECK-N-NEXT:       PF_R
+# CHECK-N-NEXT:     ]
+# CHECK-N-NEXT:     Alignment: 8
+# CHECK-N-NEXT:   }
+# CHECK-N-NEXT: ]

Added: lld/trunk/test/ELF/magic-page-combo-warn.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/magic-page-combo-warn.s?rev=360593&view=auto
==============================================================================
--- lld/trunk/test/ELF/magic-page-combo-warn.s (added)
+++ lld/trunk/test/ELF/magic-page-combo-warn.s Mon May 13 09:01:26 2019
@@ -0,0 +1,86 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# Test that we warn when a page size is set and paging is disabled by -n or -N.
+
+# RUN: ld.lld -z max-page-size=0x10 -z common-page-size=0x10 -N %t -o %t2 2>&1 | FileCheck --check-prefix=WARN %s
+# RUN: llvm-readobj --program-headers %t2 | FileCheck --check-prefix=OMAGIC %s
+# RUN: ld.lld -z max-page-size=0x10 -z common-page-size=0x10 --omagic %t -o %t2  2>&1 | FileCheck --check-prefix=WARN %s
+# RUN: llvm-readobj --program-headers %t2 | FileCheck --check-prefix=OMAGIC %s
+
+# WARN: ld.lld: warning: -z max-page-size set, but paging disabled by omagic or nmagic
+# WARN-NEXT: ld.lld: warning: -z common-page-size set, but paging disabled by omagic or nmagic
+
+# OMAGIC:     ProgramHeader {
+# OMAGIC:      Type: PT_LOAD
+# OMAGIC-NEXT:   Offset: 0xE8
+# OMAGIC-NEXT:   VirtualAddress:
+# OMAGIC-NEXT:   PhysicalAddress:
+# OMAGIC-NEXT:   FileSize:
+# OMAGIC-NEXT:   MemSize:
+# OMAGIC-NEXT:   Flags [
+# OMAGIC-NEXT:     PF_R
+# OMAGIC-NEXT:     PF_W
+# OMAGIC-NEXT:     PF_X
+# OMAGIC-NEXT:   ]
+# OMAGIC-NEXT:   Alignment: 8
+# OMAGIC-NEXT: }
+# OMAGIC-NEXT: ProgramHeader {
+# OMAGIC-NEXT:   Type: PT_GNU_STACK
+
+# RUN: ld.lld -z max-page-size=0x10 -z common-page-size=0x10 -n %t -o %t3  2>&1 | FileCheck --check-prefix=WARN %s
+# RUN: llvm-readobj --program-headers %t3 | FileCheck --check-prefix=NMAGIC %s
+# RUN: ld.lld -z max-page-size=0x10 -z common-page-size=0x10 --nmagic %t -o %t3  2>&1 | FileCheck --check-prefix=WARN %s
+# RUN: llvm-readobj --program-headers %t3 | FileCheck --check-prefix=NMAGIC %s
+
+# NMAGIC:   ProgramHeader {
+# NMAGIC-NEXT:     Type: PT_LOAD
+# NMAGIC-NEXT:     Offset: 0x158
+# NMAGIC-NEXT:     VirtualAddress:
+# NMAGIC-NEXT:     PhysicalAddress:
+# NMAGIC-NEXT:     FileSize: 1
+# NMAGIC-NEXT:     MemSize: 1
+# NMAGIC-NEXT:     Flags [
+# NMAGIC-NEXT:       PF_R
+# NMAGIC-NEXT:     ]
+# NMAGIC-NEXT:     Alignment: 8
+# NMAGIC-NEXT:   }
+# NMAGIC-NEXT:   ProgramHeader {
+# NMAGIC-NEXT:     Type: PT_LOAD
+# NMAGIC-NEXT:     Offset: 0x15C
+# NMAGIC-NEXT:     VirtualAddress:
+# NMAGIC-NEXT:     PhysicalAddress:
+# NMAGIC-NEXT:     FileSize: 2
+# NMAGIC-NEXT:     MemSize: 2
+# NMAGIC-NEXT:     Flags [
+# NMAGIC-NEXT:       PF_R
+# NMAGIC-NEXT:       PF_X
+# NMAGIC-NEXT:     ]
+# NMAGIC-NEXT:     Alignment: 4
+# NMAGIC-NEXT:   }
+# NMAGIC-NEXT:   ProgramHeader {
+# NMAGIC-NEXT:     Type: PT_LOAD (0x1)
+# NMAGIC-NEXT:     Offset: 0x15E
+# NMAGIC-NEXT:     VirtualAddress:
+# NMAGIC-NEXT:     PhysicalAddress:
+# NMAGIC-NEXT:     FileSize: 1
+# NMAGIC-NEXT:     MemSize: 1
+# NMAGIC-NEXT:     Flags [
+# NMAGIC-NEXT:       PF_R
+# NMAGIC-NEXT:       PF_W
+# NMAGIC-NEXT:     ]
+# NMAGIC-NEXT:     Alignment: 1
+# NMAGIC-NEXT:   }
+
+.global _start
+_start:
+ nop
+
+.section .ro,"a"
+nop
+
+.section .rw,"aw"
+nop
+
+.section .rx,"ax"
+nop

Modified: lld/trunk/test/ELF/relro-omagic.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/relro-omagic.s?rev=360593&r1=360592&r2=360593&view=diff
==============================================================================
--- lld/trunk/test/ELF/relro-omagic.s (original)
+++ lld/trunk/test/ELF/relro-omagic.s Mon May 13 09:01:26 2019
@@ -2,7 +2,7 @@
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
 # RUN: ld.lld -shared %t2.o -o %t2.so -soname relro-omagic.s.tmp2.so
-# RUN: ld.lld --hash-style=sysv -N %t.o %t2.so -o %t
+# RUN: ld.lld --hash-style=sysv -N %t.o -Bdynamic %t2.so -o %t
 # RUN: llvm-objdump -section-headers %t | FileCheck --check-prefix=NORELRO %s
 # RUN: llvm-readobj --program-headers %t | FileCheck --check-prefix=NOPHDRS %s
 

Modified: lld/trunk/test/ELF/segments.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/segments.s?rev=360593&r1=360592&r2=360593&view=diff
==============================================================================
--- lld/trunk/test/ELF/segments.s (original)
+++ lld/trunk/test/ELF/segments.s Mon May 13 09:01:26 2019
@@ -84,7 +84,7 @@
 
 # OMAGIC:     ProgramHeader {
 # OMAGIC:      Type: PT_LOAD
-# OMAGIC-NEXT:   Offset: 0x0
+# OMAGIC-NEXT:   Offset: 0xE8
 # OMAGIC-NEXT:   VirtualAddress:
 # OMAGIC-NEXT:   PhysicalAddress:
 # OMAGIC-NEXT:   FileSize:
@@ -94,11 +94,55 @@
 # OMAGIC-NEXT:     PF_W
 # OMAGIC-NEXT:     PF_X
 # OMAGIC-NEXT:   ]
-# OMAGIC-NEXT:   Alignment: 4096
+# OMAGIC-NEXT:   Alignment: 8
 # OMAGIC-NEXT: }
 # OMAGIC-NEXT: ProgramHeader {
 # OMAGIC-NEXT:   Type: PT_GNU_STACK
 
+# RUN: ld.lld -n %t -o %t4
+# RUN: llvm-readobj --program-headers %t4 | FileCheck --check-prefix=NMAGIC %s
+# RUN: ld.lld --nmagic %t -o %t4
+# RUN: llvm-readobj --program-headers %t4 | FileCheck --check-prefix=NMAGIC %s
+
+# NMAGIC:   ProgramHeader {
+# NMAGIC-NEXT:     Type: PT_LOAD
+# NMAGIC-NEXT:     Offset: 0x158
+# NMAGIC-NEXT:     VirtualAddress:
+# NMAGIC-NEXT:     PhysicalAddress:
+# NMAGIC-NEXT:     FileSize: 1
+# NMAGIC-NEXT:     MemSize: 1
+# NMAGIC-NEXT:     Flags [
+# NMAGIC-NEXT:       PF_R
+# NMAGIC-NEXT:     ]
+# NMAGIC-NEXT:     Alignment: 8
+# NMAGIC-NEXT:   }
+# NMAGIC-NEXT:   ProgramHeader {
+# NMAGIC-NEXT:     Type: PT_LOAD
+# NMAGIC-NEXT:     Offset: 0x15C
+# NMAGIC-NEXT:     VirtualAddress:
+# NMAGIC-NEXT:     PhysicalAddress:
+# NMAGIC-NEXT:     FileSize: 2
+# NMAGIC-NEXT:     MemSize: 2
+# NMAGIC-NEXT:     Flags [
+# NMAGIC-NEXT:       PF_R
+# NMAGIC-NEXT:       PF_X
+# NMAGIC-NEXT:     ]
+# NMAGIC-NEXT:     Alignment: 4
+# NMAGIC-NEXT:   }
+# NMAGIC-NEXT:   ProgramHeader {
+# NMAGIC-NEXT:     Type: PT_LOAD (0x1)
+# NMAGIC-NEXT:     Offset: 0x15E
+# NMAGIC-NEXT:     VirtualAddress:
+# NMAGIC-NEXT:     PhysicalAddress:
+# NMAGIC-NEXT:     FileSize: 1
+# NMAGIC-NEXT:     MemSize: 1
+# NMAGIC-NEXT:     Flags [
+# NMAGIC-NEXT:       PF_R
+# NMAGIC-NEXT:       PF_W
+# NMAGIC-NEXT:     ]
+# NMAGIC-NEXT:     Alignment: 1
+# NMAGIC-NEXT:   }
+
 .global _start
 _start:
  nop




More information about the llvm-commits mailing list