From bbb825adf446f45a5fe66aec6127fe70c782b65f Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Wed, 11 Jun 2025 09:08:31 -0700 Subject: [PATCH] extract hotpatch flag from compile symbol --- src/linker/codeview_ext/codeview.c | 11 ++++++-- src/linker/codeview_ext/codeview.h | 1 + src/linker/lnk_obj.c | 40 ++++++++++++++++++++++++++++++ src/linker/lnk_obj.h | 1 + 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/linker/codeview_ext/codeview.c b/src/linker/codeview_ext/codeview.c index b932a4be..af4aeba7 100644 --- a/src/linker/codeview_ext/codeview.c +++ b/src/linker/codeview_ext/codeview.c @@ -1213,9 +1213,10 @@ cv_str8_list_from_debug_t_parallel(TP_Context *tp, Arena *arena, CV_DebugT debug // $$Symbols internal void -cv_parse_symbol_sub_section(Arena *arena, CV_SymbolList *list, U64 offset_base, String8 data, U64 align) +cv_parse_symbol_sub_section_capped(Arena *arena, CV_SymbolList *list, U64 offset_base, String8 data, U64 align, U64 cap) { - for (U64 cursor = 0, opl = data.size; cursor < opl; ) { + U64 count = 0; + for (U64 cursor = 0, opl = data.size; cursor < opl && count < cap; count += 1) { // read symbol header CV_SymbolHeader header; cursor += str8_deserial_read_struct(data, cursor, &header); @@ -1249,6 +1250,12 @@ cv_parse_symbol_sub_section(Arena *arena, CV_SymbolList *list, U64 offset_base, } } +internal void +cv_parse_symbol_sub_section(Arena *arena, CV_SymbolList *list, U64 offset_base, String8 data, U64 align) +{ + cv_parse_symbol_sub_section_capped(arena, list, offset_base, data, align, max_U64); +} + internal CV_SymbolList cv_symbol_list_from_data_list(Arena *arena, String8List data_list, U64 align) { diff --git a/src/linker/codeview_ext/codeview.h b/src/linker/codeview_ext/codeview.h index d4b4ac4e..3b0315ad 100644 --- a/src/linker/codeview_ext/codeview.h +++ b/src/linker/codeview_ext/codeview.h @@ -432,6 +432,7 @@ internal String8List cv_str8_list_from_debug_t_parallel(TP_Context *tp, Arena *a //~ Sub Section helpers // $$Symbols +internal void cv_parse_symbol_sub_section_capped(Arena *arena, CV_SymbolList *list, U64 offset_base, String8 data, U64 align, U64 cap); internal void cv_parse_symbol_sub_section(Arena *arena, CV_SymbolList *list, U64 offset_base, String8 data, U64 align); internal void cv_symbol_list_push_node(CV_SymbolList *list, CV_SymbolNode *node); internal CV_SymbolNode * cv_symbol_list_push(Arena *arena, CV_SymbolList *list); diff --git a/src/linker/lnk_obj.c b/src/linker/lnk_obj.c index 40540dde..16879a0d 100644 --- a/src/linker/lnk_obj.c +++ b/src/linker/lnk_obj.c @@ -224,6 +224,45 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) scratch_end(scratch); } + + // + // Extract obj features from compile symbol in .debug$S + // + B8 hotpatch = 0; + { + Temp scratch = scratch_begin(&arena, 1); + + CV_Symbol comp_symbol = {0}; + for (U64 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) { + COFF_SectionHeader *sect_header = &coff_section_table[sect_idx]; + String8 name = str8_cstring_capped_reverse(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; + } + } + temp_end(temp); + } + } + found_comp_symbol:; + + if (comp_symbol.kind == CV_SymKind_COMPILE3 && comp_symbol.data.size >= sizeof(CV_SymCompile3)) { + CV_SymCompile3 *comp = (CV_SymCompile3 *)comp_symbol.data.str; + hotpatch = !!(comp->flags & CV_Compile3Flag_HotPatch); + } + + scratch_end(scratch); + } // fill out obj obj->data = input->data; @@ -232,6 +271,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer) obj->input_idx = obj_idx; obj->header = header; obj->comdats = comdats; + obj->hotpatch = hotpatch; ProfEnd(); } diff --git a/src/linker/lnk_obj.h b/src/linker/lnk_obj.h index 436c155d..3f79365c 100644 --- a/src/linker/lnk_obj.h +++ b/src/linker/lnk_obj.h @@ -13,6 +13,7 @@ typedef struct LNK_Obj U32 input_idx; COFF_FileHeaderInfo header; U32 *comdats; + B8 hotpatch; } LNK_Obj; typedef struct LNK_ObjNode