[lld] r224544 - [macho] -rpath support

Jean-Daniel Dupas devlists at shadowlab.org
Thu Dec 18 13:33:38 PST 2014


Author: jddupas
Date: Thu Dec 18 15:33:38 2014
New Revision: 224544

URL: http://llvm.org/viewvc/llvm-project?rev=224544&view=rev
Log:
[macho] -rpath support

Summary:
Work on adding -rpath support to the mach-o linker.
This patch is based on the ld64 behavior for the command line option validation.

It includes a basic test to check that the LC_RPATH load commands are properly generated when that option is used.

It also add LC_RPATH support to the binary reader, but I don't know how to test it though.


Reviewers: kledzik

Subscribers: llvm-commits

Projects: #lld

Differential Revision: http://reviews.llvm.org/D6724

Added:
    lld/trunk/test/mach-o/rpath.yaml
Modified:
    lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
    lld/trunk/lib/Driver/DarwinLdDriver.cpp
    lld/trunk/lib/Driver/DarwinLdOptions.td
    lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp

Modified: lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h?rev=224544&r1=224543&r2=224544&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h Thu Dec 18 15:33:38 2014
@@ -224,6 +224,9 @@ public:
     _existingPaths.insert(path);
   }
 
+  void addRpath(StringRef rpath);
+  const StringRefVector &rpaths() const { return _rpaths; }
+
   /// Add section alignment constraint on final layout.
   void addSectionAlignment(StringRef seg, StringRef sect, uint8_t align2);
 
@@ -334,6 +337,7 @@ private:
   uint32_t _compatibilityVersion;
   uint32_t _currentVersion;
   StringRef _installName;
+  StringRefVector _rpaths;
   bool _deadStrippableDylib;
   bool _printAtoms;
   bool _testingFileUsage;

Modified: lld/trunk/lib/Driver/DarwinLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdDriver.cpp?rev=224544&r1=224543&r2=224544&view=diff
==============================================================================
--- lld/trunk/lib/Driver/DarwinLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/DarwinLdDriver.cpp Thu Dec 18 15:33:38 2014
@@ -709,6 +709,34 @@ bool DarwinLdDriver::parse(int argc, con
     }
   }
 
+  // Handle -rpath <path>
+  if (parsedArgs->hasArg(OPT_rpath)) {
+    switch (ctx.outputMachOType()) {
+      case llvm::MachO::MH_EXECUTE:
+      case llvm::MachO::MH_DYLIB:
+      case llvm::MachO::MH_BUNDLE:
+        if (!ctx.minOS("10.5", "2.0")) {
+          if (ctx.os() == MachOLinkingContext::OS::macOSX) {
+            diagnostics << "error: -rpath can only be used when targeting "
+                           "OS X 10.5 or later\n";
+          } else {
+            diagnostics << "error: -rpath can only be used when targeting "
+                           "iOS 2.0 or later\n";
+          }
+          return false;
+        }
+        break;
+      default:
+        diagnostics << "error: -rpath can only be used when creating "
+                       "a dynamic final linked image\n";
+        return false;
+    }
+
+    for (auto rPath : parsedArgs->filtered(OPT_rpath)) {
+      ctx.addRpath(rPath->getValue());
+    }
+  }
+
   // Handle input files
   for (auto &arg : *parsedArgs) {
     bool upward;

Modified: lld/trunk/lib/Driver/DarwinLdOptions.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdOptions.td?rev=224544&r1=224543&r2=224544&view=diff
==============================================================================
--- lld/trunk/lib/Driver/DarwinLdOptions.td (original)
+++ lld/trunk/lib/Driver/DarwinLdOptions.td Thu Dec 18 15:33:38 2014
@@ -170,6 +170,9 @@ def dependency_info : Separate<["-"], "d
      HelpText<"Write binary list of files used during link">;
 def S : Flag<["-"], "S">,
      HelpText<"Remove debug information (STABS or DWARF) from the output file">;
+def rpath : Separate<["-"], "rpath">,
+     MetaVarName<"<path>">,
+     HelpText<"Add path to the runpath search path list for image being created">;
 
 def t : Flag<["-"], "t">,
      HelpText<"Print the names of the input files as ld processes them">;

Modified: lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=224544&r1=224543&r2=224544&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp Thu Dec 18 15:33:38 2014
@@ -413,6 +413,10 @@ void MachOLinkingContext::setSysLibRoots
   _syslibRoots = paths;
 }
 
