diff --git a/src/coff/coff.h b/src/coff/coff.h index 0cd16897..69b72ff3 100644 --- a/src/coff/coff.h +++ b/src/coff/coff.h @@ -294,6 +294,7 @@ typedef struct COFF_Symbol32 typedef U32 COFF_WeakExtType; enum { + COFF_WeakExt_Null = 0, COFF_WeakExt_NoLibrary = 1, COFF_WeakExt_SearchLibrary = 2, COFF_WeakExt_SearchAlias = 3, diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 1cc0d52b..788a42ed 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -468,7 +468,7 @@ lnk_make_null_obj(Arena *arena) COFF_ObjSymbol *null_abs = coff_obj_writer_push_symbol_abs(obj_writer, str8_lit(LNK_NULL_SYMBOL), 0, COFF_SymStorageClass_External); // push import stub - coff_obj_writer_push_symbol_weak(obj_writer, str8_lit(LNK_IMPORT_STUB), COFF_WeakExt_SearchAlias, null_abs); + coff_obj_writer_push_symbol_weak(obj_writer, str8_lit(LNK_IMPORT_STUB), COFF_WeakExt_Null, null_abs); // push .debug$T sections with null leaf String8 null_debug_data; @@ -1198,8 +1198,8 @@ internal int lnk_lib_member_ref_is_before(void *raw_a, void *raw_b) { LNK_LibMemberRef **a = raw_a, **b = raw_b; - LNK_Symbol *a_pull_in_ref = (*a)->lib->was_member_linked[(*a)->member_idx]; - LNK_Symbol *b_pull_in_ref = (*b)->lib->was_member_linked[(*b)->member_idx]; + LNK_Symbol *a_pull_in_ref = (*a)->lib->member_links[(*a)->member_idx]; + LNK_Symbol *b_pull_in_ref = (*b)->lib->member_links[(*b)->member_idx]; return lnk_symbol_is_before(a_pull_in_ref, b_pull_in_ref); } @@ -1478,17 +1478,14 @@ lnk_load_inputs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer ProfEnd(); } -internal force_inline void +internal void lnk_queue_lib_member(Arena *arena, LNK_LibMemberRefList *queued_members, LNK_Symbol *link_symbol, LNK_Lib *lib, U32 member_idx) { - B32 is_first_set = lnk_lib_set_link_symbol(lib, member_idx, link_symbol); - if (is_first_set) { - link_symbol->is_lib_member_linked = 1; - + B32 was_linked = lnk_lib_set_link_symbol(lib, member_idx, link_symbol); + if (was_linked) { LNK_LibMemberRef *member_ref = push_array(arena, LNK_LibMemberRef, 1); - member_ref->lib = lib; - member_ref->member_idx = member_idx; - + member_ref->lib = lib; + member_ref->member_idx = member_idx; lnk_lib_member_ref_list_push_node(queued_members, member_ref); } } @@ -1502,10 +1499,9 @@ THREAD_POOL_TASK_FUNC(lnk_search_lib_task) B32 search_anti_deps = task->search_anti_deps; LNK_LibMemberRefList *member_ref_list = &task->member_ref_lists[task_id]; - for EachNode(c, LNK_SymbolHashTrieChunk, symtab->weak_undef_chunks[task_id].first) { + for EachNode(c, LNK_SymbolHashTrieChunk, symtab->search_chunks[task_id].first) { for EachIndex(i, c->count) { LNK_Symbol *symbol = c->v[i].symbol; - if (symbol->is_lib_member_linked) { continue; } LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol); COFF_ParsedSymbol symbol_parsed = lnk_parsed_from_symbol(symbol); @@ -1548,31 +1544,33 @@ lnk_link_inputs(TP_Context *tp, LNK_Config *config, LNK_Inputer *inputer, LNK_SymbolTable *symtab, - LNK_Link *link, - LNK_ImportTables *imps) + LNK_Link *link) { ProfBeginFunction(); Temp scratch = scratch_begin(arena->v, arena->count); - B32 search_anti_deps = 0; + LNK_LibMemberRefList *member_ref_lists = push_array(scratch.arena, LNK_LibMemberRefList, tp->worker_count); + B32 search_anti_deps = 0; for (U64 resolved_members_count = 0; ; resolved_members_count = 0) { lnk_load_inputs(tp, arena, config, inputer, symtab, link); for EachNode(lib_n, LNK_LibNode, link->libs.first) { - ProfBeginV("Search %S", str8_skip_last_slash(lib_n->data.path)); + LNK_Lib *lib = &lib_n->data; + + ProfBeginV("Search %S", str8_skip_last_slash(lib->path)); do { lnk_load_inputs(tp, arena, config, inputer, symtab, link); + // search symbols in lib + MemoryZeroTyped(member_ref_lists, tp->worker_count); + tp_for_parallel(tp, arena, tp->worker_count, lnk_search_lib_task, &(LNK_SearchLibTask){ .search_anti_deps = search_anti_deps, .lib = lib, .symtab = symtab, .member_ref_lists = member_ref_lists }); + LNK_LibMemberRefList queued_members = {0}; - { - LNK_SearchLibTask task = { .search_anti_deps = search_anti_deps, .lib = &lib_n->data, .symtab = symtab }; - task.member_ref_lists = push_array(scratch.arena, LNK_LibMemberRefList, tp->worker_count); - tp_for_parallel(tp, arena, tp->worker_count, lnk_search_lib_task, &task); - lnk_lib_member_ref_list_concat_in_place_array(&queued_members, task.member_ref_lists, tp->worker_count); - } + lnk_lib_member_ref_list_concat_in_place_array(&queued_members, member_ref_lists, tp->worker_count); // sort library member refs to match the order of their appearance in obj symbol tables LNK_LibMemberRef **member_refs = lnk_array_from_lib_member_list(scratch.arena, queued_members); + //qsort(member_refs, queued_members.count, sizeof(member_refs[0]), lnk_lib_member_ref_compar); radsort(member_refs, queued_members.count, lnk_lib_member_ref_is_before); if (queued_members.count) { @@ -1583,7 +1581,7 @@ lnk_link_inputs(TP_Context *tp, LNK_LibMemberRef *member_ref = member_refs[i]; LNK_Lib *lib = member_ref->lib; - LNK_Symbol *link_symbol = lib->was_member_linked[member_ref->member_idx]; + LNK_Symbol *link_symbol = lib->member_links[member_ref->member_idx]; COFF_ArchiveMember member_info = coff_archive_member_from_offset(lib->data, lib->member_offsets[member_ref->member_idx]); COFF_DataType member_type = coff_data_type_from_data(member_info.data); @@ -1602,70 +1600,50 @@ lnk_link_inputs(TP_Context *tp, // push inputs for lib member refs for EachIndex(i, queued_members.count) { - LNK_LibMemberRef *member_ref = member_refs[i]; - LNK_Lib *lib = member_ref->lib; - LNK_Symbol *link_symbol = lib->was_member_linked[member_ref->member_idx]; + LNK_LibMemberRef *member_ref = member_refs[i]; + U64 member_idx = member_ref->member_idx; - // parse member - COFF_ArchiveMember member_info = coff_archive_member_from_offset(lib->data, lib->member_offsets[member_ref->member_idx]); + // parse member info + COFF_ArchiveMember member_info = coff_archive_member_from_offset(lib->data, lib->member_offsets[member_idx]); COFF_DataType member_type = coff_data_type_from_data(member_info.data); String8 member_name = coff_decode_member_name(lib->long_names, member_info.header.name); switch (member_type) { case COFF_DataType_Import: { - COFF_ParsedArchiveImportHeader import_header = coff_archive_import_from_data(member_info.data); + LNK_Symbol *link_symbol = lib->member_links[member_idx]; - // import machine compat check - if (import_header.machine != config->machine) { - LNK_ObjSymbolRef ref = lnk_ref_from_symbol(link_symbol); - lnk_error_obj(LNK_Error_IncompatibleMachine, - ref.obj, - "symbol %S pulls-in import from %S for an incompatible machine %S (expected machine %S)", - link_symbol->name, - str8_chop_last_slash(lib->path), - coff_string_from_machine_type(import_header.machine), - coff_string_from_machine_type(config->machine)); - break; + LNK_Symbol *import_symbols[2] = {0}; + if (str8_starts_with(link_symbol->name, str8_lit("__imp_"))) { + import_symbols[0] = link_symbol; + import_symbols[1] = lnk_symbol_table_search(symtab, str8_skip(link_symbol->name, str8_lit("__imp_").size)); + } else { + Temp temp = temp_begin(scratch.arena); + String8 imp_name = push_str8f(temp.arena, "__imp_%S", link_symbol->name); + import_symbols[0] = lnk_symbol_table_search(symtab, imp_name); + import_symbols[1] = link_symbol; + temp_end(temp); } - // was import already created? - LNK_Symbol *is_import_loaded = lnk_symbol_table_search(symtab, link_symbol->name); - if (is_import_loaded) { - COFF_SymbolValueInterpType interp = lnk_interp_from_symbol(is_import_loaded); - if (interp != COFF_SymbolValueInterp_Undefined) { - break; - } + for EachIndex(i, ArrayCount(import_symbols)) { + LNK_Symbol *import_symbol = import_symbols[i]; + if (import_symbol == 0) { continue; } + + LNK_Symbol *import_stub = lnk_symbol_table_search(symtab, str8_lit(LNK_IMPORT_STUB)); + + // same import symbol must never be queued more than once, if it is, there is a bug in the link set logic + AssertAlways(import_symbol->refs != import_stub->refs); + + // replace the import symbol with a stub, which is later replaced with the real import symbol once import obj is ready + import_symbol->refs = import_stub->refs; } - // create import stub symbol (later replaced with actual import) - LNK_Symbol *import_stub = lnk_symbol_table_search(symtab, str8_lit(LNK_IMPORT_STUB)); - LNK_ObjSymbolRef import_symbol_ref = lnk_ref_from_symbol(import_stub); - LNK_Symbol *import_symbol = lnk_make_symbol(symtab->arena->v[0], link_symbol->name, import_symbol_ref.obj, import_symbol_ref.symbol_idx); - lnk_symbol_table_push(symtab, import_symbol); - - // skip lib search - import_symbol->is_lib_member_linked = 1; - - // find DLL with import symbols - B32 is_delay_load = lnk_is_dll_delay_load(config, import_header.dll_name); - String8List *dll_names = is_delay_load ? &imps->delayed_dll_names : &imps->static_dll_names; - HashTable *imports_ht = is_delay_load ? imps->delayed_imports : imps->static_imports; - PE_MakeImportList *import_symbols = hash_table_search_path_raw(imports_ht, import_header.dll_name); - - // create record for a first time-DLL - if (import_symbols == 0) { - import_symbols = push_array(imps->arena, PE_MakeImportList, 1); - str8_list_push(imps->arena, dll_names, import_header.dll_name); - hash_table_push_path_raw(imps->arena, imports_ht, import_header.dll_name, import_symbols); - } - - // push make import info - pe_make_import_header_list_push(imps->arena, import_symbols, (PE_MakeImport){ .header = member_info.data, .make_jump_thunk = !str8_starts_with(link_symbol->name, str8_lit("__imp_")) }); + // push import member for import obj generation + lnk_lib_member_ref_list_push_node(&link->imports, member_ref); } break; case COFF_DataType_BigObj: case COFF_DataType_Obj: { if (lib->type == COFF_Archive_Thin) { - // obj path in thin archive is relative to the directory with archive + // obj path in thin archive is relative to the directory with lib String8List obj_path_list = {0}; str8_list_push(scratch.arena, &obj_path_list, str8_chop_last_slash(lib->path)); str8_list_push(scratch.arena, &obj_path_list, member_name); @@ -1747,18 +1725,6 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer link->last_cmd_lib = &config->input_list[LNK_Input_Lib].first; link->try_to_resolve_entry_point = 1; - // - // init import hash tables - // - LNK_ImportTables *imps = 0; - { - Arena *imps_arena = arena_alloc(); - imps = push_array(imps_arena, LNK_ImportTables, 1); - imps->arena = imps_arena; - imps->static_imports = hash_table_init(imps->arena, 0x1000); - imps->delayed_imports = hash_table_init(imps->arena, 0x1000); - } - // input :null_obj String8 null_obj = lnk_make_null_obj(inputer->arena); lnk_inputer_push_obj_linkgen(inputer, 0, str8_lit("* Null *"), null_obj); @@ -1774,7 +1740,7 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer } // link inputer - lnk_link_inputs(tp, arena, config, inputer, symtab, link, imps); + lnk_link_inputs(tp, arena, config, inputer, symtab, link); // TODO: need to figure out under what condition to include load config //lnk_include_symbol(config, str8_lit(MSCRT_LOAD_CONFIG_SYMBOL_NAME), 0); @@ -1786,11 +1752,64 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer ProfEnd(); } - // make and input delayed imports + // + // make imports + // { - String8List delayed_dll_names = imps->delayed_dll_names; - HashTable *delayed_imports_ht = imps->delayed_imports; + HashTable *static_imports_ht = hash_table_init(scratch.arena, 0x1000); + HashTable *delayed_imports_ht = hash_table_init(scratch.arena, 0x1000); + String8List delayed_dll_names = {0}; + String8List static_dll_names = {0}; + + for EachNode(member_ref, LNK_LibMemberRef, link->imports.first) { + LNK_Lib *lib = member_ref->lib; + U64 member_idx = member_ref->member_idx; + LNK_Symbol *link_symbol = lib->member_links[member_idx]; + + COFF_ArchiveMember member_info = coff_archive_member_from_offset(lib->data, lib->member_offsets[member_idx]); + COFF_DataType member_type = coff_data_type_from_data(member_info.data); + String8 member_name = coff_decode_member_name(lib->long_names, member_info.header.name); + COFF_ParsedArchiveImportHeader import_header = coff_archive_import_from_data(member_info.data); + + // import machine compat check + if (import_header.machine != config->machine) { + LNK_ObjSymbolRef ref = lnk_ref_from_symbol(link_symbol); + lnk_error_obj(LNK_Error_IncompatibleMachine, + ref.obj, + "symbol %S pulls-in import from %S with an incompatible machine %S (expected machine %S)", + link_symbol->name, + str8_chop_last_slash(lib->path), + coff_string_from_machine_type(import_header.machine), + coff_string_from_machine_type(config->machine)); + break; + } + + // find DLL with import symbols + B32 is_delay_load = lnk_is_dll_delay_load(config, import_header.dll_name); + String8List *dll_names = is_delay_load ? &delayed_dll_names : &static_dll_names; + HashTable *imports_ht = is_delay_load ? delayed_imports_ht : static_imports_ht; + PE_MakeImportList *import_symbols = hash_table_search_path_raw(imports_ht, import_header.dll_name); + + // create record for a first time-DLL + if (import_symbols == 0) { + import_symbols = push_array(scratch.arena, PE_MakeImportList, 1); + str8_list_push(scratch.arena, dll_names, import_header.dll_name); + hash_table_push_path_raw(scratch.arena, imports_ht, import_header.dll_name, import_symbols); + } + + B32 make_jump_thunk = 1; + if (str8_starts_with(link_symbol->name, str8_lit("__imp_"))) { + LNK_Symbol *thunk_symbol = lnk_symbol_table_search(symtab, str8_skip(link_symbol->name, str8_lit("__imp_").size)); + make_jump_thunk = thunk_symbol != 0; + } + + // push make import info + pe_make_import_header_list_push(scratch.arena, import_symbols, (PE_MakeImport){ .header = member_info.data, .make_jump_thunk = make_jump_thunk }); + } AssertAlways(delayed_dll_names.node_count == delayed_imports_ht->count); + AssertAlways(static_dll_names.node_count == static_imports_ht->count); + + // make and input delayed imports if (delayed_imports_ht->count) { ProfBegin("Build Delay Import Table"); @@ -1813,13 +1832,8 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer ProfEnd(); } - } - // make and input static imports - { - String8List static_dll_names = imps->static_dll_names; - HashTable *static_imports_ht = imps->static_imports; - AssertAlways(static_dll_names.node_count == static_imports_ht->count); + // make and input static imports if (static_imports_ht->count) { ProfBegin("Build Static Import Table"); @@ -1840,6 +1854,15 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer ProfEnd(); } + + // warn about unused delayloads + if (config->flags & LNK_ConfigFlag_CheckUnusedDelayLoadDll) { + for (String8Node *dll_name_n = config->delay_load_dll_list.first; dll_name_n != 0; dll_name_n = dll_name_n->next) { + if (!hash_table_search_path_raw(delayed_imports_ht, dll_name_n->string)) { + lnk_error(LNK_Warning_UnusedDelayLoadDll, "/DELAYLOAD: %S found no imports", dll_name_n->string); + } + } + } } if (config->export_symbol_list.count) { @@ -1967,7 +1990,7 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer // // link linker made objs // - lnk_link_inputs(tp, arena, config, inputer, symtab, link, imps); + lnk_link_inputs(tp, arena, config, inputer, symtab, link); // // finalize symbol table @@ -2104,17 +2127,6 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer ProfEnd(); } - // - // warn about unused delayloads - // - if (config->flags & LNK_ConfigFlag_CheckUnusedDelayLoadDll) { - for (String8Node *dll_name_n = config->delay_load_dll_list.first; dll_name_n != 0; dll_name_n = dll_name_n->next) { - if (!hash_table_search_path_raw(imps->delayed_imports, dll_name_n->string)) { - lnk_error(LNK_Warning_UnusedDelayLoadDll, "/DELAYLOAD: %S found no imports", dll_name_n->string); - } - } - } - // // discard COMDAT sections that are not referenced // diff --git a/src/linker/lnk.h b/src/linker/lnk.h index a3f7909c..31443404 100644 --- a/src/linker/lnk.h +++ b/src/linker/lnk.h @@ -7,8 +7,8 @@ typedef struct LNK_LibMemberRef { - LNK_Lib *lib; - U32 member_idx; + LNK_Lib *lib; + U32 member_idx; struct LNK_LibMemberRef *next; } LNK_LibMemberRef; @@ -76,25 +76,17 @@ typedef struct LNK_Inputer #define LNK_SECTION_FLAG_IS_LIVE (1 << 0) #define LNK_SECTION_FLAG_DEBUG_INFO (1 << 1) -typedef struct LNK_ImportTables -{ - Arena *arena; - String8List delayed_dll_names; - String8List static_dll_names; - HashTable *static_imports; - HashTable *delayed_imports; -} LNK_ImportTables; - typedef struct LNK_Link { - LNK_ObjList objs; - LNK_LibList libs; - LNK_ObjNode **last_symbol_input; - LNK_IncludeSymbolNode **last_include; - String8Node **last_cmd_lib; - String8Node **last_default_lib; - String8Node **last_obj_lib; - B32 try_to_resolve_entry_point; + LNK_ObjList objs; + LNK_LibList libs; + LNK_ObjNode **last_symbol_input; + LNK_IncludeSymbolNode **last_include; + String8Node **last_cmd_lib; + String8Node **last_default_lib; + String8Node **last_obj_lib; + LNK_LibMemberRefList imports; + B32 try_to_resolve_entry_point; } LNK_Link; // -- Image Layout ------------------------------------------------------------ @@ -299,7 +291,7 @@ internal LNK_LibMemberRef ** lnk_array_from_lib_member_list(Arena *arena, LNK_Li internal LNK_ObjNode * lnk_load_objs (TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer *inputer, LNK_SymbolTable *symtab, LNK_Link *link, U64 *objs_count_out); internal void lnk_load_libs (TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer *inputer, LNK_Link *link); -internal void lnk_link_inputs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer *inputer, LNK_SymbolTable *symtab, LNK_Link *link, LNK_ImportTables *imps); +internal void lnk_link_inputs(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer *inputer, LNK_SymbolTable *symtab, LNK_Link *link); internal LNK_Link * lnk_link_image (TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer *inputer, LNK_SymbolTable *symtab); // --- Optimizations ----------------------------------------------------------- diff --git a/src/linker/lnk_lib.c b/src/linker/lnk_lib.c index 2bd417e4..cd4f5e82 100644 --- a/src/linker/lnk_lib.c +++ b/src/linker/lnk_lib.c @@ -137,10 +137,11 @@ lnk_lib_from_data(Arena *arena, String8 data, String8 path, U64 input_idx, LNK_L lib_out->path = push_str8_copy(arena, path); lib_out->data = data; lib_out->type = type; + lib_out->member_count = member_count; lib_out->symbol_count = Min(symbol_count, symbol_names.count); // TODO: warn about mismatched number of symbol names and symbol count in the header lib_out->member_offsets = member_offsets; lib_out->symbol_indices = symbol_indices; - lib_out->was_member_linked = push_array(arena, LNK_Symbol *, member_count); + lib_out->member_links = push_array(arena, LNK_Symbol *, member_count); lib_out->symbol_names = symbol_names; lib_out->long_names = parse.long_names; lib_out->input_idx = input_idx; @@ -225,41 +226,33 @@ lnk_lib_set_link_symbol(LNK_Lib *lib, U32 member_idx, LNK_Symbol *link_symbol) { local_persist LNK_Symbol null_symbol; - B32 is_first_set; + LNK_Symbol *slot = ins_atomic_ptr_eval_assign(&lib->member_links[member_idx], &null_symbol); - LNK_Symbol *slot = ins_atomic_ptr_eval_assign(&lib->was_member_linked[member_idx], &null_symbol); - - for (;;) { - is_first_set = (slot == 0); + B32 was_linked = (slot == 0); + for (LNK_Symbol *leader = link_symbol;;) { // update slot symbol if it is empty or link symbol comes before symbol in the slot if (slot && slot != &null_symbol) { - if (!str8_starts_with(link_symbol->name, str8_lit("__imp_")) && str8_starts_with(slot->name, str8_lit("__imp_"))) { - // replace import address symbol with jump thunk symbol - slot = link_symbol; - is_first_set = 1; - } else if (str8_starts_with(link_symbol->name, str8_lit("__imp_")) && !str8_starts_with(slot->name, str8_lit("__imp_"))) { - // no need to replace - } else if (lnk_symbol_is_before(slot, link_symbol)) { - slot = link_symbol; + if (lnk_symbol_is_before(slot, leader)) { + leader = slot; } } else { - slot = link_symbol; + leader = link_symbol; } // try to insert back updated slot symbol - LNK_Symbol *was_replaced = ins_atomic_ptr_eval_cond_assign(&lib->was_member_linked[member_idx], slot, &null_symbol); + LNK_Symbol *swap = ins_atomic_ptr_eval_cond_assign(&lib->member_links[member_idx], leader, &null_symbol); // exit if slot symbol was null - if (was_replaced == &null_symbol) { + if (swap == &null_symbol) { break; } // reload slot symbol - slot = ins_atomic_ptr_eval_assign(&lib->was_member_linked[member_idx], &null_symbol); + slot = ins_atomic_ptr_eval_assign(&lib->member_links[member_idx], &null_symbol); } - return is_first_set; + return was_linked; } internal force_inline B32 diff --git a/src/linker/lnk_lib.h b/src/linker/lnk_lib.h index 826b507f..0cbdd673 100644 --- a/src/linker/lnk_lib.h +++ b/src/linker/lnk_lib.h @@ -5,16 +5,17 @@ typedef struct LNK_Lib { - String8 path; - String8 data; - COFF_ArchiveType type; - U32 symbol_count; - U32 *member_offsets; - U16 *symbol_indices; - LNK_Symbol **was_member_linked; - String8Array symbol_names; - String8 long_names; - U64 input_idx; + String8 path; + String8 data; + COFF_ArchiveType type; + U32 member_count; + U32 symbol_count; + U32 *member_offsets; + U16 *symbol_indices; + LNK_Symbol **member_links; + String8Array symbol_names; + String8 long_names; + U64 input_idx; } LNK_Lib; typedef struct LNK_LibNode diff --git a/src/linker/lnk_symbol_table.c b/src/linker/lnk_symbol_table.c index 3a66719e..175c5e54 100644 --- a/src/linker/lnk_symbol_table.c +++ b/src/linker/lnk_symbol_table.c @@ -551,7 +551,7 @@ lnk_symbol_table_init(TP_Arena *arena) LNK_SymbolTable *symtab = push_array(arena->v[0], LNK_SymbolTable, 1); symtab->arena = arena; symtab->chunks = push_array(arena->v[0], LNK_SymbolHashTrieChunkList, arena->count); - symtab->weak_undef_chunks = push_array(arena->v[0], LNK_SymbolHashTrieChunkList, arena->count); + symtab->search_chunks = push_array(arena->v[0], LNK_SymbolHashTrieChunkList, arena->count); return symtab; } @@ -562,7 +562,7 @@ lnk_symbol_table_push_(LNK_SymbolTable *symtab, Arena *arena, U64 worker_id, LNK COFF_SymbolValueInterpType interp = lnk_interp_from_symbol(symbol); LNK_SymbolHashTrieChunkList *chunks; if (interp == COFF_SymbolValueInterp_Weak || interp == COFF_SymbolValueInterp_Undefined) { - chunks = &symtab->weak_undef_chunks[worker_id]; + chunks = &symtab->search_chunks[worker_id]; } else { chunks = &symtab->chunks[worker_id]; } @@ -717,7 +717,7 @@ internal THREAD_POOL_TASK_FUNC(lnk_replace_weak_with_default_symbol_task) { LNK_SymbolTable *symtab = raw_task; - for EachNode(c, LNK_SymbolHashTrieChunk, symtab->weak_undef_chunks[task_id].first) { + for EachNode(c, LNK_SymbolHashTrieChunk, symtab->search_chunks[task_id].first) { for EachIndex(i, c->count) { LNK_Symbol *symbol = c->v[i].symbol; LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol); @@ -758,7 +758,7 @@ lnk_replace_weak_with_default_symbols(TP_Context *tp, LNK_SymbolTable *symtab) tp_for_parallel_prof(tp, 0, tp->worker_count, lnk_replace_weak_with_default_symbol_task, symtab, "Replace Weak With Default Symbols"); for EachIndex(i, tp->worker_count) { - lnk_symbol_hash_trie_chunk_list_concat_in_place(&symtab->chunks[i], &symtab->weak_undef_chunks[i]); + lnk_symbol_hash_trie_chunk_list_concat_in_place(&symtab->chunks[i], &symtab->search_chunks[i]); } ProfEnd(); diff --git a/src/linker/lnk_symbol_table.h b/src/linker/lnk_symbol_table.h index 190d649d..7ca55350 100644 --- a/src/linker/lnk_symbol_table.h +++ b/src/linker/lnk_symbol_table.h @@ -20,7 +20,6 @@ typedef struct LNK_ObjSymbolRefNode typedef struct LNK_Symbol { String8 name; - B8 is_lib_member_linked; LNK_ObjSymbolRefNode *refs; } LNK_Symbol; @@ -76,7 +75,7 @@ typedef struct LNK_SymbolTable TP_Arena *arena; LNK_SymbolHashTrie *root; LNK_SymbolHashTrieChunkList *chunks; - LNK_SymbolHashTrieChunkList *weak_undef_chunks; + LNK_SymbolHashTrieChunkList *search_chunks; } LNK_SymbolTable; // --- Workers Contexts --------------------------------------------------------