diff --git a/src/lib_raddbgi_make/raddbgi_make.c b/src/lib_raddbgi_make/raddbgi_make.c index c2b1d974..d7461d08 100644 --- a/src/lib_raddbgi_make/raddbgi_make.c +++ b/src/lib_raddbgi_make/raddbgi_make.c @@ -945,7 +945,29 @@ rdim_bake_section_list_push_new(RDIM_Arena *arena, RDIM_BakeSectionList *list, v return section; } -//- rjf: interned string building +//- rjf: interned string map reading/writing + +RDI_PROC RDI_U32 +rdim_idx_from_baked_string(RDIM_BakeStringMap *map, RDIM_String8 string) +{ + RDI_U64 hash = rdi_hash(string.RDIM_String8_BaseMember, string.RDIM_String8_SizeMember); + RDI_U64 slot_idx = hash%map->slots_count; + + // rjf: find existing node + RDIM_BakeStringNode *node = 0; + for(RDIM_BakeStringNode *n = map->slots[slot_idx]; n != 0; n = n->hash_next) + { + if(n->hash == hash && rdim_str8_match(n->string, string, 0)) + { + node = n; + break; + } + } + + // rjf: node -> index + RDI_U32 result = node ? node->idx : 0; + return result; +} RDI_PROC RDI_U32 rdim_bake_string(RDIM_Arena *arena, RDIM_BakeStringMap *map, RDIM_String8 string) diff --git a/src/lib_raddbgi_make/raddbgi_make.h b/src/lib_raddbgi_make/raddbgi_make.h index 1e405bdf..a51d9d4f 100644 --- a/src/lib_raddbgi_make/raddbgi_make.h +++ b/src/lib_raddbgi_make/raddbgi_make.h @@ -1063,7 +1063,8 @@ RDI_PROC void rdim_location_set_push_case(RDIM_Arena *arena, RDIM_ScopeChunkList RDI_PROC RDIM_BakeSection *rdim_bake_section_list_push(RDIM_Arena *arena, RDIM_BakeSectionList *list); RDI_PROC RDIM_BakeSection *rdim_bake_section_list_push_new(RDIM_Arena *arena, RDIM_BakeSectionList *list, void *data, RDI_U64 size, RDI_DataSectionTag tag); -//- rjf: interned string building +//- rjf: interned string map reading/writing +RDI_PROC RDI_U32 rdim_idx_from_baked_string(RDIM_BakeStringMap *map, RDIM_String8 string); RDI_PROC RDI_U32 rdim_bake_string(RDIM_Arena *arena, RDIM_BakeStringMap *map, RDIM_String8 string); //- rjf: interned index run building diff --git a/src/raddbgi_from_pdb/raddbgi_from_pdb.c b/src/raddbgi_from_pdb/raddbgi_from_pdb.c index af18e342..f1ba7813 100644 --- a/src/raddbgi_from_pdb/raddbgi_from_pdb.c +++ b/src/raddbgi_from_pdb/raddbgi_from_pdb.c @@ -605,6 +605,62 @@ p2r_comp_unit_contributions_parse_task__entry_point(Arena *arena, void *p) return out; } +//////////////////////////////// +//~ rjf: Link Name Map Building Task + +internal void * +p2r_link_name_map_build_task__entry_point(Arena *arena, void *p) +{ + P2R_LinkNameMapBuildIn *in = (P2R_LinkNameMapBuildIn *)p; + CV_RecRange *rec_ranges_first = in->sym->sym_ranges.ranges; + CV_RecRange *rec_ranges_opl = rec_ranges_first + in->sym->sym_ranges.count; + for(CV_RecRange *rec_range = rec_ranges_first; + rec_range < rec_ranges_opl; + rec_range += 1) + { + //- rjf: unpack symbol range info + CV_SymKind kind = rec_range->hdr.kind; + U64 header_struct_size = cv_header_struct_size_from_sym_kind(kind); + U8 *sym_first = in->sym->data.str + rec_range->off + 2; + U8 *sym_opl = sym_first + rec_range->hdr.size; + + //- rjf: skip bad ranges + if(sym_opl > in->sym->data.str + in->sym->data.size || sym_first + header_struct_size > in->sym->data.str + in->sym->data.size) + { + continue; + } + + //- rjf: consume symbol + switch(kind) + { + default:{}break; + case CV_SymKind_PUB32: + { + // rjf: unpack sym + CV_SymPub32 *pub32 = (CV_SymPub32 *)sym_first; + String8 name = str8_cstring_capped(pub32+1, sym_opl); + COFF_SectionHeader *section = (0 < pub32->sec && pub32->sec <= in->coff_sections->count) ? &in->coff_sections->sections[pub32->sec-1] : 0; + U64 voff = 0; + if(section != 0) + { + voff = section->voff + pub32->off; + } + + // rjf: commit to link name map + U64 hash = p2r_hash_from_voff(voff); + U64 bucket_idx = hash%in->link_name_map->buckets_count; + P2R_LinkNameNode *node = push_array(arena, P2R_LinkNameNode, 1); + SLLStackPush(in->link_name_map->buckets[bucket_idx], node); + node->voff = voff; + node->name = name; + in->link_name_map->link_name_count += 1; + in->link_name_map->bucket_collision_count += (node->next != 0); + }break; + } + } + return 0; +} + //////////////////////////////// //~ rjf: Type Parsing/Conversion Tasks @@ -2068,6 +2124,22 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) } } + ////////////////////////////////////////////////////////////// + //- rjf: kick off link name map production + // + P2R_LinkNameMap link_name_map__in_progress = {0}; + P2R_LinkNameMapBuildIn link_name_map_build_in = {0}; + TS_Ticket link_name_map_ticket = {0}; + ProfScope("kick off link name map build task") + { + link_name_map__in_progress.buckets_count = symbol_count_prediction; + link_name_map__in_progress.buckets = push_array(arena, P2R_LinkNameNode *, link_name_map__in_progress.buckets_count); + link_name_map_build_in.sym = sym; + link_name_map_build_in.coff_sections = coff_sections; + link_name_map_build_in.link_name_map = &link_name_map__in_progress; + link_name_map_ticket = ts_kickoff(p2r_link_name_map_build_task__entry_point, &link_name_map_build_in); + } + ////////////////////////////////////////////////////////////// //- rjf: types pass 1: produce type forward resolution map // @@ -3172,59 +3244,13 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) } ////////////////////////////////////////////////////////////// - //- rjf: produce link name map + //- rjf: join link name map building task // - P2R_LinkNameMap link_name_map = {0}; - ProfScope("produce link name map") + P2R_LinkNameMap *link_name_map = 0; + ProfScope("join link name map building task") { - link_name_map.buckets_count = symbol_count_prediction; - link_name_map.buckets = push_array(arena, P2R_LinkNameNode *, link_name_map.buckets_count); - CV_RecRange *rec_ranges_first = sym->sym_ranges.ranges; - CV_RecRange *rec_ranges_opl = rec_ranges_first + sym->sym_ranges.count; - for(CV_RecRange *rec_range = rec_ranges_first; - rec_range < rec_ranges_opl; - rec_range += 1) - { - //- rjf: unpack symbol range info - CV_SymKind kind = rec_range->hdr.kind; - U64 header_struct_size = cv_header_struct_size_from_sym_kind(kind); - U8 *sym_first = sym->data.str + rec_range->off + 2; - U8 *sym_opl = sym_first + rec_range->hdr.size; - - //- rjf: skip bad ranges - if(sym_opl > sym->data.str + sym->data.size || sym_first + header_struct_size > sym->data.str + sym->data.size) - { - continue; - } - - //- rjf: consume symbol - switch(kind) - { - default:{}break; - case CV_SymKind_PUB32: - { - // rjf: unpack sym - CV_SymPub32 *pub32 = (CV_SymPub32 *)sym_first; - String8 name = str8_cstring_capped(pub32+1, sym_opl); - COFF_SectionHeader *section = (0 < pub32->sec && pub32->sec <= coff_sections->count) ? &coff_sections->sections[pub32->sec-1] : 0; - U64 voff = 0; - if(section != 0) - { - voff = section->voff + pub32->off; - } - - // rjf: commit to link name map - U64 hash = p2r_hash_from_voff(voff); - U64 bucket_idx = hash%link_name_map.buckets_count; - P2R_LinkNameNode *node = push_array(arena, P2R_LinkNameNode, 1); - SLLStackPush(link_name_map.buckets[bucket_idx], node); - node->voff = voff; - node->name = name; - link_name_map.link_name_count += 1; - link_name_map.bucket_collision_count += (node->next != 0); - }break; - } - } + ts_join(link_name_map_ticket, max_U64); + link_name_map = &link_name_map__in_progress; } ////////////////////////////////////////////////////////////// @@ -3254,7 +3280,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) tasks_inputs[idx].tpi_leaf = tpi_leaf; tasks_inputs[idx].itype_fwd_map = itype_fwd_map; tasks_inputs[idx].itype_type_ptrs = itype_type_ptrs; - tasks_inputs[idx].link_name_map = &link_name_map; + tasks_inputs[idx].link_name_map = link_name_map; if(idx < global_stream_subdivision_tasks_count) { tasks_inputs[idx].sym = sym; @@ -3307,3 +3333,28 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) scratch_end(scratch); return out; } + +//////////////////////////////// +//~ rjf: Top-Level Baking Entry Point + +internal P2R_BakeOut * +p2r_bake(Arena *arena, P2R_BakeIn *in) +{ + RDIM_BakeParams bake_params = {0}; + { + bake_params.top_level_info = in->top_level_info; + bake_params.binary_sections = in->binary_sections; + bake_params.units = in->units; + bake_params.types = in->types; + bake_params.udts = in->udts; + bake_params.global_variables = in->global_variables; + bake_params.thread_variables = in->thread_variables; + bake_params.procedures = in->procedures; + bake_params.scopes = in->scopes; + } + RDIM_BakeSectionList sections = rdim_bake_sections_from_params(arena, &bake_params); + String8List bake_strings = rdim_blobs_from_bake_sections(arena, §ions); + P2R_BakeOut *out = push_array(arena, P2R_BakeOut, 1); + out->blobs = bake_strings; + return out; +} diff --git a/src/raddbgi_from_pdb/raddbgi_from_pdb.h b/src/raddbgi_from_pdb/raddbgi_from_pdb.h index 6479f997..bc88a4ff 100644 --- a/src/raddbgi_from_pdb/raddbgi_from_pdb.h +++ b/src/raddbgi_from_pdb/raddbgi_from_pdb.h @@ -53,6 +53,29 @@ struct P2R_ConvertOut RDIM_ScopeChunkList scopes; }; +//////////////////////////////// +//~ rjf: Baking Inputs/Outputs + +typedef struct P2R_BakeIn P2R_BakeIn; +struct P2R_BakeIn +{ + RDIM_TopLevelInfo top_level_info; + RDIM_BinarySectionList binary_sections; + RDIM_UnitChunkList units; + RDIM_TypeChunkList types; + RDIM_UDTChunkList udts; + RDIM_SymbolChunkList global_variables; + RDIM_SymbolChunkList thread_variables; + RDIM_SymbolChunkList procedures; + RDIM_ScopeChunkList scopes; +}; + +typedef struct P2R_BakeOut P2R_BakeOut; +struct P2R_BakeOut +{ + String8List blobs; +}; + //////////////////////////////// //~ rjf: Initial PDB Information Extraction & Conversion Preparation Task Types @@ -141,6 +164,16 @@ struct P2R_LinkNameMap U64 link_name_count; }; +//- rjf: link name map building tasks + +typedef struct P2R_LinkNameMapBuildIn P2R_LinkNameMapBuildIn; +struct P2R_LinkNameMapBuildIn +{ + CV_SymParsed *sym; + PDB_CoffSectionArray *coff_sections; + P2R_LinkNameMap *link_name_map; +}; + //- rjf: type forward resolution map build typedef struct P2R_ITypeFwdMapFillIn P2R_ITypeFwdMapFillIn; @@ -241,6 +274,11 @@ internal void *p2r_c13_stream_parse_task__entry_point(Arena *arena, void *p); internal void *p2r_comp_unit_parse_task__entry_point(Arena *arena, void *p); internal void *p2r_comp_unit_contributions_parse_task__entry_point(Arena *arena, void *p); +//////////////////////////////// +//~ rjf: Link Name Map Building Task + +internal void *p2r_link_name_map_build_task__entry_point(Arena *arena, void *p); + //////////////////////////////// //~ rjf: Type Parsing/Conversion Tasks @@ -257,4 +295,9 @@ internal void *p2r_symbol_stream_convert_task__entry_point(Arena *arena, void *p internal P2R_ConvertOut *p2r_convert(Arena *arena, P2R_ConvertIn *in); +//////////////////////////////// +//~ rjf: Top-Level Baking Entry Point + +internal P2R_BakeOut *p2r_bake(Arena *arena, P2R_BakeIn *in); + #endif // RADDBGI_FROM_PDB_H diff --git a/src/raddbgi_from_pdb/raddbgi_from_pdb_main.c b/src/raddbgi_from_pdb/raddbgi_from_pdb_main.c index 2aa4eb29..d500e8d6 100644 --- a/src/raddbgi_from_pdb/raddbgi_from_pdb_main.c +++ b/src/raddbgi_from_pdb/raddbgi_from_pdb_main.c @@ -82,23 +82,22 @@ main(int argc, char **argv) } //- rjf: bake - String8List bake_strings = {0}; + P2R_BakeOut *bake_out = 0; ProfScope("bake") { - RDIM_BakeParams bake_params = {0}; + P2R_BakeIn bake_in = {0}; { - bake_params.top_level_info = convert_out->top_level_info; - bake_params.binary_sections = convert_out->binary_sections; - bake_params.units = convert_out->units; - bake_params.types = convert_out->types; - bake_params.udts = convert_out->udts; - bake_params.global_variables = convert_out->global_variables; - bake_params.thread_variables = convert_out->thread_variables; - bake_params.procedures = convert_out->procedures; - bake_params.scopes = convert_out->scopes; + bake_in.top_level_info = convert_out->top_level_info; + bake_in.binary_sections = convert_out->binary_sections; + bake_in.units = convert_out->units; + bake_in.types = convert_out->types; + bake_in.udts = convert_out->udts; + bake_in.global_variables = convert_out->global_variables; + bake_in.thread_variables = convert_out->thread_variables; + bake_in.procedures = convert_out->procedures; + bake_in.scopes = convert_out->scopes; } - RDIM_BakeSectionList sections = rdim_bake_sections_from_params(arena, &bake_params); - bake_strings = rdim_blobs_from_bake_sections(arena, §ions); + bake_out = p2r_bake(arena, &bake_in); } //- rjf: write @@ -106,7 +105,7 @@ main(int argc, char **argv) { OS_Handle output_file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_Write, convert_in->output_name); U64 off = 0; - for(String8Node *n = bake_strings.first; n != 0; n = n->next) + for(String8Node *n = bake_out->blobs.first; n != 0; n = n->next) { os_file_write(output_file, r1u64(off, off+n->string.size), n->string.str); off += n->string.size;