From 80967fac120653d52d094aa90ffe0087219c6614 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Tue, 9 Sep 2025 19:28:44 -0700 Subject: [PATCH] pre-parse section names and flag debug info sections --- src/linker/lnk.c | 49 ++++++++++++++--------------- src/linker/lnk.h | 3 +- src/linker/lnk_debug_info.c | 9 ++---- src/linker/lnk_obj.c | 61 +++++++++++++++++++------------------ src/linker/lnk_obj.h | 1 - 5 files changed, 59 insertions(+), 64 deletions(-) diff --git a/src/linker/lnk.c b/src/linker/lnk.c index 2ec33142..05f4da83 100644 --- a/src/linker/lnk.c +++ b/src/linker/lnk.c @@ -2042,10 +2042,9 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer String8 debug_strings = {0}; for EachIndex(sect_idx, obj->header.section_count_no_null) { - if (lnk_is_coff_section_debug(obj, sect_idx)) { - continue; - } COFF_SectionHeader *section_header = §ion_table[sect_idx]; + if (section_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { continue; } + String8 section_name = coff_name_from_section_header(string_table, section_header); U64 section_number = sect_idx+1; COFF_RelocArray relocs = lnk_coff_relocs_from_section_header(obj, section_header); @@ -2199,9 +2198,9 @@ lnk_opt_ref(TP_Context *tp, LNK_SymbolTable *symtab, LNK_Config *config, LNK_Obj COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(obj, section_number); // is section eligible for walking? - if (lnk_is_coff_section_debug(obj, sect_idx)) { continue; } - if (section_header->flags & COFF_SectionFlag_LnkRemove) { continue; } - if (section_header->flags & COFF_SectionFlag_LnkCOMDAT) { continue; } + if (section_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { continue; } + if (section_header->flags & COFF_SectionFlag_LnkRemove) { continue; } + if (section_header->flags & COFF_SectionFlag_LnkCOMDAT) { continue; } // divide relocs and push task for each reloc block COFF_RelocArray relocs = lnk_coff_reloc_info_from_section_number(obj, section_number); @@ -2283,9 +2282,9 @@ lnk_opt_ref(TP_Context *tp, LNK_SymbolTable *symtab, LNK_Config *config, LNK_Obj COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(ref_obj, section_number); // is section eligible for walking? - if (section_header->flags & COFF_SectionFlag_LnkRemove) { continue; } - if (section_header->flags & LNK_SECTION_FLAG_IS_LIVE) { continue; } - if (lnk_is_coff_section_debug(ref_obj, section_number-1)) { continue; } + if (section_header->flags & COFF_SectionFlag_LnkRemove) { continue; } + if (section_header->flags & LNK_SECTION_FLAG_IS_LIVE) { continue; } + if (section_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { continue; } // mark section section_header->flags |= LNK_SECTION_FLAG_IS_LIVE; @@ -2315,8 +2314,7 @@ lnk_opt_ref(TP_Context *tp, LNK_SymbolTable *symtab, LNK_Config *config, LNK_Obj U32 section_number = sect_idx+1; COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(obj, section_number); - - if (lnk_is_coff_section_debug(obj, sect_idx)) { continue; } + if (section_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { continue; } // remove unreferenced sections if (~section_header->flags & LNK_SECTION_FLAG_IS_LIVE && section_header->flags & COFF_SectionFlag_LnkCOMDAT) { @@ -2523,7 +2521,8 @@ THREAD_POOL_TASK_FUNC(lnk_flag_debug_symbols_task) symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx); COFF_SymbolValueInterpType interp = coff_interp_symbol(symbol.section_number, symbol.value, symbol.storage_class); if (interp == COFF_SymbolValueInterp_Regular) { - if (lnk_is_coff_section_debug(obj, symbol.section_number-1)) { + COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(obj, symbol.section_number); + if (section_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { task->u.patch_symtabs.was_symbol_patched[obj_idx][symbol_idx] = 1; } } @@ -2846,7 +2845,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher) if (section_header->flags & COFF_SectionFlag_CntUninitializedData) { continue; } // get section bytes (special case debug info because it is not copied to the image) - String8 data = lnk_is_coff_section_debug(obj, sect_idx) ? obj->data : task->image_data; + String8 data = section_header->flags & LNK_SECTION_FLAG_DEBUG_INFO ? obj->data : task->image_data; Rng1U64 section_frange = rng_1u64(section_header->foff, section_header->foff + section_header->fsize); String8 section_data = str8_substr(data, section_frange); @@ -2877,7 +2876,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_reloc_patcher) 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 (!lnk_is_coff_section_debug(obj, sect_idx)) { + if (~section_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { 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); } @@ -3462,7 +3461,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_file_offsets_and_sizes_in_obj_section_headers_ta for (U64 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) { COFF_SectionHeader *sect_header = §ion_table[sect_idx]; B32 patch_section_header = (~sect_header->flags & COFF_SectionFlag_LnkRemove) && - !lnk_is_coff_section_debug(obj, sect_idx); + (~sect_header->flags & LNK_SECTION_FLAG_DEBUG_INFO); if (patch_section_header) { LNK_SectionContrib *sc = task->sect_map[obj_idx][sect_idx]; LNK_Section *sect = task->image_sects.v[sc->u.sect_idx]; @@ -4735,17 +4734,15 @@ lnk_build_rad_map(Arena *arena, String8 image_data, LNK_Config *config, U64 objs LNK_Obj *obj = objs[obj_idx]; COFF_SectionHeader *section_table = str8_deserial_get_raw_ptr(obj->data, obj->header.section_table_range.min, 0); for (U64 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) { - if (lnk_is_coff_section_debug(obj, sect_idx)) { - COFF_SectionHeader *section_header = §ion_table[sect_idx]; - if (~section_header->flags & COFF_SectionFlag_LnkRemove) { - LNK_Lib *lib = lnk_obj_get_lib(obj); - if (lib) { - String8 lib_name = str8_chop_last_dot(str8_skip_last_slash(lib->path)); - String8 obj_name = str8_skip_last_slash(obj->path); - str8_list_pushf(arena, &map, "%S(%S) SECT%X\n", lib_name, obj_name, sect_idx+1); - } else { - str8_list_pushf(arena, &map, "%S SECT%X\n", obj->path, sect_idx+1); - } + COFF_SectionHeader *section_header = §ion_table[sect_idx]; + if (~section_header->flags & COFF_SectionFlag_LnkRemove && section_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { + LNK_Lib *lib = lnk_obj_get_lib(obj); + if (lib) { + String8 lib_name = str8_chop_last_dot(str8_skip_last_slash(lib->path)); + String8 obj_name = str8_skip_last_slash(obj->path); + str8_list_pushf(arena, &map, "%S(%S) SECT%X\n", lib_name, obj_name, sect_idx+1); + } else { + str8_list_pushf(arena, &map, "%S SECT%X\n", obj->path, sect_idx+1); } } } diff --git a/src/linker/lnk.h b/src/linker/lnk.h index 4cf1404c..a3f7909c 100644 --- a/src/linker/lnk.h +++ b/src/linker/lnk.h @@ -73,7 +73,8 @@ typedef struct LNK_Inputer #define LNK_IMPORT_STUB "*** RAD_IMPORT_STUB ***" #define LNK_NULL_SYMBOL "*** RAD_NULL_SYMBOL ***" -#define LNK_SECTION_FLAG_IS_LIVE (1 << 0) +#define LNK_SECTION_FLAG_IS_LIVE (1 << 0) +#define LNK_SECTION_FLAG_DEBUG_INFO (1 << 1) typedef struct LNK_ImportTables { diff --git a/src/linker/lnk_debug_info.c b/src/linker/lnk_debug_info.c index b2de09a1..1e99fa7f 100644 --- a/src/linker/lnk_debug_info.c +++ b/src/linker/lnk_debug_info.c @@ -2934,12 +2934,9 @@ THREAD_POOL_TASK_FUNC(lnk_push_dbi_sec_contrib_task) for (U64 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) { COFF_SectionHeader *obj_sect_header = &obj_section_table[sect_idx]; - if (obj_sect_header->flags & COFF_SectionFlag_LnkRemove) { - continue; - } - if (lnk_is_coff_section_debug(obj, sect_idx)) { - continue; - } + if (obj_sect_header->flags & COFF_SectionFlag_LnkInfo) { continue; } + if (obj_sect_header->flags & COFF_SectionFlag_LnkRemove) { continue; } + if (obj_sect_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { continue; } U64 sect_number; String8 sect_data; diff --git a/src/linker/lnk_obj.c b/src/linker/lnk_obj.c index 80383349..d16155be 100644 --- a/src/linker/lnk_obj.c +++ b/src/linker/lnk_obj.c @@ -259,6 +259,19 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) } } } + + // + // mark debug info sections + // + { + for EachIndex(sect_idx, header.section_count_no_null) { + COFF_SectionHeader *sect_header = &coff_section_table[sect_idx]; + String8 sect_name = str8_cstring_capped(sect_header->name, sect_header->name + sizeof(sect_header->name)); + if (str8_starts_with(sect_name, str8_lit(".debug$"))) { + sect_header->flags |= LNK_SECTION_FLAG_DEBUG_INFO; + } + } + } B8 hotpatch = 0; if (header.machine == COFF_MachineType_X64) { @@ -271,25 +284,27 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) Temp scratch = scratch_begin(&arena, 1); CV_Symbol comp_symbol = {0}; - for (U64 sect_idx = 0; sect_idx < header.section_count_no_null; sect_idx += 1) { + for EachIndex(sect_idx, header.section_count_no_null) { COFF_SectionHeader *sect_header = &coff_section_table[sect_idx]; - String8 name = str8_cstring_capped(sect_header->name, sect_header->name+sizeof(sect_header->name)); - if (str8_match(name, str8_lit(".debug$S"), 0)) { - Temp temp = temp_begin(scratch.arena); - String8 debug_s_data = str8_substr(input->data, rng_1u64(sect_header->foff, sect_header->foff+sect_header->fsize)); - CV_DebugS debug_s = cv_parse_debug_s(temp.arena, debug_s_data); - for (String8Node *symbols_n = debug_s.data_list[CV_C13SubSectionIdxKind_Symbols].first; symbols_n != 0; symbols_n = symbols_n->next) { - CV_SymbolList symbol_list = {0}; - cv_parse_symbol_sub_section_capped(scratch.arena, &symbol_list, 0, symbols_n->string, CV_SymbolAlign, 2); - if (symbol_list.first->data.kind == CV_SymKind_COMPILE3) { - comp_symbol = symbol_list.first->data; - goto found_comp_symbol; - } else if (symbol_list.last->data.kind == CV_SymKind_COMPILE3) { - comp_symbol = symbol_list.last->data; - goto found_comp_symbol; + if (sect_header->flags & LNK_SECTION_FLAG_DEBUG_INFO) { + String8 name = str8_cstring_capped(sect_header->name, sect_header->name+sizeof(sect_header->name)); + if (str8_match(name, str8_lit(".debug$S"), 0)) { + Temp temp = temp_begin(scratch.arena); + String8 debug_s_data = str8_substr(input->data, rng_1u64(sect_header->foff, sect_header->foff+sect_header->fsize)); + CV_DebugS debug_s = cv_parse_debug_s(temp.arena, debug_s_data); + for EachNode(symbols_n, String8Node, debug_s.data_list[CV_C13SubSectionIdxKind_Symbols].first) { + CV_SymbolList symbol_list = {0}; + cv_parse_symbol_sub_section_capped(scratch.arena, &symbol_list, 0, symbols_n->string, CV_SymbolAlign, 2); + if (symbol_list.first->data.kind == CV_SymKind_COMPILE3) { + comp_symbol = symbol_list.first->data; + goto found_comp_symbol; + } else if (symbol_list.last->data.kind == CV_SymKind_COMPILE3) { + comp_symbol = symbol_list.last->data; + goto found_comp_symbol; + } } + temp_end(temp); } - temp_end(temp); } } found_comp_symbol:; @@ -556,20 +571,6 @@ lnk_try_comdat_props_from_section_number(LNK_Obj *obj, U32 section_number, COFF_ return 0; } -internal B32 -lnk_is_coff_section_debug(LNK_Obj *obj, U64 sect_idx) -{ - String8 string_table = str8_substr(obj->data, obj->header.string_table_range); - COFF_SectionHeader *section_header = lnk_coff_section_header_from_section_number(obj, sect_idx+1); - - String8 full_name = coff_name_from_section_header(string_table, section_header); - String8 name, postfix; - coff_parse_section_name(full_name, &name, &postfix); - - B32 is_debug = str8_match(name, str8_lit(".debug"), 0); - return is_debug; -} - internal COFF_ParsedSymbol lnk_parsed_symbol_from_coff_symbol_idx(LNK_Obj *obj, U64 symbol_idx) { diff --git a/src/linker/lnk_obj.h b/src/linker/lnk_obj.h index 3783f72f..9fca1cb5 100644 --- a/src/linker/lnk_obj.h +++ b/src/linker/lnk_obj.h @@ -121,7 +121,6 @@ internal COFF_SectionHeader * lnk_coff_section_table_from_obj(LNK_Obj *obj); internal String8 lnk_coff_string_table_from_obj(LNK_Obj *obj); internal String8 lnk_coff_symbol_table_from_obj(LNK_Obj *obj); internal B32 lnk_try_comdat_props_from_section_number(LNK_Obj *obj, U32 section_number, COFF_ComdatSelectType *select_out, U32 *section_number_out, U32 *section_length_out, U32 *check_sum_out); -internal B32 lnk_is_coff_section_debug(LNK_Obj *obj, U64 sect_idx); // --- Helpers -----------------------------------------------------------------