[lld] r315293 - [ELF] Set Dot initially to --image-base value when using linker scripts

James Henderson via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 10 03:09:35 PDT 2017


Author: jhenderson
Date: Tue Oct 10 03:09:35 2017
New Revision: 315293

URL: http://llvm.org/viewvc/llvm-project?rev=315293&view=rev
Log:
[ELF] Set Dot initially to --image-base value when using linker scripts

When parsing linker scripts, LLD previously started with a '.' value of 0,
regardless of the internal default image base for the target, and regardless of
switches such as --image-base. It seems reasonable to use a different image base
value when using linker scripts and --image-base is specified, since otherwise the
switch has no effect. This change does this, as well as removing unnecessary
initialisation of Dot where it is not used.

The default image base should not be used when processing linker
scripts, because this will change the behaviour for existing linker script users,
and potentially result in invalid output being produced, as a subsequent assignment
to Dot could move the location counter backwards. Instead, we maintain the existing
behaviour of starting from 0 if --image-base is not specified.

Reviewers: ruiu

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

Added:
    lld/trunk/test/ELF/linkerscript/image-base.s
Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/Target.cpp
    lld/trunk/ELF/Target.h

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=315293&r1=315292&r2=315293&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Tue Oct 10 03:09:35 2017
@@ -166,7 +166,7 @@ struct Configuration {
   uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;
   uint16_t EMachine = llvm::ELF::EM_NONE;
   uint64_t ErrorLimit = 20;
-  uint64_t ImageBase;
+  llvm::Optional<uint64_t> ImageBase;
   uint64_t MaxPageSize;
   uint64_t ZStackSize;
   unsigned LTOPartitions;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=315293&r1=315292&r2=315293&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Tue Oct 10 03:09:35 2017
@@ -908,13 +908,12 @@ static uint64_t getMaxPageSize(opt::Inpu
 }
 
 // Parses -image-base option.
-static uint64_t getImageBase(opt::InputArgList &Args) {
-  // Use default if no -image-base option is given.
-  // Because we are using "Target" here, this function
-  // has to be called after the variable is initialized.
+static Optional<uint64_t> getImageBase(opt::InputArgList &Args) {
+  // Because we are using "Config->MaxPageSize" here, this function has to be
+  // called after the variable is initialized.
   auto *Arg = Args.getLastArg(OPT_image_base);
   if (!Arg)
-    return Config->Pic ? 0 : Target->DefaultImageBase;
+    return None;
 
   StringRef S = Arg->getValue();
   uint64_t V;

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=315293&r1=315292&r2=315293&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Tue Oct 10 03:09:35 2017
@@ -365,7 +365,6 @@ void LinkerScript::processCommands(Outpu
   // script parser.
   CurAddressState = State.get();
   CurAddressState->OutSec = Aether;
-  Dot = 0;
 
   for (size_t I = 0; I < Opt.Commands.size(); ++I) {
     // Handle symbol assignments outside of any output section.
@@ -438,7 +437,7 @@ void LinkerScript::fabricateDefaultComma
     StartAddr = std::min(StartAddr, KV.second);
 
   auto Expr = [=] {
-    return std::min(StartAddr, Config->ImageBase + elf::getHeaderSize());
+    return std::min(StartAddr, Target->getImageBase() + elf::getHeaderSize());
   };
   Opt.Commands.insert(Opt.Commands.begin(),
                       make<SymbolAssignment>(".", Expr, ""));
@@ -780,9 +779,11 @@ LinkerScript::AddressState::AddressState
   }
 }
 
+// Assign addresses as instructed by linker script SECTIONS sub-commands.
 void LinkerScript::assignAddresses() {
-  // Assign addresses as instructed by linker script SECTIONS sub-commands.
-  Dot = 0;
+  // By default linker scripts use an initial value of 0 for '.', but prefer
+  // -image-base if set.
+  Dot = Config->ImageBase ? *Config->ImageBase : 0;
   auto State = make_unique<AddressState>(Opt);
   // CurAddressState captures the local AddressState and makes it accessible
   // deliberately. This is needed as there are some cases where we cannot just

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=315293&r1=315292&r2=315293&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Tue Oct 10 03:09:35 2017
@@ -1166,7 +1166,7 @@ template <class ELFT> void DynamicSectio
   if (Config->EMachine == EM_MIPS) {
     add({DT_MIPS_RLD_VERSION, 1});
     add({DT_MIPS_FLAGS, RHF_NOTPOT});
-    add({DT_MIPS_BASE_ADDRESS, Config->ImageBase});
+    add({DT_MIPS_BASE_ADDRESS, Target->getImageBase()});
     add({DT_MIPS_SYMTABNO, InX::DynSymTab->getNumSymbols()});
     add({DT_MIPS_LOCAL_GOTNO, InX::MipsGot->getLocalEntriesNum()});
     if (const SymbolBody *B = InX::MipsGot->getFirstGlobalEntry())

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=315293&r1=315292&r2=315293&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Tue Oct 10 03:09:35 2017
@@ -165,3 +165,10 @@ void TargetInfo::relaxTlsLdToLe(uint8_t
                                 uint64_t Val) const {
   llvm_unreachable("Should not have claimed to be relaxable");
 }
+
+uint64_t TargetInfo::getImageBase() {
+  // Use -image-base if set. Fall back to the target default if not.
+  if (Config->ImageBase)
+    return *Config->ImageBase;
+  return Config->Pic ? 0 : DefaultImageBase;
+}

Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=315293&r1=315292&r2=315293&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Tue Oct 10 03:09:35 2017
@@ -64,11 +64,7 @@ public:
   unsigned PageSize = 4096;
   unsigned DefaultMaxPageSize = 4096;
 
-  // On FreeBSD x86_64 the first page cannot be mmaped.
-  // On Linux that is controled by vm.mmap_min_addr. At least on some x86_64
-  // installs that is 65536, so the first 15 pages cannot be used.
-  // Given that, the smallest value that can be used in here is 0x10000.
-  uint64_t DefaultImageBase = 0x10000;
+  uint64_t getImageBase();
 
   // Offset of _GLOBAL_OFFSET_TABLE_ from base of .got section. Use -1 for
   // end of .got
@@ -108,6 +104,13 @@ public:
   virtual void relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const;
   virtual void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const;
   virtual void relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const;
+
+protected:
+  // On FreeBSD x86_64 the first page cannot be mmaped.
+  // On Linux that is controled by vm.mmap_min_addr. At least on some x86_64
+  // installs that is 65536, so the first 15 pages cannot be used.
+  // Given that, the smallest value that can be used in here is 0x10000.
+  uint64_t DefaultImageBase = 0x10000;
 };
 
 TargetInfo *getAArch64TargetInfo();

Added: lld/trunk/test/ELF/linkerscript/image-base.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/image-base.s?rev=315293&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/image-base.s (added)
+++ lld/trunk/test/ELF/linkerscript/image-base.s Tue Oct 10 03:09:35 2017
@@ -0,0 +1,18 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: echo "SECTIONS { mysym = .; }" > %t.script
+
+# RUN: ld.lld %t.o -o %t-default.elf -T %t.script
+# RUN: llvm-readobj --symbols %t-default.elf | FileCheck %s --check-prefix=DEFAULT
+# DEFAULT: Name: mysym
+# DEFAULT-NEXT: Value: 0x0
+
+# RUN: ld.lld %t.o -o %t-switch.elf -T %t.script --image-base=0x100000
+# RUN: llvm-readobj --symbols %t-switch.elf | FileCheck %s --check-prefix=SWITCH
+# SWITCH: Name: mysym
+# SWITCH-NEXT: Value: 0x100000
+
+.global _start
+_start:
+    nop




More information about the llvm-commits mailing list