diff options
Diffstat (limited to 'lld')
-rw-r--r-- | lld/include/lld/ReaderWriter/MachOLinkingContext.h | 4 | ||||
-rw-r--r-- | lld/lib/Driver/DarwinLdDriver.cpp | 28 | ||||
-rw-r--r-- | lld/lib/Driver/DarwinLdOptions.td | 3 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp | 4 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp | 5 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp | 21 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp | 1 | ||||
-rw-r--r-- | lld/test/mach-o/rpath.yaml | 38 |
8 files changed, 104 insertions, 0 deletions
diff --git a/lld/include/lld/ReaderWriter/MachOLinkingContext.h b/lld/include/lld/ReaderWriter/MachOLinkingContext.h index ff248fe9614..21de30cfee9 100644 --- a/lld/include/lld/ReaderWriter/MachOLinkingContext.h +++ b/lld/include/lld/ReaderWriter/MachOLinkingContext.h @@ -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; diff --git a/lld/lib/Driver/DarwinLdDriver.cpp b/lld/lib/Driver/DarwinLdDriver.cpp index 6c80c5c8e65..754c8ac18b7 100644 --- a/lld/lib/Driver/DarwinLdDriver.cpp +++ b/lld/lib/Driver/DarwinLdDriver.cpp @@ -709,6 +709,34 @@ bool DarwinLdDriver::parse(int argc, const char *argv[], } } + // 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; diff --git a/lld/lib/Driver/DarwinLdOptions.td b/lld/lib/Driver/DarwinLdOptions.td index 630f1e787b0..81dcc0a1d92 100644 --- a/lld/lib/Driver/DarwinLdOptions.td +++ b/lld/lib/Driver/DarwinLdOptions.td @@ -170,6 +170,9 @@ def dependency_info : Separate<["-"], "dependency_info">, 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">; diff --git a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp index b129c033740..6cdd74ba3bd 100644 --- a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp +++ b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp @@ -413,6 +413,10 @@ void MachOLinkingContext::setSysLibRoots(const StringRefVector &paths) { _syslibRoots = paths; } +void MachOLinkingContext::addRpath(StringRef rpath) { + _rpaths.push_back(rpath); +} + void MachOLinkingContext::addModifiedSearchDir(StringRef libPath, bool isSystemPath) { bool addedModifiedPath = false; diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp index 89c6213c845..ef8ad1d3325 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp @@ -460,6 +460,11 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb, 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); diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp index d931865408f..a3542c4fc50 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp @@ -428,6 +428,12 @@ uint32_t MachOFileLayout::loadCommandsSize(uint32_t &count) { ++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::writeLoadCommands() { 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); diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp index bf935659ed6..97608a03bf8 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -1210,6 +1210,7 @@ normalizedFromAtoms(const lld::File &atomFile, 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); diff --git a/lld/test/mach-o/rpath.yaml b/lld/test/mach-o/rpath.yaml new file mode 100644 index 00000000000..f0b5f718c15 --- /dev/null +++ b/lld/test/mach-o/rpath.yaml @@ -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) |