add API to DWARF writer that defines forward references and fix method

conversion in the converter
This commit is contained in:
Nikita Smith
2026-02-27 11:07:19 -08:00
parent b49c902947
commit 8007c158fa
5 changed files with 65 additions and 26 deletions
+21 -9
View File
@@ -327,9 +327,30 @@ dw_make_abbrev_entry(Arena *arena, DW_WriterTag *tag)
internal DW_WriterTag * internal DW_WriterTag *
dw_writer_tag_begin(DW_Writer *writer, DW_TagKind kind) dw_writer_tag_begin(DW_Writer *writer, DW_TagKind kind)
{
DW_WriterTag *tag = dw_writer_tag_reserve(writer, kind);
dw_writer_tag_begin_reserved(writer, tag);
return tag;
}
internal void
dw_writer_tag_end(DW_Writer *writer)
{
// pop to parent
writer->current = writer->current->parent;
}
internal DW_WriterTag *
dw_writer_tag_reserve(DW_Writer *writer, DW_TagKind kind)
{ {
DW_WriterTag *tag = dw_writer_tag_chunk_list_push(writer->arena, &writer->tag_chunk_list, 512); DW_WriterTag *tag = dw_writer_tag_chunk_list_push(writer->arena, &writer->tag_chunk_list, 512);
tag->kind = kind; tag->kind = kind;
return tag;
}
internal void
dw_writer_tag_begin_reserved(DW_Writer *writer, DW_WriterTag *tag)
{
tag->parent = writer->current; tag->parent = writer->current;
// add tag to the tree // add tag to the tree
@@ -339,15 +360,6 @@ dw_writer_tag_begin(DW_Writer *writer, DW_TagKind kind)
writer->root = tag; writer->root = tag;
} }
writer->current = tag; writer->current = tag;
return tag;
}
internal void
dw_writer_tag_end(DW_Writer *writer)
{
// pop to parent
writer->current = writer->current->parent;
} }
internal DW_WriterAttrib * internal DW_WriterAttrib *
+4 -2
View File
@@ -259,8 +259,10 @@ internal U64 dw_serial_push_form(Arena *arena, String8List *srl, DW_Version vers
//////////////////////////////// ////////////////////////////////
// Info // Info
internal DW_WriterTag * dw_writer_tag_begin(DW_Writer *writer, DW_TagKind kind); internal DW_WriterTag * dw_writer_tag_reserve (DW_Writer *writer, DW_TagKind kind);
internal void dw_writer_tag_end (DW_Writer *writer); internal DW_WriterTag * dw_writer_tag_begin (DW_Writer *writer, DW_TagKind kind);
internal void dw_writer_tag_begin_reserved(DW_Writer *writer, DW_WriterTag *tag);
internal void dw_writer_tag_end (DW_Writer *writer);
internal DW_WriterAttrib * dw_writer_push_attrib (DW_Writer *writer, DW_AttribKind kind, DW_WriterForm form ); internal DW_WriterAttrib * dw_writer_push_attrib (DW_Writer *writer, DW_AttribKind kind, DW_WriterForm form );
internal DW_WriterAttrib * dw_writer_push_attrib_address (DW_Writer *writer, DW_AttribKind kind, U64 address ); internal DW_WriterAttrib * dw_writer_push_attrib_address (DW_Writer *writer, DW_AttribKind kind, U64 address );
+1 -1
View File
@@ -1363,7 +1363,7 @@ lane_sync(); if(flags & RDI_DumpSubsetFlag_##name) ProfScope(#name)
return result_strings; return result_strings;
} }
#if 0 #if SUBPROGRAM_CONVERSION_TEST
internal String8 internal String8
rdi_string_from_type(Arena *arena, RDI_Parsed *rdi, RDI_Procedure *proc, RDI_TypeNode *type) rdi_string_from_type(Arena *arena, RDI_Parsed *rdi, RDI_Procedure *proc, RDI_TypeNode *type)
{ {
+34 -9
View File
@@ -1706,6 +1706,11 @@ d2r_convert_types(Arena *arena,
type->direct_type = enum_base_type; type->direct_type = enum_base_type;
} }
} break; } break;
case DW_TagKind_SubProgram: {
if ( ! dw_tag_has_attrib(input, cu, tag, DW_AttribKind_Declaration)) {
break;
}
} // fall-through
case DW_TagKind_SubroutineType: { case DW_TagKind_SubroutineType: {
RDIM_Type *ret_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch, tag, DW_AttribKind_Type); RDIM_Type *ret_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch, tag, DW_AttribKind_Type);
@@ -1722,9 +1727,12 @@ d2r_convert_types(Arena *arena,
} }
} }
DW_TagNode *parent = d2r_tag_iterator_parent_tag_node(it);
B32 is_method = parent->tag.kind == DW_TagKind_StructureType || parent->tag.kind == DW_TagKind_ClassType;
// init proceudre type // init proceudre type
RDIM_Type *type = d2r_create_type_from_offset(arena, type_table, tag.info_off); RDIM_Type *type = d2r_create_type_from_offset(arena, type_table, tag.info_off);
type->kind = RDI_TypeKind_Function; type->kind = is_method ? RDI_TypeKind_Method : RDI_TypeKind_Function;
type->byte_size = cu->address_size; type->byte_size = cu->address_size;
type->direct_type = ret_type; type->direct_type = ret_type;
type->count = param_list.count; type->count = param_list.count;
@@ -2330,6 +2338,12 @@ d2r_convert_symbols(Arena *arena,
d2r_tag_iterator_skip_children(it); d2r_tag_iterator_skip_children(it);
} break; } break;
case DW_TagKind_SubProgram: { case DW_TagKind_SubProgram: {
// handled during type conversion step
if (dw_tag_has_attrib(input, cu, tag, DW_AttribKind_Declaration)) {
d2r_tag_iterator_skip_children(it);
break;
}
DW_InlKind inl = DW_Inl_NotInlined; DW_InlKind inl = DW_Inl_NotInlined;
if (dw_tag_has_attrib(input, cu, tag, DW_AttribKind_Inline)) { inl = dw_const_u64_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Inline); } if (dw_tag_has_attrib(input, cu, tag, DW_AttribKind_Inline)) { inl = dw_const_u64_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Inline); }
@@ -2354,6 +2368,12 @@ d2r_convert_symbols(Arena *arena,
RDIM_Type *container_type = 0; RDIM_Type *container_type = 0;
if (dw_tag_has_attrib(input, cu, tag, DW_AttribKind_ContainingType)) { if (dw_tag_has_attrib(input, cu, tag, DW_AttribKind_ContainingType)) {
container_type = d2r_type_from_attrib(type_table, input, cu, tag, DW_AttribKind_ContainingType); container_type = d2r_type_from_attrib(type_table, input, cu, tag, DW_AttribKind_ContainingType);
} else {
DW_TagNode *parent = d2r_tag_iterator_parent_tag_node(it);
container_type = d2r_type_from_offset(type_table, parent->tag.info_off);
if (container_type == 0) {
log_user_errorf("ERROR: failed to infer parent type of subprogram from .debug_info+0x%llx\n", parent->tag.info_off);
}
} }
// get frame base expression // get frame base expression
@@ -2380,13 +2400,19 @@ d2r_convert_symbols(Arena *arena,
// sub program with user-defined parent tag is a method // sub program with user-defined parent tag is a method
DW_Tag parent_tag = d2r_tag_iterator_parent_tag(it); DW_Tag parent_tag = d2r_tag_iterator_parent_tag(it);
if (parent_tag.kind == DW_TagKind_ClassType || parent_tag.kind == DW_TagKind_StructureType) { if (parent_tag.kind == DW_TagKind_ClassType || parent_tag.kind == DW_TagKind_StructureType) {
RDI_MemberKind member_kind = RDI_MemberKind_NULL; // DW_VirtualityKind -> RDI_MemberKind
DW_VirtualityKind virtuality = dw_const_u64_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Virtuality); RDI_MemberKind member_kind = RDI_MemberKind_NULL;
switch (virtuality) { {
case DW_VirtualityKind_None: member_kind = RDI_MemberKind_Method; break; DW_VirtualityKind virtuality = DW_VirtualityKind_None;
case DW_VirtualityKind_Virtual: member_kind = RDI_MemberKind_VirtualMethod; break; if (dw_tag_has_attrib(input, cu, tag, DW_AttribKind_Virtuality)) {
case DW_VirtualityKind_PureVirtual: member_kind = RDI_MemberKind_VirtualMethod; break; // TODO: create kind for pure virutal virtuality = dw_const_u64_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Virtuality);
default: { log_user_errorf("unhandled virtuality kind"); } break; switch (virtuality) {
case DW_VirtualityKind_None: member_kind = RDI_MemberKind_Method; break;
case DW_VirtualityKind_Virtual: member_kind = RDI_MemberKind_VirtualMethod; break;
case DW_VirtualityKind_PureVirtual: member_kind = RDI_MemberKind_VirtualMethod; break; // TODO: create kind for pure virutal
default: { log_user_errorf("unhandled virtuality kind"); } break;
}
}
} }
RDIM_Type *type = d2r_type_from_offset(type_table, parent_tag.info_off); RDIM_Type *type = d2r_type_from_offset(type_table, parent_tag.info_off);
@@ -2504,7 +2530,6 @@ d2r_convert_symbols(Arena *arena,
var->type = type; var->type = type;
var->offset = voff; var->offset = voff;
var->container_symbol = 0; var->container_symbol = 0;
var->container_type = 0; // TODO: NotImplemented;
} }
} break; } break;
case DW_TagKind_FormalParameter: { case DW_TagKind_FormalParameter: {
+5 -5
View File
@@ -320,7 +320,7 @@ T_BeginTest(d2r_checksums)
} }
T_EndTest; T_EndTest;
#if 0 #if SUBPROGRAM_CONVERSION_TEST
T_BeginTest(d2r_subprogram) T_BeginTest(d2r_subprogram)
{ {
DW_Writer *writer = dw_writer_begin(DW_Format_32Bit, DW_Version_5, DW_CompUnitKind_Compile, Arch_x64); DW_Writer *writer = dw_writer_begin(DW_Format_32Bit, DW_Version_5, DW_CompUnitKind_Compile, Arch_x64);
@@ -404,17 +404,17 @@ T_BeginTest(d2r_subprogram)
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
DW_WriterTag *my_struct_type = dw_writer_declare_tag(writer); DW_WriterTag *my_struct_type = dw_writer_tag_reserve(writer, DW_TagKind_StructureType);
DW_WriterTag *const_my_struct_type = dw_writer_tag_begin(writer, DW_TagKind_ConstType); DW_WriterTag *const_my_struct_type = dw_writer_tag_begin(writer, DW_TagKind_ConstType);
dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, my_struct_type); dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, my_struct_type);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
dw_writer_tag_begin(writer, DW_TagKind_PointerType); DW_WriterTag *my_struct_ptr_type = dw_writer_tag_begin(writer, DW_TagKind_PointerType);
dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, const_my_struct_type); dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, const_my_struct_type);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
dw_writer_tag_begin_define(writer, DW_TagKind_StructureType, my_struct_type); dw_writer_tag_begin_reserved(writer, my_struct_type);
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "MyStructure"); dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "MyStructure");
dw_writer_push_attrib_uint (writer, DW_AttribKind_ByteSize, 0x100); dw_writer_push_attrib_uint (writer, DW_AttribKind_ByteSize, 0x100);
@@ -423,7 +423,7 @@ T_BeginTest(d2r_subprogram)
dw_writer_push_attrib_ref (writer, DW_AttribKind_Type, int_ptr_type); dw_writer_push_attrib_ref (writer, DW_AttribKind_Type, int_ptr_type);
dw_writer_tag_begin(writer, DW_TagKind_FormalParameter); dw_writer_tag_begin(writer, DW_TagKind_FormalParameter);
dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, my_method_this_type); dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, my_struct_ptr_type);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);