+void MachOLinkingContext::addRpath(StringRef rpath) {
+  _rpaths.push_back(rpath);
+}
+
 void MachOLinkingContext::addModifiedSearchDir(StringRef libPath,
                                                bool isSystemPath) {
   bool addedModifiedPath = false;

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp?rev=224544&r1=224543&r2=224544&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp Thu Dec 18 15:33:38 2014
@@ -460,6 +460,11 @@ readBinary(std::unique_ptr<MemoryBuffer>
       f->dependentDylibs.push_back(entry);
      }
       break;
+    case LC_RPATH: {
+      const rpath_command *rpc = reinterpret_cast<const rpath_command *>(lc);
+      f->rpaths.push_back(lc + read32(&rpc->path, isBig));
+     }
+      break;
     case LC_DYLD_INFO:
     case LC_DYLD_INFO_ONLY:
       dyldInfo = reinterpret_cast<const dyld_info_command*>(lc);

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp?rev=224544&r1=224543&r2=224544&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp Thu Dec 18 15:33:38 2014
@@ -428,6 +428,12 @@ uint32_t MachOFileLayout::loadCommandsSi
     ++count;
   }
 
+  // Add LC_RPATH
+  for (const StringRef &path : _file.rpaths) {
+    size += sizeof(rpath_command) + pointerAlign(path.size()+1);
+    ++count;
+  }
+
   // Add LC_DATA_IN_CODE if needed
   if (!_file.dataInCode.empty()) {
     size += sizeof(linkedit_data_command);
@@ -844,6 +850,21 @@ std::error_code MachOFileLayout::writeLo
       lc[sizeof(dylib_command)+dep.path.size()] = '\0';
       lc += size;
     }
+
+    // Add LC_RPATH
+    for (const StringRef &path : _file.rpaths) {
+      rpath_command *rpc = reinterpret_cast<rpath_command *>(lc);
+      uint32_t size = sizeof(rpath_command) + pointerAlign(path.size()+1);
+      rpc->cmd                         = LC_RPATH;
+      rpc->cmdsize                     = size;
+      rpc->path                        = sizeof(rpath_command); // offset
+      if (_swap)
+        swapStruct(*rpc);
+      memcpy(lc+sizeof(rpath_command), path.begin(), path.size());
+      lc[sizeof(rpath_command)+path.size()] = '\0';
+      lc += size;
+    }
+
     // Add LC_DATA_IN_CODE if needed.
     if (_dataInCodeSize != 0) {
       linkedit_data_command* dl = reinterpret_cast<linkedit_data_command*>(lc);

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=224544&r1=224543&r2=224544&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Thu Dec 18 15:33:38 2014
@@ -1210,6 +1210,7 @@ normalizedFromAtoms(const lld::File &ato
   normFile.currentVersion = context.currentVersion();
   normFile.compatVersion = context.compatibilityVersion();
   normFile.pageSize = context.pageSize();
+  normFile.rpaths = context.rpaths();
   util.addDependentDylibs(atomFile, normFile);
   util.copySegmentInfo(normFile);
   util.copySectionInfo(normFile);

Added: lld/trunk/test/mach-o/rpath.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/rpath.yaml?rev=224544&view=auto
==============================================================================
--- lld/trunk/test/mach-o/rpath.yaml (added)
+++ lld/trunk/test/mach-o/rpath.yaml Thu Dec 18 15:33:38 2014
@@ -0,0 +1,38 @@
+# Check we handle -rpath correctly:
+# RUN: lld -flavor darwin -arch x86_64 -rpath @loader_path/../Frameworks \
+# RUN:     %p/Inputs/libSystem.yaml %s -o %t
+# RUN: llvm-objdump -private-headers %t | FileCheck %s --check-prefix=CHECK-BINARY-WRITE
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_OBJECT
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+has-UUID:        false
+OS:              unknown
+sections:
+  - segment:         __TEXT
+    section:         __text
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+    alignment:       4
+    address:         0x0000000000000000
+    content:         [ 0xCC, 0xC3, 0x90, 0xC3, 0x90, 0x90, 0xC3, 0x90,
+                       0x90, 0x90, 0xC3, 0x90, 0x90, 0x90, 0x90, 0xC3,
+                       0x31, 0xC0, 0xC3 ]
+local-symbols:
+  - name:            _myStatic
+    type:            N_SECT
+    sect:            1
+    value:           0x000000000000000B
+global-symbols:
+  - name:            _main
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000001
+...
+
+
+# CHECK-BINARY-WRITE: cmd LC_RPATH
+# CHECK-BINARY-WRITE-NEXT:  cmdsize 44
+# CHECK-BINARY-WRITE-NEXT:  path @loader_path/../Frameworks (offset 12)





More information about the llvm-commits mailing list