[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

llvm-svn: 224544
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
index d931865..a3542c4 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
@@ -428,6 +428,12 @@
     ++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 @@
       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);