From a0dbe72820e508b8bef6d29bb2b272ce7c1d5a3f Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Thu, 21 Nov 2024 15:57:09 -0800 Subject: [PATCH] moved common codeview code to the main layer --- src/codeview/codeview.c | 903 ++++++++++++++++++++++++++ src/codeview/codeview.h | 81 +++ src/linker/codeview_ext/codeview.c | 997 +---------------------------- src/linker/codeview_ext/codeview.h | 85 +-- src/linker/lnk_debug_info.c | 2 +- src/linker/pdb_ext/pdb_builder.c | 2 +- src/pdb/pdb_parse.c | 47 +- src/rdi_from_pdb/rdi_from_pdb.c | 20 +- src/rdi_from_pdb/rdi_from_pdb.h | 1 - 9 files changed, 1005 insertions(+), 1133 deletions(-) diff --git a/src/codeview/codeview.c b/src/codeview/codeview.c index d63679c2..92ba9a59 100644 --- a/src/codeview/codeview.c +++ b/src/codeview/codeview.c @@ -6,6 +6,139 @@ #include "generated/codeview.meta.c" +//////////////////////////////// + +internal CV_Arch +cv_arch_from_coff_machine(COFF_MachineType machine) +{ + CV_Arch arch = 0; + switch(machine) + { + case COFF_MachineType_X64: arch = CV_Arch_X64; break; + case COFF_MachineType_X86: arch = CV_Arch_8086; break; + case COFF_MachineType_AM33: arch = CV_Arch_AM33; break; + case COFF_MachineType_ARM: NotImplemented; break; + case COFF_MachineType_ARM64: arch = CV_Arch_ARM64; break; + case COFF_MachineType_ARMNT: arch = CV_Arch_ARMNT; break; + case COFF_MachineType_EBC: arch = CV_Arch_EBC; break; + case COFF_MachineType_IA64: arch = CV_Arch_IA64; break; + case COFF_MachineType_M32R: arch = CV_Arch_M32R; break; + case COFF_MachineType_MIPS16: arch = CV_Arch_MIPS16; break; + case COFF_MachineType_MIPSFPU: NotImplemented; break; + case COFF_MachineType_MIPSFPU16: NotImplemented; break; + case COFF_MachineType_POWERPC: NotImplemented; break; + case COFF_MachineType_POWERPCFP: arch = CV_Arch_PPCFP; break; + case COFF_MachineType_R4000: NotImplemented; break; + case COFF_MachineType_RISCV32: NotImplemented; break; + case COFF_MachineType_RISCV64: NotImplemented; break; + case COFF_MachineType_RISCV128: NotImplemented; break; + case COFF_MachineType_SH3: arch = CV_Arch_SH3; break; + case COFF_MachineType_SH3DSP: arch = CV_Arch_SH3DSP; break; + case COFF_MachineType_SH4: arch = CV_Arch_SH4; break; + case COFF_MachineType_SH5: NotImplemented; break; + case COFF_MachineType_THUMB: arch = CV_Arch_THUMB; break; + case COFF_MachineType_WCEMIPSV2: NotImplemented; break; + } + return arch; +} + +internal U64 +cv_size_from_reg(CV_Arch arch, CV_Reg reg) +{ + switch(arch) + { + case CV_Arch_8086: return cv_size_from_reg_x86(reg); + case CV_Arch_X64 : return cv_size_from_reg_x64(reg); + default: NotImplemented; + } + return 0; +} + +internal B32 +cv_is_reg_sp(CV_Arch arch, CV_Reg reg) +{ + switch(arch) + { + case CV_Arch_8086: return reg == CV_Regx86_ESP; + case CV_Arch_X64: return reg == CV_Regx64_RSP; + default: NotImplemented; + } + return 0; +} + +internal U64 +cv_size_from_reg_x86(CV_Reg reg) +{ + switch(reg) + { +#define X(NAME, CODE, RDI_NAME, BYTE_POS, BYTE_SIZE) case CV_Regx86_##NAME: return BYTE_SIZE; + CV_Reg_X86_XList(X) +#undef X + } + return 0; +} + +internal U64 +cv_size_from_reg_x64(CV_Reg reg) +{ + switch(reg) + { +#define X(NAME, CODE, RDI_NAME, BYTE_POS, BYTE_SIZE) case CV_Regx64_##NAME: return BYTE_SIZE; + CV_Reg_X64_XList(X) +#undef X + } + return 0; +} + +internal CV_EncodedFramePtrReg +cv_pick_fp_encoding(CV_SymFrameproc *frameproc, B32 is_local_param) +{ + CV_EncodedFramePtrReg fp_reg = 0; + if(is_local_param) + { + fp_reg = CV_FrameprocFlags_ExtractParamBasePointer(frameproc->flags); + } + else + { + fp_reg = CV_FrameprocFlags_ExtractLocalBasePointer(frameproc->flags); + } + return fp_reg; +} + +internal CV_Reg +cv_decode_fp_reg(CV_Arch arch, CV_EncodedFramePtrReg encoded_reg) +{ + CV_Reg fp_reg = 0; + switch (arch) + { + case CV_Arch_8086: + { + switch (encoded_reg) + { + case CV_EncodedFramePtrReg_None : break; + case CV_EncodedFramePtrReg_StackPtr: AssertAlways(!"TODO(nick): not tested, this is a guess"); + fp_reg = CV_Regx86_ESP; break; + case CV_EncodedFramePtrReg_FramePtr: fp_reg = CV_Regx86_EBP; break; + case CV_EncodedFramePtrReg_BasePtr : fp_reg = CV_Regx86_EBX; break; + default: InvalidPath; + } + } break; + case CV_Arch_X64: + { + switch (encoded_reg) + { + case CV_EncodedFramePtrReg_None : break; + case CV_EncodedFramePtrReg_StackPtr: fp_reg = CV_Regx64_RSP; break; + case CV_EncodedFramePtrReg_FramePtr: fp_reg = CV_Regx64_RBP; break; + case CV_EncodedFramePtrReg_BasePtr : fp_reg = CV_Regx64_R13; break; + default: InvalidPath; + } + } break; + default: NotImplemented; + } + return fp_reg; +} + //////////////////////////////// //~ CodeView Common Decoding Helper Functions @@ -259,6 +392,760 @@ cv_inline_annot_signed_from_unsigned_operand(U32 value) return result; } +//////////////////////////////// + +internal CV_TypeIndexInfo * +cv_symbol_type_index_info_push(Arena *arena, CV_TypeIndexInfoList *list, CV_TypeIndexSource source, U64 offset) +{ + CV_TypeIndexInfo *info = push_array_no_zero(arena, CV_TypeIndexInfo, 1); + info->next = 0; + info->offset = offset; + info->source = source; + + SLLQueuePush(list->first, list->last, info); + list->count += 1; + + return info; +} + +internal CV_TypeIndexInfoList +cv_get_symbol_type_index_offsets(Arena *arena, CV_SymKind kind, String8 data) +{ + CV_TypeIndexInfoList list = {0}; + switch (kind) { + case CV_SymKind_BUILDINFO: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_SymBuildInfo, id)); + } break; + case CV_SymKind_GDATA32: + case CV_SymKind_LDATA32: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymData32, itype)); + } break; + case CV_SymKind_LPROC32_ID: + case CV_SymKind_GPROC32_ID: + case CV_SymKind_LPROC32_DPC_ID: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_SymProc32, itype)); + } break; + case CV_SymKind_GPROC32: + case CV_SymKind_LPROC32: + case CV_SymKind_LPROC32_DPC: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymProc32, itype)); + } break; + case CV_SymKind_UDT: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymUDT, itype)); + } break; + case CV_SymKind_GTHREAD32: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymThread32, itype)); + } break; + case CV_SymKind_FILESTATIC: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymFileStatic, itype)); + } break; + case CV_SymKind_LOCAL: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymLocal, itype)); + } break; + case CV_SymKind_REGREL32: + case CV_SymKind_BPREL32: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymRegrel32, itype)); + } break; + case CV_SymKind_REGISTER: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymRegister, itype)); + } break; + case CV_SymKind_CONSTANT: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymConstant, itype)); + } break; + case CV_SymKind_CALLSITEINFO: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymCallSiteInfo, itype)); + } break; + case CV_SymKind_CALLERS: + case CV_SymKind_CALLEES: + case CV_SymKind_INLINEES: { + Assert(data.size >= sizeof(CV_SymFunctionList)); + CV_SymFunctionList *func_list = (CV_SymFunctionList*)data.str; + for (U64 i = 0; i < func_list->count; ++i) { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, sizeof(CV_SymFunctionList) + i * sizeof(CV_TypeIndex)); + } + } break; + case CV_SymKind_INLINESITE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_SymInlineSite, inlinee)); + } break; + case CV_SymKind_HEAPALLOCSITE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymHeapAllocSite, itype)); + } break; + } + return list; +} + +internal CV_TypeIndexInfoList +cv_get_leaf_type_index_offsets(Arena *arena, CV_LeafKind leaf_kind, String8 data) +{ + CV_TypeIndexInfoList list = {0}; + switch (leaf_kind) { + case CV_LeafKind_NOTYPE: + case CV_LeafKind_VTSHAPE: + case CV_LeafKind_LABEL: + case CV_LeafKind_NULL: + case CV_LeafKind_NOTTRAN: { + // no type indices + } break; + case CV_LeafKind_MODIFIER: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafModifier, itype)); + } break; + case CV_LeafKind_POINTER: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafPointer, itype)); + CV_LeafPointer *ptr = (CV_LeafPointer *)data.str; + CV_PointerKind ptr_kind = CV_PointerAttribs_ExtractKind(ptr->attribs); + if (ptr_kind == CV_PointerKind_BaseType) { + // TODO: add CV_LeafPointerBaseType + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, sizeof(CV_LeafPointer) + 0); + } else { + CV_PointerMode ptr_mode = CV_PointerAttribs_ExtractMode(ptr->attribs); + if (ptr_mode == CV_PointerMode_PtrMem || ptr_mode == CV_PointerMode_PtrMethod) { + // TODO: add type for the CvLeafPointerMember to syms_cv.mc + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, sizeof(CV_LeafPointer) + 0); + } + } + } break; + case CV_LeafKind_ARRAY: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafArray, entry_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafArray, index_itype)); + } break; + case CV_LeafKind_CLASS: + case CV_LeafKind_STRUCTURE: + case CV_LeafKind_INTERFACE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct, field_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct, derived_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct, vshape_itype)); + } break; + case CV_LeafKind_CLASS2: + case CV_LeafKind_STRUCT2: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct2, field_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct2, derived_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct2, vshape_itype)); + } break; + case CV_LeafKind_UNION: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafUnion, field_itype)); + } break; + case CV_LeafKind_ALIAS: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafAlias, itype)); + } break; + case CV_LeafKind_FUNC_ID: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_LeafFuncId, scope_string_id)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafFuncId, itype)); + } break; + case CV_LeafKind_MFUNC_ID: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFuncId, owner_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFuncId, itype)); + } break; + case CV_LeafKind_STRING_ID: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_LeafStringId, substr_list_id)); + } break; + case CV_LeafKind_UDT_SRC_LINE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafUDTSrcLine, udt_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_LeafUDTSrcLine, src_string_id)); + } break; + case CV_LeafKind_UDT_MOD_SRC_LINE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafUDTModSrcLine, udt_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_LeafUDTModSrcLine, src_string_id)); + } break; + case CV_LeafKind_BUILDINFO: { + Assert(data.size >= sizeof(CV_LeafBuildInfo)); + CV_LeafBuildInfo *build_info = (CV_LeafBuildInfo *)data.str; + for (U16 i = 0; i < build_info->count; ++i) { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, sizeof(CV_LeafBuildInfo) + i * sizeof(CV_ItemId)); + } + } break; + case CV_LeafKind_ENUM: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafEnum, base_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafEnum, field_itype)); + } break; + case CV_LeafKind_PROCEDURE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafProcedure, ret_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafProcedure, arg_itype)); + } break; + case CV_LeafKind_MFUNCTION: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFunction, ret_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFunction, class_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFunction, this_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFunction, arg_itype)); + } break; + case CV_LeafKind_VFTABLE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafVFTable, owner_itype)); + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafVFTable, base_table_itype)); + } break; + case CV_LeafKind_VFTPATH: { + Assert(sizeof(CV_LeafVFPath) <= data.size); + CV_LeafVFPath *vfpath = (CV_LeafVFPath *)data.str; + for (U32 i = 0; i < vfpath->count; ++i) { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, sizeof(CV_LeafVFPath) + i * sizeof(CV_TypeId)); + } + } break; + case CV_LeafKind_TYPESERVER: + case CV_LeafKind_TYPESERVER2: + case CV_LeafKind_TYPESERVER_ST: { + // no type indices + } break; + case CV_LeafKind_SKIP: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafSkip, itype)); + } break; + case CV_LeafKind_SUBSTR_LIST: { + Assert(sizeof(CV_LeafArgList) <= data.size); + CV_LeafArgList *arg_list = (CV_LeafArgList*)data.str; + for (U32 i = 0; i < arg_list->count; ++i) { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, sizeof(CV_LeafArgList) + i * sizeof(CV_TypeIndex)); + } + } break; + case CV_LeafKind_ARGLIST: { + Assert(sizeof(CV_LeafArgList) <= data.size); + CV_LeafArgList *arg_list = (CV_LeafArgList*)data.str; + for (U32 i = 0; i < arg_list->count; ++i) { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, sizeof(CV_LeafArgList) + i * sizeof(CV_TypeIndex)); + } + } break; + case CV_LeafKind_LIST: + case CV_LeafKind_FIELDLIST: { + for (U64 cursor = 0; cursor < data.size; ) { + CV_LeafKind list_member_kind = 0; + U64 read_size = str8_deserial_read_struct(data, cursor, &list_member_kind); + + if(read_size != sizeof(list_member_kind)) { + Assert(!"malformed LF_FIELDLIST"); + break; + } + cursor += read_size; + + switch (list_member_kind) { + default: Assert(!"TODO: handle malformed field member"); break; + case CV_LeafKind_INDEX: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafIndex, itype)); + cursor += sizeof(CV_LeafIndex); + } break; + case CV_LeafKind_MEMBER: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafMember, itype)); + cursor += sizeof(CV_LeafMember); + + CV_NumericParsed size; + cursor += cv_read_numeric(data, cursor, &size); + + String8 name; + cursor += str8_deserial_read_cstr(data, cursor, &name); + } break; + case CV_LeafKind_STMEMBER: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafStMember, itype)); + cursor += sizeof(CV_LeafStMember); + + String8 name; + cursor += str8_deserial_read_cstr(data, cursor, &name); + } break; + case CV_LeafKind_METHOD: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafMethod, list_itype)); + cursor += sizeof(CV_LeafMethod); + + String8 name; + cursor += str8_deserial_read_cstr(data, cursor, &name); + } break; + case CV_LeafKind_ONEMETHOD: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafOneMethod, itype)); + + CV_LeafOneMethod onemethod; + cursor += str8_deserial_read_struct(data, cursor, &onemethod); + + CV_MethodProp prop = CV_FieldAttribs_ExtractMethodProp(onemethod.attribs); + if(prop == CV_MethodProp_PureIntro || prop == CV_MethodProp_Intro) + { + cursor += sizeof(U32); // virtoff + } + + String8 name; + cursor += str8_deserial_read_cstr(data, cursor, &name); + } break; + case CV_LeafKind_ENUMERATE: { + // no type index + cursor += sizeof(CV_LeafEnumerate); + CV_NumericParsed value; + cursor += cv_read_numeric(data, cursor, &value); + String8 name; + cursor += str8_deserial_read_cstr(data, cursor, &name); + } break; + case CV_LeafKind_NESTTYPE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafNestType, itype)); + cursor += sizeof(CV_LeafNestType); + + String8 name; + cursor += str8_deserial_read_cstr(data, cursor, &name); + } break; + case CV_LeafKind_NESTTYPEEX: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafNestTypeEx, itype)); + + cursor += sizeof(CV_LeafNestTypeEx); + String8 name; + cursor += str8_deserial_read_cstr(data, cursor, &name); + } break; + case CV_LeafKind_BCLASS: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafBClass, itype)); + + cursor += sizeof(CV_LeafBClass); + CV_NumericParsed offset; + cursor += cv_read_numeric(data, cursor, &offset); + } break; + case CV_LeafKind_VBCLASS: + case CV_LeafKind_IVBCLASS: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafVBClass, itype)); + cursor += sizeof(CV_LeafVBClass); + + CV_NumericParsed virtual_base_pointer; + cursor += cv_read_numeric(data, cursor, &virtual_base_pointer); + + CV_NumericParsed virtual_base_offset; + cursor += cv_read_numeric(data, cursor, &virtual_base_offset); + } break; + case CV_LeafKind_VFUNCTAB: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafVFuncTab, itype)); + cursor += sizeof(CV_LeafVFuncTab); + } break; + case CV_LeafKind_VFUNCOFF: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafVFuncOff, itype)); + cursor += sizeof(CV_LeafVFuncOff); + } break; + } + cursor = AlignPow2(cursor, 4); + } + } break; + case CV_LeafKind_METHOD: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMethod, list_itype)); + } break; + case CV_LeafKind_METHODLIST: { + for (U64 cursor = 0; cursor < data.size; ) { + // read method + CV_LeafMethodListMember method; + U64 read_size = str8_deserial_read_struct(data, cursor, &method); + + // error check read + if (read_size != sizeof(method)) { + Assert(!"malformed LF_METHODLIST"); + break; + } + + // push type index offset + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafMethodListMember, itype)); + + // take into account intro virtual offset + CV_MethodProp mprop = CV_FieldAttribs_ExtractMethodProp(method.attribs); + if (mprop == CV_MethodProp_Intro || mprop == CV_MethodProp_PureIntro) { + read_size += sizeof(U32); + } + + // advance + cursor += read_size; + } + } break; + case CV_LeafKind_ONEMETHOD: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafOneMethod, itype)); + } break; + case CV_LeafKind_BITFIELD: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafBitField, itype)); + } break; + case CV_LeafKind_PRECOMP: + case CV_LeafKind_REFSYM: { + // no type indices + } break; + case CV_LeafKind_INDEX: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafIndex, itype)); + } break; + case CV_LeafKind_MEMBER: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMember, itype)); + } break; + case CV_LeafKind_VFUNCTAB: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafVFuncTab, itype)); + } break; + case CV_LeafKind_VFUNCOFF: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafVFuncOff, itype)); + } break; + case CV_LeafKind_NESTTYPE: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafNestType, itype)); + } break; + case CV_LeafKind_NESTTYPEEX: { + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafNestTypeEx, itype)); + } break; + default: { + NotImplemented; + } break; + } + return list; +} + +internal CV_TypeIndexInfoList +cv_get_inlinee_type_index_offsets(Arena *arena, String8 raw_data) +{ + CV_TypeIndexInfoList list = {0}; + + U64 cursor = 0; + + // first four bytes are always signature + CV_C13InlineeLinesSig sig = max_U32; + cursor += str8_deserial_read_struct(raw_data, cursor, &sig); + + while(cursor < raw_data.size) + { + // read header + CV_C13InlineeSourceLineHeader *header = (CV_C13InlineeSourceLineHeader *) str8_deserial_get_raw_ptr(raw_data, cursor, sizeof(CV_C13InlineeSourceLineHeader)); + + // store type index offset + cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, cursor + OffsetOf(CV_C13InlineeSourceLineHeader, inlinee)); + + // advance past header + cursor += sizeof(*header); + + // skip extra files + B32 has_extra_files = (sig == CV_C13InlineeLinesSig_EXTRA_FILES); + if (has_extra_files) + { + U32 file_count = 0; + cursor += str8_deserial_read_struct(raw_data, cursor, &file_count); + cursor += /* file id: */ sizeof(U32) * file_count; + } + } + + return list; +} + +internal String8Array +cv_get_data_around_type_indices(Arena *arena, CV_TypeIndexInfoList ti_list, String8 data) +{ + String8Array result; + if(ti_list.count > 0) + { + result.count = ti_list.count + 1; + result.v = push_array_no_zero(arena, String8, result.count); + + U64 cursor = 0; + U64 ti_idx = 0; + + for(CV_TypeIndexInfo *ti_info = ti_list.first; ti_info != 0; ti_info = ti_info->next, ++ti_idx) + { + result.v[ti_idx].size = ti_info->offset - cursor; + result.v[ti_idx].str = data.str + cursor; + cursor = ti_info->offset + sizeof(CV_TypeIndex); + } + + result.v[result.count-1].size = data.size - cursor; + result.v[result.count-1].str = data.str + cursor; + } + else + { + result.count = 1; + result.v = push_array_no_zero(arena, String8, 1); + result.v[0] = data; + } + return result; +} + +internal CV_TypeIndexSource +cv_type_index_source_from_leaf_kind(CV_LeafKind leaf_kind) +{ + CV_TypeIndexSource source; + if(leaf_kind == CV_LeafKind_FUNC_ID || + leaf_kind == CV_LeafKind_MFUNC_ID || + leaf_kind == CV_LeafKind_BUILDINFO || + leaf_kind == CV_LeafKind_SUBSTR_LIST || + leaf_kind == CV_LeafKind_STRING_ID || + leaf_kind == CV_LeafKind_UDT_SRC_LINE || + leaf_kind == CV_LeafKind_UDT_MOD_SRC_LINE) + { + source = CV_TypeIndexSource_IPI; + } + else if(leaf_kind == CV_LeafKind_NOTYPE) + { + source = CV_TypeIndexSource_NULL; + } + else + { + source = CV_TypeIndexSource_TPI; + } + return source; +} + +internal U64 +cv_name_offset_from_symbol(CV_SymKind kind, String8 data) +{ + U64 offset = data.size; + switch (kind) { + case CV_SymKind_COMPILE: break; + case CV_SymKind_OBJNAME: break; + case CV_SymKind_THUNK32: { + offset = sizeof(CV_SymThunk32); + } break; + case CV_SymKind_LABEL32: { + offset = sizeof(CV_SymLabel32); + } break; + case CV_SymKind_REGISTER: { + offset = sizeof(CV_SymRegister); + } break; + case CV_SymKind_CONSTANT: { + offset = sizeof(CV_SymConstant); + CV_NumericParsed size; + offset += cv_read_numeric(data, offset, &size); + } break; + case CV_SymKind_UDT: { + offset = sizeof(CV_SymUDT); + } break; + case CV_SymKind_BPREL32: { + offset = sizeof(CV_SymBPRel32); + } break; + case CV_SymKind_LDATA32: + case CV_SymKind_GDATA32: { + offset = sizeof(CV_SymData32); + } break; + case CV_SymKind_PUB32: { + offset = sizeof(CV_SymPub32); + } break; + case CV_SymKind_LPROC32: + case CV_SymKind_GPROC32: + case CV_SymKind_LPROC32_ID: + case CV_SymKind_GPROC32_ID: { + offset = sizeof(CV_SymProc32); + } break; + case CV_SymKind_REGREL32: { + offset = sizeof(CV_SymRegrel32); + } break; + case CV_SymKind_LTHREAD32: + case CV_SymKind_GTHREAD32: { + offset = sizeof(CV_SymData32); + } break; + case CV_SymKind_COMPILE2: break; + case CV_SymKind_LOCALSLOT: { + offset = sizeof(CV_SymSlot); + } break; + case CV_SymKind_PROCREF: + case CV_SymKind_LPROCREF: + case CV_SymKind_DATAREF: { + offset = sizeof(CV_SymRef2); + } break; + case CV_SymKind_TRAMPOLINE: break; + case CV_SymKind_LOCAL: { + offset = sizeof(CV_SymLocal); + } break; + default: InvalidPath; + } + return offset; +} + +internal String8 +cv_name_from_symbol(CV_SymKind kind, String8 data) +{ + U64 buf_off = cv_name_offset_from_symbol(kind, data); + U8 *buf_ptr = data.str + buf_off; + U8 *buf_opl = data.str + data.size; + String8 name = str8_cstring_capped(buf_ptr, buf_opl); + return name; +} + +internal CV_UDTInfo +cv_get_udt_info(CV_LeafKind kind, String8 data) +{ + String8 name = str8_zero(); + String8 unique_name = str8_zero(); + CV_TypeProps props = 0; + + switch(kind) { + case CV_LeafKind_CLASS: + case CV_LeafKind_STRUCTURE: + case CV_LeafKind_INTERFACE: { + U64 cursor = 0; + + CV_LeafStruct udt; + cursor += str8_deserial_read_struct(data, cursor, &udt); + + props = udt.props; + + CV_NumericParsed size; + cursor += cv_read_numeric(data, cursor, &size); + + cursor += str8_deserial_read_cstr(data, cursor, &name); + + if (udt.props & CV_TypeProp_HasUniqueName) { + cursor += str8_deserial_read_cstr(data, cursor, &unique_name); + } + } break; + + case CV_LeafKind_CLASS2: + case CV_LeafKind_STRUCT2: { + U64 cursor = 0; + + CV_LeafStruct2 udt; + cursor += str8_deserial_read_struct(data, cursor, &udt); + + props = udt.props; + + CV_NumericParsed size; + cursor += cv_read_numeric(data, cursor, &size); + + cursor += str8_deserial_read_cstr(data, cursor, &name); + + if (udt.props & CV_TypeProp_HasUniqueName) { + cursor += str8_deserial_read_cstr(data, cursor, &unique_name); + } + } break; + + case CV_LeafKind_UNION: { + U64 cursor = 0; + + CV_LeafUnion udt; + cursor += str8_deserial_read_struct(data, cursor, &udt); + + CV_NumericParsed size; + cursor += cv_read_numeric(data, cursor, &size); + + props = udt.props; + + cursor += str8_deserial_read_cstr(data, cursor, &name); + + if(udt.props & CV_TypeProp_HasUniqueName) { + cursor += str8_deserial_read_cstr(data, cursor, &unique_name); + } + } break; + + case CV_LeafKind_ENUM: { + U64 cursor = 0; + + CV_LeafEnum udt; + cursor += str8_deserial_read_struct(data, cursor, &udt); + + props = udt.props; + + cursor += str8_deserial_read_cstr(data, cursor, &name); + + if(udt.props & CV_TypeProp_HasUniqueName) { + cursor += str8_deserial_read_cstr(data, cursor, &unique_name); + } + } break; + + // dbi/tpi.cpp:1332 + case CV_LeafKind_UDT_SRC_LINE: { + CV_LeafUDTSrcLine *src_line = str8_deserial_get_raw_ptr(data, 0, sizeof(CV_LeafUDTSrcLine)); + name = str8_struct(&src_line->udt_itype); + } break; + case CV_LeafKind_UDT_MOD_SRC_LINE: { + CV_LeafUDTModSrcLine *mod_src_line = str8_deserial_get_raw_ptr(data, 0, sizeof(CV_LeafUDTModSrcLine)); + name = str8_struct(&mod_src_line->udt_itype); + } break; + + case CV_LeafKind_ALIAS: { + str8_deserial_read_cstr(data, 0, &name); + } break; + + default: { + InvalidPath; + } break; + } + + CV_UDTInfo info = {0}; + info.name = name; + info.unique_name = unique_name; + info.props = props; + return info; +} + +internal String8 +cv_name_from_udt_info(CV_UDTInfo udt_info) +{ + if (udt_info.props & CV_TypeProp_HasUniqueName) { + return udt_info.unique_name; + } + return udt_info.name; +} + +internal B32 +cv_is_udt_name_anon(String8 name) +{ + // corresponds to fUDTAnon from dbi/tm.cpp:817 + B32 is_anon = str8_match(str8_lit(""), name, 0) || + str8_match(str8_lit("__unnamed"), name, 0) || + str8_match(str8_lit("::"), name, StringMatchFlag_RightSideSloppy) || + str8_match(str8_lit("::__unnamed"), name, StringMatchFlag_RightSideSloppy); + return is_anon; +} + +internal B32 +cv_is_udt(CV_LeafKind kind) +{ + B32 is_udt = kind == CV_LeafKind_CLASS || + kind == CV_LeafKind_STRUCTURE || + kind == CV_LeafKind_CLASS2 || + kind == CV_LeafKind_STRUCT2 || + kind == CV_LeafKind_INTERFACE || + kind == CV_LeafKind_UNION || + kind == CV_LeafKind_ENUM || + kind == CV_LeafKind_UDT_MOD_SRC_LINE || + kind == CV_LeafKind_UDT_SRC_LINE || + kind == CV_LeafKind_ALIAS; + return is_udt; +} + +internal B32 +cv_is_global_symbol(CV_SymKind kind) +{ + B32 is_global_symbol = kind == CV_SymKind_CONSTANT || + kind == CV_SymKind_GDATA16 || + kind == CV_SymKind_GDATA32_16t || + kind == CV_SymKind_GDATA32_ST || + kind == CV_SymKind_GDATA32 || + kind == CV_SymKind_GTHREAD32_16t || + kind == CV_SymKind_GTHREAD32_ST || + kind == CV_SymKind_GTHREAD32; + return is_global_symbol; +} + +internal B32 +cv_is_typedef(CV_SymKind kind) +{ + B32 is_typedef = kind == CV_SymKind_UDT_16t || + kind == CV_SymKind_UDT_ST || + kind == CV_SymKind_UDT; + return is_typedef; +} + +internal B32 +cv_is_scope_symbol(CV_SymKind kind) +{ + B32 is_scope = kind == CV_SymKind_GPROC32 || + kind == CV_SymKind_LPROC32 || + kind == CV_SymKind_BLOCK32 || + kind == CV_SymKind_THUNK32 || + kind == CV_SymKind_INLINESITE || + kind == CV_SymKind_INLINESITE2 || + kind == CV_SymKind_WITH32 || + kind == CV_SymKind_SEPCODE || + kind == CV_SymKind_GPROC32_ID || + kind == CV_SymKind_LPROC32_ID; + return is_scope; +} + +internal B32 +cv_is_end_symbol(CV_SymKind kind) +{ + B32 is_end = kind == CV_SymKind_END || + kind == CV_SymKind_PROC_ID_END || + kind == CV_SymKind_INLINESITE_END; + return is_end; +} + +internal B32 +cv_is_leaf_type_server(CV_LeafKind kind) +{ + B32 is_type_server = kind == CV_LeafKind_TYPESERVER || + kind == CV_LeafKind_TYPESERVER2 || + kind == CV_LeafKind_TYPESERVER_ST; + return is_type_server; +} + +internal B32 +cv_is_leaf_pch(CV_LeafKind kind) +{ + B32 is_pch = kind == CV_LeafKind_PRECOMP || + kind == CV_LeafKind_PRECOMP_ST || + kind == CV_LeafKind_PRECOMP_16t; + return is_pch; +} + //////////////////////////////// //~ CodeView Parsing Functions @@ -647,3 +1534,19 @@ cv_c13_parsed_from_data(Arena *arena, String8 c13_data, String8 strtbl, COFF_Sec ProfEnd(); return result; } + +//////////////////////////////// +//~ Enum <-> String + +internal String8 +cv_string_from_type_index_source(CV_TypeIndexSource ti_source) +{ + switch (ti_source) { + case CV_TypeIndexSource_NULL: return str8_lit(""); break; + case CV_TypeIndexSource_TPI: return str8_lit("TPI"); break; + case CV_TypeIndexSource_IPI: return str8_lit("IPI"); break; + case CV_TypeIndexSource_COUNT: break; + } + return str8_zero(); +} + diff --git a/src/codeview/codeview.h b/src/codeview/codeview.h index e03a8044..760f042f 100644 --- a/src/codeview/codeview.h +++ b/src/codeview/codeview.h @@ -9,6 +9,8 @@ //////////////////////////////// //~ rjf: CodeView Format Shared Types +#define CV_MinComplexTypeIndex 0x1000 + #define CV_TypeIndex_Max max_U32 typedef U32 CV_TypeIndex; typedef CV_TypeIndex CV_TypeId; @@ -2902,6 +2904,51 @@ struct CV_C13InlineeSourceLineHeader #pragma pack(pop) +//////////////////////////////// +//~ Type Index Helper + +typedef enum CV_TypeIndexSource CV_TypeIndexSource; +enum CV_TypeIndexSource +{ + CV_TypeIndexSource_NULL, + CV_TypeIndexSource_TPI, + CV_TypeIndexSource_IPI, + CV_TypeIndexSource_COUNT +}; + +typedef struct CV_TypeIndexInfo CV_TypeIndexInfo; +struct CV_TypeIndexInfo +{ + struct CV_TypeIndexInfo *next; + U64 offset; + CV_TypeIndexSource source; +}; + +typedef struct CV_TypeIndexInfoList CV_TypeIndexInfoList; +struct CV_TypeIndexInfoList +{ + U64 count; + CV_TypeIndexInfo *first; + CV_TypeIndexInfo *last; +}; + +typedef struct CV_TypeIndexArray CV_TypeIndexArray; +struct CV_TypeIndexArray +{ + U32 count; + CV_TypeIndex *v; +}; + +//////////////////////////////// + +typedef struct CV_UDTInfo CV_UDTInfo; +struct CV_UDTInfo +{ + String8 name; + String8 unique_name; + CV_TypeProps props; +}; + //////////////////////////////// //~ CodeView Common Parser Types @@ -3077,6 +3124,16 @@ struct CV_TypeIdArray U64 count; }; +//////////////////////////////// + +internal CV_Arch cv_arch_from_coff_machine(COFF_MachineType machine); +internal U64 cv_size_from_reg_x86(CV_Reg reg); +internal U64 cv_size_from_reg_x64(CV_Reg reg); +internal U64 cv_size_from_reg(CV_Arch arch, CV_Reg reg); +internal B32 cv_is_reg_sp(CV_Arch arch, CV_Reg reg); +internal CV_EncodedFramePtrReg cv_pick_fp_encoding(CV_SymFrameproc *frameproc, B32 is_local_param); +internal CV_Reg cv_decode_fp_reg(CV_Arch arch, CV_EncodedFramePtrReg encoded_reg); + //////////////////////////////// //~ CodeView Common Decoding Helper Functions @@ -3099,6 +3156,25 @@ internal U64 cv_decode_inline_annot_s32(String8 data, U64 offset, S32 *out_value internal S32 cv_inline_annot_signed_from_unsigned_operand(U32 value); +//////////////////////////////// + +internal CV_TypeIndexInfoList cv_get_symbol_type_index_offsets(Arena *arena, CV_SymKind kind, String8 data); +internal CV_TypeIndexInfoList cv_get_leaf_type_index_offsets(Arena *arena, CV_LeafKind leaf_kind, String8 data); +internal CV_TypeIndexInfoList cv_get_inlinee_type_index_offsets(Arena *arena, String8 raw_data); +internal String8Array cv_get_data_around_type_indices(Arena *arena, CV_TypeIndexInfoList ti_list, String8 data); +internal CV_TypeIndexSource cv_type_index_source_from_leaf_kind(CV_LeafKind leaf_kind); + +internal U64 cv_name_offset_from_symbol(CV_SymKind kind, String8 data); +internal String8 cv_name_from_symbol(CV_SymKind kind, String8 data); + +internal B32 cv_is_udt_name_anon(String8 name); +internal B32 cv_is_udt(CV_LeafKind kind); +internal B32 cv_is_global_symbol(CV_SymKind kind); +internal B32 cv_is_typedef(CV_SymKind kind); +internal B32 cv_is_scope_symbol(CV_SymKind kind); +internal B32 cv_is_end_symbol(CV_SymKind kind); +internal B32 cv_is_leaf_type_server(CV_LeafKind kind); +internal B32 cv_is_leaf_pch(CV_LeafKind kind); //////////////////////////////// //~ CodeView Parsing Functions @@ -3118,4 +3194,9 @@ internal CV_LeafParsed *cv_leaf_from_data(Arena *arena, String8 leaf_data, CV_Ty internal CV_C13Parsed *cv_c13_parsed_from_data(Arena *arena, String8 c13_data, String8 strtbl, COFF_SectionHeaderArray sections); +//////////////////////////////// +//~ Enum <-> String + +internal String8 cv_string_from_type_index_source(CV_TypeIndexSource ti_source); + #endif // CODEVIEW_H diff --git a/src/linker/codeview_ext/codeview.c b/src/linker/codeview_ext/codeview.c index d62b8f77..96f4d015 100644 --- a/src/linker/codeview_ext/codeview.c +++ b/src/linker/codeview_ext/codeview.c @@ -16,750 +16,6 @@ hash_from_cv_symbol(CV_Symbol *symbol) } //////////////////////////////// -// Type Index Helpers - -internal CV_TypeIndexInfo * -cv_symbol_type_index_info_push(Arena *arena, CV_TypeIndexInfoList *list, CV_TypeIndexSource source, U64 offset) -{ - CV_TypeIndexInfo *info = push_array_no_zero(arena, CV_TypeIndexInfo, 1); - info->next = 0; - info->offset = offset; - info->source = source; - - SLLQueuePush(list->first, list->last, info); - list->count += 1; - - return info; -} - -internal CV_TypeIndexInfoList -cv_get_symbol_type_index_offsets(Arena *arena, CV_SymKind kind, String8 data) -{ - CV_TypeIndexInfoList list = {0}; - switch (kind) { - case CV_SymKind_BUILDINFO: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_SymBuildInfo, id)); - } break; - case CV_SymKind_GDATA32: - case CV_SymKind_LDATA32: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymData32, itype)); - } break; - case CV_SymKind_LPROC32_ID: - case CV_SymKind_GPROC32_ID: - case CV_SymKind_LPROC32_DPC_ID: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_SymProc32, itype)); - } break; - case CV_SymKind_GPROC32: - case CV_SymKind_LPROC32: - case CV_SymKind_LPROC32_DPC: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymProc32, itype)); - } break; - case CV_SymKind_UDT: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymUDT, itype)); - } break; - case CV_SymKind_GTHREAD32: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymThread32, itype)); - } break; - case CV_SymKind_FILESTATIC: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymFileStatic, itype)); - } break; - case CV_SymKind_LOCAL: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymLocal, itype)); - } break; - case CV_SymKind_REGREL32: - case CV_SymKind_BPREL32: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymRegrel32, itype)); - } break; - case CV_SymKind_REGISTER: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymRegister, itype)); - } break; - case CV_SymKind_CONSTANT: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymConstant, itype)); - } break; - case CV_SymKind_CALLSITEINFO: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymCallSiteInfo, itype)); - } break; - case CV_SymKind_CALLERS: - case CV_SymKind_CALLEES: - case CV_SymKind_INLINEES: { - Assert(data.size >= sizeof(CV_SymFunctionList)); - CV_SymFunctionList *func_list = (CV_SymFunctionList*)data.str; - for (U64 i = 0; i < func_list->count; ++i) { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, sizeof(CV_SymFunctionList) + i * sizeof(CV_TypeIndex)); - } - } break; - case CV_SymKind_INLINESITE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_SymInlineSite, inlinee)); - } break; - case CV_SymKind_HEAPALLOCSITE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_SymHeapAllocSite, itype)); - } break; - } - return list; -} - -internal CV_TypeIndexInfoList -cv_get_leaf_type_index_offsets(Arena *arena, CV_LeafKind leaf_kind, String8 data) -{ - CV_TypeIndexInfoList list = {0}; - switch (leaf_kind) { - case CV_LeafKind_NOTYPE: - case CV_LeafKind_VTSHAPE: - case CV_LeafKind_LABEL: - case CV_LeafKind_NULL: - case CV_LeafKind_NOTTRAN: { - // no type indices - } break; - case CV_LeafKind_MODIFIER: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafModifier, itype)); - } break; - case CV_LeafKind_POINTER: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafPointer, itype)); - CV_LeafPointer *ptr = (CV_LeafPointer *)data.str; - CV_PointerKind ptr_kind = CV_PointerAttribs_ExtractKind(ptr->attribs); - if (ptr_kind == CV_PointerKind_BaseType) { - // TODO: add CV_LeafPointerBaseType - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, sizeof(CV_LeafPointer) + 0); - } else { - CV_PointerMode ptr_mode = CV_PointerAttribs_ExtractMode(ptr->attribs); - if (ptr_mode == CV_PointerMode_PtrMem || ptr_mode == CV_PointerMode_PtrMethod) { - // TODO: add type for the CvLeafPointerMember to syms_cv.mc - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, sizeof(CV_LeafPointer) + 0); - } - } - } break; - case CV_LeafKind_ARRAY: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafArray, entry_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafArray, index_itype)); - } break; - case CV_LeafKind_CLASS: - case CV_LeafKind_STRUCTURE: - case CV_LeafKind_INTERFACE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct, field_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct, derived_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct, vshape_itype)); - } break; - case CV_LeafKind_CLASS2: - case CV_LeafKind_STRUCT2: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct2, field_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct2, derived_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafStruct2, vshape_itype)); - } break; - case CV_LeafKind_UNION: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafUnion, field_itype)); - } break; - case CV_LeafKind_ALIAS: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafAlias, itype)); - } break; - case CV_LeafKind_FUNC_ID: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_LeafFuncId, scope_string_id)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafFuncId, itype)); - } break; - case CV_LeafKind_MFUNC_ID: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFuncId, owner_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFuncId, itype)); - } break; - case CV_LeafKind_STRING_ID: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_LeafStringId, substr_list_id)); - } break; - case CV_LeafKind_UDT_SRC_LINE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafUDTSrcLine, udt_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_LeafUDTSrcLine, src_string_id)); - } break; - case CV_LeafKind_UDT_MOD_SRC_LINE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafUDTModSrcLine, udt_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, OffsetOf(CV_LeafUDTModSrcLine, src_string_id)); - } break; - case CV_LeafKind_BUILDINFO: { - Assert(data.size >= sizeof(CV_LeafBuildInfo)); - CV_LeafBuildInfo *build_info = (CV_LeafBuildInfo *)data.str; - for (U16 i = 0; i < build_info->count; ++i) { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, sizeof(CV_LeafBuildInfo) + i * sizeof(CV_ItemId)); - } - } break; - case CV_LeafKind_ENUM: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafEnum, base_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafEnum, field_itype)); - } break; - case CV_LeafKind_PROCEDURE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafProcedure, ret_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafProcedure, arg_itype)); - } break; - case CV_LeafKind_MFUNCTION: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFunction, ret_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFunction, class_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFunction, this_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMFunction, arg_itype)); - } break; - case CV_LeafKind_VFTABLE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafVFTable, owner_itype)); - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafVFTable, base_table_itype)); - } break; - case CV_LeafKind_VFTPATH: { - Assert(sizeof(CV_LeafVFPath) <= data.size); - CV_LeafVFPath *vfpath = (CV_LeafVFPath *)data.str; - for (U32 i = 0; i < vfpath->count; ++i) { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, sizeof(CV_LeafVFPath) + i * sizeof(CV_TypeId)); - } - } break; - case CV_LeafKind_TYPESERVER: - case CV_LeafKind_TYPESERVER2: - case CV_LeafKind_TYPESERVER_ST: { - // no type indices - } break; - case CV_LeafKind_SKIP: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafSkip, itype)); - } break; - case CV_LeafKind_SUBSTR_LIST: { - Assert(sizeof(CV_LeafArgList) <= data.size); - CV_LeafArgList *arg_list = (CV_LeafArgList*)data.str; - for (U32 i = 0; i < arg_list->count; ++i) { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, sizeof(CV_LeafArgList) + i * sizeof(CV_TypeIndex)); - } - } break; - case CV_LeafKind_ARGLIST: { - Assert(sizeof(CV_LeafArgList) <= data.size); - CV_LeafArgList *arg_list = (CV_LeafArgList*)data.str; - for (U32 i = 0; i < arg_list->count; ++i) { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, sizeof(CV_LeafArgList) + i * sizeof(CV_TypeIndex)); - } - } break; - case CV_LeafKind_LIST: - case CV_LeafKind_FIELDLIST: { - for (U64 cursor = 0; cursor < data.size; ) { - CV_LeafKind list_member_kind = 0; - U64 read_size = str8_deserial_read_struct(data, cursor, &list_member_kind); - - if(read_size != sizeof(list_member_kind)) { - Assert(!"malformed LF_FIELDLIST"); - break; - } - cursor += read_size; - - switch (list_member_kind) { - default: Assert(!"TODO: handle malformed field member"); break; - case CV_LeafKind_INDEX: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafIndex, itype)); - cursor += sizeof(CV_LeafIndex); - } break; - case CV_LeafKind_MEMBER: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafMember, itype)); - cursor += sizeof(CV_LeafMember); - - CV_NumericParsed size; - cursor += cv_read_numeric(data, cursor, &size); - - String8 name; - cursor += str8_deserial_read_cstr(data, cursor, &name); - } break; - case CV_LeafKind_STMEMBER: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafStMember, itype)); - cursor += sizeof(CV_LeafStMember); - - String8 name; - cursor += str8_deserial_read_cstr(data, cursor, &name); - } break; - case CV_LeafKind_METHOD: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafMethod, list_itype)); - cursor += sizeof(CV_LeafMethod); - - String8 name; - cursor += str8_deserial_read_cstr(data, cursor, &name); - } break; - case CV_LeafKind_ONEMETHOD: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafOneMethod, itype)); - - CV_LeafOneMethod onemethod; - cursor += str8_deserial_read_struct(data, cursor, &onemethod); - - CV_MethodProp prop = CV_FieldAttribs_ExtractMethodProp(onemethod.attribs); - if(prop == CV_MethodProp_PureIntro || prop == CV_MethodProp_Intro) - { - cursor += sizeof(U32); // virtoff - } - - String8 name; - cursor += str8_deserial_read_cstr(data, cursor, &name); - } break; - case CV_LeafKind_ENUMERATE: { - // no type index - cursor += sizeof(CV_LeafEnumerate); - CV_NumericParsed value; - cursor += cv_read_numeric(data, cursor, &value); - String8 name; - cursor += str8_deserial_read_cstr(data, cursor, &name); - } break; - case CV_LeafKind_NESTTYPE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafNestType, itype)); - cursor += sizeof(CV_LeafNestType); - - String8 name; - cursor += str8_deserial_read_cstr(data, cursor, &name); - } break; - case CV_LeafKind_NESTTYPEEX: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafNestTypeEx, itype)); - - cursor += sizeof(CV_LeafNestTypeEx); - String8 name; - cursor += str8_deserial_read_cstr(data, cursor, &name); - } break; - case CV_LeafKind_BCLASS: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafBClass, itype)); - - cursor += sizeof(CV_LeafBClass); - CV_NumericParsed offset; - cursor += cv_read_numeric(data, cursor, &offset); - } break; - case CV_LeafKind_VBCLASS: - case CV_LeafKind_IVBCLASS: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafVBClass, itype)); - cursor += sizeof(CV_LeafVBClass); - - CV_NumericParsed virtual_base_pointer; - cursor += cv_read_numeric(data, cursor, &virtual_base_pointer); - - CV_NumericParsed virtual_base_offset; - cursor += cv_read_numeric(data, cursor, &virtual_base_offset); - } break; - case CV_LeafKind_VFUNCTAB: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafVFuncTab, itype)); - cursor += sizeof(CV_LeafVFuncTab); - } break; - case CV_LeafKind_VFUNCOFF: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafVFuncOff, itype)); - cursor += sizeof(CV_LeafVFuncOff); - } break; - } - cursor = AlignPow2(cursor, 4); - } - } break; - case CV_LeafKind_METHOD: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMethod, list_itype)); - } break; - case CV_LeafKind_METHODLIST: { - for (U64 cursor = 0; cursor < data.size; ) { - // read method - CV_LeafMethodListMember method; - U64 read_size = str8_deserial_read_struct(data, cursor, &method); - - // error check read - if (read_size != sizeof(method)) { - Assert(!"malformed LF_METHODLIST"); - break; - } - - // push type index offset - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, cursor + OffsetOf(CV_LeafMethodListMember, itype)); - - // take into account intro virtual offset - CV_MethodProp mprop = CV_FieldAttribs_ExtractMethodProp(method.attribs); - if (mprop == CV_MethodProp_Intro || mprop == CV_MethodProp_PureIntro) { - read_size += sizeof(U32); - } - - // advance - cursor += read_size; - } - } break; - case CV_LeafKind_ONEMETHOD: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafOneMethod, itype)); - } break; - case CV_LeafKind_BITFIELD: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafBitField, itype)); - } break; - case CV_LeafKind_PRECOMP: - case CV_LeafKind_REFSYM: { - // no type indices - } break; - case CV_LeafKind_INDEX: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafIndex, itype)); - } break; - case CV_LeafKind_MEMBER: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafMember, itype)); - } break; - case CV_LeafKind_VFUNCTAB: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafVFuncTab, itype)); - } break; - case CV_LeafKind_VFUNCOFF: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafVFuncOff, itype)); - } break; - case CV_LeafKind_NESTTYPE: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafNestType, itype)); - } break; - case CV_LeafKind_NESTTYPEEX: { - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_TPI, OffsetOf(CV_LeafNestTypeEx, itype)); - } break; - default: { - NotImplemented; - } break; - } - return list; -} - -internal CV_TypeIndexInfoList -cv_get_inlinee_type_index_offsets(Arena *arena, String8 raw_data) -{ - CV_TypeIndexInfoList list = {0}; - - U64 cursor = 0; - - // first four bytes are always signature - CV_C13InlineeLinesSig sig = max_U32; - cursor += str8_deserial_read_struct(raw_data, cursor, &sig); - - while (cursor < raw_data.size) { - // read header - CV_C13InlineeSourceLineHeader *header = (CV_C13InlineeSourceLineHeader *) str8_deserial_get_raw_ptr(raw_data, cursor, sizeof(CV_C13InlineeSourceLineHeader)); - - // store type index offset - cv_symbol_type_index_info_push(arena, &list, CV_TypeIndexSource_IPI, cursor + OffsetOf(CV_C13InlineeSourceLineHeader, inlinee)); - - // advance past header - cursor += sizeof(*header); - - // skip extra files - B32 has_extra_files = (sig == CV_C13InlineeLinesSig_EXTRA_FILES); - if (has_extra_files) { - U32 file_count = 0; - cursor += str8_deserial_read_struct(raw_data, cursor, &file_count); - cursor += /* file id: */ sizeof(U32) * file_count; - } - } - - return list; -} - -internal String8Array -cv_get_data_around_type_indices(Arena *arena, CV_TypeIndexInfoList ti_list, String8 data) -{ - String8Array result; - if (ti_list.count > 0) { - result.count = ti_list.count + 1; - result.v = push_array_no_zero(arena, String8, result.count); - - U64 cursor = 0; - U64 ti_idx = 0; - - for (CV_TypeIndexInfo *ti_info = ti_list.first; ti_info != 0; ti_info = ti_info->next, ++ti_idx) { - result.v[ti_idx].size = ti_info->offset - cursor; - result.v[ti_idx].str = data.str + cursor; - cursor = ti_info->offset + sizeof(CV_TypeIndex); - } - - result.v[result.count-1].size = data.size - cursor; - result.v[result.count-1].str = data.str + cursor; - } else { - result.count = 1; - result.v = push_array_no_zero(arena, String8, 1); - result.v[0] = data; - } - return result; -} - -internal CV_TypeIndexSource -cv_type_index_source_from_leaf_kind(CV_LeafKind leaf_kind) -{ - CV_TypeIndexSource source; - if (leaf_kind == CV_LeafKind_FUNC_ID || - leaf_kind == CV_LeafKind_MFUNC_ID || - leaf_kind == CV_LeafKind_BUILDINFO || - leaf_kind == CV_LeafKind_SUBSTR_LIST || - leaf_kind == CV_LeafKind_STRING_ID || - leaf_kind == CV_LeafKind_UDT_SRC_LINE || - leaf_kind == CV_LeafKind_UDT_MOD_SRC_LINE) { - source = CV_TypeIndexSource_IPI; - } else if (leaf_kind == CV_LeafKind_NOTYPE) { - source = CV_TypeIndexSource_NULL; - } else { - source = CV_TypeIndexSource_TPI; - } - return source; -} - -//////////////////////////////// - -internal U64 -cv_name_offset_from_symbol(CV_SymKind kind, String8 data) -{ - U64 offset = data.size; - switch (kind) { - case CV_SymKind_COMPILE: break; - case CV_SymKind_OBJNAME: break; - case CV_SymKind_THUNK32: { - offset = sizeof(CV_SymThunk32); - } break; - case CV_SymKind_LABEL32: { - offset = sizeof(CV_SymLabel32); - } break; - case CV_SymKind_REGISTER: { - offset = sizeof(CV_SymRegister); - } break; - case CV_SymKind_CONSTANT: { - offset = sizeof(CV_SymConstant); - CV_NumericParsed size; - offset += cv_read_numeric(data, offset, &size); - } break; - case CV_SymKind_UDT: { - offset = sizeof(CV_SymUDT); - } break; - case CV_SymKind_BPREL32: { - offset = sizeof(CV_SymBPRel32); - } break; - case CV_SymKind_LDATA32: - case CV_SymKind_GDATA32: { - offset = sizeof(CV_SymData32); - } break; - case CV_SymKind_PUB32: { - offset = sizeof(CV_SymPub32); - } break; - case CV_SymKind_LPROC32: - case CV_SymKind_GPROC32: - case CV_SymKind_LPROC32_ID: - case CV_SymKind_GPROC32_ID: { - offset = sizeof(CV_SymProc32); - } break; - case CV_SymKind_REGREL32: { - offset = sizeof(CV_SymRegrel32); - } break; - case CV_SymKind_LTHREAD32: - case CV_SymKind_GTHREAD32: { - offset = sizeof(CV_SymData32); - } break; - case CV_SymKind_COMPILE2: break; - case CV_SymKind_LOCALSLOT: { - offset = sizeof(CV_SymSlot); - } break; - case CV_SymKind_PROCREF: - case CV_SymKind_LPROCREF: - case CV_SymKind_DATAREF: { - offset = sizeof(CV_SymRef2); - } break; - case CV_SymKind_TRAMPOLINE: break; - case CV_SymKind_LOCAL: { - offset = sizeof(CV_SymLocal); - } break; - default: InvalidPath; - } - return offset; -} - -internal String8 -cv_name_from_symbol(CV_SymKind kind, String8 data) -{ - U64 buf_off = cv_name_offset_from_symbol(kind, data); - U8 *buf_ptr = data.str + buf_off; - U8 *buf_opl = data.str + data.size; - String8 name = str8_cstring_capped(buf_ptr, buf_opl); - return name; -} - -internal CV_UDTInfo -cv_get_udt_info(CV_LeafKind kind, String8 data) -{ - String8 name = str8_zero(); - String8 unique_name = str8_zero(); - CV_TypeProps props = 0; - - switch(kind) { - case CV_LeafKind_CLASS: - case CV_LeafKind_STRUCTURE: - case CV_LeafKind_INTERFACE: { - U64 cursor = 0; - - CV_LeafStruct udt; - cursor += str8_deserial_read_struct(data, cursor, &udt); - - props = udt.props; - - CV_NumericParsed size; - cursor += cv_read_numeric(data, cursor, &size); - - cursor += str8_deserial_read_cstr(data, cursor, &name); - - if (udt.props & CV_TypeProp_HasUniqueName) { - cursor += str8_deserial_read_cstr(data, cursor, &unique_name); - } - } break; - - case CV_LeafKind_CLASS2: - case CV_LeafKind_STRUCT2: { - U64 cursor = 0; - - CV_LeafStruct2 udt; - cursor += str8_deserial_read_struct(data, cursor, &udt); - - props = udt.props; - - CV_NumericParsed size; - cursor += cv_read_numeric(data, cursor, &size); - - cursor += str8_deserial_read_cstr(data, cursor, &name); - - if (udt.props & CV_TypeProp_HasUniqueName) { - cursor += str8_deserial_read_cstr(data, cursor, &unique_name); - } - } break; - - case CV_LeafKind_UNION: { - U64 cursor = 0; - - CV_LeafUnion udt; - cursor += str8_deserial_read_struct(data, cursor, &udt); - - CV_NumericParsed size; - cursor += cv_read_numeric(data, cursor, &size); - - props = udt.props; - - cursor += str8_deserial_read_cstr(data, cursor, &name); - - if(udt.props & CV_TypeProp_HasUniqueName) { - cursor += str8_deserial_read_cstr(data, cursor, &unique_name); - } - } break; - - case CV_LeafKind_ENUM: { - U64 cursor = 0; - - CV_LeafEnum udt; - cursor += str8_deserial_read_struct(data, cursor, &udt); - - props = udt.props; - - cursor += str8_deserial_read_cstr(data, cursor, &name); - - if(udt.props & CV_TypeProp_HasUniqueName) { - cursor += str8_deserial_read_cstr(data, cursor, &unique_name); - } - } break; - - // dbi/tpi.cpp:1332 - case CV_LeafKind_UDT_SRC_LINE: { - CV_LeafUDTSrcLine *src_line = str8_deserial_get_raw_ptr(data, 0, sizeof(CV_LeafUDTSrcLine)); - name = str8_struct(&src_line->udt_itype); - } break; - case CV_LeafKind_UDT_MOD_SRC_LINE: { - CV_LeafUDTModSrcLine *mod_src_line = str8_deserial_get_raw_ptr(data, 0, sizeof(CV_LeafUDTModSrcLine)); - name = str8_struct(&mod_src_line->udt_itype); - } break; - - case CV_LeafKind_ALIAS: { - str8_deserial_read_cstr(data, 0, &name); - } break; - - default: { - InvalidPath; - } break; - } - - CV_UDTInfo info = {0}; - info.name = name; - info.unique_name = unique_name; - info.props = props; - return info; -} - -internal String8 -cv_name_from_udt_info(CV_UDTInfo udt_info) -{ - if (udt_info.props & CV_TypeProp_HasUniqueName) { - return udt_info.unique_name; - } - return udt_info.name; -} - -internal B32 -cv_is_udt_name_anon(String8 name) -{ - // corresponds to fUDTAnon from dbi/tm.cpp:817 - B32 is_anon = str8_match(str8_lit(""), name, 0) || - str8_match(str8_lit("__unnamed"), name, 0) || - str8_match(str8_lit("::"), name, StringMatchFlag_RightSideSloppy) || - str8_match(str8_lit("::__unnamed"), name, StringMatchFlag_RightSideSloppy); - return is_anon; -} - -internal B32 -cv_is_udt(CV_LeafKind kind) -{ - B32 is_udt = kind == CV_LeafKind_CLASS || - kind == CV_LeafKind_STRUCTURE || - kind == CV_LeafKind_CLASS2 || - kind == CV_LeafKind_STRUCT2 || - kind == CV_LeafKind_INTERFACE || - kind == CV_LeafKind_UNION || - kind == CV_LeafKind_ENUM || - kind == CV_LeafKind_UDT_MOD_SRC_LINE || - kind == CV_LeafKind_UDT_SRC_LINE || - kind == CV_LeafKind_ALIAS; - return is_udt; -} - -internal B32 -cv_is_global_symbol(CV_SymKind kind) -{ - B32 is_global_symbol = kind == CV_SymKind_CONSTANT || - kind == CV_SymKind_GDATA16 || - kind == CV_SymKind_GDATA32_16t || - kind == CV_SymKind_GDATA32_ST || - kind == CV_SymKind_GDATA32 || - kind == CV_SymKind_GTHREAD32_16t || - kind == CV_SymKind_GTHREAD32_ST || - kind == CV_SymKind_GTHREAD32; - return is_global_symbol; -} - -internal B32 -cv_is_typedef(CV_SymKind kind) -{ - B32 is_typedef = kind == CV_SymKind_UDT_16t || - kind == CV_SymKind_UDT_ST || - kind == CV_SymKind_UDT; - return is_typedef; -} - -internal B32 -cv_is_scope_symbol(CV_SymKind kind) -{ - B32 is_scope = kind == CV_SymKind_GPROC32 || - kind == CV_SymKind_LPROC32 || - kind == CV_SymKind_BLOCK32 || - kind == CV_SymKind_THUNK32 || - kind == CV_SymKind_INLINESITE || - kind == CV_SymKind_INLINESITE2 || - kind == CV_SymKind_WITH32 || - kind == CV_SymKind_SEPCODE || - kind == CV_SymKind_GPROC32_ID || - kind == CV_SymKind_LPROC32_ID; - return is_scope; -} - -internal B32 -cv_is_end_symbol(CV_SymKind kind) -{ - B32 is_end = kind == CV_SymKind_END || - kind == CV_SymKind_PROC_ID_END || - kind == CV_SymKind_INLINESITE_END; - return is_end; -} - -internal B32 -cv_is_leaf_type_server(CV_LeafKind kind) -{ - B32 is_type_server = kind == CV_LeafKind_TYPESERVER || - kind == CV_LeafKind_TYPESERVER2 || - kind == CV_LeafKind_TYPESERVER_ST; - return is_type_server; -} - -internal B32 -cv_is_leaf_pch(CV_LeafKind kind) -{ - B32 is_pch = kind == CV_LeafKind_PRECOMP || - kind == CV_LeafKind_PRECOMP_ST || - kind == CV_LeafKind_PRECOMP_16t; - return is_pch; -} internal CV_ObjInfo cv_obj_info_from_symbol(CV_Symbol symbol) @@ -834,17 +90,6 @@ cv_precomp_info_from_leaf(CV_Leaf leaf) return result; } -internal B32 -cv_is_reg_sp(CV_Arch arch, CV_Reg reg) -{ - switch (arch) { - case CV_Arch_8086: return reg == CV_Regx86_ESP; - case CV_Arch_X64: return reg == CV_Regx64_RSP; - default: NotImplemented; - } - return 0; -} - //////////////////////////////// //~ Leaf Helpers @@ -895,7 +140,7 @@ cv_serialize_leaf_to_buffer(U8 *buffer, U64 buffer_cursor, U64 buffer_size, CV_L } internal String8 -cv_serialize_leaf_ex(Arena *arena, CV_LeafKind kind, String8 data, U64 align) +cv_serialize_raw_leaf(Arena *arena, CV_LeafKind kind, String8 data, U64 align) { U64 buffer_size = cv_compute_leaf_record_size(data, align); U8 *buffer = push_array_no_zero(arena, U8, buffer_size); @@ -907,14 +152,14 @@ cv_serialize_leaf_ex(Arena *arena, CV_LeafKind kind, String8 data, U64 align) internal String8 cv_serialize_leaf(Arena *arena, CV_Leaf *leaf, U64 align) { - return cv_serialize_leaf_ex(arena, leaf->kind, leaf->data, align); + return cv_serialize_raw_leaf(arena, leaf->kind, leaf->data, align); } internal CV_Leaf cv_make_leaf(Arena *arena, CV_LeafKind kind, String8 data) { CV_Leaf result = {0}; - String8 raw_leaf = cv_serialize_leaf_ex(arena, kind, data, 1); + String8 raw_leaf = cv_serialize_raw_leaf(arena, kind, data, 1); cv_deserial_leaf(raw_leaf, 0, 1, &result); return result; } @@ -1318,7 +563,7 @@ internal String8 cv_string_table_from_debug_s(CV_DebugS debug_s) { String8List data_list = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_StringTable); - String8 string_data = str8(0,0); + String8 string_data = str8_zero(); if (data_list.node_count > 0) { string_data = data_list.first->string; } @@ -1329,7 +574,7 @@ internal String8 cv_file_chksms_from_debug_s(CV_DebugS debug_s) { String8List data_list = cv_sub_section_from_debug_s(debug_s, CV_C13SubSectionKind_FileChksms); - String8 file_chksms = str8(0,0); + String8 file_chksms = str8_zero(); if (data_list.node_count > 0) { file_chksms = data_list.first->string; } @@ -1545,9 +790,9 @@ cv_dedup_string_tables(TP_Arena *arena, TP_Context *tp, U64 count, CV_DebugS *ar ProfBegin("Count"); CV_DedupStringTablesTask task = {0}; - task.arr = arr; - task.range_lists = range_lists; - task.string_counts = push_array(scratch.arena, U64, count); + task.arr = arr; + task.range_lists = range_lists; + task.string_counts = push_array(scratch.arena, U64, count); tp_for_parallel(tp, 0, tp->worker_count, cv_count_strings_in_debug_s_arr_task, &task); ProfEnd(); @@ -2218,78 +1463,6 @@ cv_symbol_tree_from_symbol_list(Arena *arena, CV_SymbolList list) return root; } -internal CV_SymbolList -cv_build_symbol_tree(Arena *arena, CV_ScopeList symbol_tree, U64 symbol_base, U64 align) -{ - Temp scratch = scratch_begin(&arena, 1); - - CV_SymbolList result = {0}; - - U64 cursor = symbol_base; - - // setup root frame - CV_ScopeFrame *stack = push_array(scratch.arena, CV_ScopeFrame, 1); - stack->list = &symbol_tree; - stack->curr = stack->list->first; - stack->symbol_off = cursor; - - for (; stack != 0; ) { - for (; stack->curr != 0; stack->curr = stack->curr->next) { - CV_Scope *scope = stack->curr; - CV_Symbol *symbol = &scope->symbol; - - // store symbol - CV_SymbolNode *symbol_node = cv_symbol_list_push_data(arena, &result, symbol->kind, symbol->data); - symbol_node->data.offset = cursor; - - // read & advance cursor - U64 record_size = cv_compute_symbol_record_size(symbol, align); - cursor += record_size; - - if (scope->children) { - // in every scoped symbol parent and end offsets follow record header - U32 *parent_off_ptr = (U32 *)symbol->data.str; - U32 *end_off_ptr = (U32 *)(parent_off_ptr + 1); - - // write parent symbol offset - U64 parent_off64 = stack->symbol_off; - U32 parent_off32 = safe_cast_u32(parent_off64); - *parent_off_ptr = parent_off32; - - // advance to next node so after stack pop we resume from correct node - stack->curr = stack->curr->next; - - // push new scope frame - CV_ScopeFrame *frame = push_array(scratch.arena, CV_ScopeFrame, 1); - frame->symbol_off = symbol_node->data.offset; - frame->list = scope->children; - frame->curr = frame->list->first; - frame->parent_off_ptr = parent_off_ptr; - frame->end_off_ptr = end_off_ptr; - SLLStackPush(stack, frame); - - break; - } - } - - if (stack->curr == 0) { - // write end symbol offset - if (stack->end_off_ptr) { - U64 end_symbol_size = sizeof(CV_SymbolHeader); - U64 end_off64 = cursor - end_symbol_size; - U32 end_off32 = safe_cast_u32(end_off64); - *stack->end_off_ptr = end_off32; - } - - // pop scope - SLLStackPop(stack); - } - } - - scratch_end(scratch); - return result; -} - internal U64 cv_patch_symbol_tree_offsets(CV_SymbolList list, U64 base_offset, U64 align) { @@ -2354,24 +1527,6 @@ cv_patch_symbol_tree_offsets(CV_SymbolList list, U64 base_offset, U64 align) // $$FileChksms -#if 0 -internal String8 -cv_c13_file_chksms_from_sub_sections(String8 c13_data, CV_C13Parsed *ss) -{ - ProfBeginFunction(); - String8 file_chksms = str8(0,0); - CV_C13SubSectionList file_chksms_list = ss->v[CV_C13SubSectionIdxKind_FileChksms]; - if (file_chksms_list.count > 0) { - Assert(file_chksms_list.count == 1); - CV_C13SubSectionNode *file_chksms_node = file_chksms_list.first; - Assert(file_chksms_node->kind == CV_C13SubSectionKind_FileChksms); - file_chksms = str8_substr(c13_data, file_chksms_node->range); - } - ProfEnd(); - return file_chksms; -} -#endif - internal void cv_parse_checksum_data(Arena *arena, CV_ChecksumList *list, String8 checksum_data) { @@ -2796,18 +1951,6 @@ cv_c13_make_inlinee_lines_accel(Arena *arena, CV_C13InlineeLinesParsedList inlin //////////////////////////////// -internal S32 -cv_inline_annot_convert_to_signed_operand(U32 value) -{ - if (value & 1) { - value = -(value >> 1); - } else { - value = value >> 1; - } - S32 result = (S32)value; - return result; -} - internal CV_InlineBinaryAnnotsParsed cv_c13_parse_inline_binary_annots(Arena *arena, U64 parent_voff, @@ -2937,7 +2080,7 @@ cv_c13_parse_inline_binary_annots(Arena *arena, U32 code_offset_and_line_offset = 0; cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &code_offset_and_line_offset); - S32 line_delta = cv_inline_annot_convert_to_signed_operand(code_offset_and_line_offset >> 4); + S32 line_delta = cv_inline_annot_signed_from_unsigned_operand(code_offset_and_line_offset >> 4); U32 code_delta = (code_offset_and_line_offset & 0xf); code_offset += code_delta; @@ -3076,47 +2219,6 @@ cv_c13_parse_inline_binary_annots(Arena *arena, //////////////////////////////// -internal CV_EncodedFramePtrReg -cv_pick_fp_encoding(CV_SymFrameproc *frameproc, B32 is_local_param) -{ - CV_EncodedFramePtrReg fp_reg = 0; - if (is_local_param) { - fp_reg = CV_FrameprocFlags_ExtractParamBasePointer(frameproc->flags); - } else { - fp_reg = CV_FrameprocFlags_ExtractLocalBasePointer(frameproc->flags); - } - return fp_reg; -} - -internal CV_Reg -cv_decode_fp_reg(CV_Arch arch, CV_EncodedFramePtrReg encoded_reg) -{ - CV_Reg fp_reg = 0; - switch (arch) { - case CV_Arch_8086: { - switch (encoded_reg) { - case CV_EncodedFramePtrReg_None : break; - case CV_EncodedFramePtrReg_StackPtr: AssertAlways(!"TODO(nick): not tested, this is a guess"); - fp_reg = CV_Regx86_ESP; break; - case CV_EncodedFramePtrReg_FramePtr: fp_reg = CV_Regx86_EBP; break; - case CV_EncodedFramePtrReg_BasePtr : fp_reg = CV_Regx86_EBX; break; - default: InvalidPath; - } - } break; - case CV_Arch_X64: { - switch (encoded_reg) { - case CV_EncodedFramePtrReg_None : break; - case CV_EncodedFramePtrReg_StackPtr: fp_reg = CV_Regx64_RSP; break; - case CV_EncodedFramePtrReg_FramePtr: fp_reg = CV_Regx64_RBP; break; - case CV_EncodedFramePtrReg_BasePtr : fp_reg = CV_Regx64_R13; break; - default: InvalidPath; - } - } break; - default: NotImplemented; - } - return fp_reg; -} - internal Rng1U64List cv_make_defined_range_list_from_gaps(Arena *arena, Rng1U64 defrange, CV_LvarAddrGap *gaps, U64 gap_count) { @@ -3151,84 +2253,3 @@ cv_make_defined_range_list_from_gaps(Arena *arena, Rng1U64 defrange, CV_LvarAddr return result; } -//////////////////////////////// - -internal U64 -cv_size_from_reg_x86(CV_Reg reg) -{ - switch (reg) { -#define X(NAME, CODE, RDI_NAME, BYTE_POS, BYTE_SIZE) case CV_Regx86_##NAME: return BYTE_SIZE; - CV_Reg_X86_XList(X) -#undef X - } - return 0; -} - -internal U64 -cv_size_from_reg_x64(CV_Reg reg) -{ - switch (reg) { -#define X(NAME, CODE, RDI_NAME, BYTE_POS, BYTE_SIZE) case CV_Regx64_##NAME: return BYTE_SIZE; - CV_Reg_X64_XList(X) -#undef X - } - return 0; -} - -internal U64 -cv_size_from_reg(CV_Arch arch, CV_Reg reg) -{ - switch (arch) { - case CV_Arch_8086: return cv_size_from_reg_x86(reg); - case CV_Arch_X64 : return cv_size_from_reg_x64(reg); - } - return 0; -} - -//////////////////////////////// - -internal CV_Arch -cv_arch_from_coff_machine(COFF_MachineType machine) -{ - CV_Arch arch = 0; - switch (machine) { - case COFF_MachineType_X64: arch = CV_Arch_X64; break; - case COFF_MachineType_X86: arch = CV_Arch_8086; break; - case COFF_MachineType_AM33: arch = CV_Arch_AM33; break; - case COFF_MachineType_ARM: NotImplemented; break; - case COFF_MachineType_ARM64: arch = CV_Arch_ARM64; break; - case COFF_MachineType_ARMNT: arch = CV_Arch_ARMNT; break; - case COFF_MachineType_EBC: arch = CV_Arch_EBC; break; - case COFF_MachineType_IA64: arch = CV_Arch_IA64; break; - case COFF_MachineType_M32R: arch = CV_Arch_M32R; break; - case COFF_MachineType_MIPS16: arch = CV_Arch_MIPS16; break; - case COFF_MachineType_MIPSFPU: NotImplemented; break; - case COFF_MachineType_MIPSFPU16: NotImplemented; break; - case COFF_MachineType_POWERPC: NotImplemented; break; - case COFF_MachineType_POWERPCFP: arch = CV_Arch_PPCFP; break; - case COFF_MachineType_R4000: NotImplemented; break; - case COFF_MachineType_RISCV32: NotImplemented; break; - case COFF_MachineType_RISCV64: NotImplemented; break; - case COFF_MachineType_RISCV128: NotImplemented; break; - case COFF_MachineType_SH3: arch = CV_Arch_SH3; break; - case COFF_MachineType_SH3DSP: arch = CV_Arch_SH3DSP; break; - case COFF_MachineType_SH4: arch = CV_Arch_SH4; break; - case COFF_MachineType_SH5: NotImplemented; break; - case COFF_MachineType_THUMB: arch = CV_Arch_THUMB; break; - case COFF_MachineType_WCEMIPSV2: NotImplemented; break; - } - return arch; -} - -internal String8 -cv_string_from_type_index_source(CV_TypeIndexSource ti_source) -{ - switch (ti_source) { - case CV_TypeIndexSource_NULL: return str8_lit(""); break; - case CV_TypeIndexSource_TPI: return str8_lit("TPI"); break; - case CV_TypeIndexSource_IPI: return str8_lit("IPI"); break; - case CV_TypeIndexSource_COUNT: break; - } - return str8_zero(); -} - diff --git a/src/linker/codeview_ext/codeview.h b/src/linker/codeview_ext/codeview.h index 7dfdbbf5..983536c2 100644 --- a/src/linker/codeview_ext/codeview.h +++ b/src/linker/codeview_ext/codeview.h @@ -3,8 +3,6 @@ #pragma once -#define CV_MinComplexTypeIndex 0x1000 - //////////////////////////////// // Aligns @@ -38,34 +36,6 @@ typedef struct CV_SymbolHeader //////////////////////////////// // Type Index Helpers -typedef enum CV_TypeIndexSource -{ - CV_TypeIndexSource_NULL, - CV_TypeIndexSource_TPI, - CV_TypeIndexSource_IPI, - CV_TypeIndexSource_COUNT -} CV_TypeIndexSource; - -typedef struct CV_TypeIndexInfo -{ - struct CV_TypeIndexInfo *next; - U64 offset; - CV_TypeIndexSource source; -} CV_TypeIndexInfo; - -typedef struct CV_TypeIndexInfoList -{ - U64 count; - CV_TypeIndexInfo *first; - CV_TypeIndexInfo *last; -} CV_TypeIndexInfoList; - -typedef struct CV_TypeIndexArray -{ - U32 count; - CV_TypeIndex *v; -} CV_TypeIndexArray; - //- $$Symbols typedef struct CV_Symbol @@ -198,13 +168,6 @@ typedef struct CV_C13LinesHeaderList //////////////////////////////// -typedef struct CV_UDTInfo -{ - String8 name; - String8 unique_name; - CV_TypeProps props; -} CV_UDTInfo; - typedef struct CV_TypeServerInfo { String8 name; @@ -417,42 +380,17 @@ typedef struct } CV_Str8ListFromDebugT; //////////////////////////////// -// Type Index Helpers - -internal CV_TypeIndexInfo * cv_symbol_type_index_info_push(Arena *arena, CV_TypeIndexInfoList *list, CV_TypeIndexSource source, U64 offset); -internal CV_TypeIndexInfoList cv_get_symbol_type_index_offsets(Arena *arena, CV_SymKind kind, String8 data); -internal CV_TypeIndexInfoList cv_get_leaf_type_index_offsets(Arena *arena, CV_LeafKind leaf_kind, String8 data); -internal CV_TypeIndexInfoList cv_get_inlinee_type_index_offsets(Arena *arena, String8 raw_data); -internal String8Array cv_get_data_around_type_indices(Arena *arena, CV_TypeIndexInfoList ti_list, String8 data); -internal CV_TypeIndexSource cv_type_index_source_from_leaf_kind(CV_LeafKind leaf_kind); - -//////////////////////////////// - -internal U64 cv_name_offset_from_symbol(CV_SymKind kind, String8 data); -internal String8 cv_name_from_symbol (CV_SymKind kind, String8 data); -internal String8 cv_name_from_udt_info (CV_UDTInfo udt_info); - -internal B32 cv_is_udt_name_anon (String8 name); -internal B32 cv_is_udt (CV_LeafKind kind); -internal B32 cv_is_global_symbol (CV_SymKind kind); -internal B32 cv_is_typedef (CV_SymKind kind); -internal B32 cv_is_scope_symbol (CV_SymKind kind); -internal B32 cv_is_end_symbol (CV_SymKind kind); -internal B32 cv_is_leaf_type_server(CV_LeafKind kind); -internal B32 cv_is_leaf_pch (CV_LeafKind kind); internal CV_ObjInfo cv_obj_info_from_symbol(CV_Symbol symbol); internal CV_TypeServerInfo cv_type_server_info_from_leaf(CV_Leaf leaf); internal CV_PrecompInfo cv_precomp_info_from_leaf(CV_Leaf leaf); -internal B32 cv_is_reg_sp(CV_Arch arch, CV_Reg reg); - //////////////////////////////// //~ Leaf Helpers internal U64 cv_compute_leaf_record_size(String8 data, U64 align); internal U64 cv_serialize_leaf_to_buffer(U8 *buffer, U64 buffer_cursor, U64 buffer_size, CV_LeafKind kind, String8 data, U64 align); -internal String8 cv_serialize_leaf_ex(Arena *arena, CV_LeafKind kind, String8 data, U64 align); +internal String8 cv_serialize_raw_leaf(Arena *arena, CV_LeafKind kind, String8 data, U64 align); internal String8 cv_serialize_leaf(Arena *arena, CV_Leaf *leaf, U64 align); internal CV_Leaf cv_make_leaf(Arena *arena, CV_LeafKind kind, String8 data); internal U64 cv_deserial_leaf(String8 raw_data, U64 off, U64 align, CV_Leaf *leaf_out); @@ -506,6 +444,9 @@ internal U64 cv_debug_t_array_count_leaves(U64 count, CV_DebugT *arr internal String8List cv_str8_list_from_debug_t_parallel(TP_Context *tp, Arena *arena, CV_DebugT types); +//////////////////////////////// +//~ Sub Section helpers + // $$Symbols internal void cv_parse_symbol_sub_section(Arena *arena, CV_SymbolList *list, U64 offset_base, String8 data, U64 align); internal void cv_symbol_list_push_node(CV_SymbolList *list, CV_SymbolNode *node); @@ -518,15 +459,12 @@ internal void cv_symbol_list_concat_in_place_arr(CV_SymbolList *lis internal U64 cv_symbol_list_arr_get_count(U64 count, CV_SymbolList *list_arr); internal String8List cv_data_from_symbol_list(Arena *arena, CV_SymbolList symbol_list, U64 align); internal CV_SymbolList cv_global_scope_symbols_from_list(Arena *arena, CV_SymbolList list); -internal CV_ScopeList cv_symbol_tree_from_symbol_list(Arena *arena, CV_SymbolList list); -internal CV_SymbolList cv_build_symbol_tree(Arena *arena, CV_ScopeList symbol_tree, U64 symbol_base, U64 align); internal CV_SymbolPtrArray cv_symbol_ptr_array_from_list(Arena *arena, TP_Context *tp, U64 count, CV_SymbolList *symbol_list_arr); // $$FileChksms #define CV_MAP_STRING_TO_OFFSET_FUNC(name) U64 name(void *ud, String8 string) typedef CV_MAP_STRING_TO_OFFSET_FUNC(CV_MapStringToOffsetFunc); -//internal String8 cv_c13_file_chksms_from_sub_sections(String8 c13_data, CV_C13Parsed *ss); internal void cv_c13_patch_string_offsets_in_checksum_list(CV_ChecksumList checksum_list, String8 string_data, U64 string_data_base_offset, CV_StringHashTable string_ht); internal String8List cv_c13_collect_source_file_names(Arena *arena, CV_ChecksumList checksum_list, String8 string_data); @@ -566,19 +504,6 @@ internal String8 cv_pack_string_hash_table(Arena *arena, TP_Con //////////////////////////////// -internal CV_EncodedFramePtrReg cv_pick_fp_encoding(CV_SymFrameproc *frameproc, B32 is_local_param); -internal CV_Reg cv_decode_fp_reg(CV_Arch arch, CV_EncodedFramePtrReg encoded_reg); -internal Rng1U64List cv_make_defined_range_list_from_gaps(Arena *arena, Rng1U64 defrange, CV_LvarAddrGap *gaps, U64 gap_count); - -//////////////////////////////// - -internal U64 cv_size_from_reg_x86(CV_Reg reg); -internal U64 cv_size_from_reg_x64(CV_Reg reg); -internal U64 cv_size_from_reg(CV_Arch arch, CV_Reg reg); - -//////////////////////////////// - -internal CV_Arch cv_arch_from_coff_machine(COFF_MachineType machine); -internal String8 cv_string_from_type_index_source(CV_TypeIndexSource ti_source); +internal Rng1U64List cv_make_defined_range_list_from_gaps(Arena *arena, Rng1U64 defrange, CV_LvarAddrGap *gaps, U64 gap_count); diff --git a/src/linker/lnk_debug_info.c b/src/linker/lnk_debug_info.c index 98d3a31c..97f8d4a9 100644 --- a/src/linker/lnk_debug_info.c +++ b/src/linker/lnk_debug_info.c @@ -408,7 +408,7 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, String8List lib_dir // TODO: temp hack, remove when we have null obj with .debug$T { - String8 raw_null_leaf = cv_serialize_leaf_ex(scratch.arena, CV_LeafKind_NOTYPE, str8(0,0), 1); + String8 raw_null_leaf = cv_serialize_raw_leaf(scratch.arena, CV_LeafKind_NOTYPE, str8(0,0), 1); String8List srl = {0}; str8_serial_begin(scratch.arena, &srl); diff --git a/src/linker/pdb_ext/pdb_builder.c b/src/linker/pdb_ext/pdb_builder.c index f45de413..0c28c267 100644 --- a/src/linker/pdb_ext/pdb_builder.c +++ b/src/linker/pdb_ext/pdb_builder.c @@ -1330,7 +1330,7 @@ pdb_type_server_make_leaf(PDB_TypeServer *ts, CV_LeafKind kind, String8 data) { ProfBeginFunction(); - String8 leaf = cv_serialize_leaf_ex(ts->arena, kind, data, PDB_LEAF_ALIGN); + String8 leaf = cv_serialize_raw_leaf(ts->arena, kind, data, PDB_LEAF_ALIGN); String8Node *node = str8_list_push(ts->arena, &ts->leaf_list, leaf); ProfEnd(); diff --git a/src/pdb/pdb_parse.c b/src/pdb/pdb_parse.c index e18cef23..f03c1dbf 100644 --- a/src/pdb/pdb_parse.c +++ b/src/pdb/pdb_parse.c @@ -586,50 +586,9 @@ pdb_gsi_symbol_from_string(PDB_GsiParsed *gsi, String8 symbol_data, String8 stri sym_opl = symbol_data.str + opl_off; } - String8 sym_name = str8_zero(); - switch(sym_header->kind) - { - case CV_SymKind_CONSTANT: - { - CV_SymConstant *sym = (CV_SymConstant*)(sym_header+1); - CV_NumericParsed dummy; - U64 numeric_size = cv_read_numeric(symbol_data, off + sizeof(CV_RecHeader), &dummy); - sym_name = str8_cstring_capped((U8*)(sym+1)+numeric_size, sym_opl); - }break; - case CV_SymKind_LDATA32: - case CV_SymKind_GDATA32: - { - CV_SymData32 *sym = (CV_SymData32 *)(sym_header+1); - sym_name = str8_cstring_capped(sym+1, sym_opl); - }break; - case CV_SymKind_LTHREAD32: - case CV_SymKind_GTHREAD32: - { - if(off + sizeof(CV_RecHeader) + sizeof(CV_SymThread32) <= symbol_data.size) - { - CV_SymThread32 *sym = (CV_SymThread32 *)(sym_header+1); - sym_name = str8_cstring_capped(sym+1, sym_opl); - } - }break; - case CV_SymKind_UDT: - { - if(off + sizeof(CV_RecHeader) + sizeof(CV_SymUDT) <= symbol_data.size) - { - CV_SymUDT *sym = (CV_SymUDT *)(sym_header+1); - sym_name = str8_cstring_capped(sym+1, sym_opl); - } - }break; - case CV_SymKind_LPROCREF: - case CV_SymKind_PROCREF: - { - if(off + sizeof(CV_RecHeader) + sizeof(CV_SymRef2) <= symbol_data.size) - { - CV_SymRef2 *sym = (CV_SymRef2 *)(sym_header+1); - sym_name = str8_cstring_capped(sym+1, sym_opl); - } - }break; - default: InvalidPath; - } + Rng1U64 raw_symbol_range = rng_1u64(off + sizeof(*sym_header), off + (sym_header->size - sizeof(sym_header->kind))); + String8 raw_symbol = str8_substr(symbol_data, raw_symbol_range); + String8 sym_name = cv_name_from_symbol(sym_header->kind, raw_symbol); if(str8_match(sym_name, string, 0)) { diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index 0c31249d..9b6923a0 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -415,22 +415,6 @@ p2r_location_from_addr_reg_off(Arena *arena, RDI_Arch arch, RDI_RegCode reg_code return result; } -internal CV_EncodedFramePtrReg -p2r_cv_encoded_fp_reg_from_frameproc(CV_SymFrameproc *frameproc, B32 param_base) -{ - CV_EncodedFramePtrReg result = 0; - CV_FrameprocFlags flags = frameproc->flags; - if(param_base) - { - result = CV_FrameprocFlags_ExtractParamBasePointer(flags); - } - else - { - result = CV_FrameprocFlags_ExtractLocalBasePointer(flags); - } - return result; -} - internal RDI_RegCode p2r_reg_code_from_arch_encoded_fp_reg(RDI_Arch arch, CV_EncodedFramePtrReg encoded_reg) { @@ -2762,7 +2746,7 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) U64 gap_count = ((U8*)sym_data_opl - (U8*)gaps) / sizeof(*gaps); // rjf: select frame pointer register - CV_EncodedFramePtrReg encoded_fp_reg = p2r_cv_encoded_fp_reg_from_frameproc(frameproc, defrange_target_is_param); + CV_EncodedFramePtrReg encoded_fp_reg = cv_pick_fp_encoding(frameproc, defrange_target_is_param); RDI_RegCode fp_register_code = p2r_reg_code_from_arch_encoded_fp_reg(in->arch, encoded_fp_reg); // rjf: build location @@ -2834,7 +2818,7 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) // rjf: unpack sym CV_SymDefrangeFramepointerRelFullScope *defrange_fprel_full_scope = (CV_SymDefrangeFramepointerRelFullScope*)sym_header_struct_base; - CV_EncodedFramePtrReg encoded_fp_reg = p2r_cv_encoded_fp_reg_from_frameproc(frameproc, defrange_target_is_param); + CV_EncodedFramePtrReg encoded_fp_reg = cv_pick_fp_encoding(frameproc, defrange_target_is_param); RDI_RegCode fp_register_code = p2r_reg_code_from_arch_encoded_fp_reg(in->arch, encoded_fp_reg); // rjf: build location diff --git a/src/rdi_from_pdb/rdi_from_pdb.h b/src/rdi_from_pdb/rdi_from_pdb.h index 9eef55ce..7535d450 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.h +++ b/src/rdi_from_pdb/rdi_from_pdb.h @@ -568,7 +568,6 @@ internal RDI_TypeKind p2r_rdi_type_kind_from_cv_basic_type(CV_BasicType basic_ty //~ rjf: Location Info Building Helpers internal RDIM_Location *p2r_location_from_addr_reg_off(Arena *arena, RDI_Arch arch, RDI_RegCode reg_code, U32 reg_byte_size, U32 reg_byte_pos, S64 offset, B32 extra_indirection); -internal CV_EncodedFramePtrReg p2r_cv_encoded_fp_reg_from_frameproc(CV_SymFrameproc *frameproc, B32 param_base); internal RDI_RegCode p2r_reg_code_from_arch_encoded_fp_reg(RDI_Arch arch, CV_EncodedFramePtrReg encoded_reg); internal void p2r_location_over_lvar_addr_range(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_LocationSet *locset, RDIM_Location *location, CV_LvarAddrRange *range, COFF_SectionHeader *section, CV_LvarAddrGap *gaps, U64 gap_count);