From 25430ea522558d264d1b482e53ecc791f6dbcdc4 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Sun, 12 Jul 2026 23:19:07 -0700 Subject: [PATCH] assign COMDAT symlinks after weak symbol replacement Previously, COMDAT symlinks were assigned as each object batch was loaded. Weak symbol replacement could later change the selected leader, leaving objects from earlier passes with stale COMDAT leader refs. Library search does not need symlinks to be valid, so solve this by doing a single sweep assignment of COMDAT leaders after a fixed point is found. --- src/linker/lnk.c | 8 ++++++++ src/linker/lnk_obj.c | 10 +++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/linker/lnk.c b/src/linker/lnk.c index eb839f1e..59213926 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -2271,6 +2271,14 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer // lnk_replace_weak_with_default_symbols(tp, symtab); + // + // assign COMDAT leaders + // + { + LNK_Obj **objs = lnk_array_from_obj_list(scratch.arena, link->objs); + lnk_assign_comdat_symlinks(tp, arena, symtab, link->objs.count, objs); + } + // // was entry point resolved? // diff --git a/src/linker/lnk_obj.c b/src/linker/lnk_obj.c index c3144acf..68b5ae4c 100644 --- a/src/linker/lnk_obj.c +++ b/src/linker/lnk_obj.c @@ -502,13 +502,21 @@ THREAD_POOL_TASK_FUNC(lnk_assign_comdat_symlinks_task) obj->symlinks = lnk_symlinks_from_obj(arena, task->symtab, obj); } +internal void +lnk_assign_comdat_symlinks(TP_Context *tp, TP_Arena *arena, LNK_SymbolTable *symtab, U64 objs_count, LNK_Obj **objs) +{ + ProfBeginFunction(); + LNK_InputCoffSymbolTable task = { .symtab = symtab, .objs = objs }; + tp_for_parallel(tp, arena, objs_count, lnk_assign_comdat_symlinks_task, &task); + ProfEnd(); +} + internal void lnk_push_obj_symbols(TP_Context *tp, TP_Arena *arena, LNK_SymbolTable *symtab, U64 objs_count, LNK_Obj **objs) { ProfBeginFunction(); LNK_InputCoffSymbolTable task = { .symtab = symtab, .objs = objs }; tp_for_parallel(tp, arena, objs_count, lnk_input_coff_symbol_table, &task); - tp_for_parallel(tp, arena, objs_count, lnk_assign_comdat_symlinks_task, &task); ProfEnd(); }