.debug_info dumping pass

This commit is contained in:
Ryan Fleury
2025-06-19 10:29:47 -07:00
parent a2ab822eb5
commit 7c35028a6b
13 changed files with 178 additions and 6206 deletions
+47 -41
View File
@@ -447,54 +447,60 @@ dw_string_from_tag_kind(Arena *arena, DW_TagKind kind)
internal String8
dw_string_from_attrib_kind(Arena *arena, DW_Version ver, DW_Ext ext, DW_AttribKind kind)
{
#define X(_N,...) case DW_AttribKind_##_N: return str8_lit(Stringify(_N));
#define X(_N,...) case DW_AttribKind_##_N:{result = str8_lit(Stringify(_N));}break;
String8 result = {0};
while (ext) {
U64 z = 64-clz64(ext);
if (z == 0) {
break;
}
U64 flag = 1 << (z-1);
ext &= ~flag;
switch (flag) {
case DW_Ext_Null: break;
case DW_Ext_GNU: switch (kind) { DW_AttribKind_GNU_XList(X) } break;
case DW_Ext_LLVM: switch (kind) { DW_AttribKind_LLVM_XList(X) } break;
case DW_Ext_APPLE: switch (kind) { DW_AttribKind_APPLE_XList(X) } break;
case DW_Ext_MIPS: switch (kind) { DW_AttribKind_MIPS_XList(X) } break;
default: InvalidPath; break;
//- rjf: try extensions
if(result.size != 0)
{
while(ext)
{
U64 z = 64-clz64(ext);
if(z == 0)
{
break;
}
U64 flag = 1 << (z-1);
ext &= ~flag;
switch(flag)
{
default:{}break;
case DW_Ext_Null: break;
case DW_Ext_GNU: switch (kind) { DW_AttribKind_GNU_XList(X) } break;
case DW_Ext_LLVM: switch (kind) { DW_AttribKind_LLVM_XList(X) } break;
case DW_Ext_APPLE: switch (kind) { DW_AttribKind_APPLE_XList(X) } break;
case DW_Ext_MIPS: switch (kind) { DW_AttribKind_MIPS_XList(X) } break;
}
}
}
switch (ver) {
case DW_Version_5: {
switch (kind) {
DW_AttribKind_V5_XList(X)
//- rjf: try version
if(result.size == 0)
{
for(U64 retry = 0; retry < 2; retry += 1)
{
DW_Version version = retry ? DW_Version_5 : ver;
switch(version)
{
case DW_Version_5: { switch(kind) { DW_AttribKind_V5_XList(X) } } // fall-through
case DW_Version_4: { switch(kind) { DW_AttribKind_V4_XList(X) } } // fall-through
case DW_Version_3: { switch(kind) { DW_AttribKind_V3_XList(X) } } // fall-through
case DW_Version_2: { switch(kind) { DW_AttribKind_V2_XList(X) } } // fall-through
case DW_Version_1: {}break;
case DW_Version_Null:{}break;
default:{}break;
}
} // fall-through
case DW_Version_4: {
switch (kind) {
DW_AttribKind_V4_XList(X)
}
} // fall-through
case DW_Version_3: {
switch (kind) {
DW_AttribKind_V3_XList(X)
}
} // fall-through
case DW_Version_2: {
switch (kind) {
DW_AttribKind_V2_XList(X)
}
} // fall-through
case DW_Version_1: {
} // fall-through
case DW_Version_Null: break;
}
}
//- rjf: fallback
if(result.size == 0)
{
result = push_str8f(arena, "#%u", kind);
}
#undef X
return str8_zero();
return result;
}
internal String8
+131 -171
View File
@@ -625,12 +625,6 @@ dw_print_eh_frame(Arena *arena, String8List *out, String8 indent, String8 raw_eh
scratch_end(scratch);
}
internal void
dw_print_debug_info(Arena *arena, String8List *out, String8 indent, DW_Input *input, DW_ListUnitInput lu_input, Arch arch, B32 relaxed)
{
}
internal void
dw_print_debug_abbrev(Arena *arena, String8List *out, String8 indent, DW_Input *input)
{
@@ -1927,7 +1921,7 @@ dw_dump_list_from_sections(Arena *arena, DW_Input *input, Arch arch, ExecutableI
dw_read_line_vm_header(unit_temp.arena, stmt_list, 0, input, unit_dir, unit_name, unit.address_size, unit.str_offsets_lu, &line_vm);
//- rjf: log top-level unit info
dumpf("unit: // compile_unit[%u]\n{\n", unit_idx);
dumpf("unit: // compile_unit[%I64u]\n{\n", unit_idx);
dumpf(" version: %u\n", unit.version);
dumpf(" address_size: %I64u\n", unit.address_size);
dumpf(" abbrev_off: 0x%I64x\n", unit.abbrev_off);
@@ -1935,213 +1929,179 @@ dw_dump_list_from_sections(Arena *arena, DW_Input *input, Arch arch, ExecutableI
//- rjf: log tags
S64 tag_depth = 0;
for(U64 info_off = unit.first_tag_info_off; info_off < unit.info_range.max;)
U64 tag_idx = 0;
for(U64 info_off = unit.first_tag_info_off; info_off < unit.info_range.max; tag_idx += 1)
{
// rjf: unpack tag
Temp tag_temp = temp_begin(scratch.arena);
// rjf: unpack tag
String8 tag_indent = str8_prefix(indent, (tag_depth+1)*2);
U64 tag_info_off = info_off;
DW_Tag tag = {0};
info_off += dw_read_tag_cu(tag_temp.arena, input, &unit, tag_info_off, &tag);
String8 tag_str = dw_string_from_tag_kind(tag_temp.arena, tag.kind);
rd_printf("<%x><%llx> DW_TagKind_%S (Abbrev Number: %llu)", tag_depth, tag_info_off, tag_str, tag.abbrev_id);
rd_indent();
// rjf: log top-level tag info
dumpf("%Stag: // compile_unit[%I64u].tag[%I64u]\n%S{\n", tag_indent, unit_idx, tag_idx, tag_indent);
dumpf("%S kind: %S\n", tag_indent, dw_string_from_tag_kind(tag_temp.arena, tag.kind));
dumpf("%S info_off: 0x%I64x\n", tag_indent, tag_info_off);
dumpf("%S abbrev_id: %I64u\n", tag_indent, tag.abbrev_id);
// parse attributes
for (DW_AttribNode *attrib_n = tag.attribs.first; attrib_n != 0; attrib_n = attrib_n->next) {
// rjf: log attribs
for(DW_AttribNode *attrib_n = tag.attribs.first;
attrib_n != 0;
attrib_n = attrib_n->next)
{
Temp attrib_temp = temp_begin(tag_temp.arena);
DW_Attrib *attrib = &attrib_n->v;
String8List attrib_list = {0};
// rjf: log attrib begin
dumpf("%S attrib: {");
// attribute .debug_info offset
str8_list_pushf(attrib_temp.arena, &attrib_list, "<%llx> ", attrib->info_off);
// attribute kind
String8 attrib_kind_str = dw_string_from_attrib_kind(attrib_temp.arena, unit.version, unit.ext, attrib->attrib_kind);
if (attrib_kind_str.size == 0) {
if (relaxed) {
attrib_kind_str = dw_string_from_attrib_kind(attrib_temp.arena, DW_Version_Last, unit.ext, attrib->attrib_kind);
}
}
if (attrib_kind_str.size == 0) {
str8_list_pushf(attrib_temp.arena, &attrib_list, "Unknown(%#x) ", attrib->attrib_kind);
} else {
str8_list_pushf(attrib_temp.arena, &attrib_list, "DW_AttribKind_%-20S ", attrib_kind_str);
}
// form kind
String8 form_kind_str = dw_string_from_form_kind(scratch.arena, unit.version, attrib->form_kind);
str8_list_pushf(attrib_temp.arena, &attrib_list, "DW_Form_%-15S", form_kind_str);
// rjf: log basic info
dumpf(" off: 0x%I64x", attrib->info_off);
dumpf(", kind: %S", dw_string_from_attrib_kind(attrib_temp.arena, unit.version, unit.ext, attrib->attrib_kind));
dumpf(", form_kind: %S", dw_string_from_form_kind(attrib_temp.arena, unit.version, attrib->form_kind));
// rjf: log attrib's value based on vlass
dumpf(", ");
DW_AttribClass value_class = dw_value_class_from_attrib(&unit, attrib);
switch (value_class) {
default: {
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unknown value class");
} break;
case DW_AttribClass_Undefined: {
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: undefined value class");
} break;
case DW_AttribClass_Address: {
U64 address = dw_address_from_attrib(input, &unit, attrib);
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", address);
} break;
case DW_AttribClass_Block: {
switch(value_class)
{
default: {dumpf("`unknown value class`");}break;
case DW_AttribClass_Undefined: {dumpf("`undefined value class`");}break;
case DW_AttribClass_Address: {dumpf("0x%I64x", dw_address_from_attrib(input, &unit, attrib));}break;
case DW_AttribClass_Const: {dumpf("0x%I64x", dw_const_u64_from_attrib(input, &unit, attrib));}break;
case DW_AttribClass_Block:
{
String8 block = dw_block_from_attrib(input, &unit, attrib);
String8List block_strs = numeric_str8_list_from_data(attrib_temp.arena, 16, block, 1);
String8 block_str = str8_list_join(attrib_temp.arena, &block_strs, &(StringJoin){.sep = str8_lit(", ")});
str8_list_push(attrib_temp.arena, &attrib_list, block_str);
} break;
case DW_AttribClass_Const: {
U64 constant = dw_const_u64_from_attrib(input, &unit, attrib);
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", constant);
} break;
case DW_AttribClass_ExprLoc: {
String8 exprloc = dw_exprloc_from_attrib(input, &unit, attrib);
dump(block_str);
}break;
case DW_AttribClass_ExprLoc:
{
String8 exprloc = dw_exprloc_from_attrib(input, &unit, attrib);
String8 exprloc_str = dw_format_expression_single_line(attrib_temp.arena, exprloc, unit_range.min, unit.address_size, arch, unit.version, unit.ext, unit.format);
str8_list_push(attrib_temp.arena, &attrib_list, exprloc_str);
} break;
case DW_AttribClass_Flag: {
dump(exprloc_str);
}break;
case DW_AttribClass_Flag:
{
B32 flag = dw_flag_from_attrib(input, &unit, attrib);
str8_list_pushf(attrib_temp.arena, &attrib_list, "%llu (%s)", flag, flag == 0 ? "false" : "true");
} break;
case DW_AttribClass_LinePtr: {
if (attrib->form_kind == DW_Form_SecOffset) {
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
} else {
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unexpected form %S", dw_string_from_form_kind(attrib_temp.arena, unit.version, attrib->form_kind));
dumpf("%llu: %s", flag, flag == 0 ? "false" : "true");
}break;
case DW_AttribClass_LinePtr:
case DW_AttribClass_LocListPtr:
case DW_AttribClass_MacPtr:
case DW_AttribClass_RngListPtr:
case DW_AttribClass_RngList:
case DW_AttribClass_StrOffsetsPtr:
case DW_AttribClass_AddrPtr:
{
if(attrib->form_kind == DW_Form_SecOffset)
{
dumpf("0x%I64x", attrib->form.sec_offset);
}
} break;
case DW_AttribClass_LocListPtr: {
if (attrib->form_kind == DW_Form_SecOffset) {
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
} else {
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unexpected form %S", dw_string_from_form_kind(attrib_temp.arena, unit.version, attrib->form_kind));
else
{
dumpf("`unexpected form kind %S`", dw_string_from_form_kind(attrib_temp.arena, unit.version, attrib->form_kind));
}
} break;
case DW_AttribClass_MacPtr: {
if (attrib->form_kind == DW_Form_SecOffset) {
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
} else {
str8_list_pushf(attrib_temp.arena, &attrib_list, "\?\?\?");
}
} break;
case DW_AttribClass_RngListPtr: {
if (attrib->form_kind == DW_Form_SecOffset) {
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
} else {
str8_list_pushf(attrib_temp.arena, &attrib_list, "\?\?\?");
}
} break;
case DW_AttribClass_RngList: {
if (attrib->form_kind == DW_Form_SecOffset) {
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
} else {
str8_list_pushf(attrib_temp.arena, &attrib_list, "\?\?\?");
}
} break;
case DW_AttribClass_Reference: {
if (attrib->form_kind == DW_Form_Ref1 ||
attrib->form_kind == DW_Form_Ref2 ||
attrib->form_kind == DW_Form_Ref4 ||
attrib->form_kind == DW_Form_Ref8 ||
attrib->form_kind == DW_Form_RefUData) {
}break;
case DW_AttribClass_Reference:
{
if(attrib->form_kind == DW_Form_Ref1 ||
attrib->form_kind == DW_Form_Ref2 ||
attrib->form_kind == DW_Form_Ref4 ||
attrib->form_kind == DW_Form_Ref8 ||
attrib->form_kind == DW_Form_RefUData)
{
U64 info_off = unit.info_range.min + attrib->form.ref;
str8_list_pushf(attrib_temp.arena, &attrib_list, "<%llx>", info_off);
if (!contains_1u64(unit.info_range, attrib->form.ref)) {
str8_list_pushf(attrib_temp.arena, &attrib_list, "(ERROR: out of bounds reference)");
dumpf("0x%I64x", info_off);
if(!contains_1u64(unit.info_range, attrib->form.ref))
{
dumpf(": `(out of this unit's bounds)`");
}
} else {
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.ref);
}
} break;
case DW_AttribClass_String: {
if (attrib->form_kind == DW_Form_Strp) {
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
else
{
dumpf("0x%I64x", attrib->form.ref);
}
}break;
case DW_AttribClass_String:
{
if(attrib->form_kind == DW_Form_Strp)
{
dumpf("0x%I64x", attrib->form.sec_offset);
}
String8 string = dw_string_from_attrib(input, &unit, attrib);
str8_list_pushf(attrib_temp.arena, &attrib_list, "(%S)", string);
} break;
case DW_AttribClass_StrOffsetsPtr: {
if (attrib->form_kind == DW_Form_SecOffset) {
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
} else {
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unexpected form %S", dw_string_from_form_kind(attrib_temp.arena, unit.version, attrib->form_kind));
}
} break;
case DW_AttribClass_AddrPtr: {
if (attrib->form_kind == DW_Form_SecOffset) {
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
} else {
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unexpected form %S", dw_string_from_form_kind(attrib_temp.arena, unit.version, attrib->form_kind));
}
} break;
dumpf(": \"%S\"", string);
}break;
}
String8 attrib_str = {0};
switch (attrib->attrib_kind) {
case DW_AttribKind_Language: {
// rjf: extend attrib's value with enum info
switch(attrib->attrib_kind)
{
case DW_AttribKind_Language:
{
DW_Language lang = dw_const_u64_from_attrib(input, &unit, attrib);
attrib_str = dw_string_from_language(attrib_temp.arena, lang);
} break;
case DW_AttribKind_DeclFile: {
dumpf(": %S", dw_string_from_language(attrib_temp.arena, lang));
}break;
case DW_AttribKind_DeclFile:
{
U64 file_idx = dw_const_u64_from_attrib(input, &unit, attrib);
DW_LineFile *file = dw_file_from_attrib(&unit, &line_vm, attrib);
attrib_str = str8_lit("\?\?\?");
if (file) {
attrib_str = dw_path_from_file(attrib_temp.arena, &line_vm, file);
if(file != 0)
{
dumpf(": %S", dw_path_from_file(attrib_temp.arena, &line_vm, file));
}
} break;
case DW_AttribKind_DeclLine: {
U64 line = dw_const_u64_from_attrib(input, &unit, attrib);
attrib_str = push_str8f(attrib_temp.arena, "%llu", line);
} break;
case DW_AttribKind_Inline: {
}break;
case DW_AttribKind_DeclLine:
{
dumpf(": %I64u", dw_const_u64_from_attrib(input, &unit, attrib));
}break;
case DW_AttribKind_Inline:
{
DW_InlKind inl = dw_const_u64_from_attrib(input, &unit, attrib);
attrib_str = dw_string_from_inl(attrib_temp.arena, inl);
} break;
case DW_AttribKind_Accessibility: {
dumpf(": %S", dw_string_from_inl(attrib_temp.arena, inl));
}break;
case DW_AttribKind_Accessibility:
{
DW_AccessKind access = dw_const_u64_from_attrib(input, &unit, attrib);
attrib_str = dw_string_from_access_kind(attrib_temp.arena, access);
} break;
case DW_AttribKind_CallingConvention: {
dumpf(": %S", dw_string_from_access_kind(attrib_temp.arena, access));
}break;
case DW_AttribKind_CallingConvention:
{
DW_CallingConventionKind calling_convetion = dw_const_u64_from_attrib(input, &unit, attrib);
attrib_str = dw_string_from_calling_convetion(attrib_temp.arena, calling_convetion);
} break;
case DW_AttribKind_Encoding: {
dumpf(": %S", dw_string_from_calling_convetion(attrib_temp.arena, calling_convetion));
}break;
case DW_AttribKind_Encoding:
{
DW_ATE encoding = dw_const_u64_from_attrib(input, &unit, attrib);
attrib_str = dw_string_from_attrib_type_encoding(attrib_temp.arena, encoding);
} break;
dumpf(": %S", dw_string_from_attrib_type_encoding(attrib_temp.arena, encoding));
}break;
}
if (attrib_str.size) {
str8_list_pushf(attrib_temp.arena, &attrib_list, "(%S)", attrib_str);
}
String8 print = str8_list_join(attrib_temp.arena, &attrib_list, &(StringJoin){.sep=str8_lit(" ")});
rd_printf("%S", print);
// rjf: log attrib end
dumpf(" }\n");
temp_end(attrib_temp);
}
B32 is_ender_tag = tag.abbrev_id == 0;
if (tag.has_children) {
if (is_ender_tag) {
rd_errorf("null-tag cannot have children");
}
rd_indent();
tag_depth += 1;
}
if (is_ender_tag) {
if (tag_depth == 0) {
rd_errorf("malformed data detected, too many null tags");
} else {
rd_unindent();
tag_depth -= 1;
}
// rjf: log tag closes
if(!tag.has_children || tag.abbrev_id == 0)
{
dumpf("%S}\n", tag_indent);
}
// rjf: indent/unindent
if(tag.has_children)
{
tag_depth += 1;
}
if(tag.abbrev_id)
{
tag_depth -= 1;
}
rd_unindent();
temp_end(tag_temp);
}
temp_end(unit_temp);
-1
View File
@@ -58,7 +58,6 @@ internal String8 dw_format_eh_ptr_enc (Arena *arena, DW_EhPtrEnc
internal void dw_print_cfi_program (Arena *arena, String8List *out, String8 indent, String8 raw_data, DW_CIEUnpacked *cie, DW_EhPtrCtx *ptr_ctx, Arch arch, DW_Version ver, DW_Ext ext, DW_Format format);
internal void dw_print_eh_frame (Arena *arena, String8List *out, String8 indent, String8 raw_eh_frame, Arch arch, DW_Version ver, DW_Ext ext, DW_EhPtrCtx *ptr_ctx);
internal void dw_print_debug_info (Arena *arena, String8List *out, String8 indent, DW_Input *input, DW_ListUnitInput lu_input, Arch arch, B32 relaxed);
internal void dw_print_debug_abbrev (Arena *arena, String8List *out, String8 indent, DW_Input *input);
internal void dw_print_debug_line (Arena *arena, String8List *out, String8 indent, DW_Input *input, DW_ListUnitInput lu_input, B32 relaxed);
internal void dw_print_debug_str (Arena *arena, String8List *out, String8 indent, DW_Input *input);
-80
View File
@@ -1,80 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal RDI_Arch
c2r_rdi_arch_from_coff_machine(COFF_MachineType machine)
{
switch (machine) {
case COFF_MachineType_X86: return RDI_Arch_X86;
case COFF_MachineType_X64: return RDI_Arch_X64;
case COFF_MachineType_Unknown:
case COFF_MachineType_Am33:
case COFF_MachineType_Arm:
case COFF_MachineType_Arm64:
case COFF_MachineType_ArmNt:
case COFF_MachineType_Ebc:
case COFF_MachineType_Ia64:
case COFF_MachineType_M32R:
case COFF_MachineType_Mips16:
case COFF_MachineType_MipsFpu:
case COFF_MachineType_MipsFpu16:
case COFF_MachineType_PowerPc:
case COFF_MachineType_PowerPcFp:
case COFF_MachineType_R4000:
case COFF_MachineType_RiscV32:
case COFF_MachineType_RiscV64:
case COFF_MachineType_Sh3:
case COFF_MachineType_Sh3Dsp:
case COFF_MachineType_Sh4:
case COFF_MachineType_Sh5:
case COFF_MachineType_Thumb:
case COFF_MachineType_WceMipsV2:
NotImplemented;
default:
return RDI_Arch_NULL;
}
}
internal RDI_BinarySectionFlags
c2r_rdi_binary_section_flags_from_coff_section_flags(COFF_SectionFlags flags)
{
RDI_BinarySectionFlags result = 0;
if(flags & COFF_SectionFlag_MemRead)
{
result |= RDI_BinarySectionFlag_Read;
}
if(flags & COFF_SectionFlag_MemWrite)
{
result |= RDI_BinarySectionFlag_Write;
}
if(flags & COFF_SectionFlag_MemExecute)
{
result |= RDI_BinarySectionFlag_Execute;
}
return(result);
}
internal RDIM_BinarySectionList
c2r_rdi_binary_sections_from_coff_sections(Arena *arena, String8 image_data, String8 string_table, U64 sectab_count, COFF_SectionHeader *sectab)
{
ProfBeginFunction();
RDIM_BinarySectionList binary_sections = {0};
for (U64 isec = 0; isec < sectab_count; ++isec) {
COFF_SectionHeader *coff_sec = &sectab[isec];
RDIM_BinarySection *sec = rdim_binary_section_list_push(arena, &binary_sections);
sec->name = coff_name_from_section_header(string_table, coff_sec);
sec->flags = c2r_rdi_binary_section_flags_from_coff_section_flags(coff_sec->flags);
sec->voff_first = coff_sec->voff;
sec->voff_opl = coff_sec->voff + coff_sec->vsize;
sec->foff_first = coff_sec->foff;
sec->foff_opl = coff_sec->foff + coff_sec->fsize;
}
ProfEnd();
return binary_sections;
}
-12
View File
@@ -1,12 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef RADCON_COFF_H
#define RADCON_COFF_H
internal RDI_Arch c2r_rdi_arch_from_coff_machine(COFF_MachineType machine);
internal RDI_BinarySectionFlags c2r_rdi_binary_section_flags_from_coff_section_flags(COFF_SectionFlags flags);
internal RDIM_BinarySectionList c2r_rdi_binary_sections_from_coff_sections(Arena *arena, String8 image_data, String8 string_table, U64 sectab_count, COFF_SectionHeader *sectab);
#endif // RADCON_COFF_H
-252
View File
@@ -1,252 +0,0 @@
////////////////////////////////
//~ rjf: CodeView <-> RDI Canonical Conversions
internal RDI_Arch
cv2r_rdi_arch_from_cv_arch(CV_Arch cv_arch)
{
RDI_Arch result = 0;
switch(cv_arch)
{
case CV_Arch_8086: result = RDI_Arch_X86; break;
case CV_Arch_X64: result = RDI_Arch_X64; break;
//case CV_Arch_8080: break;
//case CV_Arch_80286: break;
//case CV_Arch_80386: break;
//case CV_Arch_80486: break;
//case CV_Arch_PENTIUM: break;
//case CV_Arch_PENTIUMII: break;
//case CV_Arch_PENTIUMIII: break;
//case CV_Arch_MIPS: break;
//case CV_Arch_MIPS16: break;
//case CV_Arch_MIPS32: break;
//case CV_Arch_MIPS64: break;
//case CV_Arch_MIPSI: break;
//case CV_Arch_MIPSII: break;
//case CV_Arch_MIPSIII: break;
//case CV_Arch_MIPSIV: break;
//case CV_Arch_MIPSV: break;
//case CV_Arch_M68000: break;
//case CV_Arch_M68010: break;
//case CV_Arch_M68020: break;
//case CV_Arch_M68030: break;
//case CV_Arch_M68040: break;
//case CV_Arch_ALPHA: break;
//case CV_Arch_ALPHA_21164: break;
//case CV_Arch_ALPHA_21164A: break;
//case CV_Arch_ALPHA_21264: break;
//case CV_Arch_ALPHA_21364: break;
//case CV_Arch_PPC601: break;
//case CV_Arch_PPC603: break;
//case CV_Arch_PPC604: break;
//case CV_Arch_PPC620: break;
//case CV_Arch_PPCFP: break;
//case CV_Arch_PPCBE: break;
//case CV_Arch_SH3: break;
//case CV_Arch_SH3E: break;
//case CV_Arch_SH3DSP: break;
//case CV_Arch_SH4: break;
//case CV_Arch_SHMEDIA: break;
//case CV_Arch_ARM3: break;
//case CV_Arch_ARM4: break;
//case CV_Arch_ARM4T: break;
//case CV_Arch_ARM5: break;
//case CV_Arch_ARM5T: break;
//case CV_Arch_ARM6: break;
//case CV_Arch_ARM_XMAC: break;
//case CV_Arch_ARM_WMMX: break;
//case CV_Arch_ARM7: break;
//case CV_Arch_OMNI: break;
//case CV_Arch_IA64_1: break;
//case CV_Arch_IA64_2: break;
//case CV_Arch_CEE: break;
//case CV_Arch_AM33: break;
//case CV_Arch_M32R: break;
//case CV_Arch_TRICORE: break;
//case CV_Arch_EBC: break;
//case CV_Arch_THUMB: break;
//case CV_Arch_ARMNT: break;
//case CV_Arch_ARM64: break;
//case CV_Arch_D3D11_SHADER: break;
}
return(result);
}
internal RDI_RegCode
cv2r_rdi_reg_code_from_cv_reg_code(RDI_Arch arch, CV_Reg reg_code)
{
RDI_RegCode result = 0;
switch(arch)
{
case RDI_Arch_X86:
{
switch(reg_code)
{
#define X(CVN,C,RDN,BP,BZ) case C: result = RDI_RegCodeX86_##RDN; break;
CV_Reg_X86_XList(X)
#undef X
}
}break;
case RDI_Arch_X64:
{
switch(reg_code)
{
#define X(CVN,C,RDN,BP,BZ) case C: result = RDI_RegCodeX64_##RDN; break;
CV_Reg_X64_XList(X)
#undef X
}
}break;
}
return(result);
}
internal RDI_Language
cv2r_rdi_language_from_cv_language(CV_Language cv_language)
{
RDI_Language result = 0;
switch(cv_language)
{
case CV_Language_C: result = RDI_Language_C; break;
case CV_Language_CXX: result = RDI_Language_CPlusPlus; break;
//case CV_Language_FORTRAN: result = ; break;
//case CV_Language_MASM: result = ; break;
//case CV_Language_PASCAL: result = ; break;
//case CV_Language_BASIC: result = ; break;
//case CV_Language_COBOL: result = ; break;
//case CV_Language_LINK: result = ; break;
//case CV_Language_CVTRES: result = ; break;
//case CV_Language_CVTPGD: result = ; break;
//case CV_Language_CSHARP: result = ; break;
//case CV_Language_VB: result = ; break;
//case CV_Language_ILASM: result = ; break;
//case CV_Language_JAVA: result = ; break;
//case CV_Language_JSCRIPT: result = ; break;
//case CV_Language_MSIL: result = ; break;
//case CV_Language_HLSL: result = ; break;
}
return(result);
}
internal RDI_RegCode
cv2r_reg_code_from_arch_encoded_fp_reg(RDI_Arch arch, CV_EncodedFramePtrReg encoded_reg)
{
RDI_RegCode result = 0;
switch(arch)
{
case RDI_Arch_X86:
{
switch(encoded_reg)
{
case CV_EncodedFramePtrReg_StackPtr:
{
// TODO(allen): support CV_AllReg_VFRAME
// TODO(allen): error
}break;
case CV_EncodedFramePtrReg_FramePtr:
{
result = RDI_RegCodeX86_ebp;
}break;
case CV_EncodedFramePtrReg_BasePtr:
{
result = RDI_RegCodeX86_ebx;
}break;
}
}break;
case RDI_Arch_X64:
{
switch(encoded_reg)
{
case CV_EncodedFramePtrReg_StackPtr:
{
result = RDI_RegCodeX64_rsp;
}break;
case CV_EncodedFramePtrReg_FramePtr:
{
result = RDI_RegCodeX64_rbp;
}break;
case CV_EncodedFramePtrReg_BasePtr:
{
result = RDI_RegCodeX64_r13;
}break;
}
}break;
}
return(result);
}
internal RDI_TypeKind
cv2r_rdi_type_kind_from_cv_basic_type(CV_BasicType basic_type)
{
RDI_TypeKind result = RDI_TypeKind_NULL;
switch(basic_type)
{
case CV_BasicType_VOID: {result = RDI_TypeKind_Void;}break;
case CV_BasicType_HRESULT: {result = RDI_TypeKind_HResult;}break;
case CV_BasicType_RCHAR:
case CV_BasicType_CHAR:
case CV_BasicType_CHAR8:
{result = RDI_TypeKind_Char8;}break;
case CV_BasicType_UCHAR: {result = RDI_TypeKind_UChar8;}break;
case CV_BasicType_WCHAR: {result = RDI_TypeKind_UChar16;}break;
case CV_BasicType_CHAR16: {result = RDI_TypeKind_Char16;}break;
case CV_BasicType_CHAR32: {result = RDI_TypeKind_Char32;}break;
case CV_BasicType_BOOL8:
case CV_BasicType_INT8:
{result = RDI_TypeKind_S8;}break;
case CV_BasicType_BOOL16:
case CV_BasicType_INT16:
case CV_BasicType_SHORT:
{result = RDI_TypeKind_S16;}break;
case CV_BasicType_BOOL32:
case CV_BasicType_INT32:
case CV_BasicType_LONG:
{result = RDI_TypeKind_S32;}break;
case CV_BasicType_BOOL64:
case CV_BasicType_INT64:
case CV_BasicType_QUAD:
{result = RDI_TypeKind_S64;}break;
case CV_BasicType_INT128:
case CV_BasicType_OCT:
{result = RDI_TypeKind_S128;}break;
case CV_BasicType_UINT8: {result = RDI_TypeKind_U8;}break;
case CV_BasicType_UINT16:
case CV_BasicType_USHORT:
{result = RDI_TypeKind_U16;}break;
case CV_BasicType_UINT32:
case CV_BasicType_ULONG:
{result = RDI_TypeKind_U32;}break;
case CV_BasicType_UINT64:
case CV_BasicType_UQUAD:
{result = RDI_TypeKind_U64;}break;
case CV_BasicType_UINT128:
case CV_BasicType_UOCT:
{result = RDI_TypeKind_U128;}break;
case CV_BasicType_FLOAT16:{result = RDI_TypeKind_F16;}break;
case CV_BasicType_FLOAT32:{result = RDI_TypeKind_F32;}break;
case CV_BasicType_FLOAT32PP:{result = RDI_TypeKind_F32PP;}break;
case CV_BasicType_FLOAT48:{result = RDI_TypeKind_F48;}break;
case CV_BasicType_FLOAT64:{result = RDI_TypeKind_F64;}break;
case CV_BasicType_FLOAT80:{result = RDI_TypeKind_F80;}break;
case CV_BasicType_FLOAT128:{result = RDI_TypeKind_F128;}break;
case CV_BasicType_COMPLEX32:{result = RDI_TypeKind_ComplexF32;}break;
case CV_BasicType_COMPLEX64:{result = RDI_TypeKind_ComplexF64;}break;
case CV_BasicType_COMPLEX80:{result = RDI_TypeKind_ComplexF80;}break;
case CV_BasicType_COMPLEX128:{result = RDI_TypeKind_ComplexF128;}break;
case CV_BasicType_PTR:{result = RDI_TypeKind_Handle;}break;
}
return result;
}
-10
View File
@@ -1,10 +0,0 @@
#pragma once
////////////////////////////////
//~ rjf: CodeView => RDI Canonical Conversions
internal RDI_Arch cv2r_rdi_arch_from_cv_arch(CV_Arch arch);
internal RDI_RegCode cv2r_rdi_reg_code_from_cv_reg_code(RDI_Arch arch, CV_Reg reg_code);
internal RDI_Language cv2r_rdi_language_from_cv_language(CV_Language language);
internal RDI_RegCode cv2r_reg_code_from_arch_encoded_fp_reg(RDI_Arch arch, CV_EncodedFramePtrReg encoded_reg);
internal RDI_TypeKind cv2r_rdi_type_kind_from_cv_basic_type(CV_BasicType basic_type);
File diff suppressed because it is too large Load Diff
-42
View File
@@ -1,42 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef RADCON_DWARF_H
#define RADCON_DWARF_H
typedef struct D2R_TypeTable
{
HashTable *ht;
RDIM_TypeChunkList *types;
U64 type_chunk_cap;
RDIM_Type *varg_type;
} D2R_TypeTable;
typedef struct D2R_TagNode
{
struct D2R_TagNode *next;
DW_TagNode *cur_node;
RDIM_Type *type;
RDIM_Scope *scope;
} D2R_TagNode;
typedef struct D2R_CompUnitContribMap
{
U64 count;
U64 *info_off_arr;
RDIM_Rng1U64ChunkList *voff_range_arr;
} D2R_CompUnitContribMap;
////////////////////////////////
internal RDIM_BakeParams * d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in);
////////////////////////////////
internal RDI_Language rdi_language_from_dw_language(DW_Language v);
internal RDI_RegCodeX86 rdi_reg_from_dw_reg_x86(DW_RegX86 v);
internal B32 rdi_reg_from_dw_reg_x64(DW_RegX64 v, RDI_RegCodeX64 *code_out, U64 *off_out, U64 *size_out);
internal B32 rdi_reg_from_dw_reg(Arch arch, DW_Reg v, RDI_RegCode *code_out, U64 *off_out, U64 *size_out);
#endif // RADCON_DWARF_H
-10
View File
@@ -1,10 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal RDIM_BinarySectionList
e2r_rdi_binary_sections_from_elf_section_table(Arena *arena, ELF_Shdr64Array shdrs)
{
RDIM_BinarySectionList result = {0};
return result;
}
-9
View File
@@ -1,9 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef RADCON_ELF_H
#define RADCON_ELF_H
internal RDIM_BinarySectionList e2r_rdi_binary_sections_from_elf_section_table(Arena *arena, ELF_Shdr64Array shdrs);
#endif // RADCON_ELF_H
File diff suppressed because it is too large Load Diff
-238
View File
@@ -1,238 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef RADCON_PDB_H
#define RADCON_PDB_H
////////////////////////////////
//~ rjf: Initial PDB Information Extraction & Conversion Preparation Task Types
//- rjf: tpi hash parsing
typedef struct P2R_TPIHashParseIn P2R_TPIHashParseIn;
struct P2R_TPIHashParseIn
{
PDB_Strtbl *strtbl;
PDB_TpiParsed *tpi;
String8 hash_data;
String8 aux_data;
};
//- rjf: tpi leaves parsing
typedef struct P2R_TPILeafParseIn P2R_TPILeafParseIn;
struct P2R_TPILeafParseIn
{
String8 leaf_data;
CV_TypeId itype_first;
};
//- rjf: exe hashing
typedef struct P2R_EXEHashIn P2R_EXEHashIn;
struct P2R_EXEHashIn
{
String8 exe_data;
};
//- rjf: symbol stream parsing
typedef struct P2R_SymbolStreamParseIn P2R_SymbolStreamParseIn;
struct P2R_SymbolStreamParseIn
{
String8 data;
};
//- rjf: c13 line info stream parsing
typedef struct P2R_C13StreamParseIn P2R_C13StreamParseIn;
struct P2R_C13StreamParseIn
{
String8 data;
String8 strtbl;
COFF_SectionHeaderArray coff_sections;
};
//- rjf: comp unit parsing
typedef struct P2R_CompUnitParseIn P2R_CompUnitParseIn;
struct P2R_CompUnitParseIn
{
String8 data;
};
//- rjf: comp unit contribution table parsing
typedef struct P2R_CompUnitContributionsParseIn P2R_CompUnitContributionsParseIn;
struct P2R_CompUnitContributionsParseIn
{
String8 data;
COFF_SectionHeaderArray coff_sections;
};
////////////////////////////////
//~ rjf: Conversion Data Structure & Task Types
//- rjf: link name map (voff -> string)
typedef struct P2R_LinkNameNode P2R_LinkNameNode;
struct P2R_LinkNameNode
{
P2R_LinkNameNode *next;
U64 voff;
String8 name;
};
typedef struct P2R_LinkNameMap P2R_LinkNameMap;
struct P2R_LinkNameMap
{
P2R_LinkNameNode **buckets;
U64 buckets_count;
U64 bucket_collision_count;
U64 link_name_count;
};
//- rjf: normalized file path -> source file map
typedef struct P2R_SrcFileNode P2R_SrcFileNode;
struct P2R_SrcFileNode
{
P2R_SrcFileNode *next;
RDIM_SrcFile *src_file;
};
typedef struct P2R_SrcFileMap P2R_SrcFileMap;
struct P2R_SrcFileMap
{
P2R_SrcFileNode **slots;
U64 slots_count;
};
//- rjf: unit conversion tasks
typedef struct P2R_UnitConvertIn P2R_UnitConvertIn;
struct P2R_UnitConvertIn
{
PDB_Strtbl *pdb_strtbl;
COFF_SectionHeaderArray coff_sections;
PDB_CompUnitArray *comp_units;
PDB_CompUnitContributionArray *comp_unit_contributions;
CV_SymParsed **comp_unit_syms;
CV_C13Parsed **comp_unit_c13s;
};
typedef struct P2R_UnitConvertOut P2R_UnitConvertOut;
struct P2R_UnitConvertOut
{
RDIM_UnitChunkList units;
RDIM_SrcFileChunkList src_files;
RDIM_LineTableChunkList line_tables;
RDIM_LineTable **units_first_inline_site_line_tables;
};
//- rjf: link name map building tasks
typedef struct P2R_LinkNameMapBuildIn P2R_LinkNameMapBuildIn;
struct P2R_LinkNameMapBuildIn
{
CV_SymParsed *sym;
COFF_SectionHeaderArray coff_sections;
P2R_LinkNameMap *link_name_map;
};
//- rjf: udt conversion
typedef struct P2R_UDTConvertIn P2R_UDTConvertIn;
struct P2R_UDTConvertIn
{
CV_LeafParsed *tpi_leaf;
CV_TypeId itype_first;
CV_TypeId itype_opl;
RDIM_Type **itype_type_ptrs;
};
//- rjf: symbol stream conversion
typedef struct P2R_SymbolStreamConvertIn P2R_SymbolStreamConvertIn;
struct P2R_SymbolStreamConvertIn
{
RDI_Arch arch;
COFF_SectionHeaderArray coff_sections;
PDB_TpiHashParsed *tpi_hash;
CV_LeafParsed *tpi_leaf;
CV_LeafParsed *ipi_leaf;
CV_SymParsed *sym;
U64 sym_ranges_first;
U64 sym_ranges_opl;
RDIM_Type **itype_type_ptrs;
P2R_LinkNameMap *link_name_map;
RDIM_LineTable *first_inline_site_line_table;
};
typedef struct P2R_SymbolStreamConvertOut P2R_SymbolStreamConvertOut;
struct P2R_SymbolStreamConvertOut
{
RDIM_SymbolChunkList procedures;
RDIM_SymbolChunkList global_variables;
RDIM_SymbolChunkList thread_variables;
RDIM_ScopeChunkList scopes;
RDIM_InlineSiteChunkList inline_sites;
};
////////////////////////////////
//~ rjf: Basic Helpers
internal U64 p2r_end_of_cplusplus_container_name(String8 str);
internal U64 p2r_hash_from_voff(U64 voff);
////////////////////////////////
//~ 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 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);
////////////////////////////////
//~ rjf: Initial Parsing & Preparation Pass Tasks
ASYNC_WORK_DEF(p2r_exe_hash_work);
ASYNC_WORK_DEF(p2r_tpi_hash_parse_work);
ASYNC_WORK_DEF(p2r_tpi_leaf_work);
ASYNC_WORK_DEF(p2r_symbol_stream_parse_work);
ASYNC_WORK_DEF(p2r_c13_stream_parse_work);
ASYNC_WORK_DEF(p2r_comp_unit_parse_work);
ASYNC_WORK_DEF(p2r_comp_unit_contributions_parse_work);
////////////////////////////////
//~ rjf: Unit Conversion Tasks
ASYNC_WORK_DEF(p2r_units_convert_work);
////////////////////////////////
//~ rjf: Link Name Map Building Tasks
ASYNC_WORK_DEF(p2r_link_name_map_build_work);
////////////////////////////////
//~ rjf: UDT Conversion Tasks
ASYNC_WORK_DEF(p2r_udt_convert_work);
////////////////////////////////
//~ rjf: Symbol Stream Conversion Tasks
ASYNC_WORK_DEF(p2r_symbol_stream_convert_work);
////////////////////////////////
//~ rjf: Top-Level Conversion Entry Point
internal RDIM_BakeParams p2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in);
////////////////////////////////
internal B32 p2r_has_symbol_ref(String8 msf_data, String8List symbol_list, MSF_RawStreamTable *st);
internal B32 p2r_has_file_ref(String8 msf_data, String8List file_list, MSF_RawStreamTable *st);
internal B32 p2r_has_symbol_or_file_ref(String8 msf_data, String8List symbol_list, String8List file_list);
#endif // RADCON_PDB_H