hook RDI printers to the dumper

This commit is contained in:
Nikita Smith
2025-01-29 16:27:15 -08:00
parent 5c1e219901
commit e114ea7fdb
3 changed files with 381 additions and 58 deletions
+352 -46
View File
@@ -222,6 +222,17 @@ rd_is_pe(String8 raw_data)
return header.magic == PE_DOS_MAGIC;
}
internal B32
rd_is_rdi(String8 raw_data)
{
B32 is_rdi = 0;
if (raw_data.size > 8) {
U64 *magic = (U64 *)raw_data.str;
is_rdi = *magic == RDI_MAGIC_CONSTANT;
}
return is_rdi;
}
internal String8
rd_string_from_flags(Arena *arena, String8List list, U64 remaining_flags)
{
@@ -233,12 +244,25 @@ rd_string_from_flags(Arena *arena, String8List list, U64 remaining_flags)
if (remaining_flags != 0) {
str8_list_pushf(scratch.arena, &list, "Unknown flags: %#llx", remaining_flags);
}
result = str8_list_join(arena, &list, &(StringJoin){.sep = str8_lit(" ") });
result = str8_list_join(arena, &list, &(StringJoin){.sep = str8_lit(", ") });
scratch_end(scratch);
}
return result;
}
internal String8
rd_string_from_array_u32(Arena *arena, U32 *v, U64 count)
{
Temp scratch = scratch_begin(&arena, 1);
String8List list = {0};
for (U64 i = 0; i < count; ++i) {
str8_list_pushf(scratch.arena, &list, "%u", v[i]);
}
String8 result = str8_list_join(arena, &list, &(StringJoin){.sep=str8_lit(", ")});
scratch_end(scratch);
return result;
}
internal String8
rd_string_from_array_hex_u32(Arena *arena, U32 *v, U64 count)
{
@@ -268,7 +292,14 @@ rd_string_from_array_hex_u64(Arena *arena, U64 *v, U64 count)
internal String8
rd_string_from_range_array_u64_hex(Arena *arena, U64 *v, U64 count)
{
NotImplemented;
Temp scratch = scratch_begin(&arena, 1);
String8List list = {0};
for (U64 i = 0; i+2 <= count; i += 2) {
str8_list_pushf(scratch.arena, &list, "[%#llx, %#llx)", v[i+0], v[i+1]);
}
String8 result = str8_list_join(arena, &list, &(StringJoin){.sep=str8_lit(", ")});
scratch_end(scratch);
return result;
}
internal void
@@ -287,6 +318,8 @@ rd_format_preamble(Arena *arena, String8List *out, String8 indent, String8 input
input_type_string = "Obj";
} else if (rd_is_pe(raw_data)) {
input_type_string = "COFF/PE";
} else if (rd_is_rdi(raw_data)) {
input_type_string = "RDI";
}
DateTime universal_dt = os_now_universal_time();
@@ -695,6 +728,33 @@ rdi_string_from_language(Arena *arena, RDI_Language v)
return result;
}
internal String8
rdi_string_from_local_kind(Arena *arena, RDI_LocalKind v)
{
String8 result;
switch(v)
{
default: { result = push_str8f(arena, "<invalid RDI_LocalKind %u>", v); } break;
#define X(name) case RDI_LocalKind_##name:{ result = str8_lit(#name); } break;
RDI_LocalKind_XList
#undef X
}
return result;
}
internal String8
rdi_string_from_type_kind(Arena *arena, RDI_TypeKind v)
{
String8 result;
switch (v) {
default: { result = push_str8f(arena, "%u", v); } break;
#define X(name) case RDI_TypeKind_##name: { result = str8_lit(#name); } break;
RDI_TypeKind_XList
#undef X
}
return result;
}
internal String8
rdi_string_from_member_kind(Arena *arena, RDI_MemberKind v)
{
@@ -778,6 +838,7 @@ rdi_string_from_udt_flags(Arena *arena, RDI_UDTFlags flags)
#undef X
String8 result = rd_string_from_flags(arena, list, flags);
scratch_end(scratch);
return result;
}
internal String8
@@ -821,7 +882,7 @@ internal void
rdi_print_binary_section(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_BinarySection *bin_section)
{
Temp scratch = scratch_begin(&arena, 1);
rd_printf("name ='%S'", str8_from_idx(rdi, bin_section->name_string_idx));
rd_printf("name ='%S'", str8_from_rdi_string_idx(rdi, bin_section->name_string_idx));
rd_printf("flags =%S", rdi_string_from_binary_section_flags(scratch.arena, bin_section->flags));
rd_printf("voff_first=%#08x", bin_section->voff_first);
rd_printf("voff_opl =%#08x", bin_section->voff_opl);
@@ -857,7 +918,7 @@ rdi_print_file_path(Arena *arena, String8List *out, String8 indent, RDI_Parsed *
// stringize child
rd_indent();
rdi_stringize_file_path(arena, out, indent, rdi, child_node);
rdi_print_file_path(arena, out, indent, rdi, child_node);
rd_unindent();
// increment iterator
@@ -868,9 +929,10 @@ rdi_print_file_path(Arena *arena, String8List *out, String8 indent, RDI_Parsed *
internal void
rdi_print_source_file(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_SourceFile *source_file)
{
rd_printf("file_path_node_idx= %u", source_file->file_path_node_idx);
rd_printf("path= 'S'", str8_from_rdi_string_idx(rdi, source_file->normal_full_path_string_idx));
rd_printf("source_line_map= %u", source_file->source_line_map_idx);
rd_printf("{ file_path_node_idx= ");
rd_printf("file_path_node_idx= %u", source_file->file_path_node_idx);
rd_printf("path= '%S'", str8_from_rdi_string_idx(rdi, source_file->normal_full_path_string_idx));
rd_printf("source_line_map= %u", source_file->source_line_map_idx);
}
internal void
@@ -961,18 +1023,18 @@ rdi_print_type_node(Arena *arena, String8List *out, String8 indent, RDI_Parsed *
} else if (type->kind == RDI_TypeKind_Function) {
U32 param_idx_count = 0;
U32 *param_idx_array = rdi_idx_run_from_first_count(rdi, type->constructed.param_idx_run_first, type->constructed.count, &param_idx_count);
String8 param_idx_str = rd_string_from_array_hex_u32(scratch.arena, param_idx_array, param_idx_count);
String8 param_idx_str = rd_string_from_array_u32(scratch.arena, param_idx_array, param_idx_count);
rd_printf("constructed.params =%S", param_idx_str);
} else if (type->kind == RDI_TypeKind_Method) {
U32 param_idx_count = 0;
U32 *param_idx_array = rdi_idx_run_from_first_count(rdi, type->constructed.param_idx_run_first, type->constructed.count, &param_idx_count);
String8 this_type_str = str8_lit("???");
String8 this_type_str = str8_lit("\?\?\?");
if (param_idx_count > 0) {
this_type_str = push_str8f(scratch.arena, "%u", param_idx_array[0]);
param_idx_count -= 1;
param_idx_array += 1;
}
String8 param_idx_str = rd_string_from_array_hex_u32(scratch.arena, param_idx_array, param_idx_count);
String8 param_idx_str = rd_string_from_array_u32(scratch.arena, param_idx_array, param_idx_count);
rd_printf("constructed.this_type =%S", this_type_str);
rd_printf("constructed.params =%S", param_idx_str);
} else if (RDI_TypeKind_FirstConstructed <= type->kind && type->kind <= RDI_TypeKind_LastConstructed) {
@@ -1017,7 +1079,7 @@ rdi_print_udt(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, R
rd_indent();
RDI_EnumMember *enum_member = enum_member_array + member_lo;
for (U32 i = member_lo; i < member_hi; ++i, ++enum_member) {
rd_printf("'%S' %llu", str8_from_rdi_string_idx(rdi, enum_member->name_string_idx), enum_member->val);
rd_printf("{ %llu, '%S' }", enum_member->val, str8_from_rdi_string_idx(rdi, enum_member->name_string_idx));
}
rd_unindent();
rd_printf("}");
@@ -1034,7 +1096,7 @@ rdi_print_udt(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, R
for (U32 i = member_lo; i < member_hi; ++i, ++member) {
String8 kind_str = rdi_string_from_member_kind(scratch.arena, member->kind);
String8 name_str = str8_from_rdi_string_idx(rdi, member->name_string_idx);
rd_printf("{ kind=%S, name='%S', type=%u, off=%u }", kind_str, name_str, member->type_idx, member->off);
rd_printf("{ kind=%S, type=%u, off=%u, name='%S' }", kind_str, member->type_idx, member->off, name_str);
}
rd_unindent();
rd_printf("}");
@@ -1071,8 +1133,8 @@ internal void
rdi_print_procedure(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_Procedure *proc)
{
Temp scratch = scratch_begin(&arena, 1);
rd_printf("name ='%S'", str8_from_rdi_string(scratch.arena, rdi, proc->name_string_idx));
rd_printf("link_name ='%S'", str8_from_rdi_string(scratch.arena, rdi, proc->link_name_string_idx));
rd_printf("name ='%S'", str8_from_rdi_string_idx(rdi, proc->name_string_idx));
rd_printf("link_name ='%S'", str8_from_rdi_string_idx(rdi, proc->link_name_string_idx));
rd_printf("link_flags =%S", rdi_string_from_link_flags(scratch.arena, proc->link_flags));
rd_printf("type_idx =%u", proc->type_idx);
rd_printf("root_scope_idx=%u", proc->root_scope_idx);
@@ -1090,11 +1152,13 @@ rdi_print_scope(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi,
U64 local_count = 0;
U64 location_block_count = 0;
U64 location_data_size = 0;
U64 proc_count = 0;
RDI_Scope *scope_array = rdi_table_from_name(rdi, Scopes, &scope_count);
U64 *scope_voff_array = rdi_table_from_name(rdi, ScopeVOffData, &scope_voff_count);
RDI_Local *local_array = rdi_table_from_name(rdi, Locals, &local_count);
RDI_LocationBlock *location_block_array = rdi_table_from_name(rdi, LocationBlocks, &location_block_count);
RDI_U8 *location_data = rdi_table_from_name(rdi, LocationData, &location_data_size);
RDI_Procedure *proc_array = rdi_table_from_name(rdi, Procedures, &proc_count);
U32 voff_range_lo = ClampTop(scope->voff_range_first, scope_voff_count);
U32 voff_range_hi = ClampTop(scope->voff_range_opl, scope_voff_count);
@@ -1106,9 +1170,15 @@ rdi_print_scope(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi,
rd_printf("[%llu]", this_idx);
rd_indent();
rd_printf("proc_idx =%u", scope->proc_idx);
rd_printf("inline_site_idx=%u", scope->inline_site_idx);
rd_printf("voff_ranges =%S", voff_str);
String8 proc_name = str8_lit("???");
if (scope->proc_idx < proc_count) {
RDI_Procedure *proc = &proc_array[scope->proc_idx];
proc_name = str8_from_rdi_string_idx(rdi, proc->name_string_idx);
}
rd_printf("proc_idx =%u '%S'", scope->proc_idx, proc_name);
rd_printf("inline_site_idx=%u", scope->inline_site_idx);
rd_printf("voff_ranges =%S", voff_str);
// local_array
{
@@ -1120,7 +1190,7 @@ rdi_print_scope(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi,
rd_printf("local[%u]", local_idx);
rd_indent();
rd_printf("kind =%S", rdi_string_from_local_kind(local_ptr->kind));
rd_printf("kind =%S", rdi_string_from_local_kind(scratch.arena, local_ptr->kind));
rd_printf("name ='%S'", str8_from_rdi_string_idx(rdi, local_ptr->name_string_idx));
rd_printf("type_idx=%u", local_ptr->type_idx);
@@ -1146,7 +1216,7 @@ rdi_print_scope(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi,
RDI_LocationKind kind = *(RDI_LocationKind*)loc_base_ptr;
switch (kind) {
default: {
rd_printf("???: %u", kind);
rd_printf("\?\?\?: %u", kind);
} break;
case RDI_LocationKind_AddrBytecodeStream: {
@@ -1165,7 +1235,7 @@ rdi_print_scope(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi,
case RDI_LocationKind_AddrRegPlusU16: {
if (loc_base_ptr + sizeof(RDI_LocationRegPlusU16) > loc_data_opl) {
rd_errorf("AddrRegPlusU16(???)");
rd_printf("AddrRegPlusU16(\?\?\?)");
} else {
RDI_LocationRegPlusU16 *loc = (RDI_LocationRegPlusU16*)loc_base_ptr;
rd_printf("AddrRegPlusU16(reg: %S, off: %u)", rdi_string_from_reg_code(scratch.arena, arch, loc->reg_code), loc->offset);
@@ -1174,7 +1244,7 @@ rdi_print_scope(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi,
case RDI_LocationKind_AddrAddrRegPlusU16: {
if (loc_base_ptr + sizeof(RDI_LocationRegPlusU16) > loc_data_opl){
rd_errorf("AddrAddrRegPlusU16(???");
rd_printf("AddrAddrRegPlusU16(\?\?\?)");
} else {
RDI_LocationRegPlusU16 *loc = (RDI_LocationRegPlusU16 *)loc_base_ptr;
rd_printf("AddrAddrRegisterPlusU16(reg: %S, off: %u)", rdi_string_from_reg_code(scratch.arena, arch, loc->reg_code), loc->offset);
@@ -1183,10 +1253,10 @@ rdi_print_scope(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi,
case RDI_LocationKind_ValReg: {
if (loc_base_ptr + sizeof(RDI_LocationReg) > loc_data_opl) {
rd_errorf("ValReg(???)");
rd_printf("ValReg(\?\?\?)");
} else {
RDI_LocationReg *loc = (RDI_LocationReg*)loc_base_ptr;
str8_list_pushf(arena, out, "ValReg(reg: %S)", rdi_string_from_reg_code(scratch.arena, arch, loc->reg_code));
rd_printf("ValReg(reg: %S)", rdi_string_from_reg_code(scratch.arena, arch, loc->reg_code));
}
} break;
}
@@ -1214,8 +1284,8 @@ rdi_print_scope(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi,
child_scope_idx = child_scope->next_sibling_scope_idx;
}
rd_printf("[/%llu]", this_idx);
rd_unindent();
rd_printf("[/%llu]", this_idx);
scratch_end(scratch);
}
@@ -1229,62 +1299,298 @@ rdi_print_inline_site(Arena *arena, String8List *out, String8 indent, RDI_Parsed
rd_printf("line_table_idx=%u", inline_site->line_table_idx);
}
internal void
rdi_print_vmap_entry(Arena *arena, String8List *out, String8 indent, RDI_VMapEntry *v)
{
rd_printf("%#llx: %llu", v->voff, v->idx);
}
internal void
rdi_print(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RD_Option opts)
{
RDI_TopLevelInfo *tli = rdi_element_from_name_idx(rdi, TopLevelInfo, 0);
if (opts & RD_Option_RdiDataSections) {
NotImplemented;
rd_printf("# DATA SECTIONS");
rd_indent();
rdi_print_data_sections(arena, out, indent, rdi);
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiTopLevelInfo) {
NotImplemented;
rd_printf("# TOP LEVEL INFO");
rd_indent();
rdi_print_top_level_info(arena, out, indent, rdi, tli);
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiBinarySections) {
NotImplemented;
U64 count;
RDI_BinarySection *v = rdi_table_from_name(rdi, BinarySections, &count);
rd_printf("# BINARY SECTIONS");
rd_indent();
for (U64 idx = 0; idx < count; ++idx) {
rd_printf("section[%llu]:", idx);
rd_indent();
rdi_print_binary_section(arena, out, indent, rdi, &v[idx]);
rd_unindent();
}
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiFilePaths) {
NotImplemented;
U64 file_path_count = 0;
RDI_FilePathNode *file_path_array = rdi_table_from_name(rdi, FilePathNodes, &file_path_count);
rd_printf("# FILE PATHS");
rd_indent();
for (U64 i = 0; i < file_path_count; ++i) {
if (file_path_array[i].parent_path_node == 0) {
rdi_print_file_path(arena, out, indent, rdi, &file_path_array[i]);
}
}
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiSourceFiles) {
NotImplemented;
}
if (opts & RD_Option_RdiLineTables) {
NotImplemented;
}
if (opts & RD_Option_RdiSourceLineMaps) {
NotImplemented;
U64 source_file_count = 0;
RDI_SourceFile *source_file_array = rdi_table_from_name(rdi, SourceFiles, &source_file_count);
rd_printf("# SOURCE FILES");
rd_indent();
for (U64 i = 0; i < source_file_count; ++i) {
RDI_SourceFile *source_file = &source_file_array[i];
rd_printf("source_file[%4llu] = { file_path_node_idx = %4u, source_line_map = %4u, path = '%S' }",
i,
source_file->file_path_node_idx,
source_file->source_line_map_idx,
str8_from_rdi_string_idx(rdi, source_file->normal_full_path_string_idx));
}
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiUnits) {
NotImplemented;
U64 unit_count = 0;
RDI_Unit *unit_array = rdi_table_from_name(rdi, Units, &unit_count);
rd_printf("# UNITS");
rd_indent();
for (U64 i = 0; i < unit_count; ++i) {
rd_printf("unit[%llu]:", i);
rd_indent();
rdi_print_unit(arena, out, indent, rdi, &unit_array[i]);
rd_unindent();
}
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiUnitVMap) {
NotImplemented;
U64 vmap_count = 0;
RDI_VMapEntry *vmap_array = rdi_table_from_name(rdi, UnitVMap, &vmap_count);
rd_printf("# UNIT VMAP");
rd_indent();
for (U64 i = 0; i < vmap_count; ++i) {
rdi_print_vmap_entry(arena, out, indent, &vmap_array[i]);
}
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiLineTables) {
U64 line_table_count = 0;
RDI_LineTable *line_table_array = rdi_table_from_name(rdi, LineTables, &line_table_count);
rd_printf("# LINE TABLES");
rd_indent();
for (U64 i = 0; i < line_table_count; ++i) {
rd_printf("line_table[%llu]", i);
rd_indent();
rdi_print_line_table(arena, out, indent, rdi, &line_table_array[i]);
rd_unindent();
}
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiSourceLineMaps) {
U64 source_line_map_count = 0;
RDI_SourceLineMap *source_line_map_array = rdi_table_from_name(rdi, SourceLineMaps, &source_line_map_count);
rd_printf("# SOURCE LINE MAPS");
rd_indent();
for (U64 i = 0; i < source_line_map_count; ++i) {
rd_printf("source_line_map[%llu]:", i);
rd_indent();
rdi_print_source_line_map(arena, out, indent, rdi, &source_line_map_array[i]);
rd_unindent();
}
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiTypeNodes) {
NotImplemented;
U64 type_node_count = 0;
RDI_TypeNode *type_node_array = rdi_table_from_name(rdi, TypeNodes, &type_node_count);
rd_printf("# TYPE NODES");
rd_indent();
for (U64 i = 0; i < type_node_count; ++i) {
rd_printf("type[%llu]", i);
rd_indent();
rdi_print_type_node(arena, out, indent, rdi, &type_node_array[i]);
rd_unindent();
}
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiUserDefinedTypes) {
NotImplemented;
U64 udt_count = 0;
RDI_UDT *udt_array = rdi_table_from_name(rdi, UDTs, &udt_count);
rd_printf("# UDTS");
rd_indent();
for (U64 i = 0; i < udt_count; ++i) {
rd_printf("udt[%u]:", i);
rd_indent();
rdi_print_udt(arena, out, indent, rdi, &udt_array[i]);
rd_unindent();
}
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiGlobalVars) {
NotImplemented;
U64 gvar_count = 0;
RDI_GlobalVariable *gvar_array = rdi_table_from_name(rdi, GlobalVariables, &gvar_count);
rd_printf("# GLOBAL VARIABLES");
rd_indent();
for (U64 i = 0; i < gvar_count; ++i) {
rd_printf("global_variable[%llu]:", i);
rd_indent();
rdi_print_global_variable(arena, out, indent, rdi, &gvar_array[i]);
rd_unindent();
}
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiGlobalVarsVMap) {
U64 vmap_count = 0;
RDI_VMapEntry *vmap_array = rdi_table_from_name(rdi, GlobalVMap, &vmap_count);
rd_printf("# GLOBAL VMAP");
rd_indent();
for (U64 i = 0; i < vmap_count; ++i) {
rdi_print_vmap_entry(arena, out, indent, &vmap_array[i]);
}
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiThreadVars) {
NotImplemented;
U64 tvar_count = 0;
RDI_ThreadVariable *tvar_array = rdi_table_from_name(rdi, ThreadVariables, &tvar_count);
rd_printf("# THREAD VARIABLES");
rd_indent();
for (U64 i = 0; i < tvar_count; ++i) {
rd_printf("thread_variable[%llu]:", i);
rdi_print_thread_variable(arena, out, indent, rdi, &tvar_array[i]);
}
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiProcedures) {
U64 proc_count = 0;
RDI_Procedure *proc_array = rdi_table_from_name(rdi, Procedures, &proc_count);
rd_printf("# PROCEDURES");
rd_indent();
for (U64 i = 0; i < proc_count; ++i) {
rd_printf("procedure[%llu]:", i);
rd_indent();
rdi_print_procedure(arena, out, indent, rdi, &proc_array[i]);
rd_unindent();
}
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiScopes) {
NotImplemented;
U64 scope_count = 0;
RDI_Scope *scope_array = rdi_table_from_name(rdi, Scopes, &scope_count);
rd_printf("# SCOPES");
rd_indent();
for (U64 i = 0; i < scope_count; ++i) {
if (scope_array[i].parent_scope_idx == 0) {
rdi_print_scope(arena, out, indent, rdi, &scope_array[i], tli->arch);
}
}
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiScopeVMap) {
NotImplemented;
U64 vmap_count = 0;
RDI_VMapEntry *vmap_array = rdi_table_from_name(rdi, ScopeVMap, &vmap_count);
rd_printf("# SCOPE VMAP");
rd_indent();
for (U64 i = 0; i < vmap_count; ++i) {
rdi_print_vmap_entry(arena, out, indent, &vmap_array[i]);
}
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiInlineSites) {
NotImplemented;
U64 inline_site_count = 0;
RDI_InlineSite *inline_site_array = rdi_table_from_name(rdi, InlineSites, &inline_site_count);
rd_printf("# INLINE SITES");
rd_indent();
for (U64 i = 0; i < inline_site_count; ++i) {
rd_printf("inline_site[%llu]:", i);
rd_indent();
rdi_print_inline_site(arena, out, indent, rdi, &inline_site_array[i]);
rd_unindent();
}
rd_unindent();
rd_newline();
}
if (opts & RD_Option_RdiNameMaps) {
NotImplemented;
Temp scratch = scratch_begin(&arena, 1);
U64 name_map_count = 0;
RDI_NameMap *name_map_array = rdi_table_from_name(rdi, NameMaps, &name_map_count);
rd_printf("# NAME MAPS");
rd_indent();
for (U64 i = 0; i < name_map_count; ++i) {
if (i > 0) {
rd_newline();
}
RDI_ParsedNameMap name_map = {0};
rdi_parsed_from_name_map(rdi, &name_map_array[i], &name_map);
rd_printf("name_map[%S]",rdi_string_from_name_map_kind(i));
rd_indent();
for (U64 bucket_idx = 0; bucket_idx < name_map.bucket_count; ++bucket_idx) {
if (name_map.buckets[bucket_idx].node_count == 0) {
continue;
}
rd_printf("bucket[%llu]:", bucket_idx);
rd_indent();
RDI_NameMapNode *node_ptr = name_map.nodes + name_map.buckets[bucket_idx].first_node;
RDI_NameMapNode *node_opl = node_ptr + name_map.buckets[bucket_idx].node_count;
for (; node_ptr < node_opl; ++node_ptr) {
Temp temp = temp_begin(scratch.arena);
String8 str = str8_from_rdi_string_idx(rdi, node_ptr->string_idx);
String8 indices;
if (node_ptr->match_count == 1) {
indices = push_str8f(temp.arena, "%u", node_ptr->match_idx_or_idx_run_first);
} else {
U32 idx_count = 0;
U32 *idx_array = rdi_idx_run_from_first_count(rdi, node_ptr->match_idx_or_idx_run_first, node_ptr->match_count, &idx_count);
indices = rd_string_from_array_u32(temp.arena, idx_array, idx_count);
}
rd_printf("match \"%S\": %S", str, indices);
temp_end(temp);
}
rd_unindent();
}
rd_unindent();
}
rd_unindent();
rd_newline();
scratch_end(scratch);
}
if (opts & RD_Option_RdiStrings) {
NotImplemented;
U64 stridx_count = 0;
U32 *stridx_array = rdi_table_from_name(rdi, StringTable, &stridx_count);
rd_printf("# STRINGS");
rd_indent();
for (U64 i = 0; i < stridx_count; ++i) {
rd_printf("string[%llu]: \"%S\"", i, str8_from_rdi_string_idx(rdi, i));
}
rd_unindent();
rd_newline();
}
}
+15 -11
View File
@@ -4,7 +4,7 @@
#ifndef RADDUMP_H
#define RADDUMP_H
#define RD_INDENT_WIDTH 4
#define RD_INDENT_WIDTH 2
#define RD_INDENT_MAX 4096
#define rd_printf(f, ...) str8_list_pushf(arena, out, "%S" f, indent, __VA_ARGS__)
@@ -78,13 +78,14 @@ typedef U64 RD_Option;
#define RD_Option_RdiTypeNodes (1ull << 42ull)
#define RD_Option_RdiUserDefinedTypes (1ull << 43ull)
#define RD_Option_RdiGlobalVars (1ull << 44ull)
#define RD_Option_RdiThreadVars (1ull << 45ull)
#define RD_Option_RdiProcedures (1ull << 46ull)
#define RD_Option_RdiScopes (1ull << 47ull)
#define RD_Option_RdiScopeVMap (1ull << 48ull)
#define RD_Option_RdiInlineSites (1ull << 49ull)
#define RD_Option_RdiNameMaps (1ull << 50ull)
#define RD_Option_RdiStrings (1ull << 51ull)
#define RD_Option_RdiGlobalVarsVMap (1ull << 45ull)
#define RD_Option_RdiThreadVars (1ull << 46ull)
#define RD_Option_RdiProcedures (1ull << 48ull)
#define RD_Option_RdiScopes (1ull << 49ull)
#define RD_Option_RdiScopeVMap (1ull << 50ull)
#define RD_Option_RdiInlineSites (1ull << 51ull)
#define RD_Option_RdiNameMaps (1ull << 52ull)
#define RD_Option_RdiStrings (1ull << 53ull)
typedef struct RD_Marker
{
@@ -139,7 +140,8 @@ typedef struct RD_Line
// raddump
internal B32 rd_is_pe(String8 raw_data);
internal B32 rd_is_pe (String8 raw_data);
internal B32 rd_is_rdi(String8 raw_data);
internal String8 rd_string_from_flags(Arena *arena, String8List list, U64 remaining_flags);
@@ -163,13 +165,13 @@ internal void rd_print_disasm (Arena *arena, String8List *o
internal String8 rd_format_hex_array(Arena *arena, U8 *ptr, U64 size);
internal void rd_print_raw_data (Arena *arena, String8List *out, String8 indent, U64 bytes_per_row, U64 marker_count, RD_Marker *markers, String8 raw_data);
//
// RDI
//
internal String8 rdi_string_from_data_section_kind(Arena *arena, RDI_SectionKind v);
internal String8 rdi_string_from_arch (Arena *arena, RDI_Arch v);
internal String8 rdi_string_from_language (Arena *arena, RDI_Language v);
internal String8 rdi_string_from_local_kind (Arena *arena, RDI_LocalKind v);
internal String8 rdi_string_from_type_kind (Arena *arena, RDI_TypeKind v);
internal String8 rdi_string_from_member_kind (Arena *arena, RDI_MemberKind v);
internal String8 rdi_string_from_binary_section_flags(Arena *arena, RDI_BinarySectionFlags flags);
@@ -186,11 +188,13 @@ internal void rdi_print_line_table (Arena *arena, String8List *out, String8
internal void rdi_print_source_line_map(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_SourceLineMap *map);
internal void rdi_print_unit (Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_Unit *unit);
internal void rdi_print_type_node (Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_TypeNode *type);
internal void rdi_print_udt (Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_UDT *udt);
internal void rdi_print_global_variable(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_GlobalVariable *gvar);
internal void rdi_print_thread_variable(Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_ThreadVariable *tvar);
internal void rdi_print_procedure (Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_Procedure *proc);
internal void rdi_print_scope (Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_Scope *scope, RDI_Arch arch);
internal void rdi_print_inline_site (Arena *arena, String8List *out, String8 indent, RDI_Parsed *rdi, RDI_InlineSite *inline_site);
internal void rdi_print_vmap_entry (Arena *arena, String8List *out, String8 indent, RDI_VMapEntry *v);
// DWARF
+14 -1
View File
@@ -82,6 +82,8 @@
#include "linker/codeview_ext/codeview.c"
#include "linker/hash_table.h"
#include "linker/hash_table.c"
#include "linker/rdi/rdi.h"
#include "linker/rdi/rdi.c"
#include "raddump/raddump.h"
#include "raddump/raddump.c"
@@ -250,7 +252,18 @@ entry_point(CmdLine *cmdline)
// format input
rd_format_preamble(arena, out, indent, file_path, raw_data);
if (coff_is_regular_archive(raw_data) || coff_is_thin_archive(raw_data)) {
if (rd_is_rdi(raw_data)) {
RDI_Parsed rdi = {0};
RDI_ParseStatus parse_status = rdi_parse(raw_data.str, raw_data.size, &rdi);
switch (parse_status) {
case RDI_ParseStatus_Good: rdi_print(arena, out, indent, &rdi, opts); break;
case RDI_ParseStatus_HeaderDoesNotMatch: rd_errorf("RDI Parse: header does not match"); break;
case RDI_ParseStatus_UnsupportedVersionNumber: rd_errorf("RDI Parse: unsupported version"); break;
case RDI_ParseStatus_InvalidDataSecionLayout: rd_errorf("RDI Parse: invalid data section layout"); break;
case RDI_ParseStatus_MissingRequiredSection: rd_errorf("RDI Parse: missing required section"); break;
default: rd_errorf("RDI Parse: unknown parse status %u", parse_status); break;
}
} else if (coff_is_regular_archive(raw_data) || coff_is_thin_archive(raw_data)) {
coff_print_archive(arena, out, indent, raw_data, opts);
} else if (coff_is_big_obj(raw_data)) {
coff_print_big_obj(arena, out, indent, raw_data, opts);