Implement -rpath.
authorRafael Espindola <rafael.espindola@gmail.com>
Fri, 11 Sep 2015 21:18:56 +0000 (21:18 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Fri, 11 Sep 2015 21:18:56 +0000 (21:18 +0000)
llvm-svn: 247475

lld/ELF/Config.h
lld/ELF/Driver.cpp
lld/ELF/Options.td
lld/ELF/Writer.cpp
lld/test/elf2/shared.s

index 811169f..f844980 100644 (file)
@@ -18,6 +18,7 @@ namespace elf2 {
 struct Configuration {
   llvm::StringRef OutputFile;
   llvm::StringRef DynamicLinker;
+  std::string RPath;
 };
 
 extern Configuration *Config;
index 05e0785..a2d7022 100644 (file)
@@ -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<const char *> ArgsArr) {
   if (auto *Arg = Args.getLastArg(OPT_dynamic_linker))
     Config->DynamicLinker = Arg->getValue();
 
+  std::vector<StringRef> 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<MemoryBufferRef> Inputs;
 
index f2bbea8..9f0d9b7 100644 (file)
@@ -9,3 +9,6 @@ def output : Separate<["-"], "o">, MetaVarName<"<path>">,
 
 def dynamic_linker : Separate<["-"], "dynamic-linker">,
      HelpText<"Which dynamic linker to use">;
+
+def rpath : Separate<["-"], "rpath">,
+     HelpText<"Which dynamic linker to use">;
index 3dac96c..85b6016 100644 (file)
@@ -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<std::unique_ptr<SharedFileBase>> &SharedFiles =
         SymTab.getSharedFiles();
     for (const std::unique_ptr<SharedFileBase> &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<std::unique_ptr<SharedFileBase>> &SharedFiles =
         SymTab.getSharedFiles();
     for (const std::unique_ptr<SharedFileBase> &File : SharedFiles) {
index 8f5d73f..c39941d 100644 (file)
@@ -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
 
 // 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: ]