cleanup/naming pass over raddbgi_dump, do not require specific named params

This commit is contained in:
Ryan Fleury
2024-02-24 22:03:08 -08:00
parent 93c0e657fd
commit 7c9f127425
8 changed files with 1234 additions and 1335 deletions
+1 -1
View File
@@ -101,7 +101,7 @@ pushd build
if "%raddbg%"=="1" %compile% %gfx% ..\src\raddbg\raddbg_main.cpp %compile_link% %out%raddbg.exe || exit /b 1
if "%raddbgi_from_pdb%"=="1" %compile% ..\src\raddbgi_from_pdb\raddbgi_from_pdb_main.c %compile_link% %out%raddbgi_from_pdb.exe || exit /b 1
if "%raddbgi_from_dwarf%"=="1" %compile% ..\src\raddbgi_from_dwarf\raddbgi_from_dwarf.c %compile_link% %out%raddbgi_from_dwarf.exe || exit /b 1
if "%raddbgi_dump%"=="1" %compile% ..\src\raddbgi_dump\raddbgi_dump.c %compile_link% %out%raddbgi_dump.exe || exit /b 1
if "%raddbgi_dump%"=="1" %compile% ..\src\raddbgi_dump\raddbgi_dump_main.c %compile_link% %out%raddbgi_dump.exe || exit /b 1
if "%ryan_scratch%"=="1" %compile% ..\src\scratch\ryan_scratch.c %compile_link% %out%ryan_scratch.exe || exit /b 1
if "%cpp_tests%"=="1" %compile% ..\src\scratch\i_hate_c_plus_plus.cpp %compile_link% %out%cpp_tests.exe || exit /b 1
if "%look_at_raddbg%"=="1" %compile% ..\src\scratch\look_at_raddbg.c %compile_link% %out%look_at_raddbg.exe || exit /b 1
+24 -23
View File
@@ -5,7 +5,8 @@
//~ RADDBG Parse API
RDI_PROC RDI_ParseStatus
rdi_parse(RDI_U8 *data, RDI_U64 size, RDI_Parsed *out){
rdi_parse(RDI_U8 *data, RDI_U64 size, RDI_Parsed *out)
{
RDI_ParseStatus result = RDI_ParseStatus_Good;
// out header
@@ -193,30 +194,30 @@ rdi_parse(RDI_U8 *data, RDI_U64 size, RDI_Parsed *out){
}
}
}
#if !defined(RDI_DISABLE_NILS)
if(out->binary_sections == 0) { out->binary_sections = &rdi_binary_section_nil; out->binary_sections_count = 1; }
if(out->file_paths == 0) { out->file_paths = &rdi_file_path_node_nil; out->file_paths_count = 1; }
if(out->source_files == 0) { out->source_files = &rdi_source_file_nil; out->source_files_count = 1; }
if(out->units == 0) { out->units = &rdi_unit_nil; out->units_count = 1; }
if(out->unit_vmap == 0) { out->unit_vmap = &rdi_vmap_entry_nil; out->unit_vmap_count = 1; }
if(out->type_nodes == 0) { out->type_nodes = &rdi_type_node_nil; out->type_nodes_count = 1; }
if(out->udts == 0) { out->udts = &rdi_udt_nil; out->udts_count = 1; }
if(out->members == 0) { out->members = &rdi_member_nil; out->members_count = 1; }
if(out->enum_members == 0) { out->enum_members = &rdi_enum_member_nil; out->enum_members_count = 1; }
if(out->global_variables == 0) { out->global_variables = &rdi_global_variable_nil; out->global_variables_count = 1; }
if(out->global_vmap == 0) { out->global_vmap = &rdi_vmap_entry_nil; out->global_vmap_count = 1; }
if(out->thread_variables == 0) { out->thread_variables = &rdi_thread_variable_nil; out->thread_variables_count = 1; }
if(out->procedures == 0) { out->procedures = &rdi_procedure_nil; out->procedures_count = 1; }
if(out->scopes == 0) { out->scopes = &rdi_scope_nil; out->scopes_count = 1; }
if(out->scope_voffs == 0) { out->scope_voffs = &rdi_voff_nil; out->scope_voffs_count = 1; }
if(out->scope_vmap == 0) { out->scope_vmap = &rdi_vmap_entry_nil; out->scope_vmap_count = 1; }
if(out->locals == 0) { out->locals = &rdi_local_nil; out->locals_count = 1; }
if(out->location_blocks == 0) { out->location_blocks = &rdi_location_block_nil; out->location_blocks_count = 1; }
#endif
}
#if !defined(RDI_DISABLE_NILS)
if(out->top_level_info == 0) { out->top_level_info = &rdi_top_level_info_nil; }
if(out->binary_sections == 0) { out->binary_sections = &rdi_binary_section_nil; out->binary_sections_count = 1; }
if(out->file_paths == 0) { out->file_paths = &rdi_file_path_node_nil; out->file_paths_count = 1; }
if(out->source_files == 0) { out->source_files = &rdi_source_file_nil; out->source_files_count = 1; }
if(out->units == 0) { out->units = &rdi_unit_nil; out->units_count = 1; }
if(out->unit_vmap == 0) { out->unit_vmap = &rdi_vmap_entry_nil; out->unit_vmap_count = 1; }
if(out->type_nodes == 0) { out->type_nodes = &rdi_type_node_nil; out->type_nodes_count = 1; }
if(out->udts == 0) { out->udts = &rdi_udt_nil; out->udts_count = 1; }
if(out->members == 0) { out->members = &rdi_member_nil; out->members_count = 1; }
if(out->enum_members == 0) { out->enum_members = &rdi_enum_member_nil; out->enum_members_count = 1; }
if(out->global_variables == 0) { out->global_variables = &rdi_global_variable_nil; out->global_variables_count = 1; }
if(out->global_vmap == 0) { out->global_vmap = &rdi_vmap_entry_nil; out->global_vmap_count = 1; }
if(out->thread_variables == 0) { out->thread_variables = &rdi_thread_variable_nil; out->thread_variables_count = 1; }
if(out->procedures == 0) { out->procedures = &rdi_procedure_nil; out->procedures_count = 1; }
if(out->scopes == 0) { out->scopes = &rdi_scope_nil; out->scopes_count = 1; }
if(out->scope_voffs == 0) { out->scope_voffs = &rdi_voff_nil; out->scope_voffs_count = 1; }
if(out->scope_vmap == 0) { out->scope_vmap = &rdi_vmap_entry_nil; out->scope_vmap_count = 1; }
if(out->locals == 0) { out->locals = &rdi_local_nil; out->locals_count = 1; }
if(out->location_blocks == 0) { out->location_blocks = &rdi_location_block_nil; out->location_blocks_count = 1; }
#endif
return(result);
}
@@ -128,6 +128,7 @@ typedef struct RDI_ParsedNameMap{
//~ Global Nils
#if !defined(RDI_DISABLE_NILS)
static RDI_TopLevelInfo rdi_top_level_info_nil = {0};
static RDI_BinarySection rdi_binary_section_nil = {0};
static RDI_FilePathNode rdi_file_path_node_nil = {0};
static RDI_SourceFile rdi_source_file_nil = {0};
File diff suppressed because it is too large Load Diff
+65 -35
View File
@@ -1,45 +1,75 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef RDI_DUMP_H
#define RDI_DUMP_H
#ifndef RADDBGI_DUMP_H
#define RADDBGI_DUMP_H
////////////////////////////////
//~ Program Parameters Type
//~ rjf: RADDBG Stringize Helper Types
typedef struct RADDBGIDUMP_Params{
String8 input_name;
String8 input_data;
struct{
B8 input;
} hide_errors;
B8 dump__first;
B8 dump_data_sections;
B8 dump_top_level_info;
B8 dump_binary_sections;
B8 dump_file_paths;
B8 dump_source_files;
B8 dump_units;
B8 dump_unit_vmap;
B8 dump_type_nodes;
B8 dump_udt_data;
B8 dump_global_variables;
B8 dump_global_vmap;
B8 dump_thread_variables;
B8 dump_procedures;
B8 dump_scopes;
B8 dump_scope_vmap;
B8 dump_name_map;
B8 dump__last;
String8List errors;
} RADDBGIDUMP_Params;
typedef struct RDI_FilePathBundle RDI_FilePathBundle;
struct RDI_FilePathBundle
{
RDI_FilePathNode *file_paths;
U32 file_path_count;
};
typedef struct RDI_UDTMemberBundle RDI_UDTMemberBundle;
struct RDI_UDTMemberBundle
{
RDI_Member *members;
RDI_EnumMember *enum_members;
U32 member_count;
U32 enum_member_count;
};
typedef struct RDI_ScopeBundle RDI_ScopeBundle;
struct RDI_ScopeBundle
{
RDI_Scope *scopes;
U64 *scope_voffs;
RDI_Local *locals;
RDI_LocationBlock *location_blocks;
U8 *location_data;
U32 scope_count;
U32 scope_voff_count;
U32 local_count;
U32 location_block_count;
U32 location_data_size;
};
////////////////////////////////
//~ Program Parameters Parser
//~ rjf: RADDBGI Enum -> String Functions
static RADDBGIDUMP_Params *raddbgidump_params_from_cmd_line(Arena *arena, CmdLine *cmdline);
internal String8 rdi_string_from_data_section_tag(RDI_DataSectionTag tag);
internal String8 rdi_string_from_arch(RDI_Arch arch);
internal String8 rdi_string_from_language(RDI_Language language);
internal String8 rdi_string_from_type_kind(RDI_TypeKind type_kind);
internal String8 rdi_string_from_member_kind(RDI_MemberKind member_kind);
internal String8 rdi_string_from_local_kind(RDI_LocalKind local_kind);
#endif //RDI_DUMP_H
////////////////////////////////
//~ rjf: RADDBGI Flags -> String Functions
internal void rdi_stringize_binary_section_flags(Arena *arena, String8List *out, RDI_BinarySectionFlags flags);
internal void rdi_stringize_type_modifier_flags(Arena *arena, String8List *out, RDI_TypeModifierFlags flags);
internal void rdi_stringize_user_defined_type_flags(Arena *arena, String8List *out, RDI_UserDefinedTypeFlags flags);
internal void rdi_stringize_link_flags(Arena *arena, String8List *out, RDI_LinkFlags flags);
////////////////////////////////
//~ rjf: RADDBG Compound Stringize Functions
internal void rdi_stringize_data_sections(Arena *arena, String8List *out, RDI_Parsed *parsed, U32 indent_level);
internal void rdi_stringize_top_level_info(Arena *arena, String8List *out, RDI_Parsed *parsed, RDI_TopLevelInfo *tli, U32 indent_level);
internal void rdi_stringize_binary_section(Arena *arena, String8List *out, RDI_Parsed *parsed, RDI_BinarySection *bin_section, U32 indent_level);
internal void rdi_stringize_file_path(Arena *arena, String8List *out, RDI_Parsed *parsed, RDI_FilePathBundle *bundle, RDI_FilePathNode *file_path, U32 indent_level);
internal void rdi_stringize_source_file(Arena *arena, String8List *out, RDI_Parsed *parsed, RDI_SourceFile *source_file, U32 indent_level);
internal void rdi_stringize_unit(Arena *arena, String8List *out, RDI_Parsed *parsed, RDI_Unit *unit, U32 indent_level);
internal void rdi_stringize_type_node(Arena *arena, String8List *out, RDI_Parsed *parsed, RDI_TypeNode *type, U32 indent_level);
internal void rdi_stringize_udt(Arena *arena, String8List *out, RDI_Parsed *parsed, RDI_UDTMemberBundle *bundle, RDI_UDT *udt, U32 indent_level);
internal void rdi_stringize_global_variable(Arena *arena, String8List *out, RDI_Parsed *parsed, RDI_GlobalVariable *global_variable, U32 indent_level);
internal void rdi_stringize_thread_variable(Arena *arena, String8List *out, RDI_Parsed *parsed, RDI_ThreadVariable *thread_var, U32 indent_level);
internal void rdi_stringize_procedure(Arena *arena, String8List *out, RDI_Parsed *parsed, RDI_Procedure *proc, U32 indent_level);
internal void rdi_stringize_scope(Arena *arena, String8List *out, RDI_Parsed *parsed, RDI_ScopeBundle *bundle, RDI_Scope *scope, U32 indent_level);
#endif // RADDBGI_DUMP_H
+413
View File
@@ -0,0 +1,413 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Includes
//- rjf: [lib]
#include "lib_raddbgi_format/raddbgi_format.h"
#include "lib_raddbgi_format/raddbgi_format_parse.h"
#include "lib_raddbgi_format/raddbgi_format.c"
#include "lib_raddbgi_format/raddbgi_format_parse.c"
//- rjf: [h]
#include "base/base_inc.h"
#include "os/os_inc.h"
#include "raddbgi_dump.h"
//- rjf: [c]
#include "base/base_inc.c"
#include "os/os_inc.c"
#include "raddbgi_dump.c"
////////////////////////////////
//~ rjf: Entry Point
int
main(int argc, char **argv)
{
//////////////////////////////
//- rjf: set up
//
local_persist TCTX main_thread_tctx = {0};
tctx_init_and_equip(&main_thread_tctx);
Arena *arena = arena_alloc();
String8List args = os_string_list_from_argcv(arena, argc, argv);
CmdLine cmdline = cmd_line_from_string_list(arena, args);
String8List errors = {0};
//////////////////////////////
//- rjf: extract command line parameters
//
typedef U32 DumpFlags;
enum
{
DumpFlag_DataSections = (1<<0),
DumpFlag_TopLevelInfo = (1<<1),
DumpFlag_BinarySections = (1<<2),
DumpFlag_FilePaths = (1<<3),
DumpFlag_SourceFiles = (1<<4),
DumpFlag_Units = (1<<5),
DumpFlag_UnitVMap = (1<<6),
DumpFlag_TypeNodes = (1<<7),
DumpFlag_UDTs = (1<<8),
DumpFlag_GlobalVariables = (1<<9),
DumpFlag_GlobalVMap = (1<<10),
DumpFlag_ThreadVariables = (1<<11),
DumpFlag_Procedures = (1<<12),
DumpFlag_Scopes = (1<<13),
DumpFlag_ScopeVMap = (1<<14),
DumpFlag_NameMaps = (1<<15),
};
String8 input_name = {0};
String8 input_data = {0};
DumpFlags dump_flags = (U32)0xffffffff;
{
// rjf: extract input file path & load data
input_name = str8_list_first(&cmdline.inputs);
if(input_name.size > 0) { input_data = os_data_from_file_path(arena, input_name); }
else {str8_list_pushf(arena, &errors, "error (input): No input RADDBGI file specified.");}
if(input_name.size != 0 && input_data.size == 0) { str8_list_pushf(arena, &errors, "error (input): No input RADDBGI file successfully loaded; either the path or file contents are invalid."); }
// rjf: extract dump options
{
String8List dump_options = cmd_line_strings(&cmdline, str8_lit("dump"));
if(dump_options.first != 0)
{
dump_flags = 0;
for(String8Node *n = dump_options.first; n != 0; n = n->next)
{
if(0){}
else if(str8_match(n->string, str8_lit("data_sections"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_DataSections; }
else if(str8_match(n->string, str8_lit("top_level_info"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_TopLevelInfo; }
else if(str8_match(n->string, str8_lit("binary_sections"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_BinarySections; }
else if(str8_match(n->string, str8_lit("file_paths"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_FilePaths; }
else if(str8_match(n->string, str8_lit("source_files"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_SourceFiles; }
else if(str8_match(n->string, str8_lit("units"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_Units; }
else if(str8_match(n->string, str8_lit("unit_vmap"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_UnitVMap; }
else if(str8_match(n->string, str8_lit("type_nodes"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_TypeNodes; }
else if(str8_match(n->string, str8_lit("udt_data"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_UDTs; }
else if(str8_match(n->string, str8_lit("global_variables"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_GlobalVariables; }
else if(str8_match(n->string, str8_lit("global_vmap"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_GlobalVMap; }
else if(str8_match(n->string, str8_lit("thread_variables"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_ThreadVariables; }
else if(str8_match(n->string, str8_lit("procedures"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_Procedures; }
else if(str8_match(n->string, str8_lit("scopes"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_Scopes; }
else if(str8_match(n->string, str8_lit("scope_vmap"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_ScopeVMap; }
else if(str8_match(n->string, str8_lit("name_maps"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_NameMaps; }
}
}
}
}
//////////////////////////////
//- rjf: parse raddbg from input data
//
RDI_ParseStatus parse_status = RDI_ParseStatus_Good;
RDI_Parsed raddbg_ = {0};
RDI_Parsed *raddbg = &raddbg_;
{
parse_status = rdi_parse(input_data.str, input_data.size, &raddbg_);
if(parse_status == RDI_ParseStatus_Good)
{
str8_list_pushf(arena, &errors, "error (parse): RADDBGI file wasn't parsed successfully. (0x%x)", parse_status);
}
}
//////////////////////////////
//- rjf: output error strings to stderr
//
for(String8Node *n = errors.first; n != 0; n = n->next)
{
fwrite(n->string.str, 1, n->string.size, stderr);
fprintf(stderr, "\n");
}
//////////////////////////////
//- rjf: build dump strings
//
String8List dump = {0};
if(parse_status == RDI_ParseStatus_Good)
{
//- rjf: DATA SECTIONS
if(dump_flags & DumpFlag_DataSections)
{
str8_list_pushf(arena, &dump, "# DATA SECTIONS:\n");
rdi_stringize_data_sections(arena, &dump, raddbg, 1);
str8_list_push(arena, &dump, str8_lit("\n"));
}
//- rjf: TOP LEVEL INFO
if(dump_flags & DumpFlag_TopLevelInfo)
{
str8_list_pushf(arena, &dump, "# TOP LEVEL INFO:\n");
rdi_stringize_top_level_info(arena, &dump, raddbg, raddbg->top_level_info, 1);
str8_list_push(arena, &dump, str8_lit("\n"));
}
//- rjf: BINARY SECTIONS
if(dump_flags & DumpFlag_BinarySections)
{
str8_list_pushf(arena, &dump, "# BINARY SECTIONS:\n");
RDI_BinarySection *ptr = raddbg->binary_sections;
for(U32 i = 0; i < raddbg->binary_sections_count; i += 1, ptr += 1)
{
str8_list_pushf(arena, &dump, " section[%u]:\n", i);
rdi_stringize_binary_section(arena, &dump, raddbg, ptr, 2);
str8_list_push(arena, &dump, str8_lit("\n"));
}
str8_list_push(arena, &dump, str8_lit("\n"));
}
//- rjf: FILE PATHS
if(dump_flags & DumpFlag_FilePaths)
{
RDI_FilePathBundle file_path_bundle = {0};
{
file_path_bundle.file_paths = raddbg->file_paths;
file_path_bundle.file_path_count = raddbg->file_paths_count;
}
str8_list_pushf(arena, &dump, "# FILE PATHS\n");
RDI_FilePathNode *ptr = raddbg->file_paths;
for(U32 i = 0; i < raddbg->file_paths_count; i += 1, ptr += 1)
{
if(ptr->parent_path_node == 0)
{
rdi_stringize_file_path(arena, &dump, raddbg, &file_path_bundle, ptr, 1);
}
}
str8_list_push(arena, &dump, str8_lit("\n"));
}
//- rjf: SOURCE FILES
if(dump_flags & DumpFlag_SourceFiles)
{
str8_list_pushf(arena, &dump, "# SOURCE FILES\n");
RDI_SourceFile *ptr = raddbg->source_files;
for(U32 i = 0; i < raddbg->source_files_count; i += 1, ptr += 1)
{
str8_list_pushf(arena, &dump, " source_file[%u]:\n", i);
rdi_stringize_source_file(arena, &dump, raddbg, ptr, 2);
str8_list_push(arena, &dump, str8_lit("\n"));
}
str8_list_push(arena, &dump, str8_lit("\n"));
}
//- rjf: UNITS
if(dump_flags & DumpFlag_Units)
{
str8_list_pushf(arena, &dump, "# UNITS\n");
RDI_Unit *ptr = raddbg->units;
for (U32 i = 0; i < raddbg->units_count; i += 1, ptr += 1)
{
str8_list_pushf(arena, &dump, " unit[%u]:\n", i);
rdi_stringize_unit(arena, &dump, raddbg, ptr, 2);
str8_list_push(arena, &dump, str8_lit("\n"));
}
str8_list_push(arena, &dump, str8_lit("\n"));
}
//- rjf: UNIT VMAP
if(dump_flags & DumpFlag_UnitVMap)
{
str8_list_pushf(arena, &dump, "# UNIT VMAP\n");
RDI_VMapEntry *ptr = raddbg->unit_vmap;
for(U32 i = 0; i < raddbg->unit_vmap_count; i += 1, ptr += 1)
{
str8_list_pushf(arena, &dump, " 0x%08x: %llu\n", ptr->voff, ptr->idx);
}
str8_list_push(arena, &dump, str8_lit("\n"));
}
//- rjf: TYPE NODES
if(dump_flags & DumpFlag_TypeNodes)
{
str8_list_pushf(arena, &dump, "# TYPE NODES:\n");
RDI_TypeNode *ptr = raddbg->type_nodes;
for(U32 i = 0; i < raddbg->type_nodes_count; i += 1, ptr += 1)
{
str8_list_pushf(arena, &dump, " type[%u]:\n", i);
rdi_stringize_type_node(arena, &dump, raddbg, ptr, 2);
str8_list_push(arena, &dump, str8_lit("\n"));
}
str8_list_push(arena, &dump, str8_lit("\n"));
}
//- rjf: UDT DATA
if(dump_flags & DumpFlag_UDTs)
{
RDI_UDTMemberBundle member_bundle = {0};
{
member_bundle.members = raddbg->members;
member_bundle.enum_members = raddbg->enum_members;
member_bundle.member_count = raddbg->members_count;
member_bundle.enum_member_count = raddbg->enum_members_count;
}
str8_list_pushf(arena, &dump, "# UDTS:\n");
RDI_UDT *ptr = raddbg->udts;
for(U32 i = 0; i < raddbg->udts_count; i += 1, ptr += 1)
{
str8_list_pushf(arena, &dump, " udt[%u]:\n", i);
rdi_stringize_udt(arena, &dump, raddbg, &member_bundle, ptr, 2);
str8_list_push(arena, &dump, str8_lit("\n"));
}
str8_list_push(arena, &dump, str8_lit("\n"));
}
//- rjf: GLOBAL VARIABLES
if(dump_flags & DumpFlag_GlobalVariables)
{
str8_list_pushf(arena, &dump, "# GLOBAL VARIABLES:\n");
RDI_GlobalVariable *ptr = raddbg->global_variables;
for(U32 i = 0; i < raddbg->global_variables_count; i += 1, ptr += 1)
{
str8_list_pushf(arena, &dump, " global_variable[%u]:\n", i);
rdi_stringize_global_variable(arena, &dump, raddbg, ptr, 2);
str8_list_push(arena, &dump, str8_lit("\n"));
}
str8_list_push(arena, &dump, str8_lit("\n"));
}
//- rjf: GLOBAL VMAP
if(dump_flags & DumpFlag_GlobalVMap)
{
str8_list_pushf(arena, &dump, "# GLOBAL VMAP:\n");
RDI_VMapEntry *ptr = raddbg->global_vmap;
for(U32 i = 0; i < raddbg->global_vmap_count; i += 1, ptr += 1)
{
str8_list_pushf(arena, &dump, " 0x%08x: %llu\n", ptr->voff, ptr->idx);
}
str8_list_push(arena, &dump, str8_lit("\n"));
}
//- rjf: THREAD LOCAL VARIABLES
if(dump_flags & DumpFlag_ThreadVariables)
{
str8_list_pushf(arena, &dump, "# THREAD VARIABLES:\n");
RDI_ThreadVariable *ptr = raddbg->thread_variables;
for(U32 i = 0; i < raddbg->thread_variables_count; i += 1, ptr += 1)
{
str8_list_pushf(arena, &dump, " thread_variable[%u]:\n", i);
rdi_stringize_thread_variable(arena, &dump, raddbg, ptr, 2);
str8_list_push(arena, &dump, str8_lit("\n"));
}
str8_list_push(arena, &dump, str8_lit("\n"));
}
//- rjf: PROCEDURES
if(dump_flags & DumpFlag_Procedures)
{
str8_list_pushf(arena, &dump, "# PROCEDURES:\n");
RDI_Procedure *ptr = raddbg->procedures;
for(U32 i = 0; i < raddbg->procedures_count; i += 1, ptr += 1)
{
str8_list_pushf(arena, &dump, " procedure[%u]:\n", i);
rdi_stringize_procedure(arena, &dump, raddbg, ptr, 2);
str8_list_push(arena, &dump, str8_lit("\n"));
}
str8_list_push(arena, &dump, str8_lit("\n"));
}
//- rjf: SCOPES
if(dump_flags & DumpFlag_Scopes)
{
RDI_ScopeBundle scope_bundle = {0};
{
scope_bundle.scopes = raddbg->scopes;
scope_bundle.scope_count = raddbg->scopes_count;
scope_bundle.scope_voffs = raddbg->scope_voffs;
scope_bundle.scope_voff_count = raddbg->scope_voffs_count;
scope_bundle.locals = raddbg->locals;
scope_bundle.local_count = raddbg->locals_count;
scope_bundle.location_blocks = raddbg->location_blocks;
scope_bundle.location_block_count = raddbg->location_blocks_count;
scope_bundle.location_data = raddbg->location_data;
scope_bundle.location_data_size = raddbg->location_data_size;
}
str8_list_pushf(arena, &dump, "# SCOPES:\n");
RDI_Scope *ptr = raddbg->scopes;
for(U32 i = 0; i < raddbg->scopes_count; i += 1, ptr += 1)
{
if(ptr->parent_scope_idx == 0)
{
rdi_stringize_scope(arena, &dump, raddbg, &scope_bundle, ptr, 1);
str8_list_push(arena, &dump, str8_lit("\n"));
}
}
str8_list_push(arena, &dump, str8_lit("\n"));
}
//- rjf: SCOPE VMAP
if(dump_flags & DumpFlag_ScopeVMap)
{
str8_list_pushf(arena, &dump, "# SCOPE VMAP:\n");
RDI_VMapEntry *ptr = raddbg->scope_vmap;
for(U32 i = 0; i < raddbg->scope_vmap_count; i += 1, ptr += 1)
{
str8_list_pushf(arena, &dump, " 0x%08x: %llu\n", ptr->voff, ptr->idx);
}
str8_list_push(arena, &dump, str8_lit("\n"));
}
//- rjf: NAME MAPS
if(dump_flags & DumpFlag_NameMaps)
{
str8_list_pushf(arena, &dump, "# NAME MAP:\n");
RDI_NameMap *ptr = raddbg->name_maps;
for(U32 i = 0; i < raddbg->name_maps_count; i += 1, ptr += 1)
{
RDI_ParsedNameMap name_map = {0};
rdi_name_map_parse(raddbg, ptr, &name_map);
str8_list_pushf(arena, &dump, " name_map[%u]:\n", i);
RDI_NameMapBucket *bucket = name_map.buckets;
for(U32 j = 0; j < name_map.bucket_count; j += 1, bucket += 1)
{
if(bucket->node_count > 0)
{
str8_list_pushf(arena, &dump, " bucket[%u]:\n", j);
RDI_NameMapNode *node = name_map.nodes + bucket->first_node;
RDI_NameMapNode *node_opl = node + bucket->node_count;
for(;node < node_opl; node += 1)
{
String8 string = {0};
string.str = rdi_string_from_idx(raddbg, node->string_idx, &string.size);
str8_list_pushf(arena, &dump, " match \"%.*s\": ", str8_varg(string));
if(node->match_count == 1)
{
str8_list_pushf(arena, &dump, "%u", node->match_idx_or_idx_run_first);
}
else
{
RDI_U32 idx_count = 0;
RDI_U32 *idx_run =
rdi_idx_run_from_first_count(raddbg, node->match_idx_or_idx_run_first,
node->match_count, &idx_count);
if(idx_count > 0)
{
RDI_U32 last = idx_count - 1;
for(U32 k = 0; k < last; k += 1)
{
str8_list_pushf(arena, &dump, "%u, ", idx_run[k]);
}
str8_list_pushf(arena, &dump, "%u", idx_run[last]);
}
}
str8_list_pushf(arena, &dump, "\n");
}
}
}
str8_list_push(arena, &dump, str8_lit("\n"));
}
str8_list_push(arena, &dump, str8_lit("\n"));
}
}
//////////////////////////////
//- rjf: write dump to stdout
//
for(String8Node *n = dump.first; n != 0; n = n->next)
{
fwrite(n->string.str, 1, n->string.size, stdout);
}
return 0;
}
-776
View File
@@ -1,776 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ RADDBG Common Stringize Functions
static String8
rdi_string_from_data_section_tag(RDI_DataSectionTag tag){
String8 result = {0};
switch (tag){
#define X(N,C) case C: result = str8_lit(#N); break;
#define Y(N)
RDI_DataSectionTagXList(X,Y)
#undef X
#undef Y
}
return(result);
}
static String8
rdi_string_from_arch(RDI_Arch arch){
String8 result = {0};
switch (arch){
default: result = str8_lit("<invalid-arch>"); break;
case RDI_Arch_X86: result = str8_lit("x86"); break;
case RDI_Arch_X64: result = str8_lit("x64"); break;
}
return(result);
}
static String8
rdi_string_from_language(RDI_Language language){
String8 result = {0};
switch (language){
#define X(name,code) case code: result = str8_lit(#name); break;
RDI_LanguageXList(X)
#undef X
}
return(result);
}
static String8
rdi_string_from_type_kind(RDI_TypeKind type_kind){
String8 result = {0};
switch (type_kind){
default: result = str8_lit("<invalid-type-kind>"); break;
#define X(name,code) case code: result = str8_lit(#name); break;
#define XZ(name,code,size) X(name,code)
#define Y(a,n)
RDI_TypeKindXList(X,XZ,Y)
#undef X
#undef XZ
#undef Y
}
return(result);
}
static String8
rdi_string_from_member_kind(RDI_MemberKind member_kind){
String8 result = {0};
switch (member_kind){
default: result = str8_lit("<invalid-member-kind>"); break;
#define X(N,C) case C: result = str8_lit(#N); break;
RDI_MemberKindXList(X)
#undef X
}
return(result);
}
static String8
rdi_string_from_local_kind(RDI_LocalKind local_kind){
String8 result = {0};
switch (local_kind){
default: result = str8_lit("<invalid-local-kind>"); break;
case RDI_LocalKind_Parameter: result = str8_lit("Parameter"); break;
case RDI_LocalKind_Variable: result = str8_lit("Variable"); break;
}
return(result);
}
////////////////////////////////
//~ RADDBG Flags Stringize Functions
static void
rdi_stringize_binary_section_flags(Arena *arena, String8List *out,
RDI_BinarySectionFlags flags){
if (flags == 0){
str8_list_push(arena, out, str8_lit("0"));
}
if (flags & RDI_BinarySectionFlag_Read){
str8_list_push(arena, out, str8_lit("Read "));
}
if (flags & RDI_BinarySectionFlag_Write){
str8_list_push(arena, out, str8_lit("Write "));
}
if (flags & RDI_BinarySectionFlag_Execute){
str8_list_push(arena, out, str8_lit("Execute "));
}
}
static void
rdi_stringize_type_modifier_flags(Arena *arena, String8List *out,
RDI_TypeModifierFlags flags){
if (flags == 0){
str8_list_push(arena, out, str8_lit("0"));
}
if (flags & RDI_TypeModifierFlag_Const){
str8_list_push(arena, out, str8_lit("Const "));
}
if (flags & RDI_TypeModifierFlag_Volatile){
str8_list_push(arena, out, str8_lit("Volatile "));
}
}
static void
rdi_stringize_user_defined_type_flags(Arena *arena, String8List *out,
RDI_UserDefinedTypeFlags flags){
if (flags == 0){
str8_list_push(arena, out, str8_lit("0"));
}
if (flags & RDI_UserDefinedTypeFlag_EnumMembers){
str8_list_push(arena, out, str8_lit("EnumMembers "));
}
}
static void
rdi_stringize_link_flags(Arena *arena, String8List *out, RDI_LinkFlags flags){
if (flags == 0){
str8_list_push(arena, out, str8_lit("0"));
}
if (flags & RDI_LinkFlag_External){
str8_list_push(arena, out, str8_lit("External "));
}
if (flags & RDI_LinkFlag_TypeScoped){
str8_list_push(arena, out, str8_lit("TypeScoped "));
}
if (flags & RDI_LinkFlag_ProcScoped){
str8_list_push(arena, out, str8_lit("ProcScoped "));
}
}
////////////////////////////////
//~ RADDBG Compound Stringize Functions
static char rdi_stringize_spaces[] = " ";
static void
rdi_stringize_data_sections(Arena *arena, String8List *out, RDI_Parsed *parsed,
U32 indent_level){
U64 data_section_count = parsed->dsec_count;
RDI_DataSection *ptr = parsed->dsecs;
for (U64 i = 0; i < data_section_count; i += 1, ptr += 1){
String8 tag_str = rdi_string_from_data_section_tag(ptr->tag);
str8_list_pushf(arena, out, "%.*sdata_section[%5u] = {0x%08llx, %7u, %7u} %.*s\n",
indent_level, rdi_stringize_spaces,
i, ptr->off, ptr->encoded_size, ptr->unpacked_size, str8_varg(tag_str));
}
}
static void
rdi_stringize_top_level_info(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_TopLevelInfo *tli, U32 indent_level){
String8 arch_str = rdi_string_from_arch(tli->architecture);
String8 exe_name = {0};
exe_name.str = rdi_string_from_idx(parsed, tli->exe_name_string_idx, &exe_name.size);
str8_list_pushf(arena, out, "%.*sarchitecture=%.*s\n",
indent_level, rdi_stringize_spaces, str8_varg(arch_str));
str8_list_pushf(arena, out, "%.*sexe_name='%.*s'\n",
indent_level, rdi_stringize_spaces, str8_varg(exe_name));
str8_list_pushf(arena, out, "%.*svoff_max=0x%08llx\n",
indent_level, rdi_stringize_spaces, tli->voff_max);
}
static void
rdi_stringize_binary_section(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_BinarySection *bin_section, U32 indent_level){
String8 name = {0};
name.str = rdi_string_from_idx(parsed, bin_section->name_string_idx, &name.size);
str8_list_pushf(arena, out, "%.*sname='%.*s'\n",
indent_level, rdi_stringize_spaces, str8_varg(name));
str8_list_pushf(arena, out, "%.*sflags=", indent_level, rdi_stringize_spaces);
rdi_stringize_binary_section_flags(arena, out, bin_section->flags);
str8_list_pushf(arena, out, "\n");
str8_list_pushf(arena, out, "%.*svoff_first=0x%08x\n",
indent_level, rdi_stringize_spaces, bin_section->voff_first);
str8_list_pushf(arena, out, "%.*svoff_opl =0x%08x\n",
indent_level, rdi_stringize_spaces, bin_section->voff_opl);
str8_list_pushf(arena, out, "%.*sfoff_first=0x%08x\n",
indent_level, rdi_stringize_spaces, bin_section->foff_first);
str8_list_pushf(arena, out, "%.*sfoff_opl =0x%08x\n",
indent_level, rdi_stringize_spaces, bin_section->foff_opl);
}
static void
rdi_stringize_file_path(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_FilePathBundle *bundle, RDI_FilePathNode *file_path,
U32 indent_level){
String8 name = {0};
name.str = rdi_string_from_idx(parsed, file_path->name_string_idx, &name.size);
U32 this_idx = (U32)(file_path - bundle->file_paths);
if (file_path->source_file_idx == 0){
str8_list_pushf(arena, out, "%.*s[%u] '%.*s'\n",
indent_level, rdi_stringize_spaces,
this_idx, str8_varg(name));
}
else{
str8_list_pushf(arena, out, "%.*s[%u] '%.*s'; source_file=%u\n",
indent_level, rdi_stringize_spaces,
this_idx, str8_varg(name), file_path->source_file_idx);
}
for (U32 child = file_path->first_child;
child != 0;){
// get node for child
RDI_FilePathNode *child_node = 0;
if (child < bundle->file_path_count){
child_node = bundle->file_paths + child;
}
if (child_node == 0){
break;
}
// stringize child
rdi_stringize_file_path(arena, out, parsed, bundle, child_node, indent_level + 1);
// increment iterator
child = child_node->next_sibling;
}
}
static void
rdi_stringize_source_file(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_SourceFile *source_file, U32 indent_level){
// extract line map data
RDI_ParsedLineMap line_map = {0};
rdi_line_map_from_source_file(parsed, source_file, &line_map);
// stringize line map data
str8_list_pushf(arena, out, "%.*slines:\n", indent_level, rdi_stringize_spaces);
for (U32 i = 0; i < line_map.count; i += 1){
U32 line_num = line_map.nums[i];
U32 digit_count = 1;
if (line_num > 0){
U32 x = line_num;
for (;;){
x /= 10;
if (x == 0){
break;
}
digit_count += 1;
}
}
str8_list_pushf(arena, out, "%.*s %u: ",
indent_level, rdi_stringize_spaces, line_num);
U32 first = line_map.ranges[i];
U32 opl_raw = line_map.ranges[i + 1];
U32 opl = ClampTop(opl_raw, line_map.voff_count);
for (U32 j = first; j < opl; j += 1){
if (j == first){
str8_list_pushf(arena, out, "0x%08x\n", line_map.voffs[j]);
}
else{
str8_list_pushf(arena, out, "%.*s0x%08x\n",
indent_level + digit_count + 3, rdi_stringize_spaces,
line_map.voffs[j]);
}
}
}
}
static void
rdi_stringize_unit(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_Unit *unit, U32 indent_level){
String8 unit_name = {0};
unit_name.str = rdi_string_from_idx(parsed, unit->unit_name_string_idx, &unit_name.size);
String8 compiler_name = {0};
compiler_name.str = rdi_string_from_idx(parsed, unit->compiler_name_string_idx,
&compiler_name.size);
str8_list_pushf(arena, out, "%.*sunit_name='%.*s'\n",
indent_level, rdi_stringize_spaces, str8_varg(unit_name));
str8_list_pushf(arena, out, "%.*scompiler_name='%.*s'\n",
indent_level, rdi_stringize_spaces, str8_varg(compiler_name));
str8_list_pushf(arena, out, "%.*ssource_file_path=%u\n",
indent_level, rdi_stringize_spaces, unit->source_file_path_node);
str8_list_pushf(arena, out, "%.*sobject_file_path=%u\n",
indent_level, rdi_stringize_spaces, unit->object_file_path_node);
str8_list_pushf(arena, out, "%.*sarchive_file_path=%u\n",
indent_level, rdi_stringize_spaces, unit->archive_file_path_node);
str8_list_pushf(arena, out, "%.*sbuild_path=%u\n",
indent_level, rdi_stringize_spaces, unit->build_path_node);
String8 language_str = rdi_string_from_language(unit->language);
str8_list_pushf(arena, out, "%.*slanguage=%.*s\n",
indent_level, rdi_stringize_spaces, str8_varg(language_str));
// extract line info data
RDI_ParsedLineInfo line_info = {0};
rdi_line_info_from_unit(parsed, unit, &line_info);
// stringize line info
str8_list_pushf(arena, out, "%.*slines:\n", indent_level, rdi_stringize_spaces);
for (U32 i = 0; i < line_info.count; i += 1){
U64 first = line_info.voffs[i];
U64 opl = line_info.voffs[i + 1];
RDI_Line *line = line_info.lines + i;
RDI_Column *col = 0;
if (i < line_info.col_count){
col = line_info.cols + i;
}
if (col == 0){
str8_list_pushf(arena, out, "%.*s [0x%08llx,0x%08llx) file=%u; line=%u\n",
indent_level, rdi_stringize_spaces,
first, opl, line->file_idx, line->line_num);
}
else{
str8_list_pushf(arena, out, "%.*s [0x%08llx,0x%08llx) file=%u; line=%u; columns=[%u,%u)\n",
indent_level, rdi_stringize_spaces,
first, opl, line->file_idx, line->line_num,
col->col_first, col->col_opl);
}
}
}
static void
rdi_stringize_type_node(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_TypeNode *type, U32 indent_level){
RDI_TypeKind kind = type->kind;
String8 type_kind_str = rdi_string_from_type_kind(kind);
str8_list_pushf(arena, out, "%.*skind=%.*s\n",
indent_level, rdi_stringize_spaces, str8_varg(type_kind_str));
switch (type->kind){
case RDI_TypeKind_Modifier:
{
str8_list_pushf(arena, out, "%.*sflags=", indent_level, rdi_stringize_spaces);
rdi_stringize_type_modifier_flags(arena, out, type->flags);
str8_list_push(arena, out, str8_lit("\n"));
}break;
default:
{
if (type->flags != 0){
str8_list_pushf(arena, out, "%.*sflags=%x (missing stringizer path)",
indent_level, rdi_stringize_spaces, type->flags);
}
}break;
}
str8_list_pushf(arena, out, "%.*sbyte_size=%u\n",
indent_level, rdi_stringize_spaces, type->byte_size);
if (RDI_TypeKind_FirstBuiltIn <= kind &&
kind <= RDI_TypeKind_LastBuiltIn){
String8 name = {0};
name.str = rdi_string_from_idx(parsed, type->built_in.name_string_idx, &name.size);
str8_list_pushf(arena, out, "%.*sbuilt_in.name='%.*s'\n",
indent_level, rdi_stringize_spaces, str8_varg(name));
}
else if (RDI_TypeKind_FirstConstructed <= kind &&
kind <= RDI_TypeKind_LastConstructed){
str8_list_pushf(arena, out, "%.*sconstructed.direct_type=%u\n",
indent_level, rdi_stringize_spaces, type->constructed.direct_type_idx);
if (type->kind == RDI_TypeKind_Array){
str8_list_pushf(arena, out, "%.*sconstructed.array_count=%u\n",
indent_level, rdi_stringize_spaces, type->constructed.count);
}
if (type->kind == RDI_TypeKind_Function ||
type->kind == RDI_TypeKind_Method){
U32 run_first = type->constructed.param_idx_run_first;
U32 run_count_raw = type->constructed.count;
U32 run_count = 0;
U32 *run = rdi_idx_run_from_first_count(parsed, run_first, run_count_raw, &run_count);
U32 this_type_idx = 0;
if (run_count > 0 && type->kind == RDI_TypeKind_Method){
this_type_idx = run[0];
run += 1;
run_count -= 1;
}
if (this_type_idx != 0){
str8_list_pushf(arena, out, "%.*sconstructed.this_type=%u\n",
indent_level, rdi_stringize_spaces, this_type_idx);
}
str8_list_pushf(arena, out, "%.*sconstructed.params={",
indent_level, rdi_stringize_spaces);
if (run_count > 0){
U32 last = run_count - 1;
for (U32 j = 0; j < last; j += 1){
str8_list_pushf(arena, out, " %u,", run[j]);
}
str8_list_pushf(arena, out, " %u ", run[last]);
}
str8_list_push(arena, out, str8_lit("}\n"));
}
}
else if (RDI_TypeKind_FirstUserDefined <= kind &&
kind <= RDI_TypeKind_LastUserDefined){
String8 name = {0};
name.str = rdi_string_from_idx(parsed, type->user_defined.name_string_idx, &name.size);
str8_list_pushf(arena, out, "%.*suser_defined.name='%.*s'\n",
indent_level, rdi_stringize_spaces, str8_varg(name));
str8_list_pushf(arena, out, "%.*suser_defined.direct_type=%u\n",
indent_level, rdi_stringize_spaces,
type->user_defined.direct_type_idx);
str8_list_pushf(arena, out, "%.*suser_defined.udt=%u\n",
indent_level, rdi_stringize_spaces,
type->user_defined.udt_idx);
}
else if (kind == RDI_TypeKind_Bitfield){
str8_list_pushf(arena, out, "%.*sbitfield.off=%u\n",
indent_level, rdi_stringize_spaces, type->bitfield.off);
str8_list_pushf(arena, out, "%.*sbitfield.size=%u\n",
indent_level, rdi_stringize_spaces, type->bitfield.size);
}
}
static void
rdi_stringize_udt(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_UDTMemberBundle *member_bundle, RDI_UDT *udt,
U32 indent_level){
str8_list_pushf(arena, out, "%.*sself_type=%u\n",
indent_level, rdi_stringize_spaces, udt->self_type_idx);
str8_list_pushf(arena, out, "%.*sflags=", indent_level, rdi_stringize_spaces);
rdi_stringize_user_defined_type_flags(arena, out, udt->flags);
str8_list_push(arena, out, str8_lit("\n"));
if (udt->file_idx != 0){
str8_list_pushf(arena, out, "%.*sloc={file=%u; line=%u; col=%u}\n",
indent_level, rdi_stringize_spaces,
udt->file_idx, udt->line, udt->col);
}
// enum members
if (udt->flags & RDI_UserDefinedTypeFlag_EnumMembers){
U32 first_raw = udt->member_first;
U32 opl_raw = first_raw + udt->member_count;
U32 opl = ClampTop(opl_raw, member_bundle->enum_member_count);
U32 first = ClampTop(first_raw, opl);
if (first < opl){
str8_list_pushf(arena, out, "%.*smembers={\n", indent_level, rdi_stringize_spaces);
RDI_EnumMember *enum_member = member_bundle->enum_members + first;
for (U32 i = first; i < opl; i += 1, enum_member += 1){
String8 name = {0};
name.str = rdi_string_from_idx(parsed, enum_member->name_string_idx, &name.size);
str8_list_pushf(arena, out, "%.*s '%.*s' %llu\n",
indent_level, rdi_stringize_spaces,
str8_varg(name), enum_member->val);
}
str8_list_pushf(arena, out, "%.*s}\n", indent_level, rdi_stringize_spaces);
}
}
// field members
else{
U32 first_raw = udt->member_first;
U32 opl_raw = first_raw + udt->member_count;
U32 opl = ClampTop(opl_raw, member_bundle->member_count);
U32 first = ClampTop(first_raw, opl);
if (first < opl){
str8_list_pushf(arena, out, "%.*smembers={\n", indent_level, rdi_stringize_spaces);
RDI_Member *member = member_bundle->members + first;
for (U32 i = first; i < opl; i += 1, member += 1){
str8_list_pushf(arena, out, "%.*s {\n", indent_level, rdi_stringize_spaces);
String8 kind_str = rdi_string_from_member_kind(member->kind);
str8_list_pushf(arena, out, "%.*s kind=%.*s\n",
indent_level, rdi_stringize_spaces, str8_varg(kind_str));
if (member->name_string_idx != 0){
String8 name = {0};
name.str = rdi_string_from_idx(parsed, member->name_string_idx, &name.size);
str8_list_pushf(arena, out, "%.*s name='%.*s'\n",
indent_level, rdi_stringize_spaces, str8_varg(name));
}
str8_list_pushf(arena, out, "%.*s type=%u\n",
indent_level, rdi_stringize_spaces, member->type_idx);
str8_list_pushf(arena, out, "%.*s off=%u\n",
indent_level, rdi_stringize_spaces, member->off);
str8_list_pushf(arena, out, "%.*s }\n", indent_level, rdi_stringize_spaces);
}
str8_list_pushf(arena, out, "%.*s}\n", indent_level, rdi_stringize_spaces);
}
}
}
static void
rdi_stringize_global_variable(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_GlobalVariable *global_variable, U32 indent_level){
String8 name = {0};
name.str = rdi_string_from_idx(parsed, global_variable->name_string_idx, &name.size);
str8_list_pushf(arena, out, "%.*sname='%.*s'\n",
indent_level, rdi_stringize_spaces, str8_varg(name));
str8_list_pushf(arena, out, "%.*slink_flags=", indent_level, rdi_stringize_spaces);
rdi_stringize_link_flags(arena, out, global_variable->link_flags);
str8_list_push(arena, out, str8_lit("\n"));
str8_list_pushf(arena, out, "%.*svoff=0x%08llx\n",
indent_level, rdi_stringize_spaces, global_variable->voff);
str8_list_pushf(arena, out, "%.*stype_idx=%u\n",
indent_level, rdi_stringize_spaces, global_variable->type_idx);
str8_list_pushf(arena, out, "%.*scontainer_idx=%u\n",
indent_level, rdi_stringize_spaces, global_variable->container_idx);
}
static void
rdi_stringize_thread_variable(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_ThreadVariable *thread_var,
U32 indent_level){
String8 name = {0};
name.str = rdi_string_from_idx(parsed, thread_var->name_string_idx, &name.size);
str8_list_pushf(arena, out, "%.*sname='%.*s'\n",
indent_level, rdi_stringize_spaces, str8_varg(name));
str8_list_pushf(arena, out, "%.*slink_flags=", indent_level, rdi_stringize_spaces);
rdi_stringize_link_flags(arena, out, thread_var->link_flags);
str8_list_push(arena, out, str8_lit("\n"));
str8_list_pushf(arena, out, "%.*stls_off=0x%08x\n",
indent_level, rdi_stringize_spaces, thread_var->tls_off);
str8_list_pushf(arena, out, "%.*stype_idx=%u\n",
indent_level, rdi_stringize_spaces, thread_var->type_idx);
str8_list_pushf(arena, out, "%.*scontainer_idx=%u\n",
indent_level, rdi_stringize_spaces, thread_var->container_idx);
}
static void
rdi_stringize_procedure(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_Procedure *proc, U32 indent_level){
String8 name = {0};
name.str = rdi_string_from_idx(parsed, proc->name_string_idx, &name.size);
str8_list_pushf(arena, out, "%.*sname='%.*s'\n",
indent_level, rdi_stringize_spaces, str8_varg(name));
String8 link_name = {0};
link_name.str = rdi_string_from_idx(parsed, proc->link_name_string_idx, &link_name.size);
str8_list_pushf(arena, out, "%.*slink_name='%.*s'\n",
indent_level, rdi_stringize_spaces, str8_varg(link_name));
str8_list_pushf(arena, out, "%.*slink_flags=", indent_level, rdi_stringize_spaces);
rdi_stringize_link_flags(arena, out, proc->link_flags);
str8_list_push(arena, out, str8_lit("\n"));
str8_list_pushf(arena, out, "%.*stype_idx=%u\n",
indent_level, rdi_stringize_spaces, proc->type_idx);
str8_list_pushf(arena, out, "%.*sroot_scope_idx=%u\n",
indent_level, rdi_stringize_spaces, proc->root_scope_idx);
str8_list_pushf(arena, out, "%.*scontainer_idx=%u\n",
indent_level, rdi_stringize_spaces, proc->container_idx);
}
static void
rdi_stringize_scope(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_ScopeBundle *bundle, RDI_Scope *scope, U32 indent_level){
U32 this_idx = (U32)(scope - bundle->scopes);
str8_list_pushf(arena, out, "%.*s[%u]\n",
indent_level, rdi_stringize_spaces, this_idx);
str8_list_pushf(arena, out, "%.*s proc_idx=%u\n",
indent_level, rdi_stringize_spaces, scope->proc_idx);
// voff ranges
{
U32 voff_range_first_raw = scope->voff_range_first;
U32 voff_range_opl_raw = scope->voff_range_opl;
U32 voff_range_opl_clamped = ClampTop(voff_range_opl_raw, bundle->scope_voff_count);
U32 voff_range_first = ClampTop(voff_range_first_raw, voff_range_opl_clamped);
U32 voff_range_opl = voff_range_opl_clamped;
if ((voff_range_opl - voff_range_first) % 2 == 1){
voff_range_opl -= 1;
}
U64 *voff_ptr = bundle->scope_voffs + voff_range_first;
if (voff_range_opl - voff_range_first > 2){
str8_list_pushf(arena, out, "%.*s voff_ranges={\n",
indent_level, rdi_stringize_spaces);
for (U32 i = voff_range_first; i < voff_range_opl; i += 2, voff_ptr += 2){
str8_list_pushf(arena, out, "%.*s [0x%08llx, 0x%08llx)\n",
indent_level, rdi_stringize_spaces,
voff_ptr[0], voff_ptr[1]);
}
str8_list_pushf(arena, out, "%.*s }\n",
indent_level, rdi_stringize_spaces);
}
else if (voff_range_opl - voff_range_first == 2){
str8_list_pushf(arena, out, "%.*s voff_range=[0x%08llx, 0x%08llx)\n",
indent_level, rdi_stringize_spaces,
voff_ptr[0], voff_ptr[1]);
}
}
// locals
{
U32 local_first = scope->local_first;
U32 local_opl_raw = local_first + scope->local_count;
U32 local_opl = ClampTop(local_opl_raw, bundle->local_count);
if (local_first < local_opl){
RDI_Local *local_ptr = bundle->locals + local_first;
for (U32 i = local_first; i < local_opl; i += 1, local_ptr += 1){
str8_list_pushf(arena, out, "%.*s local[%u]\n",
indent_level, rdi_stringize_spaces, i);
String8 local_kind_str = rdi_string_from_local_kind(local_ptr->kind);
str8_list_pushf(arena, out, "%.*s kind=%.*s\n",
indent_level, rdi_stringize_spaces, str8_varg(local_kind_str));
String8 name = {0};
name.str = rdi_string_from_idx(parsed, local_ptr->name_string_idx, &name.size);
str8_list_pushf(arena, out, "%.*s name='%.*s'\n",
indent_level, rdi_stringize_spaces, str8_varg(name));
str8_list_pushf(arena, out, "%.*s type_idx=%u\n",
indent_level, rdi_stringize_spaces, local_ptr->type_idx);
U32 location_first = local_ptr->location_first;
U32 location_opl_raw = local_ptr->location_opl;
U32 location_opl = ClampTop(location_opl_raw, bundle->location_block_count);
if (location_first < location_opl){
str8_list_pushf(arena, out, "%.*s locations:\n", indent_level, rdi_stringize_spaces);
RDI_LocationBlock *block_ptr = bundle->location_blocks + location_first;
for (U32 j = location_first; j < location_opl; j += 1, block_ptr += 1){
if (block_ptr->scope_off_first == 0 && block_ptr->scope_off_opl == max_U32){
str8_list_pushf(arena, out, "%.*s case *always*:\n", indent_level, rdi_stringize_spaces);
}
else{
str8_list_pushf(arena, out, "%.*s case [0x%08x, 0x%08x):\n",
indent_level, rdi_stringize_spaces,
block_ptr->scope_off_first, block_ptr->scope_off_opl);
}
if (block_ptr->location_data_off >= bundle->location_data_size){
str8_list_pushf(arena, out, "%.*s <bad-location-data-offset>\n",
indent_level, rdi_stringize_spaces);
}
else{
str8_list_pushf(arena, out, "%.*s ", indent_level, rdi_stringize_spaces);
U8 *loc_data_opl = bundle->location_data + bundle->location_data_size;
U8 *loc_base_ptr = bundle->location_data + block_ptr->location_data_off;
RDI_LocationKind kind = (RDI_LocationKind)*loc_base_ptr;
switch (kind){
default:
{
str8_list_pushf(arena, out, "<invalid-location-kind>\n");
}break;
case RDI_LocationKind_AddrBytecodeStream:
{
str8_list_pushf(arena, out, "AddrBytecodeStream\n");
str8_list_pushf(arena, out, "%.*s ", indent_level, rdi_stringize_spaces);
U8 *bytecode_ptr = loc_base_ptr + 1;
for (;bytecode_ptr < loc_data_opl && *bytecode_ptr != 0; bytecode_ptr += 1){
str8_list_pushf(arena, out, "%02x ", *bytecode_ptr);
}
str8_list_pushf(arena, out, "\n");
}break;
case RDI_LocationKind_ValBytecodeStream:
{
str8_list_pushf(arena, out, "ValBytecodeStream\n");
str8_list_pushf(arena, out, "%.*s ", indent_level, rdi_stringize_spaces);
U8 *bytecode_ptr = loc_base_ptr + 1;
for (;bytecode_ptr < loc_data_opl && *bytecode_ptr != 0; bytecode_ptr += 1){
str8_list_pushf(arena, out, "%02x ", *bytecode_ptr);
}
str8_list_pushf(arena, out, "\n");
}break;
case RDI_LocationKind_AddrRegisterPlusU16:
{
if (loc_base_ptr + sizeof(RDI_LocationRegisterPlusU16) > loc_data_opl){
str8_list_pushf(arena, out, "AddrRegisterPlusU16( <invalid-encoding> )\n");
}
else{
RDI_LocationRegisterPlusU16 *loc = (RDI_LocationRegisterPlusU16*)loc_base_ptr;
str8_list_pushf(arena, out, "AddrRegisterPlusU16(reg: %u, off: %u)\n",
loc->register_code, loc->offset);
}
}break;
case RDI_LocationKind_AddrAddrRegisterPlusU16:
{
if (loc_base_ptr + sizeof(RDI_LocationRegisterPlusU16) > loc_data_opl){
str8_list_pushf(arena, out, "AddrAddrRegisterPlusU16( <invalid-encoding> )\n");
}
else{
RDI_LocationRegisterPlusU16 *loc = (RDI_LocationRegisterPlusU16*)loc_base_ptr;
str8_list_pushf(arena, out, "AddrAddrRegisterPlusU16(reg: %u, off: %u)\n",
loc->register_code, loc->offset);
}
}break;
case RDI_LocationKind_ValRegister:
{
if (loc_base_ptr + sizeof(RDI_LocationRegister) > loc_data_opl){
str8_list_pushf(arena, out, "ValRegister( <invalid-encoding> )\n");
}
else{
RDI_LocationRegister *loc = (RDI_LocationRegister*)loc_base_ptr;
str8_list_pushf(arena, out, "ValRegister(reg: %u)\n", loc->register_code);
}
}break;
}
}
}
}
}
}
}
// TODO(allen): static locals
for (U32 child = scope->first_child_scope_idx;
child != 0;){
// get scope for child
RDI_Scope *child_scope = 0;
if (child < bundle->scope_count){
child_scope = bundle->scopes + child;
}
if (child_scope == 0){
break;
}
// stringize child
rdi_stringize_scope(arena, out, parsed, bundle, child_scope, indent_level + 1);
// increment iterator
child = child_scope->next_sibling_scope_idx;
}
str8_list_pushf(arena, out, "%.*s[/%u]\n",
indent_level, rdi_stringize_spaces, this_idx);
}
-114
View File
@@ -1,114 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef RADDBGI_STRINGIZE_H
#define RADDBGI_STRINGIZE_H
////////////////////////////////
//~ RADDBG Stringize Helper Types
typedef struct RDI_FilePathBundle{
RDI_FilePathNode *file_paths;
U32 file_path_count;
} RDI_FilePathBundle;
typedef struct RDI_UDTMemberBundle{
RDI_Member *members;
RDI_EnumMember *enum_members;
U32 member_count;
U32 enum_member_count;
} RDI_UDTMemberBundle;
typedef struct RDI_ScopeBundle{
RDI_Scope *scopes;
U64 *scope_voffs;
RDI_Local *locals;
RDI_LocationBlock *location_blocks;
U8 *location_data;
U32 scope_count;
U32 scope_voff_count;
U32 local_count;
U32 location_block_count;
U32 location_data_size;
} RDI_ScopeBundle;
////////////////////////////////
//~ RADDBG Common Stringize Functions
static String8 rdi_string_from_data_section_tag(RDI_DataSectionTag tag);
static String8 rdi_string_from_arch(RDI_Arch arch);
static String8 rdi_string_from_language(RDI_Language language);
static String8 rdi_string_from_type_kind(RDI_TypeKind type_kind);
static String8 rdi_string_from_member_kind(RDI_MemberKind member_kind);
static String8 rdi_string_from_local_kind(RDI_LocalKind local_kind);
////////////////////////////////
//~ RADDBG Flags Stringize Functions
static void rdi_stringize_binary_section_flags(Arena *arena, String8List *out,
RDI_BinarySectionFlags flags);
static void rdi_stringize_type_modifier_flags(Arena *arena, String8List *out,
RDI_TypeModifierFlags flags);
static void rdi_stringize_user_defined_type_flags(Arena *arena, String8List *out,
RDI_UserDefinedTypeFlags flags);
static void rdi_stringize_link_flags(Arena *arena, String8List *out,
RDI_LinkFlags flags);
////////////////////////////////
//~ RADDBG Compound Stringize Functions
static void
rdi_stringize_data_sections(Arena *arena, String8List *out, RDI_Parsed *parsed,
U32 indent_level);
static void
rdi_stringize_top_level_info(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_TopLevelInfo *tli, U32 indent_level);
static void
rdi_stringize_binary_section(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_BinarySection *bin_section, U32 indent_level);
static void
rdi_stringize_file_path(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_FilePathBundle *bundle, RDI_FilePathNode *file_path,
U32 indent_level);
static void
rdi_stringize_source_file(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_SourceFile *source_file, U32 indent_level);
static void
rdi_stringize_unit(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_Unit *unit, U32 indent_level);
static void
rdi_stringize_type_node(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_TypeNode *type, U32 indent_level);
static void
rdi_stringize_udt(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_UDTMemberBundle *bundle, RDI_UDT *udt,
U32 indent_level);
static void
rdi_stringize_global_variable(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_GlobalVariable *global_variable, U32 indent_level);
static void
rdi_stringize_thread_variable(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_ThreadVariable *thread_var,
U32 indent_level);
static void
rdi_stringize_procedure(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_Procedure *proc, U32 indent_level);
static void
rdi_stringize_scope(Arena *arena, String8List *out, RDI_Parsed *parsed,
RDI_ScopeBundle *bundle, RDI_Scope *scope, U32 indent_level);
#endif // RADDBGI_STRINGIZE_H