diff options
author | Shankar Easwaran <shankare@codeaurora.org> | 2013-05-29 22:51:01 +0000 |
---|---|---|
committer | Shankar Easwaran <shankare@codeaurora.org> | 2013-05-29 22:51:01 +0000 |
commit | a5008e3a63b8fb22cbea978baf94b5552f863119 (patch) | |
tree | 886f9a6ea01324e607dfc7c8664930c758bc986a | |
parent | baa14e852b255047d3a04a730569936b8daca55b (diff) | |
download | bcm5719-llvm-a5008e3a63b8fb22cbea978baf94b5552f863119.tar.gz bcm5719-llvm-a5008e3a63b8fb22cbea978baf94b5552f863119.zip |
[lld][elf] Add --dynamic-linker option to the ELF linker.
Users can override the default value of the dynamic linker to be set to the
one that appears in the command line. The path can even be empty!.
Added a test for the option.
llvm-svn: 182889
-rw-r--r-- | lld/include/lld/ReaderWriter/ELFTargetInfo.h | 19 | ||||
-rw-r--r-- | lld/lib/Driver/GnuLdDriver.cpp | 5 | ||||
-rw-r--r-- | lld/lib/Driver/LDOptions.td | 5 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp | 10 | ||||
-rw-r--r-- | lld/test/elf/options/dynamic-linker.test | 14 |
5 files changed, 45 insertions, 8 deletions
diff --git a/lld/include/lld/ReaderWriter/ELFTargetInfo.h b/lld/include/lld/ReaderWriter/ELFTargetInfo.h index b75e09758ec..2e078f97337 100644 --- a/lld/include/lld/ReaderWriter/ELFTargetInfo.h +++ b/lld/include/lld/ReaderWriter/ELFTargetInfo.h @@ -81,10 +81,18 @@ public: return false; } - virtual StringRef getInterpreter() const { + /// \brief The path to the dynamic interpreter + virtual StringRef getDefaultInterpreter() const { return "/lib64/ld-linux-x86-64.so.2"; } + /// \brief The dynamic linker path set by the --dynamic-linker option + virtual StringRef getInterpreter() const { + if (_dynamicLinkerArg) + return _dynamicLinkerPath; + return getDefaultInterpreter(); + } + /// \brief Does the output have dynamic sections. virtual bool isDynamic() const; @@ -106,6 +114,13 @@ public: void setIsStaticExecutable(bool v) { _isStaticExecutable = v; } void setMergeCommonStrings(bool v) { _mergeCommonStrings = v; } void setUseShlibUndefines(bool use) { _useShlibUndefines = use; } + + /// \brief Set the dynamic linker path + void setInterpreter(StringRef dynamicLinker) { + _dynamicLinkerArg = true; + _dynamicLinkerPath = dynamicLinker; + } + void appendSearchPath(StringRef dirPath) { _inputSearchPaths.push_back(dirPath); } @@ -129,12 +144,14 @@ protected: bool _mergeCommonStrings; bool _runLayoutPass; bool _useShlibUndefines; + bool _dynamicLinkerArg; std::vector<StringRef> _inputSearchPaths; llvm::BumpPtrAllocator _extraStrings; std::unique_ptr<Reader> _elfReader; std::unique_ptr<Reader> _yamlReader; std::unique_ptr<Writer> _writer; std::unique_ptr<Reader> _linkerScriptReader; + StringRef _dynamicLinkerPath; }; } // end namespace lld diff --git a/lld/lib/Driver/GnuLdDriver.cpp b/lld/lib/Driver/GnuLdDriver.cpp index 78b63e6e209..25ac09343a2 100644 --- a/lld/lib/Driver/GnuLdDriver.cpp +++ b/lld/lib/Driver/GnuLdDriver.cpp @@ -193,6 +193,11 @@ GnuLdDriver::parse(int argc, const char *argv[], raw_ostream &diagnostics) { if (parsedArgs->getLastArg(OPT_use_shlib_undefs)) options->setUseShlibUndefines(true); + // Handle --dynamic-linker + if (llvm::opt::Arg *dynamicLinker = + parsedArgs->getLastArg(OPT_dynamic_linker)) + options->setInterpreter(dynamicLinker->getValue()); + // Handle -Lxxx for (llvm::opt::arg_iterator it = parsedArgs->filtered_begin(OPT_L), ie = parsedArgs->filtered_end(); diff --git a/lld/lib/Driver/LDOptions.td b/lld/lib/Driver/LDOptions.td index d2b3b8eb67d..b901b3061b7 100644 --- a/lld/lib/Driver/LDOptions.td +++ b/lld/lib/Driver/LDOptions.td @@ -18,8 +18,9 @@ def output : Separate<["-"], "o">, def relocatable : Flag<["--"], "relocatable">; def relocatable_r : Flag<["-"], "r">, Alias<relocatable>; -def dynamic_linker : Separate<["-"], "dynamic-linker">; - +def dynamic_linker : Joined<["--"], "dynamic-linker=">, + HelpText<"Set the path to the dynamic linker">; +def dynamic_linker_alias : Separate<["-"], "dynamic-linker">, Alias<dynamic_linker>; def m : Separate<["-"], "m">; def z : Separate<["-"], "z">; diff --git a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp index ebb4a6824d6..e9b171c35ec 100644 --- a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp +++ b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp @@ -22,7 +22,8 @@ #include "llvm/Support/Path.h" namespace lld { -ELFTargetInfo::ELFTargetInfo(llvm::Triple triple, std::unique_ptr<TargetHandlerBase> targetHandler) +ELFTargetInfo::ELFTargetInfo(llvm::Triple triple, + std::unique_ptr<TargetHandlerBase> targetHandler) : _outputFileType(elf::ET_EXEC), _triple(triple), _targetHandler(std::move(targetHandler)), @@ -32,11 +33,10 @@ ELFTargetInfo::ELFTargetInfo(llvm::Triple triple, std::unique_ptr<TargetHandlerB _noInhibitExec(false), _mergeCommonStrings(false), _runLayoutPass(true), - _useShlibUndefines(false) {} + _useShlibUndefines(false), + _dynamicLinkerArg(false) {} -bool ELFTargetInfo::is64Bits() const { - return getTriple().isArch64Bit(); -} +bool ELFTargetInfo::is64Bits() const { return getTriple().isArch64Bit(); } bool ELFTargetInfo::isLittleEndian() const { // TODO: Do this properly. It is not defined purely by arch. diff --git a/lld/test/elf/options/dynamic-linker.test b/lld/test/elf/options/dynamic-linker.test new file mode 100644 index 00000000000..75faf677b5d --- /dev/null +++ b/lld/test/elf/options/dynamic-linker.test @@ -0,0 +1,14 @@ +# This tests the functionality of specifying dynamic-linker argument in the +# command line +RUN: lld -flavor gnu --dynamic-linker="/xyz.so" %p/../Inputs/foo.o.x86-64 --noinhibit-exec -o %t +RUN: llvm-objdump -s %t | FileCheck -check-prefix=DYNAMICINTERP1 %s +RUN: lld -flavor gnu --dynamic-linker="" %p/../Inputs/foo.o.x86-64 --noinhibit-exec -o %t1 +RUN: llvm-objdump -s %t1 | FileCheck -check-prefix=DYNAMICINTERP2 %s +RUN: lld -flavor gnu -dynamic-linker /xyz.so %p/../Inputs/foo.o.x86-64 --noinhibit-exec -o %t2 +RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=DYNAMICINTERP1 %s + +DYNAMICINTERP1:Contents of section .interp: +DYNAMICINTERP1: 400158 2f78797a 2e736f00 /xyz.so. +DYNAMICINTERP2:Contents of section .interp: +DYNAMICINTERP2: 400158 00 + |