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

[Mach-O] Add -hidden-l

This commit is contained in:
Rui Ueyama 2022-05-12 19:58:22 +08:00
parent a5c7c98af8
commit 7f3a05ad0f
5 changed files with 73 additions and 6 deletions

View File

@ -41,6 +41,7 @@ Options:
-headerpad_max_install_names -headerpad_max_install_names
Allocate MAXPATHLEN byte padding after load commands Allocate MAXPATHLEN byte padding after load commands
-help Report usage information -help Report usage information
-hidden-l<LIB>
-install_name <NAME> -install_name <NAME>
-l<LIB> Search for a given library -l<LIB> Search for a given library
-lto_library <FILE> Ignored -lto_library <FILE> Ignored
@ -257,6 +258,9 @@ std::vector<std::string> parse_nonpositional_args(Context<E> &ctx) {
} else if (read_arg("-macos_version_min")) { } else if (read_arg("-macos_version_min")) {
ctx.arg.platform = PLATFORM_MACOS; ctx.arg.platform = PLATFORM_MACOS;
ctx.arg.platform_min_version = parse_version(ctx, arg); ctx.arg.platform_min_version = parse_version(ctx, arg);
} else if (read_joined("-hidden-l")) {
remaining.push_back("-hidden-l");
remaining.push_back(std::string(arg));
} else if (read_arg("-install_name")) { } else if (read_arg("-install_name")) {
ctx.arg.install_name = arg; ctx.arg.install_name = arg;
} else if (read_joined("-l")) { } else if (read_joined("-l")) {

View File

@ -21,6 +21,7 @@ ObjectFile<E>::create(Context<E> &ctx, MappedFile<Context<E>> *mf,
obj->mf = mf; obj->mf = mf;
obj->archive_name = archive_name; obj->archive_name = archive_name;
obj->is_alive = archive_name.empty() || ctx.all_load; obj->is_alive = archive_name.empty() || ctx.all_load;
obj->is_hidden = ctx.hidden_l;
ctx.obj_pool.emplace_back(obj); ctx.obj_pool.emplace_back(obj);
return obj; return obj;
}; };
@ -398,7 +399,7 @@ void ObjectFile<E>::resolve_symbols(Context<E> &ctx) {
if (get_rank(this, msym.is_common(), false) < get_rank(sym)) { if (get_rank(this, msym.is_common(), false) < get_rank(sym)) {
sym.file = this; sym.file = this;
sym.is_extern = msym.ext; sym.is_extern = (msym.ext && !this->is_hidden);
sym.is_imported = false; sym.is_imported = false;
switch (msym.type) { switch (msym.type) {

View File

@ -358,6 +358,13 @@ read_filelist(Context<E> &ctx, std::string arg) {
template <typename E> template <typename E>
static void read_input_files(Context<E> &ctx, std::span<std::string> args) { static void read_input_files(Context<E> &ctx, std::span<std::string> args) {
auto must_find_library = [&](std::string arg) {
MappedFile<Context<E>> *mf = find_library(ctx, arg);
if (!mf)
Fatal(ctx) << "library not found: -l" << arg;
return mf;
};
while (!args.empty()) { while (!args.empty()) {
const std::string &arg = args[0]; const std::string &arg = args[0];
args = args.subspan(1); args = args.subspan(1);
@ -383,11 +390,17 @@ static void read_input_files(Context<E> &ctx, std::span<std::string> args) {
} else if (arg == "-framework" || arg == "-needed_framework") { } else if (arg == "-framework" || arg == "-needed_framework") {
read_file(ctx, find_framework(ctx, args[0]), arg == "-needed_framework"); read_file(ctx, find_framework(ctx, args[0]), arg == "-needed_framework");
args = args.subspan(1); args = args.subspan(1);
} else if (arg == "-l" || arg == "-needed-l") { } else if (arg == "-l") {
MappedFile<Context<E>> *mf = find_library(ctx, args[0]); read_file(ctx, must_find_library(args[0]), false);
if (!mf) args = args.subspan(1);
Fatal(ctx) << "library not found: -l" << args[0]; } else if (arg == "-needed-l") {
read_file(ctx, mf, arg == "-needed-l"); read_file(ctx, must_find_library(args[0]), true);
args = args.subspan(1);
} else if (arg == "-hidden-l") {
bool orig = ctx.hidden_l;
ctx.hidden_l = true;
read_file(ctx, must_find_library(args[0]), arg == "-needed-l");
ctx.hidden_l = orig;
args = args.subspan(1); args = args.subspan(1);
} else { } else {
read_file(ctx, MappedFile<Context<E>>::must_open(ctx, arg)); read_file(ctx, MappedFile<Context<E>>::must_open(ctx, arg));

View File

@ -88,6 +88,7 @@ public:
i64 priority = 0; i64 priority = 0;
std::atomic_bool is_alive = false; std::atomic_bool is_alive = false;
bool is_dylib = false; bool is_dylib = false;
bool is_hidden = false;
std::string archive_name; std::string archive_name;
protected: protected:
@ -824,6 +825,7 @@ struct Context {
std::vector<std::string_view> cmdline_args; std::vector<std::string_view> cmdline_args;
u32 output_type = MH_EXECUTE; u32 output_type = MH_EXECUTE;
bool all_load = false; bool all_load = false;
bool hidden_l = false;
bool has_error = false; bool has_error = false;

47
test/macho/hidden-l.sh Executable file
View File

@ -0,0 +1,47 @@
#!/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 -c -o $t/a.o -fPIC -xc -
void foo() {}
EOF
rm -f $t/libfoo.a
ar rcu $t/libfoo.a $t/a.o
cat <<EOF | $CC -c -o $t/b.o -fPIC -xc -
void bar() {}
EOF
rm -f $t/libbar.a
ar rcu $t/libbar.a $t/b.o
cat <<EOF | $CC -c -o $t/c.o -xc -
void foo();
void bar();
void baz() {
foo();
bar();
}
EOF
clang --ld-path=./ld64 -shared -o $t/f.dylib $t/c.o -L$t -lfoo -Wl,-hidden-lbar
nm -g $t/f.dylib > $t/log
grep -q ' _foo$' $t/log
! grep -q ' _bar$' $t/log || false
grep -q ' _baz$' $t/log
echo OK