mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-07-17 06:41:27 -07:00
raddbgi_from_pdb: overlap link name map building with type info building, since they are independent streams of work
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user