diff options
-rw-r--r-- | lld/include/lld/ReaderWriter/ELFLinkingContext.h | 9 | ||||
-rw-r--r-- | lld/lib/Driver/GnuLdDriver.cpp | 8 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/OutputELFWriter.h | 9 | ||||
-rw-r--r-- | lld/test/elf/dynamic.test | 6 |
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: ] |