mirror of
https://github.com/rui314/mold.git
synced 2024-09-20 09:27:45 +03:00
[Mach-O] Add -rpath
This commit is contained in:
parent
1e4262753a
commit
cee6412e3d
@ -29,6 +29,7 @@ Options:
|
||||
-pagezero_size <SIZE> Specify the size of the __PAGEZERO segment
|
||||
-platform_version <PLATFORM> <MIN_VERSION> <SDK_VERSION>
|
||||
Set platform, platform version and SDK version
|
||||
-rpath <PATH> Add PATH to the runpath search path list
|
||||
-syslibroot <DIR> Prepend DIR to library search paths
|
||||
-t Print out each file the linker loads
|
||||
-v Report version information)";
|
||||
@ -174,6 +175,8 @@ void parse_nonpositional_args(Context &ctx,
|
||||
ctx.arg.platform = parse_platform(ctx, arg);
|
||||
ctx.arg.platform_min_version = parse_version(ctx, arg2);
|
||||
ctx.arg.platform_sdk_version = parse_version(ctx, arg3);
|
||||
} else if (read_arg("-rpath")) {
|
||||
ctx.arg.rpath.push_back(std::string(arg));
|
||||
} else if (read_arg("-syslibroot")) {
|
||||
ctx.arg.syslibroot.push_back(std::string(arg));
|
||||
} else if (read_flag("-t")) {
|
||||
|
@ -475,6 +475,12 @@ struct UUIDCommand {
|
||||
u8 uuid[16];
|
||||
};
|
||||
|
||||
struct RpathCommand {
|
||||
u32 cmd;
|
||||
u32 cmdsize;
|
||||
u32 path_off;
|
||||
};
|
||||
|
||||
struct LinkEditDataCommand {
|
||||
u32 cmd;
|
||||
u32 cmdsize;
|
||||
|
@ -733,8 +733,9 @@ struct Context {
|
||||
std::string entry = "_main";
|
||||
std::string map;
|
||||
std::string output;
|
||||
std::vector<std::string> syslibroot;
|
||||
std::vector<std::string> library_paths;
|
||||
std::vector<std::string> rpath;
|
||||
std::vector<std::string> syslibroot;
|
||||
} arg;
|
||||
|
||||
std::vector<std::string_view> cmdline_args;
|
||||
|
@ -159,6 +159,18 @@ static std::vector<u8> create_load_dylib_cmd(Context &ctx, std::string_view name
|
||||
return buf;
|
||||
}
|
||||
|
||||
static std::vector<u8> create_rpath_cmd(Context &ctx, std::string_view name) {
|
||||
i64 size = sizeof(RpathCommand) + name.size() + 1; // +1 for NUL
|
||||
std::vector<u8> buf(align_to(size, 8));
|
||||
RpathCommand &cmd = *(RpathCommand *)buf.data();
|
||||
|
||||
cmd.cmd = LC_RPATH;
|
||||
cmd.cmdsize = buf.size();
|
||||
cmd.path_off = sizeof(cmd);
|
||||
write_string(buf.data() + sizeof(cmd), name);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static std::vector<u8> create_function_starts_cmd(Context &ctx) {
|
||||
std::vector<u8> buf(sizeof(LinkEditDataCommand));
|
||||
LinkEditDataCommand &cmd = *(LinkEditDataCommand *)buf.data();
|
||||
@ -232,13 +244,20 @@ static std::pair<i64, std::vector<u8>> create_load_commands(Context &ctx) {
|
||||
vec.push_back(create_build_version_cmd(ctx));
|
||||
vec.push_back(create_source_version_cmd(ctx));
|
||||
vec.push_back(create_main_cmd(ctx));
|
||||
vec.push_back(create_function_starts_cmd(ctx));
|
||||
|
||||
for (DylibFile *dylib : ctx.dylibs)
|
||||
vec.push_back(create_load_dylib_cmd(ctx, dylib->install_name));
|
||||
vec.push_back(create_function_starts_cmd(ctx));
|
||||
|
||||
for (std::string_view rpath : ctx.arg.rpath)
|
||||
vec.push_back(create_rpath_cmd(ctx, rpath));
|
||||
|
||||
if (!ctx.data_in_code.contents.empty())
|
||||
vec.push_back(create_data_in_code_cmd(ctx));
|
||||
|
||||
if (ctx.arg.adhoc_codesign)
|
||||
vec.push_back(create_code_signature_cmd(ctx));
|
||||
|
||||
return {vec.size(), flatten(vec)};
|
||||
}
|
||||
|
||||
|
19
test/macho/rpath.sh
Executable file
19
test/macho/rpath.sh
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cd $(dirname $0)
|
||||
mold=`pwd`/../../ld64.mold
|
||||
echo -n "Testing $(basename -s .sh $0) ... "
|
||||
t=$(pwd)/../../out/test/macho/$(basename -s .sh $0)
|
||||
mkdir -p $t
|
||||
|
||||
cat <<EOF | cc -o $t/a.o -c -xc -
|
||||
int main() {}
|
||||
EOF
|
||||
|
||||
clang -fuse-ld=$mold -o $t/exe $t/a.o -Wl,-rpath,foo -Wl,-rpath,bar
|
||||
otool -l $t/exe > $t/log
|
||||
|
||||
grep -A3 'cmd LC_RPATH' $t/log | grep -q 'path foo'
|
||||
grep -A3 'cmd LC_RPATH' $t/log | grep -q 'path bar'
|
||||
|
||||
echo OK
|
Loading…
Reference in New Issue
Block a user