From 348034a490d74b5a79438c7f82f69461292d6857 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 13 Feb 2024 14:26:01 -0800 Subject: [PATCH] reading/cleanup/organization pass over main symbol conversion pass in raddbgi_from_pdb; automate & table-drive a few pieces via metacode tables --- src/codeview/codeview.h | 4 +- src/codeview/codeview.mdesk | 408 +++---- src/codeview/generated/codeview.meta.c | 79 ++ src/codeview/generated/codeview.meta.h | 1 + src/raddbgi_convert/pdb/raddbgi_from_pdb.c | 1116 +++++++++----------- 5 files changed, 787 insertions(+), 821 deletions(-) diff --git a/src/codeview/codeview.h b/src/codeview/codeview.h index b6a0778f..07d60867 100644 --- a/src/codeview/codeview.h +++ b/src/codeview/codeview.h @@ -1059,8 +1059,8 @@ enum CV_GenericFlags_RSCLEAN = (1 << 1), // "returnee stack cleanup" }; -typedef struct CV_Return CV_Return; -struct CV_Return +typedef struct CV_SymReturn CV_SymReturn; +struct CV_SymReturn { CV_GenericFlags flags; CV_GenericStyle style; diff --git a/src/codeview/codeview.mdesk b/src/codeview/codeview.mdesk index f05316c3..5b57fd39 100644 --- a/src/codeview/codeview.mdesk +++ b/src/codeview/codeview.mdesk @@ -152,201 +152,201 @@ cv_string_from_arch: //////////////////////////////// //~ rjf: CV Sym Kinds -@table(name val) CV_SymKindTable: +@table(name header_type_name val) CV_SymKindTable: { - {COMPILE 0x0001} - {REGISTER_16t 0x0002} - {CONSTANT_16t 0x0003} - {UDT_16t 0x0004} - {SSEARCH 0x0005} - {END 0x0006} - {SKIP 0x0007} - {CVRESERVE 0x0008} - {OBJNAME_ST 0x0009} - {ENDARG 0x000a} - {COBOLUDT_16t 0x000b} - {MANYREG_16t 0x000c} - {RETURN 0x000d} - {ENTRYTHIS 0x000e} - {BPREL16 0x0100} - {LDATA16 0x0101} - {GDATA16 0x0102} - {PUB16 0x0103} - {LPROC16 0x0104} - {GPROC16 0x0105} - {THUNK16 0x0106} - {BLOCK16 0x0107} - {WITH16 0x0108} - {LABEL16 0x0109} - {CEXMODEL16 0x010a} - {VFTABLE16 0x010b} - {REGREL16 0x010c} - {BPREL32_16t 0x0200} - {LDATA32_16t 0x0201} - {GDATA32_16t 0x0202} - {PUB32_16t 0x0203} - {LPROC32_16t 0x0204} - {GPROC32_16t 0x0205} - {THUNK32_ST 0x0206} - {BLOCK32_ST 0x0207} - {WITH32_ST 0x0208} - {LABEL32_ST 0x0209} - {CEXMODEL32 0x020a} - {VFTABLE32_16t 0x020b} - {REGREL32_16t 0x020c} - {LTHREAD32_16t 0x020d} - {GTHREAD32_16t 0x020e} - {SLINK32 0x020f} - {LPROCMIPS_16t 0x0300} - {GPROCMIPS_16t 0x0301} - {PROCREF_ST 0x0400} - {DATAREF_ST 0x0401} - {ALIGN 0x0402} - {LPROCREF_ST 0x0403} - {OEM 0x0404} - {TI16_MAX 0x1000} - {CONSTANT_ST 0x1002} - {UDT_ST 0x1003} - {COBOLUDT_ST 0x1004} - {MANYREG_ST 0x1005} - {BPREL32_ST 0x1006} - {LDATA32_ST 0x1007} - {GDATA32_ST 0x1008} - {PUB32_ST 0x1009} - {LPROC32_ST 0x100a} - {GPROC32_ST 0x100b} - {VFTABLE32 0x100c} - {REGREL32_ST 0x100d} - {LTHREAD32_ST 0x100e} - {GTHREAD32_ST 0x100f} - {LPROCMIPS_ST 0x1010} - {GPROCMIPS_ST 0x1011} - {FRAMEPROC 0x1012} - {COMPILE2_ST 0x1013} - {MANYREG2_ST 0x1014} - {LPROCIA64_ST 0x1015} - {GPROCIA64_ST 0x1016} - {LOCALSLOT_ST 0x1017} - {PARAMSLOT_ST 0x1018} - {ANNOTATION 0x1019} - {GMANPROC_ST 0x101a} - {LMANPROC_ST 0x101b} - {RESERVED1 0x101c} - {RESERVED2 0x101d} - {RESERVED3 0x101e} - {RESERVED4 0x101f} - {LMANDATA_ST 0x1020} - {GMANDATA_ST 0x1021} - {MANFRAMEREL_ST 0x1022} - {MANREGISTER_ST 0x1023} - {MANSLOT_ST 0x1024} - {MANMANYREG_ST 0x1025} - {MANREGREL_ST 0x1026} - {MANMANYREG2_ST 0x1027} - {MANTYPREF 0x1028} - {UNAMESPACE_ST 0x1029} - {ST_MAX 0x1100} - {OBJNAME 0x1101} - {THUNK32 0x1102} - {BLOCK32 0x1103} - {WITH32 0x1104} - {LABEL32 0x1105} - {REGISTER 0x1106} - {CONSTANT 0x1107} - {UDT 0x1108} - {COBOLUDT 0x1109} - {MANYREG 0x110a} - {BPREL32 0x110b} - {LDATA32 0x110c} - {GDATA32 0x110d} - {PUB32 0x110e} - {LPROC32 0x110f} - {GPROC32 0x1110} - {REGREL32 0x1111} - {LTHREAD32 0x1112} - {GTHREAD32 0x1113} - {LPROCMIPS 0x1114} - {GPROCMIPS 0x1115} - {COMPILE2 0x1116} - {MANYREG2 0x1117} - {LPROCIA64 0x1118} - {GPROCIA64 0x1119} - {LOCALSLOT 0x111a} - {PARAMSLOT 0x111b} - {LMANDATA 0x111c} - {GMANDATA 0x111d} - {MANFRAMEREL 0x111e} - {MANREGISTER 0x111f} - {MANSLOT 0x1120} - {MANMANYREG 0x1121} - {MANREGREL 0x1122} - {MANMANYREG2 0x1123} - {UNAMESPACE 0x1124} - {PROCREF 0x1125} - {DATAREF 0x1126} - {LPROCREF 0x1127} - {ANNOTATIONREF 0x1128} - {TOKENREF 0x1129} - {GMANPROC 0x112a} - {LMANPROC 0x112b} - {TRAMPOLINE 0x112c} - {MANCONSTANT 0x112d} - {ATTR_FRAMEREL 0x112e} - {ATTR_REGISTER 0x112f} - {ATTR_REGREL 0x1130} - {ATTR_MANYREG 0x1131} - {SEPCODE 0x1132} - {DEFRANGE_2005 0x1134} - {DEFRANGE2_2005 0x1135} - {SECTION 0x1136} - {COFFGROUP 0x1137} - {EXPORT 0x1138} - {CALLSITEINFO 0x1139} - {FRAMECOOKIE 0x113a} - {DISCARDED 0x113b} - {COMPILE3 0x113c} - {ENVBLOCK 0x113d} - {LOCAL 0x113e} - {DEFRANGE 0x113f} - {DEFRANGE_SUBFIELD 0x1140} - {DEFRANGE_REGISTER 0x1141} - {DEFRANGE_FRAMEPOINTER_REL 0x1142} - {DEFRANGE_SUBFIELD_REGISTER 0x1143} - {DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE 0x1144} - {DEFRANGE_REGISTER_REL 0x1145} - {LPROC32_ID 0x1146} - {GPROC32_ID 0x1147} - {LPROCMIPS_ID 0x1148} - {GPROCMIPS_ID 0x1149} - {LPROCIA64_ID 0x114a} - {GPROCIA64_ID 0x114b} - {BUILDINFO 0x114c} - {INLINESITE 0x114d} - {INLINESITE_END 0x114e} - {PROC_ID_END 0x114f} - {DEFRANGE_HLSL 0x1150} - {GDATA_HLSL 0x1151} - {LDATA_HLSL 0x1152} - {FILESTATIC 0x1153} - {LPROC32_DPC 0x1155} - {LPROC32_DPC_ID 0x1156} - {DEFRANGE_DPC_PTR_TAG 0x1157} - {DPC_SYM_TAG_MAP 0x1158} - {ARMSWITCHTABLE 0x1159} - {CALLEES 0x115a} - {CALLERS 0x115b} - {POGODATA 0x115c} - {INLINESITE2 0x115d} - {HEAPALLOCSITE 0x115e} - {MOD_TYPEREF 0x115f} - {REF_MINIPDB 0x1160} - {PDBMAP 0x1161} - {GDATA_HLSL32 0x1162} - {LDATA_HLSL32 0x1163} - {GDATA_HLSL32_EX 0x1164} - {LDATA_HLSL32_EX 0x1165} - {FASTLINK 0x1167} - {INLINEES 0x1168} + {COMPILE Compile 0x0001} + {REGISTER_16t - 0x0002} + {CONSTANT_16t - 0x0003} + {UDT_16t - 0x0004} + {SSEARCH StartSearch 0x0005} + {END - 0x0006} + {SKIP - 0x0007} + {CVRESERVE - 0x0008} + {OBJNAME_ST - 0x0009} + {ENDARG - 0x000a} + {COBOLUDT_16t - 0x000b} + {MANYREG_16t - 0x000c} + {RETURN Return 0x000d} + {ENTRYTHIS - 0x000e} + {BPREL16 - 0x0100} + {LDATA16 - 0x0101} + {GDATA16 - 0x0102} + {PUB16 - 0x0103} + {LPROC16 - 0x0104} + {GPROC16 - 0x0105} + {THUNK16 - 0x0106} + {BLOCK16 - 0x0107} + {WITH16 - 0x0108} + {LABEL16 - 0x0109} + {CEXMODEL16 - 0x010a} + {VFTABLE16 - 0x010b} + {REGREL16 - 0x010c} + {BPREL32_16t - 0x0200} + {LDATA32_16t - 0x0201} + {GDATA32_16t - 0x0202} + {PUB32_16t - 0x0203} + {LPROC32_16t - 0x0204} + {GPROC32_16t - 0x0205} + {THUNK32_ST - 0x0206} + {BLOCK32_ST - 0x0207} + {WITH32_ST - 0x0208} + {LABEL32_ST - 0x0209} + {CEXMODEL32 - 0x020a} + {VFTABLE32_16t - 0x020b} + {REGREL32_16t - 0x020c} + {LTHREAD32_16t - 0x020d} + {GTHREAD32_16t - 0x020e} + {SLINK32 SLink32 0x020f} + {LPROCMIPS_16t - 0x0300} + {GPROCMIPS_16t - 0x0301} + {PROCREF_ST - 0x0400} + {DATAREF_ST - 0x0401} + {ALIGN - 0x0402} + {LPROCREF_ST - 0x0403} + {OEM OEM 0x0404} + {TI16_MAX - 0x1000} + {CONSTANT_ST - 0x1002} + {UDT_ST - 0x1003} + {COBOLUDT_ST - 0x1004} + {MANYREG_ST - 0x1005} + {BPREL32_ST - 0x1006} + {LDATA32_ST - 0x1007} + {GDATA32_ST - 0x1008} + {PUB32_ST - 0x1009} + {LPROC32_ST - 0x100a} + {GPROC32_ST - 0x100b} + {VFTABLE32 VPath32 0x100c} + {REGREL32_ST - 0x100d} + {LTHREAD32_ST - 0x100e} + {GTHREAD32_ST - 0x100f} + {LPROCMIPS_ST - 0x1010} + {GPROCMIPS_ST - 0x1011} + {FRAMEPROC Frameproc 0x1012} + {COMPILE2_ST - 0x1013} + {MANYREG2_ST - 0x1014} + {LPROCIA64_ST - 0x1015} + {GPROCIA64_ST - 0x1016} + {LOCALSLOT_ST - 0x1017} + {PARAMSLOT_ST - 0x1018} + {ANNOTATION Annotation 0x1019} + {GMANPROC_ST - 0x101a} + {LMANPROC_ST - 0x101b} + {RESERVED1 - 0x101c} + {RESERVED2 - 0x101d} + {RESERVED3 - 0x101e} + {RESERVED4 - 0x101f} + {LMANDATA_ST - 0x1020} + {GMANDATA_ST - 0x1021} + {MANFRAMEREL_ST - 0x1022} + {MANREGISTER_ST - 0x1023} + {MANSLOT_ST - 0x1024} + {MANMANYREG_ST - 0x1025} + {MANREGREL_ST - 0x1026} + {MANMANYREG2_ST - 0x1027} + {MANTYPREF - 0x1028} + {UNAMESPACE_ST - 0x1029} + {ST_MAX - 0x1100} + {OBJNAME Objname 0x1101} + {THUNK32 Thunk32 0x1102} + {BLOCK32 Block32 0x1103} + {WITH32 - 0x1104} + {LABEL32 Label32 0x1105} + {REGISTER Register 0x1106} + {CONSTANT Constant 0x1107} + {UDT UDT 0x1108} + {COBOLUDT - 0x1109} + {MANYREG Manyreg 0x110a} + {BPREL32 BPRel32 0x110b} + {LDATA32 Data32 0x110c} + {GDATA32 Data32 0x110d} + {PUB32 Pub32 0x110e} + {LPROC32 Proc32 0x110f} + {GPROC32 Proc32 0x1110} + {REGREL32 Regrel32 0x1111} + {LTHREAD32 Thread32 0x1112} + {GTHREAD32 Thread32 0x1113} + {LPROCMIPS - 0x1114} + {GPROCMIPS - 0x1115} + {COMPILE2 Compile2 0x1116} + {MANYREG2 Manyreg2 0x1117} + {LPROCIA64 - 0x1118} + {GPROCIA64 - 0x1119} + {LOCALSLOT Slot 0x111a} + {PARAMSLOT - 0x111b} + {LMANDATA - 0x111c} + {GMANDATA - 0x111d} + {MANFRAMEREL AttrFrameRel 0x111e} + {MANREGISTER AttrReg 0x111f} + {MANSLOT - 0x1120} + {MANMANYREG AttrManyReg 0x1121} + {MANREGREL AttrRegRel 0x1122} + {MANMANYREG2 - 0x1123} + {UNAMESPACE UNamespace 0x1124} + {PROCREF Ref2 0x1125} + {DATAREF Ref2 0x1126} + {LPROCREF Ref2 0x1127} + {ANNOTATIONREF - 0x1128} + {TOKENREF - 0x1129} + {GMANPROC - 0x112a} + {LMANPROC - 0x112b} + {TRAMPOLINE Trampoline 0x112c} + {MANCONSTANT - 0x112d} + {ATTR_FRAMEREL AttrFrameRel 0x112e} + {ATTR_REGISTER AttrReg 0x112f} + {ATTR_REGREL AttrRegRel 0x1130} + {ATTR_MANYREG AttrManyReg 0x1131} + {SEPCODE Sepcode 0x1132} + {DEFRANGE_2005 - 0x1134} + {DEFRANGE2_2005 - 0x1135} + {SECTION Section 0x1136} + {COFFGROUP CoffGroup 0x1137} + {EXPORT Export 0x1138} + {CALLSITEINFO CallSiteInfo 0x1139} + {FRAMECOOKIE FrameCookie 0x113a} + {DISCARDED Discarded 0x113b} + {COMPILE3 Compile3 0x113c} + {ENVBLOCK EnvBlock 0x113d} + {LOCAL Local 0x113e} + {DEFRANGE - 0x113f} + {DEFRANGE_SUBFIELD DefrangeSubfield 0x1140} + {DEFRANGE_REGISTER DefrangeRegister 0x1141} + {DEFRANGE_FRAMEPOINTER_REL DefrangeFramepointerRel 0x1142} + {DEFRANGE_SUBFIELD_REGISTER DefrangeSubfieldRegister 0x1143} + {DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE DefrangeFramepointerRelFullScope 0x1144} + {DEFRANGE_REGISTER_REL DefrangeRegisterRel 0x1145} + {LPROC32_ID - 0x1146} + {GPROC32_ID - 0x1147} + {LPROCMIPS_ID - 0x1148} + {GPROCMIPS_ID - 0x1149} + {LPROCIA64_ID - 0x114a} + {GPROCIA64_ID - 0x114b} + {BUILDINFO BuildInfo 0x114c} + {INLINESITE InlineSite 0x114d} + {INLINESITE_END - 0x114e} + {PROC_ID_END - 0x114f} + {DEFRANGE_HLSL - 0x1150} + {GDATA_HLSL - 0x1151} + {LDATA_HLSL - 0x1152} + {FILESTATIC FileStatic 0x1153} + {LPROC32_DPC - 0x1155} + {LPROC32_DPC_ID - 0x1156} + {DEFRANGE_DPC_PTR_TAG - 0x1157} + {DPC_SYM_TAG_MAP - 0x1158} + {ARMSWITCHTABLE - 0x1159} + {CALLEES FunctionList 0x115a} + {CALLERS FunctionList 0x115b} + {POGODATA PogoInfo 0x115c} + {INLINESITE2 InlineSite2 0x115d} + {HEAPALLOCSITE HeapAllocSite 0x115e} + {MOD_TYPEREF ModTypeRef 0x115f} + {REF_MINIPDB RefMiniPdb 0x1160} + {PDBMAP - 0x1161} + {GDATA_HLSL32 - 0x1162} + {LDATA_HLSL32 - 0x1163} + {GDATA_HLSL32_EX - 0x1164} + {LDATA_HLSL32_EX - 0x1165} + {FASTLINK FastLink 0x1167} + {INLINEES Inlinees 0x1168} } @enum(U16) CV_SymKind: @@ -360,6 +360,26 @@ cv_string_from_sym_kind: @expand(CV_SymKindTable a) `case CV_SymKind_$(a.name):{result = str8_lit("$(a.name)");}break`; } +@gen(functions) +{ + `internal U64 cv_header_struct_size_from_sym_kind(CV_SymKind v);`; +} + +@gen(functions) @c_file +{ + `internal U64`; + `cv_header_struct_size_from_sym_kind(CV_SymKind v)`; + `{`; + `U64 result = 0;`; + `switch(v)`; + `{`; + `default:{}break;`; + @expand(CV_SymKindTable a) `$(a.header_type_name != "-" -> "case CV_SymKind_"..a.name..":{result = sizeof(CV_Sym"..a.header_type_name..");}break;")`; + `}`; + `return result;`; + `}`; +} + //////////////////////////////// //~ rjf: CV Leaf diff --git a/src/codeview/generated/codeview.meta.c b/src/codeview/generated/codeview.meta.c index 6db9136c..b65dc4fc 100644 --- a/src/codeview/generated/codeview.meta.c +++ b/src/codeview/generated/codeview.meta.c @@ -449,6 +449,85 @@ case CV_LeafKind_STRUCT2:{result = str8_lit("STRUCT2");}break; return result; } +internal U64 +cv_header_struct_size_from_sym_kind(CV_SymKind v) +{ +U64 result = 0; +switch(v) +{ +default:{}break; +case CV_SymKind_COMPILE:{result = sizeof(CV_SymCompile);}break; +case CV_SymKind_SSEARCH:{result = sizeof(CV_SymStartSearch);}break; +case CV_SymKind_RETURN:{result = sizeof(CV_SymReturn);}break; +case CV_SymKind_SLINK32:{result = sizeof(CV_SymSLink32);}break; +case CV_SymKind_OEM:{result = sizeof(CV_SymOEM);}break; +case CV_SymKind_VFTABLE32:{result = sizeof(CV_SymVPath32);}break; +case CV_SymKind_FRAMEPROC:{result = sizeof(CV_SymFrameproc);}break; +case CV_SymKind_ANNOTATION:{result = sizeof(CV_SymAnnotation);}break; +case CV_SymKind_OBJNAME:{result = sizeof(CV_SymObjname);}break; +case CV_SymKind_THUNK32:{result = sizeof(CV_SymThunk32);}break; +case CV_SymKind_BLOCK32:{result = sizeof(CV_SymBlock32);}break; +case CV_SymKind_LABEL32:{result = sizeof(CV_SymLabel32);}break; +case CV_SymKind_REGISTER:{result = sizeof(CV_SymRegister);}break; +case CV_SymKind_CONSTANT:{result = sizeof(CV_SymConstant);}break; +case CV_SymKind_UDT:{result = sizeof(CV_SymUDT);}break; +case CV_SymKind_MANYREG:{result = sizeof(CV_SymManyreg);}break; +case CV_SymKind_BPREL32:{result = sizeof(CV_SymBPRel32);}break; +case CV_SymKind_LDATA32:{result = sizeof(CV_SymData32);}break; +case CV_SymKind_GDATA32:{result = sizeof(CV_SymData32);}break; +case CV_SymKind_PUB32:{result = sizeof(CV_SymPub32);}break; +case CV_SymKind_LPROC32:{result = sizeof(CV_SymProc32);}break; +case CV_SymKind_GPROC32:{result = sizeof(CV_SymProc32);}break; +case CV_SymKind_REGREL32:{result = sizeof(CV_SymRegrel32);}break; +case CV_SymKind_LTHREAD32:{result = sizeof(CV_SymThread32);}break; +case CV_SymKind_GTHREAD32:{result = sizeof(CV_SymThread32);}break; +case CV_SymKind_COMPILE2:{result = sizeof(CV_SymCompile2);}break; +case CV_SymKind_MANYREG2:{result = sizeof(CV_SymManyreg2);}break; +case CV_SymKind_LOCALSLOT:{result = sizeof(CV_SymSlot);}break; +case CV_SymKind_MANFRAMEREL:{result = sizeof(CV_SymAttrFrameRel);}break; +case CV_SymKind_MANREGISTER:{result = sizeof(CV_SymAttrReg);}break; +case CV_SymKind_MANMANYREG:{result = sizeof(CV_SymAttrManyReg);}break; +case CV_SymKind_MANREGREL:{result = sizeof(CV_SymAttrRegRel);}break; +case CV_SymKind_UNAMESPACE:{result = sizeof(CV_SymUNamespace);}break; +case CV_SymKind_PROCREF:{result = sizeof(CV_SymRef2);}break; +case CV_SymKind_DATAREF:{result = sizeof(CV_SymRef2);}break; +case CV_SymKind_LPROCREF:{result = sizeof(CV_SymRef2);}break; +case CV_SymKind_TRAMPOLINE:{result = sizeof(CV_SymTrampoline);}break; +case CV_SymKind_ATTR_FRAMEREL:{result = sizeof(CV_SymAttrFrameRel);}break; +case CV_SymKind_ATTR_REGISTER:{result = sizeof(CV_SymAttrReg);}break; +case CV_SymKind_ATTR_REGREL:{result = sizeof(CV_SymAttrRegRel);}break; +case CV_SymKind_ATTR_MANYREG:{result = sizeof(CV_SymAttrManyReg);}break; +case CV_SymKind_SEPCODE:{result = sizeof(CV_SymSepcode);}break; +case CV_SymKind_SECTION:{result = sizeof(CV_SymSection);}break; +case CV_SymKind_COFFGROUP:{result = sizeof(CV_SymCoffGroup);}break; +case CV_SymKind_EXPORT:{result = sizeof(CV_SymExport);}break; +case CV_SymKind_CALLSITEINFO:{result = sizeof(CV_SymCallSiteInfo);}break; +case CV_SymKind_FRAMECOOKIE:{result = sizeof(CV_SymFrameCookie);}break; +case CV_SymKind_DISCARDED:{result = sizeof(CV_SymDiscarded);}break; +case CV_SymKind_COMPILE3:{result = sizeof(CV_SymCompile3);}break; +case CV_SymKind_ENVBLOCK:{result = sizeof(CV_SymEnvBlock);}break; +case CV_SymKind_LOCAL:{result = sizeof(CV_SymLocal);}break; +case CV_SymKind_DEFRANGE_SUBFIELD:{result = sizeof(CV_SymDefrangeSubfield);}break; +case CV_SymKind_DEFRANGE_REGISTER:{result = sizeof(CV_SymDefrangeRegister);}break; +case CV_SymKind_DEFRANGE_FRAMEPOINTER_REL:{result = sizeof(CV_SymDefrangeFramepointerRel);}break; +case CV_SymKind_DEFRANGE_SUBFIELD_REGISTER:{result = sizeof(CV_SymDefrangeSubfieldRegister);}break; +case CV_SymKind_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:{result = sizeof(CV_SymDefrangeFramepointerRelFullScope);}break; +case CV_SymKind_DEFRANGE_REGISTER_REL:{result = sizeof(CV_SymDefrangeRegisterRel);}break; +case CV_SymKind_BUILDINFO:{result = sizeof(CV_SymBuildInfo);}break; +case CV_SymKind_INLINESITE:{result = sizeof(CV_SymInlineSite);}break; +case CV_SymKind_FILESTATIC:{result = sizeof(CV_SymFileStatic);}break; +case CV_SymKind_CALLEES:{result = sizeof(CV_SymFunctionList);}break; +case CV_SymKind_CALLERS:{result = sizeof(CV_SymFunctionList);}break; +case CV_SymKind_POGODATA:{result = sizeof(CV_SymPogoInfo);}break; +case CV_SymKind_INLINESITE2:{result = sizeof(CV_SymInlineSite2);}break; +case CV_SymKind_HEAPALLOCSITE:{result = sizeof(CV_SymHeapAllocSite);}break; +case CV_SymKind_MOD_TYPEREF:{result = sizeof(CV_SymModTypeRef);}break; +case CV_SymKind_REF_MINIPDB:{result = sizeof(CV_SymRefMiniPdb);}break; +case CV_SymKind_FASTLINK:{result = sizeof(CV_SymFastLink);}break; +case CV_SymKind_INLINEES:{result = sizeof(CV_SymInlinees);}break; +} +return result; +} C_LINKAGE_BEGIN C_LINKAGE_END diff --git a/src/codeview/generated/codeview.meta.h b/src/codeview/generated/codeview.meta.h index a04b4f8c..fe61870e 100644 --- a/src/codeview/generated/codeview.meta.h +++ b/src/codeview/generated/codeview.meta.h @@ -455,6 +455,7 @@ internal String8 cv_string_from_numeric_kind(CV_NumericKind v); internal String8 cv_string_from_arch(CV_Arch v); internal String8 cv_string_from_sym_kind(CV_SymKind v); internal String8 cv_string_from_leaf_kind(CV_LeafKind v); +internal U64 cv_header_struct_size_from_sym_kind(CV_SymKind v); C_LINKAGE_BEGIN C_LINKAGE_END diff --git a/src/raddbgi_convert/pdb/raddbgi_from_pdb.c b/src/raddbgi_convert/pdb/raddbgi_from_pdb.c index b85ee234..a992ee85 100644 --- a/src/raddbgi_convert/pdb/raddbgi_from_pdb.c +++ b/src/raddbgi_convert/pdb/raddbgi_from_pdb.c @@ -1940,65 +1940,70 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); - - // extract important values from parameters String8 data = sym->data; U64 user_id_base = (((U64)sym_unique_id) << 32); U64 sym_unique_id_hash = raddbgi_hash((U8*)&sym_unique_id, sizeof(sym_unique_id)); - // PASS 1: map out data associations + ////////////////////////////// + //- rjf: PASS 1: map out data associations + // ProfScope("map out data associations") { - // state variables RADDBGIC_Symbol *current_proc = 0; - - // loop - CV_RecRange *rec_range = sym->sym_ranges.ranges; - CV_RecRange *opl = rec_range + sym->sym_ranges.count; - for(;rec_range < opl; rec_range += 1) + 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) { - // symbol data range - U64 opl_off_raw = rec_range->off + rec_range->hdr.size; - U64 opl_off = ClampTop(opl_off_raw, data.size); + //- rjf: rec range -> symbol info range + U64 sym_off_first = rec_range->off + 2; + U64 sym_off_opl = rec_range->off + rec_range->hdr.size; - U64 off_raw = rec_range->off + 2; - U64 off = ClampTop(off_raw, opl_off); + //- rjf: skip invalid ranges + if(sym_off_opl > data.size || sym_off_first > data.size || sym_off_first > sym_off_opl) + { + continue; + } - U8 *first = data.str + off; - U64 cap = (opl_off - off); + //- rjf: unpack symbol info + CV_SymKind kind = rec_range->hdr.kind; + U64 sym_header_struct_size = cv_header_struct_size_from_sym_kind(kind); + void *sym_header_struct_base = data.str + sym_off_first; - CV_SymKind kind = rec_range->hdr.kind; + //- rjf: skip bad sizes + if(sym_off_first + sym_header_struct_size > sym_off_opl) + { + continue; + } + + //- rjf: consume symbol based on kind switch(kind) { default:{}break; + //- rjf: FRAMEPROC case CV_SymKind_FRAMEPROC: { - if(sizeof(CV_SymFrameproc) > cap) + CV_SymFrameproc *frameproc = (CV_SymFrameproc*)sym_header_struct_base; + if(current_proc == 0) { // TODO(allen): error } else { - CV_SymFrameproc *frameproc = (CV_SymFrameproc*)first; - if(current_proc == 0) - { - // TODO(allen): error - } - else - { - PDBCONV_FrameProcData data = {0}; - data.frame_size = frameproc->frame_size; - data.flags = frameproc->flags; - pdbconv_symbol_frame_proc_write(ctx, current_proc, &data); - } + PDBCONV_FrameProcData data = {0}; + data.frame_size = frameproc->frame_size; + data.flags = frameproc->flags; + pdbconv_symbol_frame_proc_write(ctx, current_proc, &data); } }break; + //- rjf: LPROC32/GPROC32 case CV_SymKind_LPROC32: case CV_SymKind_GPROC32: { - U64 symbol_id = user_id_base + off; + U64 symbol_id = user_id_base + sym_off_first; U64 symbol_hash = pdbconv_hash_from_symbol_user_id(sym_unique_id_hash, symbol_id); current_proc = raddbgic_symbol_handle_from_user_id(ctx->root, symbol_id, symbol_hash); }break; @@ -2006,31 +2011,44 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) } } - // PASS 2: main symbol construction pass + ////////////////////////////// + //- rjf: PASS 2: main symbol construction pass + // ProfScope("main symbol construction pass") { - // state variables RADDBGIC_LocationSet *defrange_target = 0; B32 defrange_target_is_param = 0; - - // loop - CV_RecRange *rec_range = sym->sym_ranges.ranges; - CV_RecRange *opl = rec_range + sym->sym_ranges.count; U64 local_num = 1; U64 scope_num = 1; - for(;rec_range < opl; rec_range += 1) + 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) { - // symbol data range - U64 opl_off_raw = rec_range->off + rec_range->hdr.size; - U64 opl_off = ClampTop(opl_off_raw, data.size); + //- rjf: rec range -> symbol info range + U64 sym_off_first = rec_range->off + 2; + U64 sym_off_opl = rec_range->off + rec_range->hdr.size; - U64 off_raw = rec_range->off + 2; - U64 off = ClampTop(off_raw, opl_off); + //- rjf: skip invalid ranges + if(sym_off_opl > data.size || sym_off_first > data.size || sym_off_first > sym_off_opl) + { + continue; + } - U8 *first = data.str + off; - U64 cap = (opl_off - off); + //- rjf: unpack symbol info + CV_SymKind kind = rec_range->hdr.kind; + U64 sym_header_struct_size = cv_header_struct_size_from_sym_kind(kind); + void *sym_header_struct_base = data.str + sym_off_first; + void *sym_data_opl = data.str + sym_off_opl; - // current state + //- rjf: skip bad sizes + if(sym_off_first + sym_header_struct_size > sym_off_opl) + { + continue; + } + + //- rjf: unpack current state RADDBGIC_Scope *current_scope = pdbconv_symbol_current_scope(ctx); RADDBGIC_Symbol *current_procedure = 0; if(current_scope != 0) @@ -2038,148 +2056,63 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) current_procedure = current_scope->symbol; } - CV_SymKind kind = rec_range->hdr.kind; + //- rjf: consume symbol based on kind switch(kind) { default:{}break; + //- rjf: END case CV_SymKind_END: - //ProfScope("CV_SymKind_END") { - // pop scope stack pdbconv_symbol_pop_scope(ctx); defrange_target = 0; defrange_target_is_param = 0; }break; - case CV_SymKind_FRAMEPROC: - //ProfScope("CV_SymKind_FRAMEPROC") - { - if(sizeof(CV_SymFrameproc) > cap) - { - // TODO(allen): error - } - else - { - // do nothing (handled in 'association map' pass) - } - }break; - + //- rjf: BLOCK32 case CV_SymKind_BLOCK32: - //ProfScope("CV_SymKind_BLOCK32") { - if(sizeof(CV_SymBlock32) > cap) + CV_SymBlock32 *block32 = (CV_SymBlock32*)sym_header_struct_base; + + // scope + U64 scope_id = user_id_base + scope_num; + scope_num += 1; + U64 scope_hash = pdbconv_hash_from_scope_user_id(sym_unique_id_hash, scope_id); + RADDBGIC_Scope *block_scope = raddbgic_scope_handle_from_user_id(ctx->root, scope_id, scope_hash); + raddbgic_scope_set_parent(ctx->root, block_scope, current_scope); + pdbconv_symbol_push_scope(ctx, block_scope, current_procedure); + + // set voff range + COFF_SectionHeader *section = pdbconv_sec_header_from_sec_num(ctx, block32->sec); + if(section != 0) { - // TODO(allen): error - } - else - { - CV_SymBlock32 *block32 = (CV_SymBlock32*)first; - - // scope - U64 scope_id = user_id_base + scope_num; - U64 scope_hash = pdbconv_hash_from_scope_user_id(sym_unique_id_hash, scope_id); - scope_num += 1; - RADDBGIC_Scope *block_scope = raddbgic_scope_handle_from_user_id(ctx->root, scope_id, scope_hash); - raddbgic_scope_set_parent(ctx->root, block_scope, current_scope); - pdbconv_symbol_push_scope(ctx, block_scope, current_procedure); - - // set voff range - COFF_SectionHeader *section = pdbconv_sec_header_from_sec_num(ctx, block32->sec); - if(section != 0) - { - U64 voff_first = section->voff + block32->off; - U64 voff_last = voff_first + block32->len; - raddbgic_scope_add_voff_range(ctx->root, block_scope, voff_first, voff_last); - } + U64 voff_first = section->voff + block32->off; + U64 voff_last = voff_first + block32->len; + raddbgic_scope_add_voff_range(ctx->root, block_scope, voff_first, voff_last); } }break; + //- rjf: LDATA32/GDATA32 case CV_SymKind_LDATA32: case CV_SymKind_GDATA32: - //ProfScope("CV_SymKind_LDATA32/CV_SymKind_GDATA32") { - if(sizeof(CV_SymData32) > cap) + CV_SymData32 *data32 = (CV_SymData32*)sym_header_struct_base; + String8 name = str8_cstring_capped(data32+1, sym_data_opl); + + // determine voff + COFF_SectionHeader *section = pdbconv_sec_header_from_sec_num(ctx, data32->sec); + U64 voff = ((section != 0)?section->voff:0) + data32->off; + + // deduplicate global variable symbols with the same name & offset + // * PDB likes to have duplicates of these spread across + // * different symbol streams so we deduplicate across the + // * entire translation context. + if(!pdbconv_known_global_lookup(&ctx->known_globals, name, voff)) { - // TODO(allen): error - } - else - { - CV_SymData32 *data32 = (CV_SymData32*)first; + pdbconv_known_global_insert(ctx->arena, &ctx->known_globals, name, voff); - // name - String8 name = str8_cstring_capped((char*)(data32 + 1), first + cap); - - // determine voff - COFF_SectionHeader *section = pdbconv_sec_header_from_sec_num(ctx, data32->sec); - U64 voff = ((section != 0)?section->voff:0) + data32->off; - - // deduplicate global variable symbols with the same name & offset - // * PDB likes to have duplicates of these spread across - // * different symbol streams so we deduplicate across the - // * entire translation context. - if(!pdbconv_known_global_lookup(&ctx->known_globals, name, voff)) - { - pdbconv_known_global_insert(ctx->arena, &ctx->known_globals, name, voff); - - // type of variable - RADDBGIC_Type *type = pdbconv_type_resolve_itype(ctx, data32->itype); - - // container type - RADDBGIC_Type *container_type = 0; - U64 container_name_opl = pdbconv_end_of_cplusplus_container_name(name); - if(container_name_opl > 2) - { - String8 container_name = str8(name.str, container_name_opl - 2); - container_type = pdbconv_type_from_name(ctx, container_name); - } - - // container symbol - RADDBGIC_Symbol *container_symbol = 0; - if(container_type == 0) - { - container_symbol = current_procedure; - } - - // determine link kind - B32 is_extern = (kind == CV_SymKind_GDATA32); - - // cons this symbol - U64 symbol_id = user_id_base + off; - U64 symbol_hash = pdbconv_hash_from_symbol_user_id(sym_unique_id_hash, symbol_id); - RADDBGIC_Symbol *symbol = raddbgic_symbol_handle_from_user_id(ctx->root, symbol_id, symbol_hash); - - RADDBGIC_SymbolInfo info = zero_struct; - info.kind = RADDBGIC_SymbolKind_GlobalVariable; - info.name = name; - info.type = type; - info.is_extern = is_extern; - info.offset = voff; - info.container_type = container_type; - info.container_symbol = container_symbol; - - raddbgic_symbol_set_info(ctx->root, symbol, &info); - } - } - }break; - - case CV_SymKind_LPROC32: - case CV_SymKind_GPROC32: - //ProfScope("CV_SymKind_LPROC32/CV_SymKind_GPROC32") - { - if(sizeof(CV_SymProc32) > cap) - { - // TODO(allen): error - } - else - { - CV_SymProc32 *proc32 = (CV_SymProc32*)first; - - // name - String8 name = str8_cstring_capped((char*)(proc32 + 1), first + cap); - - // type of procedure - RADDBGIC_Type *type = pdbconv_type_resolve_itype(ctx, proc32->itype); + // type of variable + RADDBGIC_Type *type = pdbconv_type_resolve_itype(ctx, data32->itype); // container type RADDBGIC_Type *container_type = 0; @@ -2197,119 +2130,288 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) container_symbol = current_procedure; } - // get this symbol handle - U64 symbol_id = user_id_base + off; - U64 symbol_hash = pdbconv_hash_from_symbol_user_id(sym_unique_id_hash, symbol_id); - RADDBGIC_Symbol *proc_symbol = raddbgic_symbol_handle_from_user_id(ctx->root, symbol_id, symbol_hash); - - // scope - - // NOTE: even if there could be a containing scope at this point (which should be - // illegal in C/C++ but not necessarily in another language) we would not pass - // it here because these scopes refer to the ranges of code that make up a - // procedure *not* the namespaces, so a procedure's root scope always has - // no parent. - U64 scope_id = user_id_base + scope_num; - U64 scope_hash = pdbconv_hash_from_scope_user_id(sym_unique_id_hash, scope_id); - RADDBGIC_Scope *root_scope = raddbgic_scope_handle_from_user_id(ctx->root, scope_id, scope_hash); - pdbconv_symbol_push_scope(ctx, root_scope, proc_symbol); - scope_num += 1; - - // set voff range - U64 voff = 0; - COFF_SectionHeader *section = pdbconv_sec_header_from_sec_num(ctx, proc32->sec); - if(section != 0) - { - U64 voff_first = section->voff + proc32->off; - U64 voff_last = voff_first + proc32->len; - raddbgic_scope_add_voff_range(ctx->root, root_scope, voff_first, voff_last); - - voff = voff_first; - } - - // link name - String8 link_name = {0}; - if(voff != 0) - { - link_name = pdbconv_link_name_find(&ctx->link_names, voff); - } - // determine link kind - B32 is_extern = (kind == CV_SymKind_GPROC32); + B32 is_extern = (kind == CV_SymKind_GDATA32); + + // cons this symbol + U64 symbol_id = user_id_base + sym_off_first; + U64 symbol_hash = pdbconv_hash_from_symbol_user_id(sym_unique_id_hash, symbol_id); + RADDBGIC_Symbol *symbol = raddbgic_symbol_handle_from_user_id(ctx->root, symbol_id, symbol_hash); - // set symbol info RADDBGIC_SymbolInfo info = zero_struct; - info.kind = RADDBGIC_SymbolKind_Procedure; + info.kind = RADDBGIC_SymbolKind_GlobalVariable; info.name = name; - info.link_name = link_name; info.type = type; info.is_extern = is_extern; + info.offset = voff; info.container_type = container_type; info.container_symbol = container_symbol; - info.root_scope = root_scope; - raddbgic_symbol_set_info(ctx->root, proc_symbol, &info); + raddbgic_symbol_set_info(ctx->root, symbol, &info); } }break; - case CV_SymKind_REGREL32: - ProfScope("CV_SymKind_REGREL32") + //- rjf: LPROC32/GPROC32 + case CV_SymKind_LPROC32: + case CV_SymKind_GPROC32: { - if(sizeof(CV_SymRegrel32) > cap) + CV_SymProc32 *proc32 = (CV_SymProc32*)sym_header_struct_base; + String8 name = str8_cstring_capped(proc32+1, sym_data_opl); + RADDBGIC_Type *type = pdbconv_type_resolve_itype(ctx, proc32->itype); + + // container type + RADDBGIC_Type *container_type = 0; + U64 container_name_opl = pdbconv_end_of_cplusplus_container_name(name); + if(container_name_opl > 2) { - // TODO(allen): error + String8 container_name = str8(name.str, container_name_opl - 2); + container_type = pdbconv_type_from_name(ctx, container_name); } + + // container symbol + RADDBGIC_Symbol *container_symbol = 0; + if(container_type == 0) + { + container_symbol = current_procedure; + } + + // get this symbol handle + U64 symbol_id = user_id_base + sym_off_first; + U64 symbol_hash = pdbconv_hash_from_symbol_user_id(sym_unique_id_hash, symbol_id); + RADDBGIC_Symbol *proc_symbol = raddbgic_symbol_handle_from_user_id(ctx->root, symbol_id, symbol_hash); + + // scope + + // NOTE: even if there could be a containing scope at this point (which should be + // illegal in C/C++ but not necessarily in another language) we would not pass + // it here because these scopes refer to the ranges of code that make up a + // procedure *not* the namespaces, so a procedure's root scope always has + // no parent. + U64 scope_id = user_id_base + scope_num; + U64 scope_hash = pdbconv_hash_from_scope_user_id(sym_unique_id_hash, scope_id); + RADDBGIC_Scope *root_scope = raddbgic_scope_handle_from_user_id(ctx->root, scope_id, scope_hash); + pdbconv_symbol_push_scope(ctx, root_scope, proc_symbol); + scope_num += 1; + + // set voff range + U64 voff = 0; + COFF_SectionHeader *section = pdbconv_sec_header_from_sec_num(ctx, proc32->sec); + if(section != 0) + { + U64 voff_first = section->voff + proc32->off; + U64 voff_last = voff_first + proc32->len; + raddbgic_scope_add_voff_range(ctx->root, root_scope, voff_first, voff_last); + + voff = voff_first; + } + + // link name + String8 link_name = {0}; + if(voff != 0) + { + link_name = pdbconv_link_name_find(&ctx->link_names, voff); + } + + // determine link kind + B32 is_extern = (kind == CV_SymKind_GPROC32); + + // set symbol info + RADDBGIC_SymbolInfo info = zero_struct; + info.kind = RADDBGIC_SymbolKind_Procedure; + info.name = name; + info.link_name = link_name; + info.type = type; + info.is_extern = is_extern; + info.container_type = container_type; + info.container_symbol = container_symbol; + info.root_scope = root_scope; + + raddbgic_symbol_set_info(ctx->root, proc_symbol, &info); + }break; + + //- rjf: REGREL32 + case CV_SymKind_REGREL32: + { + // TODO(allen): hide this when it's redundant with better information + // from a CV_SymKind_LOCAL record. + + CV_SymRegrel32 *regrel32 = (CV_SymRegrel32*)sym_header_struct_base; + String8 name = str8_cstring_capped(regrel32+1, sym_data_opl); + RADDBGIC_Type *type = pdbconv_type_resolve_itype(ctx, regrel32->itype); + + // extract regrel's info + CV_Reg cv_reg = regrel32->reg; + U32 var_off = regrel32->reg_off; + + // need arch for analyzing register stuff + RADDBGI_Arch arch = ctx->arch; + U64 addr_size = ctx->addr_size; + + // determine if this is a parameter + RADDBGI_LocalKind local_kind = RADDBGI_LocalKind_Variable; + { + B32 is_stack_reg = 0; + switch (arch) + { + case RADDBGI_Arch_X86: is_stack_reg = (cv_reg == CV_Regx86_ESP); break; + case RADDBGI_Arch_X64: is_stack_reg = (cv_reg == CV_Regx64_RSP); break; + } + if(is_stack_reg) + { + U32 frame_size = 0xFFFFFFFF; + if(current_procedure != 0) + { + PDBCONV_FrameProcData *frameproc = + pdbconv_symbol_frame_proc_read(ctx, current_procedure); + frame_size = frameproc->frame_size; + } + if(var_off > frame_size) + { + local_kind = RADDBGI_LocalKind_Parameter; + } + } + } + + // emit local + U64 local_id = user_id_base + local_num;; + U64 local_id_hash = pdbconv_hash_from_local_user_id(sym_unique_id_hash, local_id); + RADDBGIC_Local *local_var = raddbgic_local_handle_from_user_id(ctx->root, local_id, local_id_hash); + local_num += 1; + + RADDBGIC_LocalInfo info = {0}; + info.kind = local_kind; + info.scope = current_scope; + info.name = name; + info.type = type; + raddbgic_local_set_basic_info(ctx->root, local_var, &info); + + // add location to local + { + // will there be an extra indirection to the value + B32 extra_indirection_to_value = 0; + switch (arch) + { + case RADDBGI_Arch_X86: + { + if(local_kind == RADDBGI_LocalKind_Parameter && + (type->byte_size > 4 || !IsPow2OrZero(type->byte_size))) + { + extra_indirection_to_value = 1; + } + }break; + + case RADDBGI_Arch_X64: + { + if(local_kind == RADDBGI_LocalKind_Parameter && + (type->byte_size > 8 || !IsPow2OrZero(type->byte_size))) + { + extra_indirection_to_value = 1; + } + }break; + } + + // get raddbg register code + RADDBGI_RegisterCode register_code = raddbgi_reg_code_from_cv_reg_code(arch, cv_reg); + // TODO(allen): real byte_size & byte_pos from cv_reg goes here + U32 byte_size = 8; + U32 byte_pos = 0; + + // set location case + RADDBGIC_Location *loc = + pdbconv_location_from_addr_reg_off(ctx, register_code, byte_size, byte_pos, + (S64)(S32)var_off, extra_indirection_to_value); + + RADDBGIC_LocationSet *locset = raddbgic_location_set_from_local(ctx->root, local_var); + raddbgic_location_set_add_case(ctx->root, locset, 0, max_U64, loc); + } + }break; + + //- rjf: LTHREAD32/GTHREAD32 + case CV_SymKind_LTHREAD32: + case CV_SymKind_GTHREAD32: + { + CV_SymThread32 *thread32 = (CV_SymThread32*)sym_header_struct_base; + String8 name = str8_cstring_capped(thread32+1, sym_data_opl); + U32 tls_off = thread32->tls_off; + RADDBGIC_Type *type = pdbconv_type_resolve_itype(ctx, thread32->itype); + + // container type + RADDBGIC_Type *container_type = 0; + U64 container_name_opl = pdbconv_end_of_cplusplus_container_name(name); + if(container_name_opl > 2) + { + String8 container_name = str8(name.str, container_name_opl - 2); + container_type = pdbconv_type_from_name(ctx, container_name); + } + + // container symbol + RADDBGIC_Symbol *container_symbol = 0; + if(container_type == 0) + { + container_symbol = current_procedure; + } + + // determine link kind + B32 is_extern = (kind == CV_SymKind_GTHREAD32); + + // setup symbol + U64 symbol_id = user_id_base + sym_off_first; + U64 symbol_hash = pdbconv_hash_from_symbol_user_id(sym_unique_id_hash, symbol_id); + RADDBGIC_Symbol *symbol = raddbgic_symbol_handle_from_user_id(ctx->root, symbol_id, symbol_hash); + + RADDBGIC_SymbolInfo info = zero_struct; + info.kind = RADDBGIC_SymbolKind_ThreadVariable; + info.name = name; + info.type = type; + info.is_extern = is_extern; + info.offset = tls_off; + info.container_type = container_type; + info.container_symbol = container_symbol; + + raddbgic_symbol_set_info(ctx->root, symbol, &info); + }break; + + //- rjf: LOCAL + case CV_SymKind_LOCAL: + { + CV_SymLocal *slocal = (CV_SymLocal*)sym_header_struct_base; + String8 name = str8_cstring_capped(slocal+1, sym_data_opl); + RADDBGIC_Type *type = pdbconv_type_resolve_itype(ctx, slocal->itype); + + // determine how to handle + B32 begin_a_global_modification = 0; + if((slocal->flags & CV_LocalFlag_Global) || + (slocal->flags & CV_LocalFlag_Static)) + { + begin_a_global_modification = 1; + } + + // emit a global modification + if(begin_a_global_modification) + { + // TODO(allen): add global modification symbols + defrange_target = 0; + defrange_target_is_param = 0; + } + + // emit a local variable else { - // TODO(allen): hide this when it's redundant with better information - // from a CV_SymKind_LOCAL record. - - CV_SymRegrel32 *regrel32 = (CV_SymRegrel32*)first; - - // name - String8 name = str8_cstring_capped((char*)(regrel32 + 1), first + cap); - - // type of variable - RADDBGIC_Type *type = pdbconv_type_resolve_itype(ctx, regrel32->itype); - - // extract regrel's info - CV_Reg cv_reg = regrel32->reg; - U32 var_off = regrel32->reg_off; - - // need arch for analyzing register stuff - RADDBGI_Arch arch = ctx->arch; - U64 addr_size = ctx->addr_size; - - // determine if this is a parameter + // local kind RADDBGI_LocalKind local_kind = RADDBGI_LocalKind_Variable; + if(slocal->flags & CV_LocalFlag_Param) { - B32 is_stack_reg = 0; - switch (arch) - { - case RADDBGI_Arch_X86: is_stack_reg = (cv_reg == CV_Regx86_ESP); break; - case RADDBGI_Arch_X64: is_stack_reg = (cv_reg == CV_Regx64_RSP); break; - } - if(is_stack_reg) - { - U32 frame_size = 0xFFFFFFFF; - if(current_procedure != 0) - { - PDBCONV_FrameProcData *frameproc = - pdbconv_symbol_frame_proc_read(ctx, current_procedure); - frame_size = frameproc->frame_size; - } - if(var_off > frame_size) - { - local_kind = RADDBGI_LocalKind_Parameter; - } - } + local_kind = RADDBGI_LocalKind_Parameter; } // emit local - U64 local_id = user_id_base + local_num;; + U64 local_id = user_id_base + local_num; U64 local_id_hash = pdbconv_hash_from_local_user_id(sym_unique_id_hash, local_id); RADDBGIC_Local *local_var = raddbgic_local_handle_from_user_id(ctx->root, local_id, local_id_hash); local_num += 1; + local_var->kind = local_kind; + local_var->name = name; + local_var->type = type; RADDBGIC_LocalInfo info = {0}; info.kind = local_kind; @@ -2318,415 +2420,179 @@ pdbconv_symbol_cons(PDBCONV_Ctx *ctx, CV_SymParsed *sym, U32 sym_unique_id) info.type = type; raddbgic_local_set_basic_info(ctx->root, local_var, &info); - // add location to local - { - // will there be an extra indirection to the value - B32 extra_indirection_to_value = 0; - switch (arch) - { - case RADDBGI_Arch_X86: - { - if(local_kind == RADDBGI_LocalKind_Parameter && - (type->byte_size > 4 || !IsPow2OrZero(type->byte_size))) - { - extra_indirection_to_value = 1; - } - }break; - - case RADDBGI_Arch_X64: - { - if(local_kind == RADDBGI_LocalKind_Parameter && - (type->byte_size > 8 || !IsPow2OrZero(type->byte_size))) - { - extra_indirection_to_value = 1; - } - }break; - } - - // get raddbg register code - RADDBGI_RegisterCode register_code = raddbgi_reg_code_from_cv_reg_code(arch, cv_reg); - // TODO(allen): real byte_size & byte_pos from cv_reg goes here - U32 byte_size = 8; - U32 byte_pos = 0; - - // set location case - RADDBGIC_Location *loc = - pdbconv_location_from_addr_reg_off(ctx, register_code, byte_size, byte_pos, - (S64)(S32)var_off, extra_indirection_to_value); - - RADDBGIC_LocationSet *locset = raddbgic_location_set_from_local(ctx->root, local_var); - raddbgic_location_set_add_case(ctx->root, locset, 0, max_U64, loc); - } - } - }break; - - case CV_SymKind_LTHREAD32: - case CV_SymKind_GTHREAD32: - //ProfScope("CV_SymKind_LTHREAD32/CV_SymKind_GTHREAD32") - { - if(sizeof(CV_SymThread32) > cap) - { - // TODO(allen): error - } - else - { - CV_SymThread32 *thread32 = (CV_SymThread32*)first; - - // name - String8 name = str8_cstring_capped((char*)(thread32 + 1), first + cap); - - // determine tls off - U32 tls_off = thread32->tls_off; - - // type of variable - RADDBGIC_Type *type = pdbconv_type_resolve_itype(ctx, thread32->itype); - - // container type - RADDBGIC_Type *container_type = 0; - U64 container_name_opl = pdbconv_end_of_cplusplus_container_name(name); - if(container_name_opl > 2) - { - String8 container_name = str8(name.str, container_name_opl - 2); - container_type = pdbconv_type_from_name(ctx, container_name); - } - - // container symbol - RADDBGIC_Symbol *container_symbol = 0; - if(container_type == 0) - { - container_symbol = current_procedure; - } - - // determine link kind - B32 is_extern = (kind == CV_SymKind_GTHREAD32); - - // setup symbol - U64 symbol_id = user_id_base + off; - U64 symbol_hash = pdbconv_hash_from_symbol_user_id(sym_unique_id_hash, symbol_id); - RADDBGIC_Symbol *symbol = raddbgic_symbol_handle_from_user_id(ctx->root, symbol_id, symbol_hash); - - RADDBGIC_SymbolInfo info = zero_struct; - info.kind = RADDBGIC_SymbolKind_ThreadVariable; - info.name = name; - info.type = type; - info.is_extern = is_extern; - info.offset = tls_off; - info.container_type = container_type; - info.container_symbol = container_symbol; - - raddbgic_symbol_set_info(ctx->root, symbol, &info); - } - }break; - - case CV_SymKind_LOCAL: - //ProfScope("CV_SymKind_LOCAL") - { - if(sizeof(CV_SymLocal) > cap) - { - // TODO(allen): error - } - else - { - CV_SymLocal *slocal = (CV_SymLocal*)first; - - // name - String8 name = str8_cstring_capped((char*)(slocal + 1), first + cap); - - // type of variable - RADDBGIC_Type *type = pdbconv_type_resolve_itype(ctx, slocal->itype); - - // determine how to handle - B32 begin_a_global_modification = 0; - if((slocal->flags & CV_LocalFlag_Global) || - (slocal->flags & CV_LocalFlag_Static)) - { - begin_a_global_modification = 1; - } - - // emit a global modification - if(begin_a_global_modification) - { - // TODO(allen): add global modification symbols - defrange_target = 0; - defrange_target_is_param = 0; - } - - // emit a local variable - else - { - // local kind - RADDBGI_LocalKind local_kind = RADDBGI_LocalKind_Variable; - if(slocal->flags & CV_LocalFlag_Param) - { - local_kind = RADDBGI_LocalKind_Parameter; - } - - // emit local - U64 local_id = user_id_base + local_num; - U64 local_id_hash = pdbconv_hash_from_local_user_id(sym_unique_id_hash, local_id); - RADDBGIC_Local *local_var = raddbgic_local_handle_from_user_id(ctx->root, local_id, local_id_hash); - local_num += 1; - local_var->kind = local_kind; - local_var->name = name; - local_var->type = type; - - RADDBGIC_LocalInfo info = {0}; - info.kind = local_kind; - info.scope = current_scope; - info.name = name; - info.type = type; - raddbgic_local_set_basic_info(ctx->root, local_var, &info); - - defrange_target = raddbgic_location_set_from_local(ctx->root, local_var); - defrange_target_is_param = (local_kind == RADDBGI_LocalKind_Parameter); - } + defrange_target = raddbgic_location_set_from_local(ctx->root, local_var); + defrange_target_is_param = (local_kind == RADDBGI_LocalKind_Parameter); } }break; + //- rjf: DEFRANGE_REGISTESR case CV_SymKind_DEFRANGE_REGISTER: - //ProfScope("CV_SymKind_DEFRANGE_REGISTER") { - if(sizeof(CV_SymDefrangeRegister) > cap) - { - // TODO(allen): error - } - else - { - if(defrange_target == 0) - { - // TODO(allen): error - } - else - { - CV_SymDefrangeRegister *defrange_register = (CV_SymDefrangeRegister*)first; - - // TODO(allen): offset & size from cv_reg code - RADDBGI_Arch arch = ctx->arch; - CV_Reg cv_reg = defrange_register->reg; - RADDBGI_RegisterCode register_code = raddbgi_reg_code_from_cv_reg_code(arch, cv_reg); - - // setup location - RADDBGIC_Location *location = raddbgic_location_val_reg(ctx->root, register_code); - - // extract range info - CV_LvarAddrRange *range = &defrange_register->range; - CV_LvarAddrGap *gaps = (CV_LvarAddrGap*)(defrange_register + 1); - U64 gap_count = ((first + cap) - (U8*)gaps)/sizeof(*gaps); - - // emit locations - pdbconv_location_over_lvar_addr_range(ctx, defrange_target, location, - range, gaps, gap_count); - } - } + if(defrange_target == 0) { break; } + CV_SymDefrangeRegister *defrange_register = (CV_SymDefrangeRegister*)sym_header_struct_base; + + // TODO(allen): offset & size from cv_reg code + RADDBGI_Arch arch = ctx->arch; + CV_Reg cv_reg = defrange_register->reg; + RADDBGI_RegisterCode register_code = raddbgi_reg_code_from_cv_reg_code(arch, cv_reg); + + // setup location + RADDBGIC_Location *location = raddbgic_location_val_reg(ctx->root, register_code); + + // extract range info + CV_LvarAddrRange *range = &defrange_register->range; + CV_LvarAddrGap *gaps = (CV_LvarAddrGap*)(defrange_register+1); + U64 gap_count = ((U8*)sym_data_opl - (U8*)gaps) / sizeof(*gaps); + + // emit locations + pdbconv_location_over_lvar_addr_range(ctx, defrange_target, location, + range, gaps, gap_count); }break; + //- rjf: DEFRANGE_FRAMEPOINTER_REL case CV_SymKind_DEFRANGE_FRAMEPOINTER_REL: - //ProfScope("CV_SymKind_DEFRANGE_FRAMEPOINTER_REL") { - if(sizeof(CV_SymDefrangeFramepointerRel) > cap) - { - // TODO(allen): error - } - else - { - if(defrange_target == 0) - { - // TODO(allen): error - } - else - { - CV_SymDefrangeFramepointerRel *defrange_fprel = (CV_SymDefrangeFramepointerRel*)first; - - // select frame pointer register - CV_EncodedFramePtrReg encoded_fp_reg = - pdbconv_cv_encoded_fp_reg_from_proc(ctx, current_procedure, defrange_target_is_param); - RADDBGI_RegisterCode fp_register_code = - pdbconv_reg_code_from_arch_encoded_fp_reg(ctx->arch, encoded_fp_reg); - - // setup location - B32 extra_indirection = 0; - U32 byte_size = ctx->addr_size; - U32 byte_pos = 0; - S64 var_off = (S64)defrange_fprel->off; - RADDBGIC_Location *location = - pdbconv_location_from_addr_reg_off(ctx, fp_register_code, byte_size, byte_pos, - var_off, extra_indirection); - - // extract range info - CV_LvarAddrRange *range = &defrange_fprel->range; - CV_LvarAddrGap *gaps = (CV_LvarAddrGap*)(defrange_fprel + 1); - U64 gap_count = ((first + cap) - (U8*)gaps)/sizeof(*gaps); - - // emit locations - pdbconv_location_over_lvar_addr_range(ctx, defrange_target, location, - range, gaps, gap_count); - } - } + if(defrange_target == 0) { break; } + CV_SymDefrangeFramepointerRel *defrange_fprel = (CV_SymDefrangeFramepointerRel*)sym_header_struct_base; + + // select frame pointer register + CV_EncodedFramePtrReg encoded_fp_reg = + pdbconv_cv_encoded_fp_reg_from_proc(ctx, current_procedure, defrange_target_is_param); + RADDBGI_RegisterCode fp_register_code = + pdbconv_reg_code_from_arch_encoded_fp_reg(ctx->arch, encoded_fp_reg); + + // setup location + B32 extra_indirection = 0; + U32 byte_size = ctx->addr_size; + U32 byte_pos = 0; + S64 var_off = (S64)defrange_fprel->off; + RADDBGIC_Location *location = + pdbconv_location_from_addr_reg_off(ctx, fp_register_code, byte_size, byte_pos, + var_off, extra_indirection); + + // extract range info + CV_LvarAddrRange *range = &defrange_fprel->range; + CV_LvarAddrGap *gaps = (CV_LvarAddrGap*)(defrange_fprel + 1); + U64 gap_count = ((U8*)sym_data_opl - (U8*)gaps) / sizeof(*gaps); + + // emit locations + pdbconv_location_over_lvar_addr_range(ctx, defrange_target, location, + range, gaps, gap_count); }break; + //- rjf: DEFRANGE_SUBFIELD_REGISTER case CV_SymKind_DEFRANGE_SUBFIELD_REGISTER: - //ProfScope("CV_SymKind_DEFRANGE_SUBFIELD_REGISTER") { - if(sizeof(CV_SymDefrangeSubfieldRegister) > cap) + if(defrange_target == 0) { break; } + CV_SymDefrangeSubfieldRegister *defrange_subfield_register = (CV_SymDefrangeSubfieldRegister*)sym_header_struct_base; + + // TODO(allen): full "subfield" location system + if(defrange_subfield_register->field_offset == 0) { - // TODO(allen): error - } - else - { - if(defrange_target == 0) - { - // TODO(allen): error - } - else - { - CV_SymDefrangeSubfieldRegister *defrange_subfield_register = (CV_SymDefrangeSubfieldRegister*)first; - - // TODO(allen): full "subfield" location system - if(defrange_subfield_register->field_offset == 0) - { - - // TODO(allen): offset & size from cv_reg code - RADDBGI_Arch arch = ctx->arch; - CV_Reg cv_reg = defrange_subfield_register->reg; - RADDBGI_RegisterCode register_code = raddbgi_reg_code_from_cv_reg_code(arch, cv_reg); - - // setup location - RADDBGIC_Location *location = raddbgic_location_val_reg(ctx->root, register_code); - - // extract range info - CV_LvarAddrRange *range = &defrange_subfield_register->range; - CV_LvarAddrGap *gaps = (CV_LvarAddrGap*)(defrange_subfield_register + 1); - U64 gap_count = ((first + cap) - (U8*)gaps)/sizeof(*gaps); - - // emit locations - pdbconv_location_over_lvar_addr_range(ctx, defrange_target, location, - range, gaps, gap_count); - } - } + + // TODO(allen): offset & size from cv_reg code + RADDBGI_Arch arch = ctx->arch; + CV_Reg cv_reg = defrange_subfield_register->reg; + RADDBGI_RegisterCode register_code = raddbgi_reg_code_from_cv_reg_code(arch, cv_reg); + + // setup location + RADDBGIC_Location *location = raddbgic_location_val_reg(ctx->root, register_code); + + // extract range info + CV_LvarAddrRange *range = &defrange_subfield_register->range; + CV_LvarAddrGap *gaps = (CV_LvarAddrGap*)(defrange_subfield_register + 1); + U64 gap_count = ((U8*)sym_data_opl - (U8*)gaps) / sizeof(*gaps); + + // emit locations + pdbconv_location_over_lvar_addr_range(ctx, defrange_target, location, + range, gaps, gap_count); } }break; + //- rjf: DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE case CV_SymKind_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE: - //ProfScope("CV_SymKind_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE") { - if(sizeof(CV_SymDefrangeFramepointerRelFullScope) > cap) - { - // TODO(allen): error - } - else - { - if(defrange_target == 0) - { - // TODO(allen): error - } - else - { - CV_SymDefrangeFramepointerRelFullScope *defrange_fprel_full_scope = - (CV_SymDefrangeFramepointerRelFullScope*)first; - - // select frame pointer register - CV_EncodedFramePtrReg encoded_fp_reg = - pdbconv_cv_encoded_fp_reg_from_proc(ctx, current_procedure, defrange_target_is_param); - RADDBGI_RegisterCode fp_register_code = - pdbconv_reg_code_from_arch_encoded_fp_reg(ctx->arch, encoded_fp_reg); - - // setup location - B32 extra_indirection = 0; - U32 byte_size = ctx->addr_size; - U32 byte_pos = 0; - S64 var_off = (S64)defrange_fprel_full_scope->off; - RADDBGIC_Location *location = - pdbconv_location_from_addr_reg_off(ctx, fp_register_code, byte_size, byte_pos, - var_off, extra_indirection); - - - // emit location - raddbgic_location_set_add_case(ctx->root, defrange_target, 0, max_U64, location); - } - } + if(defrange_target == 0) { break; } + CV_SymDefrangeFramepointerRelFullScope *defrange_fprel_full_scope = + (CV_SymDefrangeFramepointerRelFullScope*)sym_header_struct_base; + + // select frame pointer register + CV_EncodedFramePtrReg encoded_fp_reg = + pdbconv_cv_encoded_fp_reg_from_proc(ctx, current_procedure, defrange_target_is_param); + RADDBGI_RegisterCode fp_register_code = + pdbconv_reg_code_from_arch_encoded_fp_reg(ctx->arch, encoded_fp_reg); + + // setup location + B32 extra_indirection = 0; + U32 byte_size = ctx->addr_size; + U32 byte_pos = 0; + S64 var_off = (S64)defrange_fprel_full_scope->off; + RADDBGIC_Location *location = + pdbconv_location_from_addr_reg_off(ctx, fp_register_code, byte_size, byte_pos, + var_off, extra_indirection); + + + // emit location + raddbgic_location_set_add_case(ctx->root, defrange_target, 0, max_U64, location); }break; + //- rjf: DEFRANGE_REGISTER_REL case CV_SymKind_DEFRANGE_REGISTER_REL: - //ProfScope("CV_SymKind_DEFRANGE_REGISTER_REL") { - if(sizeof(CV_SymDefrangeRegisterRel) > cap) - { - // TODO(allen): error - } - else - { - CV_SymDefrangeRegisterRel *defrange_register_rel = (CV_SymDefrangeRegisterRel*)first; - if(defrange_target == 0) - { - // TODO(rjf): error - } - else - { - // TODO(allen): offset & size from cv_reg code - RADDBGI_Arch arch = ctx->arch; - CV_Reg cv_reg = defrange_register_rel->reg; - RADDBGI_RegisterCode register_code = raddbgi_reg_code_from_cv_reg_code(arch, cv_reg); - U32 byte_size = ctx->addr_size; - U32 byte_pos = 0; - - B32 extra_indirection_to_value = 0; - S64 var_off = defrange_register_rel->reg_off; - - // setup location - RADDBGIC_Location *location = - pdbconv_location_from_addr_reg_off(ctx, register_code, byte_size, byte_pos, - var_off, extra_indirection_to_value); - - // extract range info - CV_LvarAddrRange *range = &defrange_register_rel->range; - CV_LvarAddrGap *gaps = (CV_LvarAddrGap*)(defrange_register_rel + 1); - U64 gap_count = ((first + cap) - (U8*)gaps)/sizeof(*gaps); - - - // emit locations - pdbconv_location_over_lvar_addr_range(ctx, defrange_target, location, - range, gaps, gap_count); - } - } + if(defrange_target == 0) { break; } + CV_SymDefrangeRegisterRel *defrange_register_rel = (CV_SymDefrangeRegisterRel*)sym_header_struct_base; + + // TODO(allen): offset & size from cv_reg code + RADDBGI_Arch arch = ctx->arch; + CV_Reg cv_reg = defrange_register_rel->reg; + RADDBGI_RegisterCode register_code = raddbgi_reg_code_from_cv_reg_code(arch, cv_reg); + U32 byte_size = ctx->addr_size; + U32 byte_pos = 0; + + B32 extra_indirection_to_value = 0; + S64 var_off = defrange_register_rel->reg_off; + + // setup location + RADDBGIC_Location *location = + pdbconv_location_from_addr_reg_off(ctx, register_code, byte_size, byte_pos, + var_off, extra_indirection_to_value); + + // extract range info + CV_LvarAddrRange *range = &defrange_register_rel->range; + CV_LvarAddrGap *gaps = (CV_LvarAddrGap*)(defrange_register_rel + 1); + U64 gap_count = ((U8*)sym_data_opl - (U8*)gaps) / sizeof(*gaps); + + // emit locations + pdbconv_location_over_lvar_addr_range(ctx, defrange_target, location, + range, gaps, gap_count); }break; + //- rjf: FILESTATIC case CV_SymKind_FILESTATIC: - //ProfScope("CV_SymKind_FILESTATIC") { - if(sizeof(CV_SymFileStatic) > cap) - { - // TODO(allen): error - } - else - { - CV_SymFileStatic *file_static = (CV_SymFileStatic*)first; - - // name - String8 name = str8_cstring_capped((char*)(file_static + 1), first + cap); - - // type of variable - RADDBGIC_Type *type = pdbconv_type_resolve_itype(ctx, file_static->itype); - - // TODO(allen): emit a global modifier symbol - - // defrange records from this point attach to this location information - defrange_target = 0; - defrange_target_is_param = 0; - } + CV_SymFileStatic *file_static = (CV_SymFileStatic*)sym_header_struct_base; + String8 name = str8_cstring_capped(file_static+1, sym_data_opl); + RADDBGIC_Type *type = pdbconv_type_resolve_itype(ctx, file_static->itype); + + // TODO(allen): emit a global modifier symbol + + // defrange records from this point attach to this location information + defrange_target = 0; + defrange_target_is_param = 0; }break; } } - // if scope stack isn't empty emit an error + //- rjf: non-empty scope stack? -> error { - RADDBGIC_Scope* scope = pdbconv_symbol_current_scope(ctx); + RADDBGIC_Scope *scope = pdbconv_symbol_current_scope(ctx); if(scope != 0) { // TODO(allen): emit error } } - // clear the scope stack + //- rjf: clear scope stack pdbconv_symbol_clear_scope_stack(ctx); }