1
1
mirror of https://github.com/rui314/mold.git synced 2024-09-20 09:27:45 +03:00

[Mach-O] Add -reexport-l

This commit is contained in:
Rui Ueyama 2022-06-26 18:25:52 +08:00
parent 7b5b1a340b
commit 335698851b
6 changed files with 48 additions and 1 deletions

View File

@ -71,6 +71,7 @@ Options:
-platform_version <PLATFORM> <MIN_VERSION> <SDK_VERSION>
Set platform, platform version and SDK version
-random_uuid Generate a random LC_UUID load command
-reexport-l<LIB> Search for a given library
-rpath <PATH> Add PATH to the runpath search path list
-search_dylibs_first
-search_paths_first
@ -372,6 +373,9 @@ std::vector<std::string> parse_nonpositional_args(Context<E> &ctx) {
ctx.arg.quick_exit = false;
} else if (read_flag("-random_uuid")) {
ctx.arg.uuid = UUID_RANDOM;
} else if (read_joined("-reexport-l")) {
remaining.push_back("-reexport-l");
remaining.push_back(std::string(arg));
} else if (read_arg("-rpath")) {
ctx.arg.rpath.push_back(std::string(arg));
} else if (read_flag("-search_paths_first")) {

View File

@ -738,6 +738,7 @@ DylibFile<E> *DylibFile<E>::create(Context<E> &ctx, MappedFile<Context<E>> *mf)
DylibFile<E> *dylib = new DylibFile<E>(mf);
dylib->is_alive = (ctx.needed_l || !ctx.arg.dead_strip_dylibs);
dylib->is_weak = ctx.weak_l;
dylib->is_reexported = ctx.reexport_l;
ctx.dylib_pool.emplace_back(dylib);
switch (get_file_type(mf)) {

View File

@ -726,6 +726,9 @@ static void read_input_files(Context<E> &ctx, std::span<std::string> args) {
} else if (opt == "-weak-l") {
ctx.weak_l = true;
read_file(ctx, must_find_library(arg));
} else if (opt == "-reexport-l") {
ctx.reexport_l = true;
read_file(ctx, must_find_library(arg));
} else {
unreachable();
}
@ -733,6 +736,7 @@ static void read_input_files(Context<E> &ctx, std::span<std::string> args) {
ctx.needed_l = false;
ctx.hidden_l = false;
ctx.weak_l = false;
ctx.reexport_l = false;
}
// An object file can contain linker directives to load other object

View File

@ -166,6 +166,7 @@ public:
std::string_view install_name;
i64 dylib_idx = 0;
std::vector<std::string_view> reexported_libs;
bool is_reexported = false;
private:
void read_trie(Context<E> &ctx, u8 *start, i64 offset = 0,
@ -883,6 +884,7 @@ struct Context {
bool needed_l = false;
bool hidden_l = false;
bool weak_l = false;
bool reexport_l = false;
std::unordered_set<std::string_view> loaded_archives;
u8 uuid[16] = {};

View File

@ -155,7 +155,13 @@ create_load_dylib_cmd(Context<E> &ctx, DylibFile<E> &dylib) {
std::vector<u8> buf(align_to(size, 8));
DylibCommand &cmd = *(DylibCommand *)buf.data();
cmd.cmd = (dylib.is_weak ? LC_LOAD_WEAK_DYLIB : LC_LOAD_DYLIB);
if (dylib.is_reexported)
cmd.cmd = LC_REEXPORT_DYLIB;
else if (dylib.is_weak)
cmd.cmd = LC_LOAD_WEAK_DYLIB;
else
cmd.cmd = LC_LOAD_DYLIB;
cmd.cmdsize = buf.size();
cmd.nameoff = sizeof(cmd);
cmd.timestamp = 2;

30
test/macho/reexport-l.sh Executable file
View File

@ -0,0 +1,30 @@
#!/bin/bash
export LC_ALL=C
set -e
CC="${TEST_CC:-cc}"
CXX="${TEST_CXX:-c++}"
GCC="${TEST_GCC:-gcc}"
GXX="${TEST_GXX:-g++}"
OBJDUMP="${OBJDUMP:-objdump}"
MACHINE="${MACHINE:-$(uname -m)}"
testname=$(basename "$0" .sh)
echo -n "Testing $testname ... "
cd "$(dirname "$0")"/../..
t=out/test/macho/$testname
mkdir -p $t
cat <<EOF | $CC -o $t/a.o -shared -xc -
void foo() {}
EOF
clang --ld-path=./ld64 -shared -o $t/libfoo.dylib $t/a.o
cat <<EOF | $CC -o $t/b.o -c -xc -
void bar() {}
EOF
clang -shared -o $t/libbar.dylib $t/b.o -L$t -Wl,-reexport-lfoo
objdump --macho --dylibs-used $t/libbar.dylib | grep -q 'libfoo.*reexport'
echo OK