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

[Mach-O] Support -all_load

This commit is contained in:
Rui Ueyama 2022-05-09 16:41:20 +08:00
parent abaceb458f
commit 72ef8fc73a
6 changed files with 67 additions and 20 deletions

View File

@ -21,6 +21,8 @@ Options:
an Objective-C class or category
-adhoc_codesign Add ad-hoc code signature to the output file
-no_adhoc_codesign
-all_load Include all objects from static archives
-noall_load
-arch <ARCH_NAME> Specify target architecture
-bundle Produce a mach-o bundle
-dead_strip Remove unreachable functions and data
@ -186,6 +188,10 @@ std::vector<std::string> parse_nonpositional_args(Context<E> &ctx) {
ctx.arg.adhoc_codesign = true;
} else if (read_flag("-no_adhoc_codesign")) {
ctx.arg.adhoc_codesign = false;
} else if (read_flag("-all_load")) {
remaining.push_back("-all_load");
} else if (read_flag("-noall_load")) {
remaining.push_back("-noall_load");
} else if (read_arg("-arch")) {
if (arg == "x86_64")
ctx.arg.arch = CPU_TYPE_X86_64;
@ -197,6 +203,7 @@ std::vector<std::string> parse_nonpositional_args(Context<E> &ctx) {
ctx.output_type = MH_BUNDLE;
} else if (read_flag("-color-diagnostics") ||
read_flag("--color-diagnostics")) {
ctx.arg.color_diagnostics = true;
} else if (read_flag("-dead_strip")) {
ctx.arg.dead_strip = true;
} else if (read_flag("-dead_strip_dylibs")) {

View File

@ -20,7 +20,7 @@ ObjectFile<E>::create(Context<E> &ctx, MappedFile<Context<E>> *mf,
ObjectFile<E> *obj = new ObjectFile<E>;
obj->mf = mf;
obj->archive_name = archive_name;
obj->is_alive = archive_name.empty();
obj->is_alive = archive_name.empty() || ctx.all_load;
ctx.obj_pool.emplace_back(obj);
return obj;
};

View File

@ -326,28 +326,32 @@ read_filelist(Context<E> &ctx, std::string arg) {
template <typename E>
static void read_input_files(Context<E> &ctx, std::span<std::string> args) {
while (!args.empty()) {
if (args[0].starts_with("-filelist")) {
for (std::string &path : read_filelist(ctx, args[1])) {
const std::string &arg = args[0];
args = args.subspan(1);
if (arg == "-all_load") {
ctx.all_load = true;
} else if (arg == "-noall_load") {
ctx.all_load = false;
} else if (arg == "-filelist") {
for (std::string &path : read_filelist(ctx, args[0])) {
MappedFile<Context<E>> *mf = MappedFile<Context<E>>::open(ctx, path);
if (!mf)
Fatal(ctx) << "-filepath " << args[1] << ": cannot open file: " << path;
Fatal(ctx) << "-filepath " << args[0] << ": cannot open file: " << path;
read_file(ctx, mf);
}
args = args.subspan(2);
} else if (args[0] == "-framework" || args[0] == "-needed_framework") {
bool needed = (args[0] == "-needed_framework");
read_file(ctx, find_framework(ctx, args[1]), needed);
args = args.subspan(2);
} else if (args[0] == "-l" || args[0] == "-needed-l") {
MappedFile<Context<E>> *mf = find_library(ctx, args[1]);
if (!mf)
Fatal(ctx) << "library not found: -l" << args[1];
bool needed = (args[0] == "-needed-l");
read_file(ctx, mf, needed);
args = args.subspan(2);
} else {
read_file(ctx, MappedFile<Context<E>>::must_open(ctx, args[0]));
args = args.subspan(1);
} else if (arg == "-framework" || arg == "-needed_framework") {
read_file(ctx, find_framework(ctx, args[0]), arg == "-needed_framework");
args = args.subspan(1);
} else if (arg == "-l" || arg == "-needed-l") {
MappedFile<Context<E>> *mf = find_library(ctx, args[0]);
if (!mf)
Fatal(ctx) << "library not found: -l" << args[0];
read_file(ctx, mf, arg == "-needed-l");
args = args.subspan(1);
} else {
read_file(ctx, MappedFile<Context<E>>::must_open(ctx, arg));
}
}

View File

@ -30,7 +30,7 @@ void print_map(Context<E> &ctx) {
if (file.is_alive) {
out << "[" << std::setw(3) << i << "] " << file << "\n";
for (Symbol<E> *sym : file.syms)
if (sym->file == &file)
if (sym && sym->file == &file)
syms.push_back({sym->get_addr(ctx), 0, (u32)i, sym->name});
}
}

View File

@ -795,7 +795,7 @@ struct Context {
bool ObjC = false;
bool adhoc_codesign = true;
bool color_diagnostics = false;
bool dead_strip = true;
bool dead_strip = false;
bool dead_strip_dylibs = false;
bool deduplicate = true;
bool demangle = false;
@ -822,6 +822,7 @@ struct Context {
std::vector<std::string_view> cmdline_args;
u32 output_type = MH_EXECUTE;
bool all_load = false;
bool has_error = false;

35
test/macho/all-load.sh Executable file
View File

@ -0,0 +1,35 @@
#!/bin/bash
export LC_ALL=C
set -e
CC="${CC:-cc}"
CXX="${CXX:-c++}"
GCC="${GCC:-gcc}"
GXX="${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 -c -xc -
int foo = 3;
EOF
cat <<EOF | $CC -o $t/b.o -c -xc -
int bar = 5;
EOF
rm -f $t/c.a
ar rc $t/c.a $t/a.o $t/b.o
cat <<EOF | $CC -o $t/d.o -c -xc -
int main() {}
EOF
clang --ld-path=./ld64 -o $t/exe $t/d.o -Wl,-all_load $t/c.a
nm $t/exe | grep -q 'D _foo$'
nm $t/exe | grep -q 'D _bar$'
echo OK