summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/include/lld/ReaderWriter/ELFTargetInfo.h19
-rw-r--r--lld/lib/Driver/GnuLdDriver.cpp5
-rw-r--r--lld/lib/Driver/LDOptions.td5
-rw-r--r--lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp10
-rw-r--r--lld/test/elf/options/dynamic-linker.test14
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
+
OpenPOWER on IntegriCloud