From 72ef8fc73afb97360b76d0af8200ed16dc4618ea Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Mon, 9 May 2022 16:41:20 +0800 Subject: [PATCH] [Mach-O] Support -all_load --- macho/cmdline.cc | 7 +++++++ macho/input-files.cc | 2 +- macho/main.cc | 38 +++++++++++++++++++++----------------- macho/mapfile.cc | 2 +- macho/mold.h | 3 ++- test/macho/all-load.sh | 35 +++++++++++++++++++++++++++++++++++ 6 files changed, 67 insertions(+), 20 deletions(-) create mode 100755 test/macho/all-load.sh diff --git a/macho/cmdline.cc b/macho/cmdline.cc index c4922f93..816ae9c7 100644 --- a/macho/cmdline.cc +++ b/macho/cmdline.cc @@ -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 Specify target architecture -bundle Produce a mach-o bundle -dead_strip Remove unreachable functions and data @@ -186,6 +188,10 @@ std::vector parse_nonpositional_args(Context &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 parse_nonpositional_args(Context &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")) { diff --git a/macho/input-files.cc b/macho/input-files.cc index 1fb783b2..14538b48 100644 --- a/macho/input-files.cc +++ b/macho/input-files.cc @@ -20,7 +20,7 @@ ObjectFile::create(Context &ctx, MappedFile> *mf, ObjectFile *obj = new ObjectFile; 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; }; diff --git a/macho/main.cc b/macho/main.cc index 0ef993ae..bb87b305 100644 --- a/macho/main.cc +++ b/macho/main.cc @@ -326,28 +326,32 @@ read_filelist(Context &ctx, std::string arg) { template static void read_input_files(Context &ctx, std::span 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> *mf = MappedFile>::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> *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>::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> *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>::must_open(ctx, arg)); } } diff --git a/macho/mapfile.cc b/macho/mapfile.cc index 5df4ce4d..6b492330 100644 --- a/macho/mapfile.cc +++ b/macho/mapfile.cc @@ -30,7 +30,7 @@ void print_map(Context &ctx) { if (file.is_alive) { out << "[" << std::setw(3) << i << "] " << file << "\n"; for (Symbol *sym : file.syms) - if (sym->file == &file) + if (sym && sym->file == &file) syms.push_back({sym->get_addr(ctx), 0, (u32)i, sym->name}); } } diff --git a/macho/mold.h b/macho/mold.h index 49c6ebe0..4f6aea84 100644 --- a/macho/mold.h +++ b/macho/mold.h @@ -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 cmdline_args; u32 output_type = MH_EXECUTE; + bool all_load = false; bool has_error = false; diff --git a/test/macho/all-load.sh b/test/macho/all-load.sh new file mode 100755 index 00000000..59262960 --- /dev/null +++ b/test/macho/all-load.sh @@ -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 <