[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
This commit is contained in:
parent
f27ae73617
commit
23dd15e26d
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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">;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
Loading…
Reference in New Issue