From 1fe85acff8199d7a21c25774c5620bef8ec442d4 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Thu, 31 Jul 2025 22:19:24 -0700 Subject: [PATCH] refactor include symbols to go through same code path as alternate name symbols --- src/linker/lnk.c | 34 +++++++++++++++------------------- src/linker/lnk_config.c | 17 +++++++++++++---- src/linker/lnk_config.h | 1 + 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/linker/lnk.c b/src/linker/lnk.c index fcdd68ab..7ed2f76a 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -1208,7 +1208,6 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config) LNK_AltNameNode **last_alt_name = &config->alt_name_list.first; LNK_InputObjList input_obj_list = {0}; LNK_InputImportList input_import_list = {0}; - LNK_SymbolList input_weak_list = {0}; LNK_InputLib **input_libs[LNK_InputSource_Count] = { &config->input_list[LNK_Input_Lib].first, &config->input_default_lib_list.first, @@ -1341,21 +1340,21 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config) case State_InputSymbols: { ProfBegin("Input Symbols"); - ProfBegin("Push /INCLUDE Symbols"); + // push a relocation which references an undefined include symbol + COFF_ObjWriter *obj_writer = coff_obj_writer_alloc(0, COFF_MachineType_Unknown); + COFF_ObjSection *sect = coff_obj_writer_push_section(obj_writer, str8_lit(".radinc$"), 0, str8_zero()); for (; *last_include_symbol; last_include_symbol = &(*last_include_symbol)->next) { - String8 name = push_str8_copy(symtab->arena->v[0], (*last_include_symbol)->string); - LNK_Symbol *symbol = lnk_make_undefined_symbol(symtab->arena->v[0], name, 0); - lnk_symbol_list_push(scratch.arena, &lookup_undef_list, symbol); + COFF_ObjSymbol *include_symbol = coff_obj_writer_push_symbol_undef(obj_writer, (*last_include_symbol)->string); + coff_obj_writer_section_push_reloc(obj_writer, sect, 0, include_symbol, 0); } - ProfEnd(); - // we defined new symbols, give unresolved symbols another chance to be resolved - lnk_symbol_list_concat_in_place(&lookup_undef_list, &unresolved_undef_list); - lnk_symbol_list_concat_in_place(&lookup_weak_list, &input_weak_list); - lnk_symbol_list_concat_in_place(&lookup_weak_list, &unresolved_weak_list); - - // reset inputs - MemoryZeroStruct(&input_weak_list); + // input obj with includes + LNK_InputObj *input = lnk_input_obj_list_push(scratch.arena, &input_obj_list); + input->path = str8_lit("* INCLUDE SYMBOLS *"); + input->dedup_id = push_str8f(scratch.arena, "%S %llu", input->path, input_obj_list.count); + input->data = coff_obj_writer_serialize(tp_arena->v[0], obj_writer); + + coff_obj_writer_release(&obj_writer); ProfEnd(); } break; @@ -1448,12 +1447,9 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config) LNK_SymbolInputResult input_result = lnk_input_obj_symbols(tp, tp_arena, symtab, obj_node_arr); // schedule symbol input - lnk_symbol_list_concat_in_place(&input_weak_list, &input_result.weak_symbols); - lnk_symbol_list_concat_in_place(&lookup_undef_list, &input_result.undef_symbols); - - // give another chance to unresolved symbols lnk_symbol_list_concat_in_place(&lookup_undef_list, &unresolved_undef_list); - lnk_symbol_list_concat_in_place(&input_weak_list, &unresolved_weak_list); + lnk_symbol_list_concat_in_place(&lookup_undef_list, &input_result.undef_symbols); + lnk_symbol_list_concat_in_place(&lookup_weak_list, &input_result.weak_symbols); // reset input objs MemoryZeroStruct(&input_obj_list); @@ -2017,7 +2013,7 @@ lnk_build_link_context(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config) state_list_push(scratch.arena, state_list, State_InputImports); continue; } - if (input_weak_list.count || *last_include_symbol != 0) { + if (*last_include_symbol != 0) { state_list_push(scratch.arena, state_list, State_InputSymbols); continue; } diff --git a/src/linker/lnk_config.c b/src/linker/lnk_config.c index 5cf2475d..426a5b25 100644 --- a/src/linker/lnk_config.c +++ b/src/linker/lnk_config.c @@ -1342,8 +1342,16 @@ lnk_apply_cmd_option_to_config(Arena *arena, LNK_Config *config, String8 cmd_nam } break; case LNK_CmdSwitch_Include: { - String8List include_symbol_list = str8_list_copy(arena, &value_strings); - str8_list_concat_in_place(&config->include_symbol_list, &include_symbol_list); + for (String8Node *value_n = value_strings.first; value_n != 0; value_n = value_n->next) { + // is this a duplicate symbol? + if (hash_table_search_string_raw(config->include_symbol_ht, value_n->string, 0)) { + continue; + } + + String8 include_symbol = push_str8_copy(arena, value_n->string); + hash_table_push_string_raw(arena, config->include_symbol_ht, include_symbol, 0); + str8_list_push(arena, &config->include_symbol_list, include_symbol); + } } break; case LNK_CmdSwitch_Incremental: { @@ -1986,8 +1994,9 @@ lnk_config_from_cmd_line(Arena *arena, String8List raw_cmd_line, LNK_CmdLine cmd config->pdb_hash_type_names = LNK_TypeNameHashMode_None; config->pdb_hash_type_name_length = 8; config->data_dir_count = PE_DataDirectoryIndex_COUNT; - config->export_ht = hash_table_init(scratch.arena, max_U16/2); - config->alt_name_ht = hash_table_init(scratch.arena, 0x100); + config->export_ht = hash_table_init(arena, max_U16/2); + config->alt_name_ht = hash_table_init(arena, 0x100); + config->include_symbol_ht = hash_table_init(arena, 0x100); // process command line switches for (LNK_CmdOption *cmd = cmd_line.first_option; cmd != 0; cmd = cmd->next) { diff --git a/src/linker/lnk_config.h b/src/linker/lnk_config.h index 07eee00c..aa6cdba1 100644 --- a/src/linker/lnk_config.h +++ b/src/linker/lnk_config.h @@ -394,6 +394,7 @@ typedef struct LNK_Config LNK_IO_Flags io_flags; HashTable *export_ht; HashTable *alt_name_ht; + HashTable *include_symbol_ht; } LNK_Config; // --- MSVC Error Codes --------------------------------------------------------