From e1b716860517d4993de6652de6be19ad1cd69f9d Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Thu, 21 Aug 2025 15:57:25 -0700 Subject: [PATCH] update weak vs undefined replacement rule --- src/linker/lnk.c | 3 +++ src/linker/lnk_symbol_table.c | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 8c4858db..1ddc0c99 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -1521,6 +1521,9 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config) if (symbol_ht) { COFF_SymbolValueInterpType interp = lnk_interp_from_symbol(symbol_ht->symbol); if (interp == COFF_SymbolValueInterp_Undefined) { + // clear out slot so weak symbol can replace undefined symbol + symbol_ht->symbol = 0; + // make obj with alternamte name symbol String8 alt_name_obj; { diff --git a/src/linker/lnk_symbol_table.c b/src/linker/lnk_symbol_table.c index cfa7276e..fd1fd461 100644 --- a/src/linker/lnk_symbol_table.c +++ b/src/linker/lnk_symbol_table.c @@ -141,7 +141,11 @@ lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src) COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(weak_parsed, weak->defined.obj->header.is_big_obj); if (weak_ext->characteristics == COFF_WeakExt_SearchLibrary) { - can_replace = lnk_symbol_defined_is_before(dst, src); + // NOTE: MSVC does not let a weak symbol to replace an undefined one, + // but LLD links without errors or warnings, meaning undefined symbols + // are resolved to the weak, which can potentially change behaviour of + // the linked image + can_replace = dst_interp == COFF_SymbolValueInterp_Weak; } else if (weak_ext->characteristics == COFF_WeakExt_NoLibrary) { can_replace = dst_interp == COFF_SymbolValueInterp_Weak; } else if (weak_ext->characteristics == COFF_WeakExt_SearchAlias) {