get DWARF converter up and running

This commit is contained in:
Nikita Smith
2025-09-25 12:38:21 -07:00
parent 05fbd06f82
commit d3d91c64cc
2 changed files with 570 additions and 573 deletions
+57 -60
View File
@@ -200,7 +200,7 @@ d2r_collect_proc_params(Arena *arena, D2R_TypeTable *type_table, DW_Input *input
if (has_vargs) { if (has_vargs) {
RDIM_TypeNode *n = push_array(scratch.arena, RDIM_TypeNode, 1); RDIM_TypeNode *n = push_array(scratch.arena, RDIM_TypeNode, 1);
n->v = type_table->varg_type; n->v = type_table->builtin_types[RDI_TypeKind_Variadic];
SLLQueuePush(list.first, list.last, n); SLLQueuePush(list.first, list.last, n);
++list.count; ++list.count;
} }
@@ -1126,11 +1126,36 @@ d2r_push_scope(Arena *arena, RDIM_ScopeChunkList *scopes, U64 scope_chunk_cap, D
//////////////////////////////// ////////////////////////////////
//~ rjf: Main Conversion Entry Point //~ rjf: Main Conversion Entry Point
static const U64 UNIT_CHUNK_CAP = 256;
static const U64 UDT_CHUNK_CAP = 256;
static const U64 TYPE_CHUNK_CAP = 256;
static const U64 GVAR_CHUNK_CAP = 256;
static const U64 TVAR_CHUNK_CAP = 256;
static const U64 PROC_CHUNK_CAP = 256;
static const U64 SCOPE_CHUNK_CAP = 256;
static const U64 INLINE_SITE_CHUNK_CAP = 256;
static const U64 SRC_FILE_CAP = 256;
static const U64 LINE_TABLE_CAP = 256;
RDIM_TopLevelInfo top_level_info = {0};
RDIM_BinarySectionList binary_sections = {0};
RDIM_UnitChunkList units = {0};
RDIM_UDTChunkList udts = {0};
RDIM_TypeChunkList types = {0};
RDIM_SymbolChunkList gvars = {0};
RDIM_SymbolChunkList tvars = {0};
RDIM_SymbolChunkList procs = {0};
RDIM_ScopeChunkList scopes = {0};
RDIM_InlineSiteChunkList inline_sites = {0};
RDIM_SrcFileChunkList src_files = {0};
RDIM_LineTableChunkList line_tables = {0};
internal RDIM_BakeParams internal RDIM_BakeParams
d2r_convert(Arena *arena, D2R_ConvertParams *params) d2r_convert(Arena *arena, D2R_ConvertParams *params)
{ {
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
if (lane_idx() == 0) {
//////////////////////////////// ////////////////////////////////
ProfBegin("compute exe hash"); ProfBegin("compute exe hash");
@@ -1141,66 +1166,37 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
Arch arch = Arch_Null; Arch arch = Arch_Null;
U64 image_base = 0; U64 image_base = 0;
RDIM_BinarySectionList binary_sections = {0};
DW_Input input = {0}; DW_Input input = {0};
switch(params->exe_kind) switch(params->exe_kind) {
{
default:{}break; default:{}break;
case ExecutableImageKind_CoffPe: case ExecutableImageKind_CoffPe: {
{
PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, params->exe_data); PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, params->exe_data);
String8 raw_sections = str8_substr(params->exe_data, pe.section_table_range);
COFF_SectionHeader *section_table = str8_deserial_get_raw_ptr(raw_sections, 0, sizeof(COFF_SectionHeader) * pe.section_count);
String8 string_table = str8_substr(params->exe_data, pe.string_table_range);
arch = pe.arch; arch = pe.arch;
image_base = pe.image_base; image_base = pe.image_base;
String8 raw_sections = str8_substr(params->exe_data, pe.section_table_range); binary_sections = c2r_rdi_binary_sections_from_coff_sections(arena, params->exe_data, string_table, pe.section_count, section_table);
U64 section_count = raw_sections.size / sizeof(COFF_SectionHeader); input = dw_input_from_coff_section_table(scratch.arena, params->exe_data, string_table, pe.section_count, section_table);
COFF_SectionHeader *section_table = (COFF_SectionHeader *)raw_sections.str; } break;
String8 string_table = str8_substr(params->exe_data, pe.string_table_range);
binary_sections = c2r_rdi_binary_sections_from_coff_sections(arena, params->exe_data, string_table, section_count, section_table);
input = dw_input_from_coff_section_table(scratch.arena, params->exe_data, string_table, section_count, section_table);
}break;
case ExecutableImageKind_Elf32: case ExecutableImageKind_Elf32:
case ExecutableImageKind_Elf64: case ExecutableImageKind_Elf64: {
{
ELF_Bin bin = elf_bin_from_data(scratch.arena, params->dbg_data); ELF_Bin bin = elf_bin_from_data(scratch.arena, params->dbg_data);
arch = arch_from_elf_machine(bin.hdr.e_machine); arch = arch_from_elf_machine(bin.hdr.e_machine);
image_base = elf_base_addr_from_bin(&bin); image_base = elf_base_addr_from_bin(&bin);
binary_sections = e2r_rdi_binary_sections_from_elf_section_table(arena, bin.shdrs); binary_sections = e2r_rdi_binary_sections_from_elf_section_table(arena, bin.shdrs);
input = dw_input_from_elf_bin(scratch.arena, params->dbg_data, &bin); input = dw_input_from_elf_bin(scratch.arena, params->dbg_data, &bin);
}break; } break;
} }
//////////////////////////////// ////////////////////////////////
RDIM_TopLevelInfo top_level_info = rdim_make_top_level_info(params->exe_name, arch, exe_hash, binary_sections); top_level_info = rdim_make_top_level_info(params->exe_name, arch, exe_hash, binary_sections);
//////////////////////////////// ////////////////////////////////
U64 arch_addr_size = rdi_addr_size_from_arch(arch); U64 arch_addr_size = rdi_addr_size_from_arch(top_level_info.arch);
////////////////////////////////
static const U64 UNIT_CHUNK_CAP = 256;
static const U64 UDT_CHUNK_CAP = 256;
static const U64 TYPE_CHUNK_CAP = 256;
static const U64 GVAR_CHUNK_CAP = 256;
static const U64 TVAR_CHUNK_CAP = 256;
static const U64 PROC_CHUNK_CAP = 256;
static const U64 SCOPE_CHUNK_CAP = 256;
static const U64 INLINE_SITE_CHUNK_CAP = 256;
static const U64 SRC_FILE_CAP = 256;
static const U64 LINE_TABLE_CAP = 256;
RDIM_UnitChunkList units = {0};
RDIM_UDTChunkList udts = {0};
RDIM_TypeChunkList types = {0};
RDIM_SymbolChunkList gvars = {0};
RDIM_SymbolChunkList tvars = {0};
RDIM_SymbolChunkList procs = {0};
RDIM_ScopeChunkList scopes = {0};
RDIM_InlineSiteChunkList inline_sites = {0};
RDIM_SrcFileChunkList src_files = {0};
RDIM_LineTableChunkList line_tables = {0};
//////////////////////////////// ////////////////////////////////
@@ -1253,10 +1249,8 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
//////////////////////////////// ////////////////////////////////
ProfBegin("Convert Line Tables"); ProfBegin("Convert Line Tables");
HashTable *source_file_ht = hash_table_init(scratch.arena, 0x4000); HashTable *source_file_ht = hash_table_init(scratch.arena, 0x4000);
RDIM_LineTable **cu_line_tables_rdi = push_array(scratch.arena, RDIM_LineTable *, cu_ranges.count); RDIM_LineTable **cu_line_tables_rdi = push_array(scratch.arena, RDIM_LineTable *, cu_ranges.count);
for (U64 cu_idx = 0; cu_idx < cu_ranges.count; ++cu_idx) { for (U64 cu_idx = 0; cu_idx < cu_ranges.count; ++cu_idx) {
cu_line_tables_rdi[cu_idx] = rdim_line_table_chunk_list_push(arena, &line_tables, LINE_TABLE_CAP); cu_line_tables_rdi[cu_idx] = rdim_line_table_chunk_list_push(arena, &line_tables, LINE_TABLE_CAP);
@@ -1349,13 +1343,25 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
//Assert(line_idx == line_seq->count); //Assert(line_idx == line_seq->count);
} }
} }
ProfEnd(); ProfEnd();
//////////////////////////////// ////////////////////////////////
ProfBegin("Convert Units"); RDIM_Type *builtin_types[RDI_TypeKind_Count] = {0};
for (RDI_TypeKind type_kind = RDI_TypeKind_FirstBuiltIn; type_kind <= RDI_TypeKind_LastBuiltIn; type_kind += 1) {
RDIM_Type *type = rdim_type_chunk_list_push(arena, &types, TYPE_CHUNK_CAP);
type->kind = type_kind;
type->name.str = rdi_string_from_type_kind(type_kind, &type->name.size);
type->byte_size = rdi_size_from_basic_type_kind(type_kind);
builtin_types[type_kind] = type;
}
builtin_types[RDI_TypeKind_Void]->byte_size = arch_addr_size;
builtin_types[RDI_TypeKind_Handle]->byte_size = arch_addr_size;
builtin_types[RDI_TypeKind_Variadic] = rdim_type_chunk_list_push(arena, &types, TYPE_CHUNK_CAP);
////////////////////////////////
ProfBegin("Convert Units");
for (U64 cu_idx = 0; cu_idx < cu_ranges.count; ++cu_idx) { for (U64 cu_idx = 0; cu_idx < cu_ranges.count; ++cu_idx) {
Temp comp_temp = temp_begin(scratch.arena); Temp comp_temp = temp_begin(scratch.arena);
@@ -1397,8 +1403,7 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
type_table->ht = hash_table_init(comp_temp.arena, 0x4000); type_table->ht = hash_table_init(comp_temp.arena, 0x4000);
type_table->types = &types; type_table->types = &types;
type_table->type_chunk_cap = TYPE_CHUNK_CAP; type_table->type_chunk_cap = TYPE_CHUNK_CAP;
type_table->varg_type = d2r_create_type(arena, type_table); type_table->builtin_types = builtin_types;
type_table->varg_type->kind = RDI_TypeKind_Variadic;
D2R_TagNode *free_tags = push_array(comp_temp.arena, D2R_TagNode, 1); D2R_TagNode *free_tags = push_array(comp_temp.arena, D2R_TagNode, 1);
D2R_TagNode *tag_stack = push_array(comp_temp.arena, D2R_TagNode, 1); D2R_TagNode *tag_stack = push_array(comp_temp.arena, D2R_TagNode, 1);
@@ -1510,7 +1515,7 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
RDIM_Type *param_type = d2r_type_from_attrib(arena, type_table, &input, cu, n->tag, DW_AttribKind_Type); RDIM_Type *param_type = d2r_type_from_attrib(arena, type_table, &input, cu, n->tag, DW_AttribKind_Type);
rdim_type_list_push(comp_temp.arena, &param_list, param_type); rdim_type_list_push(comp_temp.arena, &param_list, param_type);
} else if (n->tag.kind == DW_TagKind_UnspecifiedParameters) { } else if (n->tag.kind == DW_TagKind_UnspecifiedParameters) {
rdim_type_list_push(comp_temp.arena, &param_list, type_table->varg_type); rdim_type_list_push(comp_temp.arena, &param_list, type_table->builtin_types[RDI_TypeKind_Variadic]);
} else { } else {
// TODO: error handling // TODO: error handling
AssertAlways(!"unexpected tag"); AssertAlways(!"unexpected tag");
@@ -1636,18 +1641,10 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
default: AssertAlways(!"unexpected base type encoding"); break; // TODO: error handling default: AssertAlways(!"unexpected base type encoding"); break; // TODO: error handling
} }
// TODO(rjf): this is not good. we can't grab existing type nodes & mutate them here.
// to parallelize this properly, we need to *produce* new data only, otherwise threads
// will stomp over each other everywhere.
//
RDIM_Type *base_type = 0; // rdim_builtin_type_from_kind(types, kind);
base_type->kind = kind;
base_type->byte_size = byte_size;
RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off); RDIM_Type *type = d2r_find_or_create_type_from_offset(arena, type_table, tag.info_off);
type->kind = RDI_TypeKind_Alias; type->kind = RDI_TypeKind_Alias;
type->name = dw_string_from_tag_attrib_kind(&input, cu, tag, DW_AttribKind_Name); type->name = dw_string_from_tag_attrib_kind(&input, cu, tag, DW_AttribKind_Name);
type->direct_type = base_type; type->direct_type = type_table->builtin_types[kind];
} break; } break;
case DW_TagKind_PointerType: { case DW_TagKind_PointerType: {
RDIM_Type *direct_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_AttribKind_Type); RDIM_Type *direct_type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_AttribKind_Type);
@@ -2040,7 +2037,6 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
temp_end(comp_temp); temp_end(comp_temp);
} }
ProfEnd(); ProfEnd();
{ {
@@ -2107,8 +2103,9 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
} }
} }
} }
}
//////////////////////////////// lane_sync();
RDIM_BakeParams bake_params = {0}; RDIM_BakeParams bake_params = {0};
bake_params.top_level_info = top_level_info; bake_params.top_level_info = top_level_info;
+1 -1
View File
@@ -20,7 +20,7 @@ typedef struct D2R_TypeTable
HashTable *ht; HashTable *ht;
RDIM_TypeChunkList *types; RDIM_TypeChunkList *types;
U64 type_chunk_cap; U64 type_chunk_cap;
RDIM_Type *varg_type; RDIM_Type **builtin_types;
} D2R_TypeTable; } D2R_TypeTable;
typedef struct D2R_TagNode typedef struct D2R_TagNode