1
1
mirror of https://github.com/rui314/mold.git synced 2024-10-04 08:37:28 +03:00

[Mach-O] Fix weak undef symbols

This commit is contained in:
Rui Ueyama 2022-06-26 15:39:30 +08:00
parent fe72463f55
commit 1524746a80
6 changed files with 59 additions and 15 deletions

View File

@ -20,7 +20,7 @@ void InputFile<E>::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<E>::parse_symbols(Context<E> &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 <typename E>
static u64 get_rank(Symbol<E> &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 <typename E>
@ -559,14 +559,14 @@ void ObjectFile<E>::resolve_symbols(Context<E> &ctx) {
Symbol<E> &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<E>::convert_common_symbols(Context<E> &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<E>::resolve_symbols(Context<E> &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;

View File

@ -255,9 +255,13 @@ template <typename E>
static void claim_unresolved_symbols(Context<E> &ctx) {
Timer t(ctx, "claim_unresolved_symbols");
for (std::string_view name : ctx.arg.U)
if (Symbol<E> *sym = get_symbol(ctx, name); !sym->file)
for (std::string_view name : ctx.arg.U) {
Symbol<E> *sym = get_symbol(ctx, name);
if (!sym->file) {
sym->is_imported = true;
sym->is_weak = true;
}
}
tbb::parallel_for_each(ctx.objs, [&](ObjectFile<E> *file) {
for (i64 i = 0; i < file->mach_syms.size(); i++) {

View File

@ -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;

View File

@ -680,7 +680,7 @@ static u32 get_dylib_idx(InputFile<E> *file) {
template <typename E>
void BindEncoder::add(Symbol<E> &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<E>::add(Context<E> &ctx, Symbol<E> &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);

40
test/macho/weak-def.sh Executable file
View File

@ -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 <<EOF | $CC -c -o $t/a.o -xc -
#include <stdio.h>
int foo() __attribute__((weak));
int foo() {
return 3;
}
int main() {
printf("%d\n", foo());
}
EOF
cat <<EOF | $CC -c -o $t/b.o -xc -
int foo() { return 42; }
EOF
clang --ld-path=./ld64 -o $t/exe1 $t/a.o
$t/exe1 | grep -q '^3$'
clang --ld-path=./ld64 -o $t/exe1 $t/a.o $t/b.o
$t/exe1 | grep -q '^42$'
echo OK

View File

@ -25,10 +25,10 @@ cat <<EOF | $CC -c -o $t/b.o -xc -
int foo() { return 42; }
EOF
clang -o $t/exe1 $t/a.o -Wl,-U,_foo
clang --ld-path=./ld64 -o $t/exe1 $t/a.o -Wl,-U,_foo
$t/exe1 | grep -q '^5$'
clang -o $t/exe2 $t/a.o $t/b.o -Wl,-U,_foo
clang --ld-path=./ld64 -o $t/exe2 $t/a.o $t/b.o -Wl,-U,_foo
$t/exe2 | grep -q '^42$'
echo OK