diff --git a/macho/input-files.cc b/macho/input-files.cc index 7baaa13e..33f9be40 100644 --- a/macho/input-files.cc +++ b/macho/input-files.cc @@ -20,7 +20,7 @@ void InputFile::clear_symbols() { sym->file = nullptr; sym->scope = SCOPE_LOCAL; sym->is_imported = false; - sym->is_weak_def = false; + sym->is_weak = false; sym->subsec = nullptr; sym->value = 0; sym->is_common = false; @@ -138,7 +138,7 @@ void ObjectFile::parse_symbols(Context &ctx) { sym.subsec = nullptr; sym.scope = SCOPE_LOCAL; sym.is_common = false; - sym.is_weak_def = false; + sym.is_weak = false; switch (msym.type) { case N_UNDF: @@ -533,7 +533,7 @@ template static u64 get_rank(Symbol &sym) { if (!sym.file) return 7 << 24; - return get_rank(sym.file, sym.is_common, sym.is_weak_def); + return get_rank(sym.file, sym.is_common, sym.is_weak); } template @@ -559,14 +559,14 @@ void ObjectFile::resolve_symbols(Context &ctx) { Symbol &sym = *this->syms[i]; std::scoped_lock lock(sym.mu); - bool is_weak_def = (msym.desc & N_WEAK_DEF); + bool is_weak = (msym.desc & N_WEAK_DEF); sym.scope = merge_scope(sym, msym); - if (get_rank(this, msym.is_common(), is_weak_def) < get_rank(sym)) { + if (get_rank(this, msym.is_common(), is_weak) < get_rank(sym)) { sym.file = this; sym.is_imported = false; - sym.is_weak_def = is_weak_def; + sym.is_weak = is_weak; switch (msym.type) { case N_UNDF: @@ -647,7 +647,7 @@ void ObjectFile::convert_common_symbols(Context &ctx) { subsections.emplace_back(subsec); sym.is_imported = false; - sym.is_weak_def = false; + sym.is_weak = false; sym.subsec = subsec; sym.value = 0; sym.is_common = false; @@ -832,7 +832,7 @@ void DylibFile::resolve_symbols(Context &ctx) { sym->file = this; sym->scope = SCOPE_LOCAL; sym->is_imported = true; - sym->is_weak_def = this->is_weak; + sym->is_weak = this->is_weak; sym->subsec = nullptr; sym->value = 0; sym->is_common = false; diff --git a/macho/main.cc b/macho/main.cc index 2f1163db..6b50ed52 100644 --- a/macho/main.cc +++ b/macho/main.cc @@ -255,9 +255,13 @@ template static void claim_unresolved_symbols(Context &ctx) { Timer t(ctx, "claim_unresolved_symbols"); - for (std::string_view name : ctx.arg.U) - if (Symbol *sym = get_symbol(ctx, name); !sym->file) + for (std::string_view name : ctx.arg.U) { + Symbol *sym = get_symbol(ctx, name); + if (!sym->file) { sym->is_imported = true; + sym->is_weak = true; + } + } tbb::parallel_for_each(ctx.objs, [&](ObjectFile *file) { for (i64 i = 0; i < file->mach_syms.size(); i++) { diff --git a/macho/mold.h b/macho/mold.h index 20ccd272..a8f16d94 100644 --- a/macho/mold.h +++ b/macho/mold.h @@ -281,7 +281,7 @@ struct Symbol { u8 scope : 2 = SCOPE_LOCAL; bool is_common : 1 = false; - bool is_weak_def : 1 = false; + bool is_weak : 1 = false; bool is_imported : 1 = false; bool referenced_dynamically : 1 = false; diff --git a/macho/output-chunks.cc b/macho/output-chunks.cc index 753bd092..cf27749e 100644 --- a/macho/output-chunks.cc +++ b/macho/output-chunks.cc @@ -680,7 +680,7 @@ static u32 get_dylib_idx(InputFile *file) { template void BindEncoder::add(Symbol &sym, i64 seg_idx, i64 offset) { i64 dylib_idx = get_dylib_idx(sym.file); - i64 flags = (sym.file->is_weak ? BIND_SYMBOL_FLAGS_WEAK_IMPORT : 0); + i64 flags = (sym.is_weak ? BIND_SYMBOL_FLAGS_WEAK_IMPORT : 0); if (last_dylib != dylib_idx) { if (dylib_idx < 16) { @@ -767,7 +767,7 @@ void LazyBindSection::add(Context &ctx, Symbol &sym) { encode_uleb(contents, dylib_idx); } - i64 flags = (sym.file->is_weak ? BIND_SYMBOL_FLAGS_WEAK_IMPORT : 0); + i64 flags = (sym.is_weak ? BIND_SYMBOL_FLAGS_WEAK_IMPORT : 0); assert(flags < 16); emit(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | flags); diff --git a/test/macho/weak-def.sh b/test/macho/weak-def.sh new file mode 100755 index 00000000..1405cc17 --- /dev/null +++ b/test/macho/weak-def.sh @@ -0,0 +1,40 @@ +#!/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 < + +int foo() __attribute__((weak)); + +int foo() { + return 3; +} + +int main() { + printf("%d\n", foo()); +} +EOF + +cat <