diff --git a/src/coff/coff_parse.c b/src/coff/coff_parse.c index 1db0b582..c2d129f7 100644 --- a/src/coff/coff_parse.c +++ b/src/coff/coff_parse.c @@ -166,13 +166,20 @@ coff_section_header_array_from_name(Arena *arena, String8 string_table, COFF_Sec } -internal COFF_ParsedSymbol -coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32) -{ - COFF_ParsedSymbol result = {0}; - result.name = coff_read_symbol_name(string_table, &sym32->name); - result.value = sym32->value; - result.section_number = sym32->section_number; +internal COFF_ParsedSymbol +coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32) +{ + COFF_ParsedSymbol result = coff_parse_symbol32_no_name(sym32); + result.name = coff_read_symbol_name(string_table, &sym32->name); + return result; +} + +internal force_inline COFF_ParsedSymbol +coff_parse_symbol32_no_name(COFF_Symbol32 *sym32) +{ + COFF_ParsedSymbol result = {0}; + result.value = sym32->value; + result.section_number = sym32->section_number; result.type = sym32->type; result.storage_class = sym32->storage_class; result.aux_symbol_count = sym32->aux_symbol_count; @@ -180,12 +187,19 @@ coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32) return result; } -internal COFF_ParsedSymbol -coff_parse_symbol16(String8 string_table, COFF_Symbol16 *sym16) -{ - COFF_ParsedSymbol result = {0}; - result.name = coff_read_symbol_name(string_table, &sym16->name); - result.value = sym16->value; +internal COFF_ParsedSymbol +coff_parse_symbol16(String8 string_table, COFF_Symbol16 *sym16) +{ + COFF_ParsedSymbol result = coff_parse_symbol16_no_name(sym16); + result.name = coff_read_symbol_name(string_table, &sym16->name); + return result; +} + +internal force_inline COFF_ParsedSymbol +coff_parse_symbol16_no_name(COFF_Symbol16 *sym16) +{ + COFF_ParsedSymbol result = {0}; + result.value = sym16->value; if (sym16->section_number == COFF_Symbol_DebugSection16) { result.section_number = COFF_Symbol_DebugSection32; } else if (sym16->section_number == COFF_Symbol_AbsSection16) { @@ -200,8 +214,8 @@ coff_parse_symbol16(String8 string_table, COFF_Symbol16 *sym16) return result; } -internal COFF_ParsedSymbol -coff_parse_symbol(COFF_FileHeaderInfo header, String8 string_table, String8 symbol_table, U32 symbol_idx) +internal COFF_ParsedSymbol +coff_parse_symbol(COFF_FileHeaderInfo header, String8 string_table, String8 symbol_table, U32 symbol_idx) { COFF_ParsedSymbol symbol; if (header.is_big_obj) { @@ -209,8 +223,20 @@ coff_parse_symbol(COFF_FileHeaderInfo header, String8 string_table, String8 symb } else { symbol = coff_parse_symbol16(string_table, (COFF_Symbol16 *)symbol_table.str + symbol_idx); } - return symbol; -} + return symbol; +} + +internal force_inline COFF_ParsedSymbol +coff_parse_symbol_no_name(COFF_FileHeaderInfo header, String8 symbol_table, U32 symbol_idx) +{ + COFF_ParsedSymbol symbol; + if (header.is_big_obj) { + symbol = coff_parse_symbol32_no_name((COFF_Symbol32 *)symbol_table.str + symbol_idx); + } else { + symbol = coff_parse_symbol16_no_name((COFF_Symbol16 *)symbol_table.str + symbol_idx); + } + return symbol; +} internal COFF_Symbol32Array coff_symbol_array_from_data_16(Arena *arena, String8 raw_coff, U64 symbol_array_off, U64 symbol_count) diff --git a/src/coff/coff_parse.h b/src/coff/coff_parse.h index edcb2952..ac377eae 100644 --- a/src/coff/coff_parse.h +++ b/src/coff/coff_parse.h @@ -259,9 +259,12 @@ internal String8 coff_name_from_section_header (String8 str //////////////////////////////// // Symbol -internal COFF_ParsedSymbol coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32); -internal COFF_ParsedSymbol coff_parse_symbol16(String8 string_table, COFF_Symbol16 *sym16); -internal COFF_ParsedSymbol coff_parse_symbol (COFF_FileHeaderInfo header, String8 string_table, String8 symbol_table, U32 symbol_idx); +internal COFF_ParsedSymbol coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32); +internal COFF_ParsedSymbol coff_parse_symbol16(String8 string_table, COFF_Symbol16 *sym16); +internal COFF_ParsedSymbol coff_parse_symbol (COFF_FileHeaderInfo header, String8 string_table, String8 symbol_table, U32 symbol_idx); +internal force_inline COFF_ParsedSymbol coff_parse_symbol32_no_name(COFF_Symbol32 *sym32); +internal force_inline COFF_ParsedSymbol coff_parse_symbol16_no_name(COFF_Symbol16 *sym16); +internal force_inline COFF_ParsedSymbol coff_parse_symbol_no_name (COFF_FileHeaderInfo header, String8 symbol_table, U32 symbol_idx); internal COFF_Symbol32Array coff_symbol_array_from_data_16(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count); internal COFF_Symbol32Array coff_symbol_array_from_data_32(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count); diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 38b8f989..194eff03 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -1703,7 +1703,7 @@ THREAD_POOL_TASK_FUNC(lnk_search_lib_task) for (U64 i = i_begin; i < i_end; i += 1) { LNK_Symbol *symbol = c->v[i].symbol; LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol); - COFF_ParsedSymbol symbol_parsed = lnk_parsed_from_symbol(symbol); + COFF_ParsedSymbol symbol_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(symbol_ref.obj, symbol_ref.symbol_idx); COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed); if (symbol_interp == COFF_SymbolValueInterp_Undefined) { @@ -1722,11 +1722,11 @@ THREAD_POOL_TASK_FUNC(lnk_search_lib_task) if (search_anti_deps) { LNK_ObjSymbolRef dep_symbol = {0}; if (lnk_resolve_weak_symbol(symtab, symbol_ref, &dep_symbol)) { - COFF_ParsedSymbol dep_parsed = lnk_parsed_symbol_from_coff_symbol_idx(dep_symbol.obj, dep_symbol.symbol_idx); + COFF_ParsedSymbol dep_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(dep_symbol.obj, dep_symbol.symbol_idx); COFF_SymbolValueInterpType dep_interp = coff_interp_from_parsed_symbol(dep_parsed); if (dep_interp == COFF_SymbolValueInterp_Weak) { U32 member_idx; - if (lnk_search_lib(lib, symbol_parsed.name, &member_idx)) { + if (lnk_search_lib(lib, symbol->name, &member_idx)) { lnk_queue_lib_member(arena, task->imports_hm, task->link->lib_member_infos_hm, member_ref_list, symbol, lib, lib_member_infos, member_idx); } } @@ -2668,7 +2668,7 @@ lnk_resolve_reloc_target_symbol(Arena *arena, LNK_SymbolTable *symtab, LNK_ObjSy } // unpack symbol - COFF_ParsedSymbol result_parsed = lnk_parsed_symbol_from_coff_symbol_idx(result.obj, result.symbol_idx); + COFF_ParsedSymbol result_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(result.obj, result.symbol_idx); COFF_SymbolValueInterpType result_interp = coff_interp_from_parsed_symbol(result_parsed); // resolve symbol @@ -2803,7 +2803,7 @@ THREAD_POOL_TASK_FUNC(lnk_opt_ref_task) if (ref_symbol.obj == 0) { continue; } // unpack resolved symbol - COFF_ParsedSymbol ref_parsed = lnk_parsed_symbol_from_coff_symbol_idx(ref_symbol.obj, ref_symbol.symbol_idx); + COFF_ParsedSymbol ref_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(ref_symbol.obj, ref_symbol.symbol_idx); COFF_SymbolValueInterpType ref_interp = coff_interp_from_parsed_symbol(ref_parsed); if (ref_interp == COFF_SymbolValueInterp_Regular) { @@ -3018,8 +3018,8 @@ lnk_icf_color_space_from_section(LNK_Obj *obj, U32 sect_idx) // fold MSVC vftables separately from other read-only data LNK_ObjSymbolRef symlink_ref = {0}; if (lnk_obj_get_comdat_symlink(obj, sect_idx + 1, &symlink_ref)) { - COFF_ParsedSymbol symlink_symbol = lnk_parsed_symbol_from_coff_symbol_idx(symlink_ref.obj, symlink_ref.symbol_idx); - if (str8_starts_with(symlink_symbol.name, str8_lit(MSCRT_VFTABLE_SYMBOL_PREFIX))) { + String8 symlink_name = lnk_symbol_name_from_coff_symbol_idx(symlink_ref.obj, symlink_ref.symbol_idx); + if (str8_starts_with(symlink_name, str8_lit(MSCRT_VFTABLE_SYMBOL_PREFIX))) { result = LNK_ICF_ColorSpace_VFTable; } } @@ -3126,12 +3126,12 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task) LNK_ObjSymbolRef target_ref = { .obj = obj, .symbol_idx = symbol_idx }; B32 is_symbol_found = lnk_resolve_reloc_target_symbol(scratch.arena, task->symtab, target_ref, str8_lit("/OPT:ICF"), &target_ref); if (is_symbol_found) { - COFF_ParsedSymbol symbol = lnk_parsed_symbol_from_coff_symbol_idx(target_ref.obj, target_ref.symbol_idx); + COFF_ParsedSymbol symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(target_ref.obj, target_ref.symbol_idx); if (coff_interp_from_parsed_symbol(symbol) == COFF_SymbolValueInterp_Regular) { target_ref.obj->section_flags[symbol.section_number - 1] |= LNK_SECTION_FLAG_NOICF; } } else { - COFF_ParsedSymbol original_symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx); + COFF_ParsedSymbol original_symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx); if (coff_interp_from_parsed_symbol(original_symbol) == COFF_SymbolValueInterp_Regular) { obj->section_flags[original_symbol.section_number - 1] |= LNK_SECTION_FLAG_NOICF; } else { @@ -3283,7 +3283,7 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task) LNK_ObjSymbolRef target_ref = { .obj = obj, .symbol_idx = r->isymbol }; B32 is_symbol_found = lnk_resolve_reloc_target_symbol(scratch2.arena, task->symtab, target_ref, str8_lit("/OPT:ICF"), &target_ref); if (is_symbol_found) { - COFF_ParsedSymbol target_symbol = lnk_parsed_symbol_from_coff_symbol_idx(target_ref.obj, target_ref.symbol_idx); + COFF_ParsedSymbol target_symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(target_ref.obj, target_ref.symbol_idx); target->interp = coff_interp_from_parsed_symbol(target_symbol); target->value = target_symbol.value; @@ -3297,7 +3297,7 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task) target_obj->section_flags[target_sect - 1] & COFF_SectionFlag_LnkCOMDAT) { LNK_ObjSymbolRef leader_ref = {0}; if (lnk_obj_get_comdat_symlink(target_obj, target_sect, &leader_ref)) { - COFF_ParsedSymbol leader_symbol = lnk_parsed_symbol_from_coff_symbol_idx(leader_ref.obj, leader_ref.symbol_idx); + COFF_ParsedSymbol leader_symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(leader_ref.obj, leader_ref.symbol_idx); if (leader_symbol.section_number != 0 && leader_symbol.section_number <= leader_ref.obj->header.section_count_no_null) { target_obj = leader_ref.obj; target_sect = leader_symbol.section_number; @@ -3650,7 +3650,7 @@ THREAD_POOL_TASK_FUNC(lnk_opt_icf_task) U64 hop_count = 0; U64 hop_cap = 1024; for(; hop_count < hop_cap; hop_count += 1) { - COFF_ParsedSymbol symlink_parsed = lnk_parsed_symbol_from_coff_symbol_idx(symlink_ref.obj, symlink_ref.symbol_idx); + COFF_ParsedSymbol symlink_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(symlink_ref.obj, symlink_ref.symbol_idx); LNK_ObjSymbolRef next_symlink_ref = {0}; if (!lnk_obj_get_comdat_symlink(symlink_ref.obj, symlink_parsed.section_number, &next_symlink_ref)) { break; } if (MemoryMatchStruct(&next_symlink_ref, &symlink_ref)) { break; } @@ -3944,7 +3944,7 @@ THREAD_POOL_TASK_FUNC(lnk_set_comdat_leaders_contribs_task) LNK_ObjSymbolRef symlink_ref = {0}; if ( ! lnk_obj_get_comdat_symlink(obj, section_number, &symlink_ref)) { continue; } - COFF_ParsedSymbol symlink_parsed = lnk_parsed_symbol_from_coff_symbol_idx(symlink_ref.obj, symlink_ref.symbol_idx); + COFF_ParsedSymbol symlink_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(symlink_ref.obj, symlink_ref.symbol_idx); task->sect_map[obj_idx][sect_idx] = task->sect_map[symlink_ref.obj->input_idx][symlink_parsed.section_number - 1]; } ProfEnd(); @@ -3959,7 +3959,7 @@ THREAD_POOL_TASK_FUNC(lnk_flag_debug_symbols_task) COFF_ParsedSymbol symbol; for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) { - symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx); + symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx); COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class); if (interp == COFF_SymbolValueInterp_Regular) { if (obj->section_flags[symbol.section_number-1] & LNK_SECTION_FLAG_DEBUG) { @@ -3979,7 +3979,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_comdat_leaders_task) ProfBeginV("Patch COMDAT Offsets in %S", obj->path); COFF_ParsedSymbol symbol; for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) { - symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx); + symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx); COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol); if (interp != COFF_SymbolValueInterp_Regular) { continue; } @@ -3987,7 +3987,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_comdat_leaders_task) LNK_ObjSymbolRef symlink_ref = {0}; if ( ! lnk_obj_get_comdat_symlink(obj, symbol.section_number, &symlink_ref)) { continue; } - COFF_ParsedSymbol leader_symbol = lnk_parsed_symbol_from_coff_symbol_idx(symlink_ref.obj, symlink_ref.symbol_idx); + COFF_ParsedSymbol leader_symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(symlink_ref.obj, symlink_ref.symbol_idx); if (symlink_ref.obj == obj && leader_symbol.section_number == symbol.section_number) { continue; } B32 is_external = symbol.storage_class == COFF_SymStorageClass_External; @@ -4012,7 +4012,9 @@ THREAD_POOL_TASK_FUNC(lnk_patch_comdat_leaders_task) should_patch = 1; } } else { - if (is_external && str8_match(symbol.name, leader_symbol.name, 0)) { + String8 symbol_name = lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx); + String8 leader_name = lnk_symbol_name_from_coff_symbol_idx(symlink_ref.obj, symlink_ref.symbol_idx); + if (is_external && str8_match(symbol_name, leader_name, 0)) { value = leader_symbol.value; should_patch = 1; } @@ -4111,10 +4113,10 @@ THREAD_POOL_TASK_FUNC(lnk_patch_common_block_symbols_task) ProfBeginV("Patch Common Block Symbols [%S]", obj->path); COFF_ParsedSymbol symbol; for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) { - symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx); + symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx); COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class); if (interp == COFF_SymbolValueInterp_Common) { - LNK_Symbol *defn = lnk_symbol_table_search(task->symtab, symbol.name); + LNK_Symbol *defn = lnk_symbol_table_search(task->symtab, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx)); COFF_ParsedSymbol defn_parsed = lnk_parsed_from_symbol(defn); Assert(lnk_interp_from_symbol(defn) == COFF_SymbolValueInterp_Regular); if (defn) { @@ -4145,7 +4147,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_regular_symbols_task) ProfBeginV("Patch Regular Symbols [%S]", obj->path); COFF_ParsedSymbol symbol; for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) { - symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx); + symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx); if (task->u.patch_symtabs.was_symbol_patched[obj_idx][symbol_idx]) { continue; } @@ -4183,7 +4185,7 @@ lnk_patch_obj_symtab(LNK_SymbolTable *symtab, LNK_Obj *obj, B8 *was_symbol_patch COFF_ParsedSymbol fixup_dst; for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + fixup_dst.aux_symbol_count)) { - fixup_dst = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx); + fixup_dst = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx); if (was_symbol_patched[symbol_idx]) { continue; } COFF_SymbolValueInterpType fixup_dst_type = coff_interp_symbol(fixup_dst.section_number, fixup_dst.value, fixup_dst.storage_class); @@ -4193,7 +4195,7 @@ lnk_patch_obj_symtab(LNK_SymbolTable *symtab, LNK_Obj *obj, B8 *was_symbol_patch LNK_ObjSymbolRef fixup_symbol = {0}; B32 is_resolved = lnk_resolve_symbol(symtab, symbol_to_resolve, &fixup_symbol); if (is_resolved) { - COFF_ParsedSymbol fixup_src = lnk_parsed_symbol_from_coff_symbol_idx(fixup_symbol.obj, fixup_symbol.symbol_idx); + COFF_ParsedSymbol fixup_src = lnk_parsed_symbol_from_coff_symbol_idx_no_name(fixup_symbol.obj, fixup_symbol.symbol_idx); COFF_SymbolValueInterpType fixup_type = coff_interp_symbol(fixup_src.section_number, fixup_src.value, fixup_src.storage_class); B32 was_fixup_removed = fixup_src.section_number == lnk_obj_get_removed_section_number(fixup_symbol.obj); @@ -4341,13 +4343,14 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher) U32 symbol_secoff = 0; S64 symbol_voff = 0; { - COFF_ParsedSymbol symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, reloc->isymbol); + COFF_ParsedSymbol symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, reloc->isymbol); COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol); if (interp == COFF_SymbolValueInterp_Regular) { if (symbol.section_number == lnk_obj_get_removed_section_number(obj)) { if (~section_flags & LNK_SECTION_FLAG_DEBUG) { String8 sect_name = coff_name_from_section_header(string_table, §ion_table[sect_idx]); - lnk_error_obj(LNK_Error_RelocationAgainstRemovedSection, obj, "relocating against symbol that is in a removed section (symbol: %S, reloc-section: %S 0x%llx, reloc-index: 0x%llx)", symbol.name, sect_name, sect_idx+1, reloc_idx); + String8 symbol_name = lnk_symbol_name_from_coff_symbol_idx(obj, reloc->isymbol); + lnk_error_obj(LNK_Error_RelocationAgainstRemovedSection, obj, "relocating against symbol that is in a removed section (symbol: %S, reloc-section: %S 0x%llx, reloc-index: 0x%llx)", symbol_name, sect_name, sect_idx+1, reloc_idx); } continue; } @@ -4358,7 +4361,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher) // There aren't enough bits in COFF symbol to store full image base address, // so we special case __ImageBase. A better solution would be to add // a 64-bit symbol format to COFF. - if (str8_match(symbol.name, str8_lit("__ImageBase"), 0)) { + if (str8_match(lnk_symbol_name_from_coff_symbol_idx(obj, reloc->isymbol), str8_lit("__ImageBase"), 0)) { symbol.value = task->image_base; } symbol_secnum = 0; @@ -4447,7 +4450,7 @@ THREAD_POOL_TASK_FUNC(lnk_flag_hotpatch_contribs_task) if (obj->hotpatch) { COFF_ParsedSymbol symbol; for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) { - symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx); + symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx); COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class); if (interp == COFF_SymbolValueInterp_Regular && COFF_SymbolType_IsFunc(symbol.type)) { LNK_SectionContrib *sc = task->sect_map[obj_idx][symbol.section_number-1]; @@ -4862,7 +4865,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_section_symbols_task) ProfBegin("Patch Section Symbols [%S]", obj->path); COFF_ParsedSymbol symbol; for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) { - symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx); + symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx); COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class); if (interp == COFF_SymbolValueInterp_Undefined) { if (symbol.storage_class == COFF_SymStorageClass_Section) { @@ -4885,7 +4888,8 @@ THREAD_POOL_TASK_FUNC(lnk_patch_section_symbols_task) } if (!is_referenced) { continue; } - LNK_Section *sect = lnk_section_table_search(task->sectab, symbol.name, symbol.value); + String8 symbol_name = lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx); + LNK_Section *sect = lnk_section_table_search(task->sectab, symbol_name, symbol.value); if (sect && (~sect->flags & COFF_SectionFlag_LnkRemove)) { if (~sect->flags & COFF_SectionFlag_MemDiscardable) { LNK_SectionContrib *first_sc = lnk_get_first_section_contrib(sect); @@ -4901,7 +4905,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_section_symbols_task) symbol16->storage_class = COFF_SymStorageClass_Static; } } else { - lnk_error_obj(LNK_Error_SectRefsDiscardedMemory, obj, "symbol %S (No. 0x%llx) references section with discard flag", symbol.name, symbol_idx); + lnk_error_obj(LNK_Error_SectRefsDiscardedMemory, obj, "symbol %S (No. 0x%llx) references section with discard flag", symbol_name, symbol_idx); } } else { U64 fallback_voff = 0; @@ -4929,7 +4933,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_section_symbols_task) symbol16->storage_class = COFF_SymStorageClass_Static; } - lnk_error_obj(LNK_Warning_UndefinedSectionSymbol, obj, "undefined section symbol %S (No. 0x%llx) refers to an image section that doesn't exist; patching to %#llx", symbol.name, symbol_idx, fallback_voff); + lnk_error_obj(LNK_Warning_UndefinedSectionSymbol, obj, "undefined section symbol %S (No. 0x%llx) refers to an image section that doesn't exist; patching to %#llx", symbol_name, symbol_idx, fallback_voff); } } } @@ -4955,7 +4959,7 @@ THREAD_POOL_TASK_FUNC(lnk_gather_base_reloc_pages_task) for EachIndex(reloc_idx, relocs.count) { COFF_Reloc *r = &relocs.v[reloc_idx]; - COFF_ParsedSymbol symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, r->isymbol); + COFF_ParsedSymbol symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, r->isymbol); COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol); if (symbol_interp == COFF_SymbolValueInterp_Abs) { continue; } @@ -4983,7 +4987,7 @@ THREAD_POOL_TASK_FUNC(lnk_gather_base_reloc_pages_task) switch (is_addr) { case 4: { if (task->is_large_addr_aware) { - lnk_error_obj(LNK_Error_LargeAddrAwareRequired, obj, "found out of range ADDR32 relocation for '%S', link with /LARGEADDRESSAWARE:NO", symbol.name); + lnk_error_obj(LNK_Error_LargeAddrAwareRequired, obj, "found out of range ADDR32 relocation for '%S', link with /LARGEADDRESSAWARE:NO", lnk_symbol_name_from_coff_symbol_idx(obj, r->isymbol)); } else { u64_list_push(arena, page->v.entries_addr32, reloc_voff); } diff --git a/src/linker/lnk_obj.c b/src/linker/lnk_obj.c index baa482f7..6b497992 100644 --- a/src/linker/lnk_obj.c +++ b/src/linker/lnk_obj.c @@ -125,13 +125,38 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) } // - // error check symbol table + // error check symbol table and cache name lengths for primary symbols // + U64 primary_symbol_count = 0; + { + COFF_ParsedSymbol symbol; + for (U64 symbol_idx = 0; symbol_idx < header.symbol_count; symbol_idx += 1 + symbol.aux_symbol_count) { + symbol = coff_parse_symbol_no_name(header, raw_coff_symbol_table, symbol_idx); + primary_symbol_count += 1; + } + } + + U64 name_block_count = CeilIntegerDiv(header.symbol_count, 64); + LNK_SymbolNameCache symbol_name_cache = { + .masks = push_array(arena, U64, name_block_count), + .block_bases = push_array_no_zero(arena, U32, name_block_count), + .name_sizes = push_array_no_zero(arena, U32, primary_symbol_count), + }; { COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(input->data, header.section_table_range).str; + U64 next_block = 0; + U32 name_count = 0; COFF_ParsedSymbol symbol; for (U64 symbol_idx = 0; symbol_idx < header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) { symbol = coff_parse_symbol(header, raw_coff_string_table, raw_coff_symbol_table, symbol_idx); + U64 block_idx = symbol_idx >> 6; + while (next_block <= block_idx) { + symbol_name_cache.block_bases[next_block++] = name_count; + } + if (symbol.name.size) { + symbol_name_cache.masks[block_idx] |= 1ull << (symbol_idx & 63); + symbol_name_cache.name_sizes[name_count++] = safe_cast_u32(symbol.name.size); + } COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class); if (interp == COFF_SymbolValueInterp_Regular) { if (symbol.section_number == 0 || symbol.section_number > header.section_count_no_null) { @@ -149,6 +174,9 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) } } } + while (next_block < name_block_count) { + symbol_name_cache.block_bases[next_block++] = name_count; + } } // @@ -161,7 +189,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) COFF_ParsedSymbol symbol; for (U64 symbol_idx = 0; symbol_idx < header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) { - symbol = coff_parse_symbol(header, raw_coff_string_table, raw_coff_symbol_table, symbol_idx); + symbol = coff_parse_symbol_no_name(header, raw_coff_symbol_table, symbol_idx); COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class); if (interp == COFF_SymbolValueInterp_Regular) { @@ -208,7 +236,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) } // extract COMDAT info for current section - COFF_ParsedSymbol symbol = coff_parse_symbol(header, raw_coff_string_table, raw_coff_symbol_table, symbol_idx); + COFF_ParsedSymbol symbol = coff_parse_symbol_no_name(header, raw_coff_symbol_table, symbol_idx); COFF_ComdatSelectType select = COFF_ComdatSelect_Null; U32 section_number = 0; coff_parse_secdef(symbol, header.is_big_obj, &select, §ion_number, 0, 0); @@ -247,7 +275,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) { COFF_ParsedSymbol symbol; for (U32 symbol_idx = 0; symbol_idx < header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) { - symbol = coff_parse_symbol(header, raw_coff_string_table, raw_coff_symbol_table, symbol_idx); + symbol = coff_parse_symbol_no_name(header, raw_coff_symbol_table, symbol_idx); COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol); if (interp == COFF_SymbolValueInterp_Regular && symbol.storage_class == COFF_SymStorageClass_Static && symbol.aux_symbol_count > 0) { COFF_ComdatSelectType selection = COFF_ComdatSelect_Null; @@ -335,6 +363,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) obj->path = push_str8_copy(arena, input->path); obj->header = header; obj->section_flags = section_flags; + obj->symbol_name_cache = symbol_name_cache; obj->comdats = comdats; obj->exclude_from_debug_info = input->exclude_from_debug_info; obj->hotpatch = hotpatch; @@ -426,7 +455,7 @@ THREAD_POOL_TASK_FUNC(lnk_input_coff_symbol_table) LNK_Obj *obj = task->objs[task_id]; COFF_ParsedSymbol symbol = {0}; for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) { - symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx); + symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx); COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol); switch (interp) { case COFF_SymbolValueInterp_Regular: { @@ -435,27 +464,27 @@ THREAD_POOL_TASK_FUNC(lnk_input_coff_symbol_table) if (*section.flags & COFF_SectionFlag_LnkRemove) { break; } - LNK_Symbol *defn = lnk_make_symbol(arena, symbol.name, obj, symbol_idx); + LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx); lnk_symbol_table_push_(task->symtab, arena, worker_id, defn); } } break; case COFF_SymbolValueInterp_Weak: { - LNK_Symbol *defn = lnk_make_symbol(arena, symbol.name, obj, symbol_idx); + LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx); lnk_symbol_table_push_(task->symtab, arena, worker_id, defn); } break; case COFF_SymbolValueInterp_Undefined: { if (symbol.storage_class == COFF_SymStorageClass_External) { - LNK_Symbol *defn = lnk_make_symbol(arena, symbol.name, obj, symbol_idx); + LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx); lnk_symbol_table_push_(task->symtab, arena, worker_id, defn); } } break; case COFF_SymbolValueInterp_Common: { - LNK_Symbol *defn = lnk_make_symbol(arena, symbol.name, obj, symbol_idx); + LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx); lnk_symbol_table_push_(task->symtab, arena, worker_id, defn); } break; case COFF_SymbolValueInterp_Abs: { if (symbol.storage_class == COFF_SymStorageClass_External) { - LNK_Symbol *defn = lnk_make_symbol(arena, symbol.name, obj, symbol_idx); + LNK_Symbol *defn = lnk_make_symbol(arena, lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx), obj, symbol_idx); lnk_symbol_table_push_(task->symtab, arena, worker_id, defn); } } break; @@ -473,7 +502,7 @@ lnk_symlinks_from_obj(Arena *arena, LNK_SymbolTable *symtab, LNK_Obj *obj) LNK_ObjSymbolRef *symlinks = push_array(arena, LNK_ObjSymbolRef, obj->header.section_count_no_null + 1); COFF_ParsedSymbol symbol = {0}; for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) { - symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx); + symbol = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx); COFF_SymbolValueInterpType interp = coff_interp_from_parsed_symbol(symbol); if (interp != COFF_SymbolValueInterp_Regular) { continue; } @@ -484,13 +513,14 @@ lnk_symlinks_from_obj(Arena *arena, LNK_SymbolTable *symtab, LNK_Obj *obj) // external symbols if (symbol.storage_class == COFF_SymStorageClass_External && symbol.aux_symbol_count == 0) { + String8 symbol_name = lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx); B32 can_set_symlink = (symlink->obj == 0 || symbol.value == 0); if (!can_set_symlink && symlink->obj == obj) { - COFF_ParsedSymbol leader = lnk_parsed_symbol_from_coff_symbol_idx(symlink->obj, symlink->symbol_idx); + COFF_ParsedSymbol leader = lnk_parsed_symbol_from_coff_symbol_idx_no_name(symlink->obj, symlink->symbol_idx); B32 leader_is_same_section = leader.section_number == symbol.section_number; B32 leader_is_static_anchor = (leader_is_same_section && leader.storage_class == COFF_SymStorageClass_Static && leader.aux_symbol_count == 0); - B32 leader_is_vftable = str8_starts_with(leader.name, str8_lit(MSCRT_VFTABLE_SYMBOL_PREFIX)); - B32 current_is_vftable = str8_starts_with(symbol.name, str8_lit(MSCRT_VFTABLE_SYMBOL_PREFIX)); + B32 leader_is_vftable = str8_starts_with(lnk_symbol_name_from_coff_symbol_idx(symlink->obj, symlink->symbol_idx), str8_lit(MSCRT_VFTABLE_SYMBOL_PREFIX)); + B32 current_is_vftable = str8_starts_with(symbol_name, str8_lit(MSCRT_VFTABLE_SYMBOL_PREFIX)); // prefer public symbols to local static anchors; prefer vftable public // symbols to other public symbols so ICF keeps vftables in their own color space @@ -498,7 +528,7 @@ lnk_symlinks_from_obj(Arena *arena, LNK_SymbolTable *symtab, LNK_Obj *obj) } if (can_set_symlink) { - LNK_SymbolHashTrie *link_symbol = lnk_symbol_table_search_(symtab, symbol.name); + LNK_SymbolHashTrie *link_symbol = lnk_symbol_table_search_(symtab, symbol_name); if (link_symbol) { *symlink = lnk_ref_from_symbol(link_symbol->symbol); } @@ -741,7 +771,7 @@ lnk_try_comdat_props_from_section_number(LNK_Obj *obj, U32 section_number, COFF_ Assert(section_number > 0); U32 symbol_idx = obj->comdats[section_number-1]; if (symbol_idx != max_U32) { - COFF_ParsedSymbol secdef = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx); + COFF_ParsedSymbol secdef = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx); coff_parse_secdef(secdef, obj->header.is_big_obj, select_out, section_number_out, section_length_out, check_sum_out); return 1; } @@ -757,19 +787,39 @@ lnk_coff_section_header_from_section_number(LNK_Obj *obj, U64 section_number) return §ion_table[sect_idx]; } -internal COFF_ParsedSymbol +internal force_inline COFF_ParsedSymbol +lnk_parsed_symbol_from_coff_symbol_idx_no_name(LNK_Obj *obj, U64 symbol_idx) +{ + return coff_parse_symbol_no_name(obj->header, lnk_coff_symbol_table_from_obj(obj), safe_cast_u32(symbol_idx)); +} + +internal force_inline String8 +lnk_symbol_name_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx) +{ + String8 result = {0}; + U64 block_idx = symbol_idx >> 6; + U64 bit = 1ull << (symbol_idx & 63); + U64 mask = obj->symbol_name_cache.masks[block_idx]; + if (mask & bit) { + U64 name_idx = obj->symbol_name_cache.block_bases[block_idx] + count_bits_set64(mask & (bit - 1)); + U64 name_size = obj->symbol_name_cache.name_sizes[name_idx]; + + String8 symbol_table = lnk_coff_symbol_table_from_obj(obj); + COFF_SymbolName *name = obj->header.is_big_obj ? &((COFF_Symbol32 *)symbol_table.str)[symbol_idx].name + : &((COFF_Symbol16 *)symbol_table.str)[symbol_idx].name; + U8 *name_ptr = name->long_name.zeroes == 0 + ? obj->data.str + obj->header.string_table_range.min + name->long_name.string_table_offset + : name->short_name; + result = str8(name_ptr, name_size); + } + return result; +} + +internal force_inline COFF_ParsedSymbol lnk_parsed_symbol_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx) { - String8 string_table = str8_substr(obj->data, obj->header.string_table_range); - String8 symbol_table = str8_substr(obj->data, obj->header.symbol_table_range); - - COFF_ParsedSymbol result = {0}; - if (obj->header.is_big_obj) { - result = coff_parse_symbol32(string_table, (COFF_Symbol32 *)symbol_table.str + symbol_idx); - } else { - result = coff_parse_symbol16(string_table, (COFF_Symbol16 *)symbol_table.str + symbol_idx); - } - + COFF_ParsedSymbol result = lnk_parsed_symbol_from_coff_symbol_idx_no_name(obj, symbol_idx); + result.name = lnk_symbol_name_from_coff_symbol_idx(obj, symbol_idx); return result; } diff --git a/src/linker/lnk_obj.h b/src/linker/lnk_obj.h index 1cba2e1c..7655072e 100644 --- a/src/linker/lnk_obj.h +++ b/src/linker/lnk_obj.h @@ -5,6 +5,13 @@ // --- Input ------------------------------------------------------------------- +typedef struct LNK_SymbolNameCache +{ + U64 *masks; + U32 *block_bases; + U32 *name_sizes; +} LNK_SymbolNameCache; + typedef struct LNK_Obj { String8 path; @@ -12,6 +19,7 @@ typedef struct LNK_Obj COFF_FileHeaderInfo header; COFF_SectionFlags *section_flags; + LNK_SymbolNameCache symbol_name_cache; // flags B8 hotpatch; @@ -148,7 +156,9 @@ internal U32List lnk_obj_collect_associated_sections(Arena *arena, LNK_ // --- Symbol & Section Helpers ------------------------------------------------ internal COFF_SectionHeader * lnk_coff_section_header_from_section_number(LNK_Obj *obj, U64 section_number); -internal COFF_ParsedSymbol lnk_parsed_symbol_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx); +internal force_inline COFF_ParsedSymbol lnk_parsed_symbol_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx); +internal force_inline COFF_ParsedSymbol lnk_parsed_symbol_from_coff_symbol_idx_no_name(LNK_Obj *obj, U64 symbol_idx); +internal force_inline String8 lnk_symbol_name_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx); internal U64 lnk_obj_sect_idx_from_section_number(LNK_Obj *obj, U64 section_number); internal U64 lnk_obj_section_number_from_sect_idx(LNK_Obj *obj, U64 sect_idx); internal String8 lnk_obj_section_name_from_section_number(LNK_Obj *obj, U64 section_number); diff --git a/src/linker/lnk_symbol_table.c b/src/linker/lnk_symbol_table.c index ea02e1d9..33557435 100644 --- a/src/linker/lnk_symbol_table.c +++ b/src/linker/lnk_symbol_table.c @@ -105,12 +105,12 @@ lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src) { B32 can_replace = 0; - COFF_ParsedSymbol dst_parsed = lnk_parsed_from_symbol(dst); - COFF_ParsedSymbol src_parsed = lnk_parsed_from_symbol(src); - COFF_SymbolValueInterpType dst_interp = lnk_interp_from_symbol(dst); - COFF_SymbolValueInterpType src_interp = lnk_interp_from_symbol(src); LNK_ObjSymbolRef dst_ref = lnk_ref_from_symbol(dst); LNK_ObjSymbolRef src_ref = lnk_ref_from_symbol(src); + COFF_ParsedSymbol dst_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(dst_ref.obj, dst_ref.symbol_idx); + COFF_ParsedSymbol src_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(src_ref.obj, src_ref.symbol_idx); + COFF_SymbolValueInterpType dst_interp = coff_interp_from_parsed_symbol(dst_parsed); + COFF_SymbolValueInterpType src_interp = coff_interp_from_parsed_symbol(src_parsed); LNK_Obj *dst_obj = dst_ref.obj; LNK_Obj *src_obj = src_ref.obj; @@ -338,9 +338,9 @@ lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src) internal void lnk_on_symbol_replace(LNK_Symbol *dst, LNK_Symbol *src) { - COFF_ParsedSymbol dst_parsed = lnk_parsed_from_symbol(dst); - COFF_SymbolValueInterpType dst_interp = lnk_interp_from_symbol(dst); LNK_ObjSymbolRef dst_ref = lnk_ref_from_symbol(dst); + COFF_ParsedSymbol dst_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(dst_ref.obj, dst_ref.symbol_idx); + COFF_SymbolValueInterpType dst_interp = coff_interp_from_parsed_symbol(dst_parsed); if (dst_interp == COFF_SymbolValueInterp_Regular) { // remove replaced section from the output @@ -537,7 +537,8 @@ lnk_parsed_from_symbol(LNK_Symbol *symbol) internal COFF_SymbolValueInterpType lnk_interp_from_symbol(LNK_Symbol *symbol) { - COFF_ParsedSymbol symbol_parsed = lnk_parsed_from_symbol(symbol); + LNK_ObjSymbolRef ref = lnk_ref_from_symbol(symbol); + COFF_ParsedSymbol symbol_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(ref.obj, ref.symbol_idx); return coff_interp_from_parsed_symbol(symbol_parsed); } @@ -662,7 +663,7 @@ lnk_resolve_weak_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_Ob goto exit; } - COFF_ParsedSymbol current_parsed = lnk_parsed_symbol_from_coff_symbol_idx(current_symbol.obj, current_symbol.symbol_idx); + COFF_ParsedSymbol current_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(current_symbol.obj, current_symbol.symbol_idx); COFF_SymbolValueInterpType current_interp = coff_interp_symbol(current_parsed.section_number, current_parsed.value, current_parsed.storage_class); if (current_interp == COFF_SymbolValueInterp_Weak) { // record visited symbol @@ -671,7 +672,7 @@ lnk_resolve_weak_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_Ob SLLQueuePush(sf, sl, s); // does weak symbol have a definition? - LNK_Symbol *defn_symbol = lnk_symbol_table_search(symtab, current_parsed.name); + LNK_Symbol *defn_symbol = lnk_symbol_table_search(symtab, lnk_symbol_name_from_coff_symbol_idx(current_symbol.obj, current_symbol.symbol_idx)); COFF_ParsedSymbol defn_parsed = lnk_parsed_from_symbol(defn_symbol); COFF_SymbolValueInterpType defn_interp = coff_interp_symbol(defn_parsed.section_number, defn_parsed.value, defn_parsed.storage_class); if (defn_interp != COFF_SymbolValueInterp_Weak) { @@ -682,19 +683,19 @@ lnk_resolve_weak_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_Ob COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(current_parsed, current_symbol.obj->header.is_big_obj); // no definition -- fallback to default symbol - COFF_ParsedSymbol tag_parsed = lnk_parsed_symbol_from_coff_symbol_idx(current_symbol.obj, weak_ext->tag_index); + COFF_ParsedSymbol tag_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(current_symbol.obj, weak_ext->tag_index); COFF_SymbolValueInterpType tag_interp = coff_interp_symbol(tag_parsed.section_number, tag_parsed.value, tag_parsed.storage_class); current_symbol = (LNK_ObjSymbolRef){ .obj = current_symbol.obj, .symbol_idx = weak_ext->tag_index }; if (weak_ext->characteristics == COFF_WeakExt_AntiDependency) { if (tag_interp == COFF_SymbolValueInterp_Undefined || tag_interp == COFF_SymbolValueInterp_Weak) { - LNK_Symbol *dep_symbol = lnk_symbol_table_search(symtab, tag_parsed.name); + LNK_Symbol *dep_symbol = lnk_symbol_table_search(symtab, lnk_symbol_name_from_coff_symbol_idx(current_symbol.obj, weak_ext->tag_index)); tag_interp = lnk_interp_from_symbol(dep_symbol); } if (tag_interp == COFF_SymbolValueInterp_Weak) { break; } } } else if (current_interp == COFF_SymbolValueInterp_Undefined) { - LNK_Symbol *defn_symbol = lnk_symbol_table_search(symtab, current_parsed.name); + LNK_Symbol *defn_symbol = lnk_symbol_table_search(symtab, lnk_symbol_name_from_coff_symbol_idx(current_symbol.obj, current_symbol.symbol_idx)); COFF_SymbolValueInterpType defn_interp = lnk_interp_from_symbol(defn_symbol); // unresolved undefined symbol @@ -719,7 +720,7 @@ internal B32 lnk_resolve_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_ObjSymbolRef *symbol_out) { B32 is_resolved = 1; - COFF_ParsedSymbol symbol_parsed = lnk_parsed_symbol_from_coff_symbol_idx(symbol.obj, symbol.symbol_idx); + COFF_ParsedSymbol symbol_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(symbol.obj, symbol.symbol_idx); COFF_SymbolValueInterpType symbol_interp = coff_interp_symbol(symbol_parsed.section_number, symbol_parsed.value, symbol_parsed.storage_class); switch (symbol_interp) { case COFF_SymbolValueInterp_Regular: { @@ -727,7 +728,7 @@ lnk_resolve_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_ObjSymb *symbol_out = lnk_obj_get_comdat_symlink(symbol.obj, symbol_parsed.section_number, &symlink) ? symlink : symbol; } break; case COFF_SymbolValueInterp_Weak: { - LNK_Symbol *defn = lnk_symbol_table_search(symtab, symbol_parsed.name); + LNK_Symbol *defn = lnk_symbol_table_search(symtab, lnk_symbol_name_from_coff_symbol_idx(symbol.obj, symbol.symbol_idx)); COFF_ParsedSymbol defn_parsed = lnk_parsed_from_symbol(defn); COFF_SymbolValueInterpType defn_interp = lnk_interp_from_symbol(defn); if (defn_interp != COFF_SymbolValueInterp_Undefined) { @@ -737,7 +738,7 @@ lnk_resolve_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_ObjSymb } } break; case COFF_SymbolValueInterp_Undefined: { - LNK_Symbol *defn = lnk_symbol_table_search(symtab, symbol_parsed.name); + LNK_Symbol *defn = lnk_symbol_table_search(symtab, lnk_symbol_name_from_coff_symbol_idx(symbol.obj, symbol.symbol_idx)); if (defn) { *symbol_out = lnk_ref_from_symbol(defn); } else { @@ -745,12 +746,12 @@ lnk_resolve_symbol(LNK_SymbolTable *symtab, LNK_ObjSymbolRef symbol, LNK_ObjSymb } } break; case COFF_SymbolValueInterp_Common: { - LNK_Symbol *defn = lnk_symbol_table_search(symtab, symbol_parsed.name); + LNK_Symbol *defn = lnk_symbol_table_search(symtab, lnk_symbol_name_from_coff_symbol_idx(symbol.obj, symbol.symbol_idx)); *symbol_out = lnk_ref_from_symbol(defn); } break; case COFF_SymbolValueInterp_Abs: { if (symbol_parsed.storage_class == COFF_SymStorageClass_External) { - LNK_Symbol *defn = lnk_symbol_table_search(symtab, symbol_parsed.name); + LNK_Symbol *defn = lnk_symbol_table_search(symtab, lnk_symbol_name_from_coff_symbol_idx(symbol.obj, symbol.symbol_idx)); *symbol_out = lnk_ref_from_symbol(defn); } else { *symbol_out = symbol; @@ -769,12 +770,12 @@ THREAD_POOL_TASK_FUNC(lnk_replace_weak_with_default_symbol_task) for EachIndex(i, c->count) { LNK_Symbol *symbol = c->v[i].symbol; LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol); - COFF_ParsedSymbol symbol_parsed = lnk_parsed_from_symbol(symbol); + COFF_ParsedSymbol symbol_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(symbol_ref.obj, symbol_ref.symbol_idx); COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed); if (symbol_interp == COFF_SymbolValueInterp_Weak) { LNK_ObjSymbolRef resolve = {0}; if (lnk_resolve_weak_symbol(symtab, symbol_ref, &resolve)) { - COFF_ParsedSymbol resolve_parsed = lnk_parsed_symbol_from_coff_symbol_idx(resolve.obj, resolve.symbol_idx); + COFF_ParsedSymbol resolve_parsed = lnk_parsed_symbol_from_coff_symbol_idx_no_name(resolve.obj, resolve.symbol_idx); COFF_SymbolValueInterpType resolve_interp = coff_interp_from_parsed_symbol(resolve_parsed); if (resolve_interp == COFF_SymbolValueInterp_Weak) { COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(resolve_parsed, symbol_ref.obj->header.is_big_obj);