summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShankar Easwaran <shankare@codeaurora.org>2013-05-29 22:51:01 +0000
committerShankar Easwaran <shankare@codeaurora.org>2013-05-29 22:51:01 +0000
commita5008e3a63b8fb22cbea978baf94b5552f863119 (patch)
tree886f9a6ea01324e607dfc7c8664930c758bc986a
parentbaa14e852b255047d3a04a730569936b8daca55b (diff)
downloadbcm5719-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.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