summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/include/lld/ReaderWriter/ELFLinkingContext.h9
-rw-r--r--lld/lib/Driver/GnuLdDriver.cpp8
-rw-r--r--lld/lib/ReaderWriter/ELF/OutputELFWriter.h9
-rw-r--r--lld/test/elf/dynamic.test6
4 files changed, 30 insertions, 2 deletions
diff --git a/lld/include/lld/ReaderWriter/ELFLinkingContext.h b/lld/include/lld/ReaderWriter/ELFLinkingContext.h
index 3a9a850891a..18c307c17ce 100644
--- a/lld/include/lld/ReaderWriter/ELFLinkingContext.h
+++ b/lld/include/lld/ReaderWriter/ELFLinkingContext.h
@@ -180,6 +180,14 @@ public:
_sysrootPath = path;
}
+ void addRpath(StringRef path) {
+ _rpathList.push_back(path);
+ }
+
+ range<const StringRef *> getRpathList() const {
+ return _rpathList;
+ }
+
private:
ELFLinkingContext() LLVM_DELETED_FUNCTION;
@@ -213,6 +221,7 @@ protected:
StringRefVector _initFunctions;
StringRefVector _finiFunctions;
StringRef _sysrootPath;
+ StringRefVector _rpathList;
};
} // end namespace lld
diff --git a/lld/lib/Driver/GnuLdDriver.cpp b/lld/lib/Driver/GnuLdDriver.cpp
index a43a811b752..d0de52fc3fd 100644
--- a/lld/lib/Driver/GnuLdDriver.cpp
+++ b/lld/lib/Driver/GnuLdDriver.cpp
@@ -289,6 +289,14 @@ bool GnuLdDriver::parse(int argc, const char *argv[],
break;
}
+ case OPT_rpath: {
+ SmallVector<StringRef, 2> rpaths;
+ StringRef(inputArg->getValue()).split(rpaths, ":");
+ for (auto path : rpaths)
+ ctx->addRpath(path);
+ break;
+ }
+
case OPT_sysroot:
ctx->setSysroot(inputArg->getValue());
break;
diff --git a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
index df9582b9c87..3c3db33952e 100644
--- a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
+++ b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
@@ -160,6 +160,15 @@ void OutputELFWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
dyn.d_un.d_val = _dynamicStringTable->addString(loadName.getKey());
_dynamicTable->addEntry(dyn);
}
+ const auto &rpathList = _context.getRpathList();
+ if (!rpathList.empty()) {
+ auto rpath = new (_alloc) std::string(join(rpathList.begin(),
+ rpathList.end(), ":"));
+ Elf_Dyn dyn;
+ dyn.d_tag = DT_RPATH;
+ dyn.d_un.d_val = _dynamicStringTable->addString(*rpath);
+ _dynamicTable->addEntry(dyn);
+ }
// The dynamic symbol table need to be sorted earlier because the hash
// table needs to be built using the dynamic symbol table. It would be
// late to sort the symbols due to that in finalize. In the dynamic symbol
diff --git a/lld/test/elf/dynamic.test b/lld/test/elf/dynamic.test
index e459b42f09d..1b889bff8fe 100644
--- a/lld/test/elf/dynamic.test
+++ b/lld/test/elf/dynamic.test
@@ -1,6 +1,7 @@
# Checks functionality of dynamic executables
RUN: lld -flavor gnu -target x86_64-linux %p/Inputs/use-shared.x86-64 \
-RUN: %p/Inputs/shared.so-x86-64 -o %t -e main --allow-shlib-undefined
+RUN: %p/Inputs/shared.so-x86-64 -o %t -e main --allow-shlib-undefined \
+RUN: -rpath /l1:/l2 -rpath /l3
RUN: lld -flavor gnu -target x86_64-linux %p/Inputs/use-shared.x86-64 \
RUN: %p/Inputs/shared.so-x86-64 -emit-yaml -o %t2 --allow-shlib-undefined \
RUN: --noinhibit-exec
@@ -59,7 +60,7 @@ CHECK-NEXT: Binding: Global
CHECK-NEXT: Type: Function
CHECK: }
-CHECK: DynamicSection [ (14 entries)
+CHECK: DynamicSection [ (15 entries)
CHECK: Tag Type Name/Value
CHECK: 0x0000000000000004 HASH
CHECK: 0x0000000000000005 STRTAB
@@ -74,5 +75,6 @@ CHECK: 0x0000000000000003 PLTGOT
CHECK: 0x0000000000000014 PLTREL RELA
CHECK: 0x0000000000000017 JMPREL
CHECK: 0x0000000000000001 NEEDED SharedLibrary (shared.so-x86-64)
+CHECK: 0x000000000000000F RPATH /l1:/l2:/l3
CHECK: 0x0000000000000000 NULL 0x0
CHECK: ]
OpenPOWER on IntegriCloud