From 37689b2e4a20f6b33442d280f36fdad8502a68f5 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Tue, 27 May 2025 14:41:16 -0700 Subject: [PATCH] section collector --- src/linker/lnk_debug_info.c | 11 +++++++--- src/linker/lnk_debug_info.h | 1 + src/linker/lnk_obj.c | 40 ++++++++++++++++++++++++++++--------- src/linker/lnk_obj.h | 11 ++++++++-- 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/linker/lnk_debug_info.c b/src/linker/lnk_debug_info.c index 708a9e93..4e5973ff 100644 --- a/src/linker/lnk_debug_info.c +++ b/src/linker/lnk_debug_info.c @@ -373,9 +373,9 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, String8List lib_dir ProfBegin("Collect CodeView"); // TODO: fix memory leak, we need a Temp wrapper for pool arena B32 collect_discarded_flag = 0; - String8List *debug_s_list_arr = lnk_collect_obj_chunks_parallel(tp, tp_arena, obj_count, obj_arr, str8_lit(".debug"), str8_lit("S"), collect_discarded_flag); - String8List *debug_p_list_arr = lnk_collect_obj_chunks_parallel(tp, tp_arena, obj_count, obj_arr, str8_lit(".debug"), str8_lit("P"), collect_discarded_flag); - String8List *debug_t_list_arr = lnk_collect_obj_chunks_parallel(tp, tp_arena, obj_count, obj_arr, str8_lit(".debug"), str8_lit("T"), collect_discarded_flag); + String8List *debug_s_list_arr = lnk_collect_obj_sections(tp, tp_arena, obj_count, obj_arr, str8_lit(".debug$S"), collect_discarded_flag); + String8List *debug_p_list_arr = lnk_collect_obj_sections(tp, tp_arena, obj_count, obj_arr, str8_lit(".debug$P"), collect_discarded_flag); + String8List *debug_t_list_arr = lnk_collect_obj_sections(tp, tp_arena, obj_count, obj_arr, str8_lit(".debug$T"), collect_discarded_flag); ProfEnd(); if (lnk_get_log_status(LNK_Log_Debug) || PROFILE_TELEMETRY) { @@ -3269,9 +3269,13 @@ lnk_build_pdb(TP_Context *tp, Rng1U64Array image_section_file_ranges = {0}; image_section_file_ranges.count = image_section_table_count; image_section_file_ranges.v = push_array(scratch.arena, Rng1U64, image_section_table_count); + Rng1U64Array image_section_virt_ranges = {0}; + image_section_virt_ranges.count = image_section_table_count; + image_section_virt_ranges.v = push_array(scratch.arena, Rng1U64, image_section_table_count); for (U64 i = 0; i < image_section_table_count; i += 1) { COFF_SectionHeader *sect_header = image_section_table[i]; image_section_file_ranges.v[i] = rng_1u64(sect_header->foff, sect_header->foff + sect_header->fsize); + image_section_virt_ranges.v[i] = rng_1u64(sect_header->voff, sect_header->voff + sect_header->vsize); } LNK_PushDbiSecContribTaskData task = {0}; @@ -3280,6 +3284,7 @@ lnk_build_pdb(TP_Context *tp, task.sc_list = push_array(scratch.arena, PDB_DbiSectionContribList, obj_count); task.image_data = image_data; task.image_section_file_ranges = image_section_file_ranges; + task.image_section_virt_ranges = image_section_virt_ranges; tp_for_parallel(tp, tp_arena, obj_count, lnk_push_dbi_sec_contrib_task, &task); dbi_sec_list_concat_arr(&pdb->dbi->sec_contrib_list, obj_count, task.sc_list); diff --git a/src/linker/lnk_debug_info.h b/src/linker/lnk_debug_info.h index 7188830e..2bdc9aac 100644 --- a/src/linker/lnk_debug_info.h +++ b/src/linker/lnk_debug_info.h @@ -317,6 +317,7 @@ typedef struct PDB_DbiSectionContribList *sc_list; String8 image_data; Rng1U64Array image_section_file_ranges; + Rng1U64Array image_section_virt_ranges; } LNK_PushDbiSecContribTaskData; typedef struct diff --git a/src/linker/lnk_obj.c b/src/linker/lnk_obj.c index f9e7b7d1..3c8895f8 100644 --- a/src/linker/lnk_obj.c +++ b/src/linker/lnk_obj.c @@ -357,19 +357,41 @@ lnk_section_header_from_section_number(LNK_Obj *obj, U64 section_number) return 0; } -internal String8List * -lnk_collect_obj_chunks_parallel(TP_Context *tp, TP_Arena *arena, U64 obj_count, LNK_Obj **obj_arr, String8 name, String8 postfix, B32 collect_discarded) +internal +THREAD_POOL_TASK_FUNC(lnk_collect_obj_chunks_task) { - NotImplemented; - return 0; + LNK_SectionCollector *task = raw_task; + LNK_Obj *obj = task->objs[task_id]; + + COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(obj->data, obj->header.section_table_range).str; + String8 string_table = str8_substr(obj->data, obj->header.string_table_range); + for (U32 sect_idx = 0; sect_idx < obj->header.section_count_no_null; sect_idx += 1) { + COFF_SectionHeader *section_header = §ion_table[sect_idx]; + + if (section_header->flags & COFF_SectionFlag_LnkRemove) { + if (!task->collect_discarded) { + continue; + } + } + + String8 section_name = coff_name_from_section_header(string_table, section_header); + if (str8_match(section_name, task->name, 0)) { + String8 section_data = str8_substr(obj->data, rng_1u64(section_header->foff, section_header->foff + section_header->fsize)); + str8_list_push(arena, &task->out_lists[task_id], section_data); + } + } } -internal String8List -lnk_collect_obj_chunks(Arena *arena, LNK_Obj *obj, String8 name, String8 postfix, B32 collect_discarded) +internal String8List * +lnk_collect_obj_sections(TP_Context *tp, TP_Arena *arena, U64 objs_count, LNK_Obj **objs, String8 name, B32 collect_discarded) { - NotImplemented; - String8List result = {0}; - return result; + LNK_SectionCollector task = {0}; + task.objs = objs; + task.name = name; + task.collect_discarded = collect_discarded; + task.out_lists = push_array(arena->v[0], String8List, objs_count); + tp_for_parallel(tp, arena, objs_count, lnk_collect_obj_chunks_task, &task); + return task.out_lists; } internal void diff --git a/src/linker/lnk_obj.h b/src/linker/lnk_obj.h index 093a1334..3f374609 100644 --- a/src/linker/lnk_obj.h +++ b/src/linker/lnk_obj.h @@ -81,6 +81,14 @@ typedef struct LNK_SymbolList *undef_lists; } LNK_InputCoffSymbolTable; +typedef struct +{ + LNK_Obj **objs; + String8 name; + B32 collect_discarded; + String8List *out_lists; +} LNK_SectionCollector; + //////////////////////////////// internal void lnk_error_obj(LNK_ErrorCode code, LNK_Obj *obj, char *fmt, ...); @@ -105,8 +113,7 @@ internal COFF_SectionHeader * lnk_coff_section_header_from_section_number(LNK_Ob //////////////////////////////// -internal String8List * lnk_collect_obj_chunks_parallel(TP_Context *tp, TP_Arena *arena, U64 obj_count, LNK_Obj **obj_arr, String8 name, String8 postfix, B32 collect_discarded); -internal String8List lnk_collect_obj_chunks(Arena *arena, LNK_Obj *obj, String8 name, String8 postfix, B32 collect_discarded); +internal String8List * lnk_collect_obj_sections(TP_Context *tp, TP_Arena *arena, U64 objs_count, LNK_Obj **objs, String8 name, B32 collect_discarded); ////////////////////////////////