From 7646487a9010dd548810dd207a098e608b6f2675 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 16 Feb 2024 07:28:55 -0800 Subject: [PATCH] raddbgi_from_pdb: type info baking --- src/lib_raddbgi_make/raddbgi_make.c | 146 ++++++++++++++++++- src/lib_raddbgi_make/raddbgi_make.h | 13 +- src/raddbgi_from_pdb/raddbgi_from_pdb.c | 28 ++-- src/raddbgi_from_pdb/raddbgi_from_pdb.h | 1 + src/raddbgi_from_pdb/raddbgi_from_pdb_main.c | 1 + 5 files changed, 167 insertions(+), 22 deletions(-) diff --git a/src/lib_raddbgi_make/raddbgi_make.c b/src/lib_raddbgi_make/raddbgi_make.c index d7fa2c3b..0ef52b47 100644 --- a/src/lib_raddbgi_make/raddbgi_make.c +++ b/src/lib_raddbgi_make/raddbgi_make.c @@ -531,6 +531,7 @@ rdim_type_chunk_list_push(RDIM_Arena *arena, RDIM_TypeChunkList *list, RDI_U64 c list->chunk_count += 1; } RDIM_Type *result = &n->v[n->count]; + result->idx = (RDI_U32)list->total_count; n->count += 1; list->total_count += 1; return result; @@ -578,6 +579,7 @@ rdim_udt_chunk_list_push(RDIM_Arena *arena, RDIM_UDTChunkList *list, RDI_U64 cap list->chunk_count += 1; } RDIM_UDT *result = &n->v[n->count]; + result->idx = (RDI_U32)list->total_count; n->count += 1; list->total_count += 1; return result; @@ -601,20 +603,22 @@ rdim_udt_chunk_list_concat_in_place(RDIM_UDTChunkList *dst, RDIM_UDTChunkList *t } RDI_PROC RDIM_UDTMember * -rdim_udt_push_member(RDIM_Arena *arena, RDIM_UDT *udt) +rdim_udt_push_member(RDIM_Arena *arena, RDIM_UDTChunkList *list, RDIM_UDT *udt) { RDIM_UDTMember *mem = rdim_push_array(arena, RDIM_UDTMember, 1); RDIM_SLLQueuePush(udt->first_member, udt->last_member, mem); udt->member_count += 1; + list->total_member_count += 1; return mem; } RDI_PROC RDIM_UDTEnumVal * -rdim_udt_push_enum_val(RDIM_Arena *arena, RDIM_UDT *udt) +rdim_udt_push_enum_val(RDIM_Arena *arena, RDIM_UDTChunkList *list, RDIM_UDT *udt) { RDIM_UDTEnumVal *mem = rdim_push_array(arena, RDIM_UDTEnumVal, 1); RDIM_SLLQueuePush(udt->first_enum_val, udt->last_enum_val, mem); udt->enum_val_count += 1; + list->total_enum_val_count += 1; return mem; } @@ -1677,13 +1681,145 @@ rdim_bake(RDIM_Arena *arena, RDIM_BakeParams *params) // ProfScope("build sections for type info") { + //////////////////////////// + //- rjf: build all type nodes + // + RDI_TypeNode *type_nodes = push_array(arena, RDI_TypeNode, params->types.total_count); + { + RDI_U64 dst_idx = 0; + for(RDIM_TypeChunkNode *n = params->types.first; n != 0; n = n->next) + { + for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1, dst_idx += 1) + { + RDIM_Type *src = &n->v[chunk_idx]; + RDI_TypeNode *dst = &type_nodes[dst_idx]; + + //- rjf: fill shared type node info + dst->kind = src->kind; + dst->byte_size = src->byte_size; + + //- rjf: fill built-in-only type node info + if(RDI_TypeKind_FirstBuiltIn <= dst->kind && dst->kind <= RDI_TypeKind_LastBuiltIn) + { + dst->built_in.name_string_idx = rdim_bake_string(arena, &strings, src->name); + } + + //- rjf: fill constructed type node info + else if(RDI_TypeKind_FirstConstructed <= dst->kind && dst->kind <= RDI_TypeKind_LastConstructed) + { + dst->constructed.direct_type_idx = src->direct_type ? src->direct_type->idx : 0; + dst->constructed.count = src->count; + if(dst->kind == RDI_TypeKind_Function || dst->kind == RDI_TypeKind_Method) + { + RDI_U32 param_idx_run_count = src->count; + RDI_U32 *param_idx_run = rdim_push_array_no_zero(arena, RDI_U32, param_idx_run_count); + for(RDI_U32 idx = 0; idx < param_idx_run_count; idx += 1) + { + param_idx_run[idx] = src->param_types[idx]->idx; + } + dst->constructed.param_idx_run_first = rdim_bake_idx_run(arena, &idx_runs, param_idx_run, param_idx_run_count); + } + else if(dst->kind == RDI_TypeKind_MemberPtr) + { + // TODO(rjf): member pointers not currently supported. + } + } + + //- rjf: fill user-defined-type info + else if(RDI_TypeKind_FirstUserDefined <= dst->kind && dst->kind <= RDI_TypeKind_LastUserDefined) + { + dst->user_defined.name_string_idx = rdim_bake_string(arena, &strings, src->name); + dst->user_defined.udt_idx = src->udt ? src->udt->idx : 0; + dst->user_defined.direct_type_idx = src->direct_type ? src->direct_type->idx : 0; + } + + //- rjf: fill bitfield info + else if(dst->kind == RDI_TypeKind_Bitfield) + { + dst->bitfield.off = src->off; + dst->bitfield.size = src->count; + } + } + } + } + //////////////////////////// + //- rjf: build all udts & members + // + RDI_UDT * udts = push_array(arena, RDI_UDT, params->udts.total_count); + RDI_Member * members = push_array(arena, RDI_Member, params->udts.total_member_count); + RDI_EnumMember *enum_members = push_array(arena, RDI_EnumMember, params->udts.total_enum_val_count); + { + RDI_U32 dst_udt_idx = 0; + RDI_U32 dst_member_idx = 0; + RDI_U32 dst_enum_member_idx = 0; + for(RDIM_UDTChunkNode *n = params->udts.first; n != 0; n = n->next) + { + for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1, dst_udt_idx += 1) + { + RDIM_UDT *src_udt = &n->v[chunk_idx]; + RDI_UDT *dst_udt = &udts[dst_udt_idx]; + + //- rjf: fill basics + dst_udt->self_type_idx = src_udt->self_type ? src_udt->self_type->idx : 0; + if(src_udt->source_path.size != 0) + { + RDIM_BakePathNode *path_node = rdim_bake_path_node_from_string(arena, &path_tree, src_udt->source_path); + RDIM_BakeSrcNode *src_node = rdim_bake_src_node_from_path_node(arena, &path_tree, path_node); + dst_udt->file_idx = src_node->idx; + } + dst_udt->line = src_udt->line; + dst_udt->col = src_udt->col; + + //- rjf: fill members + if(src_udt->member_count != 0) + { + dst_udt->member_first = dst_member_idx; + dst_udt->member_count = src_udt->member_count; + for(RDIM_UDTMember *src_member = src_udt->first_member; + src_member != 0; + src_member = src_member->next, dst_member_idx += 1) + { + RDI_Member *dst_member = &members[dst_member_idx]; + dst_member->kind = src_member->kind; + dst_member->name_string_idx = rdim_bake_string(arena, &strings, src_member->name); + dst_member->type_idx = src_member->type ? src_member->type->idx : 0; + dst_member->off = src_member->off; + } + } + + //- rjf: fill enum members + else if(src_udt->enum_val_count != 0) + { + dst_udt->flags |= RDI_UserDefinedTypeFlag_EnumMembers; + dst_udt->member_first = dst_enum_member_idx; + dst_udt->member_count = src_udt->enum_val_count; + for(RDIM_UDTEnumVal *src_member = src_udt->first_enum_val; + src_member != 0; + src_member = src_member->next, dst_enum_member_idx += 1) + { + RDI_EnumMember *dst_member = &enum_members[dst_enum_member_idx]; + dst_member->name_string_idx = rdim_bake_string(arena, &strings, src_member->name); + dst_member->val = src_member->val; + } + } + } + } + } + + //////////////////////////// + //- rjf: push all type info sections + // + rdim_bake_section_list_push_new(arena, §ions, type_nodes, sizeof(RDI_TypeNode) * params->types.total_count, RDI_DataSectionTag_TypeNodes); + rdim_bake_section_list_push_new(arena, §ions, udts, sizeof(RDI_UDT) * params->udts.total_count, RDI_DataSectionTag_UDTs); + rdim_bake_section_list_push_new(arena, §ions, members , sizeof(RDI_Member) * params->udts.total_member_count, RDI_DataSectionTag_Members); + rdim_bake_section_list_push_new(arena, §ions, enum_members, sizeof(RDI_EnumMember) * params->udts.total_enum_val_count, RDI_DataSectionTag_EnumMembers); } ////////////////////////////// //- rjf: build sections for symbol info // - ProfScope("build sections for type info") + ProfScope("build sections for symbol info") { } @@ -1729,9 +1865,9 @@ rdim_bake(RDIM_Arena *arena, RDIM_BakeParams *params) } ////////////////////////////// - //- rjf: build blob strings for header & all sections + //- rjf: finalize: build blob strings for header & all sections // - ProfScope("build blob strings for header & all sections") + ProfScope("finalize: build blob strings for header & all sections") { // rjf: push empty header & data section table RDI_Header *baked_rdi_header = rdim_push_array(arena, RDI_Header, 1); diff --git a/src/lib_raddbgi_make/raddbgi_make.h b/src/lib_raddbgi_make/raddbgi_make.h index aa39b08e..e784acef 100644 --- a/src/lib_raddbgi_make/raddbgi_make.h +++ b/src/lib_raddbgi_make/raddbgi_make.h @@ -505,6 +505,7 @@ typedef struct RDIM_Type RDIM_Type; struct RDIM_Type { RDI_TypeKind kind; + RDI_U32 idx; RDI_U32 byte_size; RDI_U32 flags; RDI_U32 off; @@ -564,13 +565,14 @@ struct RDIM_UDTEnumVal typedef struct RDIM_UDT RDIM_UDT; struct RDIM_UDT { + RDI_U32 idx; RDIM_Type *self_type; RDIM_UDTMember *first_member; RDIM_UDTMember *last_member; - RDI_U64 member_count; RDIM_UDTEnumVal *first_enum_val; RDIM_UDTEnumVal *last_enum_val; - RDI_U64 enum_val_count; + RDI_U32 member_count; + RDI_U32 enum_val_count; RDIM_String8 source_path; RDI_U32 line; RDI_U32 col; @@ -592,6 +594,8 @@ struct RDIM_UDTChunkList RDIM_UDTChunkNode *last; RDI_U64 chunk_count; RDI_U64 total_count; + RDI_U64 total_member_count; + RDI_U64 total_enum_val_count; }; //////////////////////////////// @@ -774,6 +778,7 @@ struct RDIM_BakeParams RDIM_BinarySectionList binary_sections; RDIM_UnitChunkList units; RDIM_TypeChunkList types; + RDIM_UDTChunkList udts; RDIM_SymbolChunkList global_variables; RDIM_SymbolChunkList thread_variables; RDIM_SymbolChunkList procedures; @@ -1352,8 +1357,8 @@ RDI_PROC void rdim_type_chunk_list_push_array(RDIM_Arena *arena, RDIM_TypeChunkL RDI_PROC void rdim_type_chunk_list_concat_in_place(RDIM_TypeChunkList *dst, RDIM_TypeChunkList *to_push); RDI_PROC RDIM_UDT *rdim_udt_chunk_list_push(RDIM_Arena *arena, RDIM_UDTChunkList *list, RDI_U64 cap); RDI_PROC void rdim_udt_chunk_list_concat_in_place(RDIM_UDTChunkList *dst, RDIM_UDTChunkList *to_push); -RDI_PROC RDIM_UDTMember *rdim_udt_push_member(RDIM_Arena *arena, RDIM_UDT *udt); -RDI_PROC RDIM_UDTEnumVal *rdim_udt_push_enum_val(RDIM_Arena *arena, RDIM_UDT *udt); +RDI_PROC RDIM_UDTMember *rdim_udt_push_member(RDIM_Arena *arena, RDIM_UDTChunkList *list, RDIM_UDT *udt); +RDI_PROC RDIM_UDTEnumVal *rdim_udt_push_enum_val(RDIM_Arena *arena, RDIM_UDTChunkList *list, RDIM_UDT *udt); //////////////////////////////// //~ rjf: Location Info Building diff --git a/src/raddbgi_from_pdb/raddbgi_from_pdb.c b/src/raddbgi_from_pdb/raddbgi_from_pdb.c index 6a2ae202..6feead4c 100644 --- a/src/raddbgi_from_pdb/raddbgi_from_pdb.c +++ b/src/raddbgi_from_pdb/raddbgi_from_pdb.c @@ -4025,6 +4025,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) if(cv_basic_ptr_kind != 0) { dst_type->kind = RDI_TypeKind_Ptr; + dst_type->idx = (RDI_U32)(itype-itype_first); dst_type->byte_size = arch_addr_size; dst_type->direct_type = basic_type; } @@ -4607,7 +4608,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) next_read_ptr = name.str+name.size+1; // rjf: emit member - RDIM_UDTMember *mem = rdim_udt_push_member(arena, dst_udt); + RDIM_UDTMember *mem = rdim_udt_push_member(arena, &udts, dst_udt); mem->kind = RDI_MemberKind_DataField; mem->name = name; mem->type = p2r_type_ptr_from_itype(lf->itype); @@ -4628,7 +4629,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) next_read_ptr = name.str+name.size+1; // rjf: emit member - RDIM_UDTMember *mem = rdim_udt_push_member(arena, dst_udt); + RDIM_UDTMember *mem = rdim_udt_push_member(arena, &udts, dst_udt); mem->kind = RDI_MemberKind_StaticData; mem->name = name; mem->type = p2r_type_ptr_from_itype(lf->itype); @@ -4705,14 +4706,14 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) { default: { - RDIM_UDTMember *mem = rdim_udt_push_member(arena, dst_udt); + RDIM_UDTMember *mem = rdim_udt_push_member(arena, &udts, dst_udt); mem->kind = RDI_MemberKind_Method; mem->name = name; mem->type = method_type; }break; case CV_MethodProp_Static: { - RDIM_UDTMember *mem = rdim_udt_push_member(arena, dst_udt); + RDIM_UDTMember *mem = rdim_udt_push_member(arena, &udts, dst_udt); mem->kind = RDI_MemberKind_StaticMethod; mem->name = name; mem->type = method_type; @@ -4722,7 +4723,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) case CV_MethodProp_Intro: case CV_MethodProp_PureIntro: { - RDIM_UDTMember *mem = rdim_udt_push_member(arena, dst_udt); + RDIM_UDTMember *mem = rdim_udt_push_member(arena, &udts, dst_udt); mem->kind = RDI_MemberKind_VirtualMethod; mem->name = name; mem->type = method_type; @@ -4760,7 +4761,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) { default: { - RDIM_UDTMember *mem = rdim_udt_push_member(arena, dst_udt); + RDIM_UDTMember *mem = rdim_udt_push_member(arena, &udts, dst_udt); mem->kind = RDI_MemberKind_Method; mem->name = name; mem->type = method_type; @@ -4768,7 +4769,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) case CV_MethodProp_Static: { - RDIM_UDTMember *mem = rdim_udt_push_member(arena, dst_udt); + RDIM_UDTMember *mem = rdim_udt_push_member(arena, &udts, dst_udt); mem->kind = RDI_MemberKind_StaticMethod; mem->name = name; mem->type = method_type; @@ -4779,7 +4780,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) case CV_MethodProp_Intro: case CV_MethodProp_PureIntro: { - RDIM_UDTMember *mem = rdim_udt_push_member(arena, dst_udt); + RDIM_UDTMember *mem = rdim_udt_push_member(arena, &udts, dst_udt); mem->kind = RDI_MemberKind_VirtualMethod; mem->name = name; mem->type = method_type; @@ -4799,7 +4800,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) next_read_ptr = name.str+name.size+1; // rjf: emit member - RDIM_UDTMember *mem = rdim_udt_push_member(arena, dst_udt); + RDIM_UDTMember *mem = rdim_udt_push_member(arena, &udts, dst_udt); mem->kind = RDI_MemberKind_NestedType; mem->name = name; mem->type = p2r_type_ptr_from_itype(lf->itype); @@ -4819,7 +4820,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) next_read_ptr = name.str+name.size+1; // rjf: emit member - RDIM_UDTMember *mem = rdim_udt_push_member(arena, dst_udt); + RDIM_UDTMember *mem = rdim_udt_push_member(arena, &udts, dst_udt); mem->kind = RDI_MemberKind_NestedType; mem->name = name; mem->type = p2r_type_ptr_from_itype(lf->itype); @@ -4840,7 +4841,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) next_read_ptr = offset_ptr+offset.encoded_size; // rjf: emit member - RDIM_UDTMember *mem = rdim_udt_push_member(arena, dst_udt); + RDIM_UDTMember *mem = rdim_udt_push_member(arena, &udts, dst_udt); mem->kind = RDI_MemberKind_Base; mem->type = p2r_type_ptr_from_itype(lf->itype); mem->off = (U32)offset64; @@ -4862,7 +4863,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) CV_NumericParsed num2 = cv_numeric_from_data_range(num2_ptr, field_leaf_opl); // rjf: emit member - RDIM_UDTMember *mem = rdim_udt_push_member(arena, dst_udt); + RDIM_UDTMember *mem = rdim_udt_push_member(arena, &udts, dst_udt); mem->kind = RDI_MemberKind_VirtualBase; mem->type = p2r_type_ptr_from_itype(lf->itype); }break; @@ -5005,7 +5006,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) next_read_ptr = name.str+name.size+1; // rjf: emit member - RDIM_UDTEnumVal *enum_val = rdim_udt_push_enum_val(arena, dst_udt); + RDIM_UDTEnumVal *enum_val = rdim_udt_push_enum_val(arena, &udts, dst_udt); enum_val->name = name; enum_val->val = val64; }break; @@ -5811,6 +5812,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) rdim_unit_chunk_list_push_array(arena, &out->units, &units); rdim_type_chunk_list_push_array(arena, &out->types, &itype_types); rdim_type_chunk_list_concat_in_place(&out->types, &extra_types); + out->udts = udts; out->global_variables = all_global_variables; out->thread_variables = all_thread_variables; out->procedures = all_procedures; diff --git a/src/raddbgi_from_pdb/raddbgi_from_pdb.h b/src/raddbgi_from_pdb/raddbgi_from_pdb.h index 7d1943f3..07bcd9dc 100644 --- a/src/raddbgi_from_pdb/raddbgi_from_pdb.h +++ b/src/raddbgi_from_pdb/raddbgi_from_pdb.h @@ -46,6 +46,7 @@ struct P2R_ConvertOut RDIM_BinarySectionList binary_sections; RDIM_UnitChunkList units; RDIM_TypeChunkList types; + RDIM_UDTChunkList udts; RDIM_SymbolChunkList global_variables; RDIM_SymbolChunkList thread_variables; RDIM_SymbolChunkList procedures; diff --git a/src/raddbgi_from_pdb/raddbgi_from_pdb_main.c b/src/raddbgi_from_pdb/raddbgi_from_pdb_main.c index 1c183fb0..d06b3e0b 100644 --- a/src/raddbgi_from_pdb/raddbgi_from_pdb_main.c +++ b/src/raddbgi_from_pdb/raddbgi_from_pdb_main.c @@ -87,6 +87,7 @@ main(int argc, char **argv) bake_params.top_level_info = convert_out->top_level_info; bake_params.binary_sections = convert_out->binary_sections; 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;