From 1319a23f982eea5c88895d4c44fbaf8dad97b6fd Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 25 Jan 2024 13:23:50 -0800 Subject: [PATCH] raddbg_from_pdb: cv struct2/class2 paths --- src/raddbg_convert/pdb/raddbg_codeview.h | 5 +- .../pdb/raddbg_codeview_stringize.c | 2 +- src/raddbg_convert/pdb/raddbg_from_pdb.c | 46 ++++++++++++++++++- src/raddbg_convert/pdb/raddbg_pdb.c | 30 ++++++++++++ 4 files changed, 77 insertions(+), 6 deletions(-) diff --git a/src/raddbg_convert/pdb/raddbg_codeview.h b/src/raddbg_convert/pdb/raddbg_codeview.h index d8317878..aeed9188 100644 --- a/src/raddbg_convert/pdb/raddbg_codeview.h +++ b/src/raddbg_convert/pdb/raddbg_codeview.h @@ -2709,7 +2709,7 @@ typedef struct CV_LeafVFPath{ // CV_TypeId[count] base; } CV_LeafVFPath; -// (LeafKind: CLASS2, CLASS2) +// (LeafKind: CLASS2, STRUCT2) typedef struct CV_LeafStruct2{ // NOTE: still reverse engineering this - if you find docs please help! CV_TypeProps props; @@ -2718,12 +2718,11 @@ typedef struct CV_LeafStruct2{ CV_TypeId derived_itype; CV_TypeId vshape_itype; U16 unknown2; - U16 size; + // CV_Numeric size // U8[] name (null terminated) // U8[] unique_name (null terminated) } CV_LeafStruct2; - // (LeafIDKind: FUNC_ID) typedef struct CV_LeafFuncId{ CV_ItemId scope_string_id; diff --git a/src/raddbg_convert/pdb/raddbg_codeview_stringize.c b/src/raddbg_convert/pdb/raddbg_codeview_stringize.c index 1dee063d..10534908 100644 --- a/src/raddbg_convert/pdb/raddbg_codeview_stringize.c +++ b/src/raddbg_convert/pdb/raddbg_codeview_stringize.c @@ -2054,7 +2054,7 @@ cv_stringize_leaf_range(Arena *arena, String8List *out, str8_list_pushf(arena, out, " derived_itype=%u\n", struct2->derived_itype); str8_list_pushf(arena, out, " vshape_itype=%u\n", struct2->vshape_itype); str8_list_pushf(arena, out, " unknown2=0x%x\n", struct2->unknown2); - str8_list_pushf(arena, out, " size=%u\n", struct2->size); + //str8_list_pushf(arena, out, " size=%u\n", struct2->size); String8 name = str8_cstring_capped((U8*)(struct2 + 1), first + cap); str8_list_pushf(arena, out, " name='%.*s'\n", str8_varg(name)); diff --git a/src/raddbg_convert/pdb/raddbg_from_pdb.c b/src/raddbg_convert/pdb/raddbg_from_pdb.c index e44d5f56..f5ef721b 100644 --- a/src/raddbg_convert/pdb/raddbg_from_pdb.c +++ b/src/raddbg_convert/pdb/raddbg_from_pdb.c @@ -294,6 +294,38 @@ pdbconv_type_resolve_fwd(PDBCONV_Ctx *ctx, CV_TypeId itype){ } }break; + case CV_LeafKind_CLASS2: + case CV_LeafKind_STRUCT2: + { + // TODO(allen): error if bad range + if (sizeof(CV_LeafStruct2) <= cap){ + CV_LeafStruct2 *lf_struct = (CV_LeafStruct2*)first; + + // size + U8 *numeric_ptr = (U8*)(lf_struct + 1); + CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, first + cap); + + // name + U8 *name_ptr = (U8 *)numeric_ptr + size.encoded_size; + String8 name = str8_cstring_capped((char*)name_ptr, first + cap); + + // unique name + U8 *unique_name_ptr = name_ptr + name.size + 1; + String8 unique_name = str8_cstring_capped((char*)unique_name_ptr, first + cap); + + if (lf_struct->props & CV_TypeProp_FwdRef){ + B32 do_unique_name_lookup = ((lf_struct->props & CV_TypeProp_Scoped) != 0) && + ((lf_struct->props & CV_TypeProp_HasUniqueName) != 0); + if (do_unique_name_lookup){ + result = pdb_tpi_first_itype_from_name(ctx->hash, ctx->leaf, unique_name, 1); + } + else{ + result = pdb_tpi_first_itype_from_name(ctx->hash, ctx->leaf, name, 0); + } + } + } + }break; + case CV_LeafKind_UNION: { // TODO(allen): error if bad range @@ -1371,10 +1403,20 @@ pdbconv_type_cons_leaf_record(PDBCONV_Ctx *ctx, CV_TypeId itype){ // TODO(allen): handle props + // size + U8 *numeric_ptr = (U8*)(lf_struct + 1); + CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, first + cap); + U64 size_u64 = cv_u64_from_numeric(&size); + // name - U8 *name_ptr = (U8*)(lf_struct + 1); + U8 *name_ptr = numeric_ptr + size.encoded_size; String8 name = str8_cstring_capped((char*)name_ptr, first + cap); + if(str8_match(name, str8_lit("Foo"), 0)) + { + int x = 0; + } + // incomplete type if (lf_struct->props & CV_TypeProp_FwdRef){ RADDBG_TypeKind type_kind = RADDBG_TypeKind_IncompleteStruct; @@ -1390,7 +1432,7 @@ pdbconv_type_cons_leaf_record(PDBCONV_Ctx *ctx, CV_TypeId itype){ if (range->hdr.kind == CV_LeafKind_CLASS2){ type_kind = RADDBG_TypeKind_Class; } - result = cons_type_udt(ctx->root, type_kind, name, lf_struct->size); + result = cons_type_udt(ctx->root, type_kind, name, size_u64); // remember to revisit this for members { diff --git a/src/raddbg_convert/pdb/raddbg_pdb.c b/src/raddbg_convert/pdb/raddbg_pdb.c index 3d88c1e4..0460653a 100644 --- a/src/raddbg_convert/pdb/raddbg_pdb.c +++ b/src/raddbg_convert/pdb/raddbg_pdb.c @@ -846,6 +846,36 @@ pdb_tpi_itypes_from_name(Arena *arena, PDB_TpiHashParsed *tpi_hash, CV_LeafParse } }break; + case CV_LeafKind_CLASS2: + case CV_LeafKind_STRUCT2: + { + if (sizeof(CV_LeafStruct2) <= cap){ + CV_LeafStruct2 *lf_struct = (CV_LeafStruct2*)first; + + if (!(lf_struct->props & CV_TypeProp_FwdRef)){ + // size + U8 *numeric_ptr = (U8*)(lf_struct + 1); + CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, first + cap); + + // name + U8 *name_ptr = numeric_ptr + size.encoded_size; + String8 name = str8_cstring_capped((char*)name_ptr, (char *)(first + cap)); + + // unique name + if (compare_unique_name){ + if (lf_struct->props & CV_TypeProp_HasUniqueName) { + U8 *unique_name_ptr = name_ptr + name.size + 1; + String8 unique_name = str8_cstring_capped((char*)unique_name_ptr, (char *)(first + cap)); + extracted_name = unique_name; + } + } + else{ + extracted_name = name; + } + } + } + }break; + case CV_LeafKind_UNION: { if (sizeof(CV_LeafUnion) <= cap){