From 2e9eac13c7aaedffa567e65949c3a49ed9a13859 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 11 Sep 2015 21:18:56 +0000 Subject: [PATCH] Implement -rpath. llvm-svn: 247475 --- lld/ELF/Config.h | 1 + lld/ELF/Driver.cpp | 7 +++++++ lld/ELF/Options.td | 3 +++ lld/ELF/Writer.cpp | 13 +++++++++++++ lld/test/elf2/shared.s | 3 ++- 5 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 811169f..f844980 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -18,6 +18,7 @@ namespace elf2 { struct Configuration { llvm::StringRef OutputFile; llvm::StringRef DynamicLinker; + std::string RPath; }; extern Configuration *Config; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 05e0785..a2d7022 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -14,6 +14,7 @@ #include "SymbolTable.h" #include "Writer.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/FileSystem.h" using namespace llvm; @@ -72,6 +73,12 @@ void LinkerDriver::link(ArrayRef ArgsArr) { if (auto *Arg = Args.getLastArg(OPT_dynamic_linker)) Config->DynamicLinker = Arg->getValue(); + std::vector RPaths; + for (auto *Arg : Args.filtered(OPT_rpath)) + RPaths.push_back(Arg->getValue()); + if (!RPaths.empty()) + Config->RPath = llvm::join(RPaths.begin(), RPaths.end(), ":"); + // Create a list of input files. std::vector Inputs; diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index f2bbea8..9f0d9b7 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -9,3 +9,6 @@ def output : Separate<["-"], "o">, MetaVarName<"">, def dynamic_linker : Separate<["-"], "dynamic-linker">, HelpText<"Which dynamic linker to use">; + +def rpath : Separate<["-"], "rpath">, + HelpText<"Which dynamic linker to use">; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 3dac96c..85b6016 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -221,6 +221,12 @@ public: ++NumEntries; // DT_STRTAB ++NumEntries; // DT_STRSZ + StringRef RPath = Config->RPath; + if (!RPath.empty()) { + ++NumEntries; // DT_RUNPATH + DynStrSec.add(RPath); + } + const std::vector> &SharedFiles = SymTab.getSharedFiles(); for (const std::unique_ptr &File : SharedFiles) @@ -251,6 +257,13 @@ public: P->d_un.d_val = DynStrSec.data().size(); ++P; + StringRef RPath = Config->RPath; + if (!RPath.empty()) { + P->d_tag = DT_RUNPATH; + P->d_un.d_val = DynStrSec.getFileOff(RPath); + ++P; + } + const std::vector> &SharedFiles = SymTab.getSharedFiles(); for (const std::unique_ptr &File : SharedFiles) { diff --git a/lld/test/elf2/shared.s b/lld/test/elf2/shared.s index 8f5d73f..c39941d 100644 --- a/lld/test/elf2/shared.s +++ b/lld/test/elf2/shared.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o -// RUN: lld -flavor gnu2 -dynamic-linker /lib64/ld-linux-x86-64.so.2 %t.o %p/Inputs/i686-simple-library.so -o %t +// RUN: lld -flavor gnu2 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -rpath foo -rpath bar %t.o %p/Inputs/i686-simple-library.so -o %t // RUN: llvm-readobj --program-headers --dynamic-table -t -s -dyn-symbols -section-data %t | FileCheck %s // REQUIRES: x86 @@ -143,6 +143,7 @@ // CHECK-NEXT: 0x00000006 SYMTAB [[DYNSYMADDR]] // CHECK-NEXT: 0x00000005 STRTAB [[DYNSTRADDR]] // CHECK-NEXT: 0x0000000A STRSZ +// CHECK-NEXT: 0x0000001D RUNPATH foo:bar // CHECK-NEXT: 0x00000001 NEEDED SharedLibrary ({{.*}}/Inputs/i686-simple-library.so) // CHECK-NEXT: 0x00000000 NULL 0x0 // CHECK-NEXT: ] -- 2.7.4