diff options
-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 + |