forked from OSchip/llvm-project
[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
This commit is contained in:
parent
437e6bd286
commit
e48d1262b8
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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>">,
|
||||
|
|
|
@ -247,6 +247,30 @@ private:
|
|||
// different 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:
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue