[lld] e48d126 - [lld-macho] Support -rpath

Jez Ng via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 12 19:51:12 PDT 2020


Author: Jez Ng
Date: 2020-08-12T19:50:28-07:00
New Revision: e48d1262b88f7088f3e2b41b459f508829a2ea1c

URL: https://github.com/llvm/llvm-project/commit/e48d1262b88f7088f3e2b41b459f508829a2ea1c
DIFF: https://github.com/llvm/llvm-project/commit/e48d1262b88f7088f3e2b41b459f508829a2ea1c.diff

LOG: [lld-macho] Support -rpath

Pretty straightforward; just emits LC_RPATH for dyld to consume.

Note that lld itself does not yet support dylib lookup via @rpath.

Reviewed By: #lld-macho, compnerd

Differential Revision: https://reviews.llvm.org/D85701

Added: 
    lld/test/MachO/rpath.s

Modified: 
    lld/MachO/Config.h
    lld/MachO/Driver.cpp
    lld/MachO/Options.td
    lld/MachO/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/MachO/Config.h b/lld/MachO/Config.h
index da217cf2a8f0..362069ea8040 100644
--- a/lld/MachO/Config.h
+++ b/lld/MachO/Config.h
@@ -41,6 +41,7 @@ struct Configuration {
   llvm::MachO::HeaderFileType outputType;
   std::vector<llvm::StringRef> librarySearchPaths;
   std::vector<llvm::StringRef> frameworkSearchPaths;
+  std::vector<llvm::StringRef> runtimePaths;
   llvm::DenseMap<llvm::StringRef, SymbolPriorityEntry> priorities;
 };
 

diff  --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 55ec2d226f08..2ffedaaf42c4 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -499,6 +499,7 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
       args.getLastArgValue(OPT_install_name, config->outputFile);
   config->headerPad = args::getHex(args, OPT_headerpad, /*Default=*/32);
   config->outputType = args.hasArg(OPT_dylib) ? MH_DYLIB : MH_EXECUTE;
+  config->runtimePaths = args::getStrings(args, OPT_rpath);
 
   std::vector<StringRef> roots;
   for (const Arg *arg : args.filtered(OPT_syslibroot))
@@ -569,6 +570,8 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
     case OPT_L:
     case OPT_headerpad:
     case OPT_install_name:
+    case OPT_rpath:
+    case OPT_sub_library:
     case OPT_Z:
     case OPT_arch:
     case OPT_syslibroot:

diff  --git a/lld/MachO/Options.td b/lld/MachO/Options.td
index b606ff5d8821..e53c1bd87ecd 100644
--- a/lld/MachO/Options.td
+++ b/lld/MachO/Options.td
@@ -410,7 +410,6 @@ def undefined : Separate<["-"], "undefined">,
 def rpath : Separate<["-"], "rpath">,
      MetaVarName<"<path>">,
      HelpText<"Add <path> to dyld search list for dylibs with load path prefix `@rpath/'">,
-     Flags<[HelpHidden]>,
      Group<grp_resolve>;
 def commons : Separate<["-"], "commons">,
      MetaVarName<"<treatment>">,

diff  --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 6243f6c3f8c9..a8a2159b9ff0 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -247,6 +247,30 @@ class LCLoadDylinker : public LoadCommand {
   // 
diff erent location.
   const StringRef path = "/usr/lib/dyld";
 };
+
+class LCRPath : public LoadCommand {
+public:
+  LCRPath(StringRef path) : path(path) {}
+
+  uint32_t getSize() const override {
+    return alignTo(sizeof(rpath_command) + path.size() + 1, WordSize);
+  }
+
+  void writeTo(uint8_t *buf) const override {
+    auto *c = reinterpret_cast<rpath_command *>(buf);
+    buf += sizeof(rpath_command);
+
+    c->cmd = LC_RPATH;
+    c->cmdsize = getSize();
+    c->path = sizeof(rpath_command);
+
+    memcpy(buf, path.data(), path.size());
+    buf[path.size()] = '\0';
+  }
+
+private:
+  StringRef path;
+};
 } // namespace
 
 void Writer::scanRelocations() {
@@ -268,6 +292,8 @@ void Writer::createLoadCommands() {
       make<LCDyldInfo>(in.binding, lazyBindingSection, exportSection));
   in.header->addLoadCommand(make<LCSymtab>(symtabSection, stringTableSection));
   in.header->addLoadCommand(make<LCDysymtab>());
+  for (StringRef path : config->runtimePaths)
+    in.header->addLoadCommand(make<LCRPath>(path));
 
   switch (config->outputType) {
   case MH_EXECUTE:

diff  --git a/lld/test/MachO/rpath.s b/lld/test/MachO/rpath.s
new file mode 100644
index 000000000000..e72fe5b6bdca
--- /dev/null
+++ b/lld/test/MachO/rpath.s
@@ -0,0 +1,16 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
+# RUN: lld -flavor darwinnew -o %t %t.o
+
+## Check that -rpath generates LC_RPATH.
+# RUN: lld -flavor darwinnew -o %t %t.o -rpath /some/rpath
+# RUN: llvm-objdump --macho --all-headers %t | FileCheck %s
+# CHECK:      LC_RPATH
+# CHECK-NEXT: cmdsize 24
+# CHECK-NEXT: path /some/rpath
+
+.text
+.global _main
+_main:
+  mov $0, %rax
+  ret


        


More information about the llvm-commits mailing list