test basic types

This commit is contained in:
Nikita Smith
2026-02-18 19:16:51 -08:00
parent 09f02f7d08
commit d26c890246
4 changed files with 260 additions and 47 deletions
+3
View File
@@ -196,11 +196,14 @@ internal DW_WriterAttrib * dw_writer_push_attrib_uint (DW_Writer *writer,
internal DW_WriterAttrib * dw_writer_push_attrib_enum (DW_Writer *writer, DW_AttribKind kind, S64 e ); internal DW_WriterAttrib * dw_writer_push_attrib_enum (DW_Writer *writer, DW_AttribKind kind, S64 e );
internal DW_WriterAttrib * dw_writer_push_attrib_ref (DW_Writer *writer, DW_AttribKind kind, DW_WriterTag *ref ); internal DW_WriterAttrib * dw_writer_push_attrib_ref (DW_Writer *writer, DW_AttribKind kind, DW_WriterTag *ref );
internal DW_WriterAttrib * dw_writer_push_attrib_exprloc (DW_Writer *writer, DW_AttribKind kind, String8 exprloc ); internal DW_WriterAttrib * dw_writer_push_attrib_exprloc (DW_Writer *writer, DW_AttribKind kind, String8 exprloc );
internal DW_WriterAttrib * dw_writer_push_attrib_expression (DW_Writer *writer, DW_AttribKind kind, DW_ExprEnc *encs, U64 encs_count);
internal DW_WriterAttrib * dw_writer_push_attrib_line_ptr (DW_Writer *writer, DW_AttribKind kind, void * line_ptr ); internal DW_WriterAttrib * dw_writer_push_attrib_line_ptr (DW_Writer *writer, DW_AttribKind kind, void * line_ptr );
internal DW_WriterAttrib * dw_writer_push_attrib_mac_ptr (DW_Writer *writer, DW_AttribKind kind, void * mac_ptr ); internal DW_WriterAttrib * dw_writer_push_attrib_mac_ptr (DW_Writer *writer, DW_AttribKind kind, void * mac_ptr );
internal DW_WriterAttrib * dw_writer_push_attrib_rng_list_ptr(DW_Writer *writer, DW_AttribKind kind, void * rng_list_ptr); internal DW_WriterAttrib * dw_writer_push_attrib_rng_list_ptr(DW_Writer *writer, DW_AttribKind kind, void * rng_list_ptr);
internal DW_WriterAttrib * dw_writer_push_attrib_implicit (DW_Writer *writer, DW_AttribKind kind, S64 implicit ); internal DW_WriterAttrib * dw_writer_push_attrib_implicit (DW_Writer *writer, DW_AttribKind kind, S64 implicit );
#define dw_writer_push_attrib_expressionv(w, k, ...) dw_writer_push_attrib_expression(w, k, (DW_ExprEnc[]){ __VA_ARGS__ }, ArrayCount(((DW_ExprEnc[]){ __VA_ARGS__ })) )
internal void dw_writer_emit(DW_Writer *writer); internal void dw_writer_emit(DW_Writer *writer);
#ifdef OBJ_H #ifdef OBJ_H
internal void dw_writer_emit_to_obj(DW_Writer *writer, OBJ *obj); internal void dw_writer_emit_to_obj(DW_Writer *writer, OBJ *obj);
+43 -21
View File
@@ -1566,7 +1566,7 @@ d2r_is_type_tag_converted(DW_TagNode *tag_node)
} }
internal RDIM_Type * internal RDIM_Type *
d2r_find_or_convert_type(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Language cu_lang, DW_Tag tag, DW_AttribKind kind) d2r_find_or_convert_type(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Language cu_lang, Arch arch, DW_Tag tag, DW_AttribKind kind)
{ {
RDIM_Type *type = type_table->builtin_types[RDI_TypeKind_Void]; RDIM_Type *type = type_table->builtin_types[RDI_TypeKind_Void];
@@ -1589,7 +1589,7 @@ d2r_find_or_convert_type(Arena *arena, D2R_TypeTable *type_table, DW_Input *inpu
if (type == 0) { if (type == 0) {
// issue type conversion // issue type conversion
DW_TagNode *ref_node = dw_tag_node_from_info_off(cu, ref.info_off); DW_TagNode *ref_node = dw_tag_node_from_info_off(cu, ref.info_off);
d2r_convert_types(arena, type_table, input, cu, cu_lang, ref_node); d2r_convert_types(arena, type_table, input, cu, cu_lang, arch, ref_node);
// if we do not have a converted type at this point then debug info is malformed // if we do not have a converted type at this point then debug info is malformed
type = d2r_type_from_offset(type_table, ref.info_off); type = d2r_type_from_offset(type_table, ref.info_off);
@@ -1614,6 +1614,7 @@ d2r_convert_types(Arena *arena,
DW_Input *input, DW_Input *input,
DW_CompUnit *cu, DW_CompUnit *cu,
DW_Language cu_lang, DW_Language cu_lang,
Arch arch,
DW_TagNode *root) DW_TagNode *root)
{ {
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
@@ -1639,7 +1640,7 @@ d2r_convert_types(Arena *arena,
Assert(!tag_node->first_child); Assert(!tag_node->first_child);
d2r_tag_iterator_skip_children(it); d2r_tag_iterator_skip_children(it);
} else { } else {
RDIM_Type *direct_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, tag, DW_AttribKind_Type); RDIM_Type *direct_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch, tag, DW_AttribKind_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->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->kind = RDI_TypeKind_Class; type->kind = RDI_TypeKind_Class;
@@ -1697,7 +1698,7 @@ d2r_convert_types(Arena *arena,
log_user_errorf("childless enum @ .debug_info+%llx", tag.info_off); log_user_errorf("childless enum @ .debug_info+%llx", tag.info_off);
} }
} else { } else {
RDIM_Type *enum_base_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, tag, DW_AttribKind_Type); RDIM_Type *enum_base_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch, tag, DW_AttribKind_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->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->kind = RDI_TypeKind_Enum; type->kind = RDI_TypeKind_Enum;
@@ -1706,7 +1707,7 @@ d2r_convert_types(Arena *arena,
} }
} break; } break;
case DW_TagKind_SubroutineType: { case DW_TagKind_SubroutineType: {
RDIM_Type *ret_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, 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);
// collect parameters // collect parameters
RDIM_TypeList param_list = {0}; RDIM_TypeList param_list = {0};
@@ -1732,7 +1733,7 @@ d2r_convert_types(Arena *arena,
d2r_tag_iterator_skip_children(it); d2r_tag_iterator_skip_children(it);
} break; } break;
case DW_TagKind_Typedef: { case DW_TagKind_Typedef: {
RDIM_Type *direct_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, tag, DW_AttribKind_Type); RDIM_Type *direct_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch, tag, DW_AttribKind_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_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);
@@ -1757,25 +1758,43 @@ d2r_convert_types(Arena *arena,
case DW_ATE_Boolean: kind = RDI_TypeKind_Bool; break; case DW_ATE_Boolean: kind = RDI_TypeKind_Bool; break;
case DW_ATE_ComplexFloat: { case DW_ATE_ComplexFloat: {
switch (byte_size) { switch (byte_size) {
case 4: kind = RDI_TypeKind_ComplexF32; break; case 8: kind = RDI_TypeKind_ComplexF32; break;
case 8: kind = RDI_TypeKind_ComplexF64; break; case 16: kind = RDI_TypeKind_ComplexF64; break;
case 10: kind = RDI_TypeKind_ComplexF80; break; case 24: kind = RDI_TypeKind_ComplexF80; break;
case 16: kind = RDI_TypeKind_ComplexF128; break; case 32: kind = RDI_TypeKind_ComplexF128; break;
default: log_user_errorf("unexpected size"); break; default: log_user_errorf("unexpected size"); break;
} }
} break; } break;
case DW_ATE_Float: { case DW_ATE_Float: {
String8 name = dw_string_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Name);
if (arch == Arch_x64 || arch == Arch_arm64) {
if (str8_match(name, str8_lit("__float80"), 0)) {
kind = RDI_TypeKind_F80;
} else if (str8_match(name, str8_lit("__float128"), 0)) {
kind = RDI_TypeKind_F128;
} else if (str8_match(name, str8_lit("_Float16"), 0)) {
kind = RDI_TypeKind_F16;
} else if (str8_match(name, str8_lit("__bf16"), 0)) {
NotImplemented;
}
if (kind != RDI_TypeKind_NULL) { break; }
}
switch (byte_size) { switch (byte_size) {
D2R_ValueType_Float_XList D2R_ValueType_Float_XList
default: log_user_errorf("unexpected size"); break; default: log_user_errorf("unexpected size"); break;
} }
} break; } break;
case DW_ATE_Signed: { case DW_ATE_Signed: {
String8 name = dw_string_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Name);
if (str8_match(name, str8_lit("wchar_t"), 0)) { goto do_signed_char; }
switch (byte_size) { switch (byte_size) {
D2R_ValueType_Signed_XList D2R_ValueType_Signed_XList
default: log_user_errorf("unexpected size"); break; default: log_user_errorf("unexpected size"); break;
} }
} break; } break;
do_signed_char:;
case DW_ATE_SignedChar: { case DW_ATE_SignedChar: {
switch (byte_size) { switch (byte_size) {
case 1: kind = RDI_TypeKind_Char8; break; case 1: kind = RDI_TypeKind_Char8; break;
@@ -1790,6 +1809,7 @@ d2r_convert_types(Arena *arena,
default: log_user_errorf("unexpected size"); break; default: log_user_errorf("unexpected size"); break;
} }
} break; } break;
case DW_ATE_Utf:
case DW_ATE_UnsignedChar: { case DW_ATE_UnsignedChar: {
switch (byte_size) { switch (byte_size) {
case 1: kind = RDI_TypeKind_UChar8; break; case 1: kind = RDI_TypeKind_UChar8; break;
@@ -1819,9 +1839,6 @@ d2r_convert_types(Arena *arena,
case DW_ATE_DecimalFloat: { case DW_ATE_DecimalFloat: {
NotImplemented; NotImplemented;
} break; } break;
case DW_ATE_Utf: {
NotImplemented;
} break;
case DW_ATE_Ucs: { case DW_ATE_Ucs: {
NotImplemented; NotImplemented;
} break; } break;
@@ -1839,7 +1856,7 @@ d2r_convert_types(Arena *arena,
type->byte_size = byte_size; type->byte_size = byte_size;
} break; } break;
case DW_TagKind_PointerType: { case DW_TagKind_PointerType: {
RDIM_Type *direct_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, tag, DW_AttribKind_Type); RDIM_Type *direct_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch, tag, DW_AttribKind_Type);
// TODO: // TODO:
if (dw_tag_has_attrib(input, cu, tag, DW_AttribKind_Allocated)) { if (dw_tag_has_attrib(input, cu, tag, DW_AttribKind_Allocated)) {
@@ -1877,7 +1894,7 @@ d2r_convert_types(Arena *arena,
log_infof("TODO: handle name attrib @ .debug_info+%llx", tag.info_off); log_infof("TODO: handle name attrib @ .debug_info+%llx", tag.info_off);
} }
RDIM_Type *direct_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, tag, DW_AttribKind_Type); RDIM_Type *direct_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch, tag, DW_AttribKind_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_Modifier; type->kind = RDI_TypeKind_Modifier;
type->byte_size = cu->address_size; type->byte_size = cu->address_size;
@@ -1889,7 +1906,7 @@ d2r_convert_types(Arena *arena,
log_infof("TODO: handle name attrib @ .debug_info+%llx", tag.info_off); log_infof("TODO: handle name attrib @ .debug_info+%llx", tag.info_off);
} }
RDIM_Type *direct_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, tag, DW_AttribKind_Type); RDIM_Type *direct_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch, tag, DW_AttribKind_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_Modifier; type->kind = RDI_TypeKind_Modifier;
type->byte_size = cu->address_size; type->byte_size = cu->address_size;
@@ -1904,7 +1921,7 @@ d2r_convert_types(Arena *arena,
log_infof("TODO: handle alignment attrib @ .debug_info+%llx", tag.info_off); log_infof("TODO: handle alignment attrib @ .debug_info+%llx", tag.info_off);
} }
RDIM_Type *direct_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, tag, DW_AttribKind_Type); RDIM_Type *direct_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch, tag, DW_AttribKind_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_Modifier; type->kind = RDI_TypeKind_Modifier;
type->byte_size = cu->address_size; type->byte_size = cu->address_size;
@@ -1980,7 +1997,7 @@ d2r_convert_types(Arena *arena,
SLLStackPush(subrange_stack, s); SLLStackPush(subrange_stack, s);
} }
RDIM_Type *array_base_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, tag, DW_AttribKind_Type); RDIM_Type *array_base_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch, tag, DW_AttribKind_Type);
RDIM_Type *direct_type = array_base_type; RDIM_Type *direct_type = array_base_type;
U64 size_cursor = array_base_type->byte_size; U64 size_cursor = array_base_type->byte_size;
for EachNode(s, struct SubrangeNode, subrange_stack) { for EachNode(s, struct SubrangeNode, subrange_stack) {
@@ -2016,7 +2033,7 @@ d2r_convert_types(Arena *arena,
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_StructureType || parent_tag.kind == DW_TagKind_ClassType) { if (parent_tag.kind == DW_TagKind_StructureType || parent_tag.kind == DW_TagKind_ClassType) {
RDIM_Type *parent = d2r_type_from_offset(type_table, parent_tag.info_off); RDIM_Type *parent = d2r_type_from_offset(type_table, parent_tag.info_off);
RDIM_Type *type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, tag, DW_AttribKind_Type); RDIM_Type *type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch, tag, DW_AttribKind_Type);
RDIM_UDTMember *member = rdim_udt_push_member(arena, &g_d2r_shared.udts, parent->udt); RDIM_UDTMember *member = rdim_udt_push_member(arena, &g_d2r_shared.udts, parent->udt);
member->kind = RDI_MemberKind_Base; member->kind = RDI_MemberKind_Base;
member->type = type; member->type = type;
@@ -2965,6 +2982,11 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
type->byte_size = rdi_size_from_basic_type_kind(type_kind); type->byte_size = rdi_size_from_basic_type_kind(type_kind);
builtin_types[type_kind] = type; builtin_types[type_kind] = type;
} }
// fixup float80 size
if (arch == Arch_x64 || arch == Arch_arm64) {
builtin_types[RDI_TypeKind_F80]->byte_size = 16;
}
builtin_types[RDI_TypeKind_Void]->byte_size = rdi_addr_size_from_arch(g_d2r_shared.top_level_info.arch); builtin_types[RDI_TypeKind_Void]->byte_size = rdi_addr_size_from_arch(g_d2r_shared.top_level_info.arch);
builtin_types[RDI_TypeKind_Handle]->byte_size = rdi_addr_size_from_arch(g_d2r_shared.top_level_info.arch); builtin_types[RDI_TypeKind_Handle]->byte_size = rdi_addr_size_from_arch(g_d2r_shared.top_level_info.arch);
@@ -3011,7 +3033,7 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
type_table->builtin_types = builtin_types; type_table->builtin_types = builtin_types;
// convert debug info // convert debug info
d2r_convert_types(arena, type_table, &input, cu, cu_lang, tag_tree.root); d2r_convert_types(arena, type_table, &input, cu, cu_lang, arch, tag_tree.root);
d2r_convert_udts(arena, type_table, &input, cu, cu_lang, tag_tree.root); d2r_convert_udts(arena, type_table, &input, cu, cu_lang, tag_tree.root);
d2r_convert_symbols(arena, type_table, global_scope, &input, cu, cu_lang, image_base, arch, tag_tree.root); d2r_convert_symbols(arena, type_table, global_scope, &input, cu, cu_lang, image_base, arch, tag_tree.root);
+2 -2
View File
@@ -241,8 +241,8 @@ internal DW_Tag d2r_tag_iterator_parent_tag (D2R_TagIterator *ite
internal void d2r_flag_converted_tag(DW_TagNode *tag_node); internal void d2r_flag_converted_tag(DW_TagNode *tag_node);
internal B8 d2r_is_tag_converted (DW_TagNode *tag_node); internal B8 d2r_is_tag_converted (DW_TagNode *tag_node);
internal RDIM_Type * d2r_find_or_convert_type(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Language cu_lang, DW_Tag tag, DW_AttribKind kind); internal RDIM_Type * d2r_find_or_convert_type(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Language cu_lang, Arch arch, DW_Tag tag, DW_AttribKind kind);
internal void d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Language cu_lang, DW_TagNode *root); internal void d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Language cu_lang, Arch arch, DW_TagNode *root);
//////////////////////////////// ////////////////////////////////
//~ UDT Conversion //~ UDT Conversion
+212 -24
View File
@@ -25,10 +25,13 @@ d2r_rdi_from_dwarf_writer(Arena *arena, DW_Writer *writer)
String8 exe = t_read_file(scratch.arena, str8_lit("a.exe")); String8 exe = t_read_file(scratch.arena, str8_lit("a.exe"));
Assert(exe.size > 0); Assert(exe.size > 0);
B32 was_pdb_deleted = os_delete_file_at_path(t_make_file_path(scratch.arena, str8_lit("a.pdb")));
Assert(was_pdb_deleted);
t_invoke(str8_lit("radbin.exe"), str8_lit("-rdi a.exe"), max_U64); t_invoke(str8_lit("radbin.exe"), str8_lit("-rdi a.exe"), max_U64);
Assert(g_last_exit_code == 0); Assert(g_last_exit_code == 0);
String8 raw_rdi = t_read_file(scratch.arena, str8_lit("a.rdi")); String8 raw_rdi = t_read_file(arena, str8_lit("a.rdi"));
Assert(raw_rdi.size > 0); Assert(raw_rdi.size > 0);
RDI_Parsed *rdi = push_array(arena, RDI_Parsed, 1); RDI_Parsed *rdi = push_array(arena, RDI_Parsed, 1);
@@ -39,36 +42,221 @@ d2r_rdi_from_dwarf_writer(Arena *arena, DW_Writer *writer)
return rdi; return rdi;
} }
internal RDI_TypeNode *
d2rt_type_from_name(RDI_Parsed *rdi, RDI_ParsedNameMap *map, char *name)
{
String8 s = str8_cstring(name);
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, map, s.str, s.size);
U32 id_count = 0;
U32 *ids = rdi_matches_from_map_node(rdi, node, &id_count);
if (id_count == 1) {
return rdi_element_from_name_idx(rdi, TypeNodes, ids[0]);
}
return 0;
}
T_BeginTest(d2r_types)
{
DW_Writer *writer = dw_writer_begin(DW_Format_32Bit, DW_Version_5, DW_CompUnitKind_Compile, Arch_x64);
{
dw_writer_tag_begin(writer, DW_TagKind_CompileUnit);
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Producer, "Test");
#define DeclBaseType(tt, n, e, s) \
DW_WriterTag *tt = dw_writer_tag_begin(writer, DW_TagKind_BaseType); \
dw_writer_push_attrib_sint(writer, DW_AttribKind_ByteSize, s); \
dw_writer_push_attrib_enum(writer, DW_AttribKind_Encoding, DW_ATE_##e); \
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, n); \
dw_writer_tag_end(writer);
DeclBaseType(char_type, "char", SignedChar, 1);
DeclBaseType(unsigned_char_type, "unsigned char", UnsignedChar, 1);
DeclBaseType(char8_type, "char8_t", Utf, 1);
DeclBaseType(char16_type, "char16_t", Utf, 2);
DeclBaseType(char32_type, "char32_t", Utf, 4);
DeclBaseType(wchar_type, "wchar_t", Signed, 4);
DeclBaseType(bool_type, "_Bool", Boolean, 1);
DeclBaseType(short_type, "short", Signed, 2);
DeclBaseType(unsigned_short_type, "unsigned short", Unsigned, 2);
DeclBaseType(short_unsigned_int_type, "short unsigned int", Unsigned, 2);
DeclBaseType(short_int_type, "short int", Signed, 2);
DeclBaseType(unsigned_int_type, "unsigned int", Unsigned, 4);
DeclBaseType(int_type, "int", Signed, 4);
DeclBaseType(long_int_type, "long int", Signed, 8);
DeclBaseType(long_unsigned_int_type, "long unsigned int", Unsigned, 8);
DeclBaseType(long_long_int_type, "long long int", Signed, 8);
DeclBaseType(long_long_unsigned_int, "long long unsigned int", Unsigned, 8);
DeclBaseType(float_type, "float", Float, 4);
DeclBaseType(double_type, "double", Float, 8);
DeclBaseType(long_double_type, "long double", Float, 16);
DeclBaseType(float16_type, "_Float16", Float, 2);
DeclBaseType(float80_type, "__float80", Float, 16);
DeclBaseType(float128_type, "_float128", Float, 16);
DeclBaseType(complex_float, "complex float", ComplexFloat, 8);
DeclBaseType(complex_doulbe, "complex double", ComplexFloat, 16);
DeclBaseType(complex_long_double, "complex long double", ComplexFloat, 32);
//DeclBaseType("__bf16", Float, 2);
#undef DeclBaseType
#define DeclStdint(n, a) \
do { \
dw_writer_tag_begin(writer, DW_TagKind_Typedef); \
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, n); \
dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, a); \
dw_writer_tag_end(writer); \
} while (0)
DeclStdint("uint8_t", unsigned_char_type);
DeclStdint("uint16_t", unsigned_short_type);
DeclStdint("uint32_t", unsigned_int_type);
DeclStdint("uint64_t", long_unsigned_int_type);
DeclStdint("int8_t", char_type);
DeclStdint("int16_t", short_type);
DeclStdint("int32_t", int_type);
DeclStdint("int64_t", long_int_type);
#undef DeclStdInt
dw_writer_tag_end(writer);
}
RDI_Parsed *rdi = d2r_rdi_from_dwarf_writer(scratch.arena, writer);
RDI_NameMap *types_nm = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Types);
T_Ok(types_nm);
RDI_ParsedNameMap types_map = {0};
rdi_parsed_from_name_map(rdi, types_nm, &types_map);
#define TestBuiltinType(n, bs, r) \
do { \
RDI_TypeNode *alias = d2rt_type_from_name(rdi, &types_map, n); \
T_Ok(alias); \
T_Ok(alias->kind == RDI_TypeKind_Alias); \
T_Ok(alias->flags == 0); \
T_Ok(alias->byte_size == bs); \
RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, alias->user_defined.direct_type_idx); \
T_Ok(type); \
T_Ok(type->kind == RDI_TypeKind_##r); \
T_Ok(type->flags == 0); \
T_Ok(type->byte_size == alias->byte_size); \
T_Ok(str8_match(str8_from_rdi_string_idx(rdi, type->built_in.name_string_idx), str8_lit(Stringify(r)), 0)); \
} while (0)
TestBuiltinType("char", 1, Char8);
TestBuiltinType("char8_t", 1, UChar8);
TestBuiltinType("char16_t", 2, UChar16);
TestBuiltinType("char32_t", 4, UChar32);
TestBuiltinType("unsigned char", 1, UChar8);
TestBuiltinType("wchar_t", 4, Char32);
TestBuiltinType("_Bool", 1, Bool);
TestBuiltinType("short", 2, S16);
TestBuiltinType("unsigned short", 2, U16);
TestBuiltinType("short unsigned int", 2, U16);
TestBuiltinType("short int", 2, S16);
TestBuiltinType("unsigned int", 4, U32);
TestBuiltinType("int", 4, S32);
TestBuiltinType("long int", 8, S64);
TestBuiltinType("long unsigned int", 8, U64);
TestBuiltinType("long long int", 8, S64);
TestBuiltinType("float", 4, F32);
TestBuiltinType("double", 8, F64);
TestBuiltinType("long double", 16, F128);
TestBuiltinType("_Float16", 2, F16);
TestBuiltinType("__float80", 16, F80);
TestBuiltinType("_float128", 16, F128);
TestBuiltinType("complex float", 8, ComplexF32);
TestBuiltinType("complex double", 16, ComplexF64);
TestBuiltinType("complex long double", 32, ComplexF128);
// TODO: bfloat16
//TestBuiltinType("__bf16", 2, BF16);
#undef TestBuiltinType
#define TestStdint(n, s, t) \
do { \
RDI_TypeNode *td = d2rt_type_from_name(rdi, &types_map, n); \
T_Ok(td); \
T_Ok(td->kind == RDI_TypeKind_Alias); \
T_Ok(td->flags == 0); \
T_Ok(td->byte_size == s); \
RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, td->user_defined.direct_type_idx); \
T_Ok(type); \
T_Ok(type->kind == RDI_TypeKind_Alias); \
T_Ok(type->flags == 0); \
T_Ok(type->byte_size = td->byte_size); \
T_Ok(str8_match(str8_from_rdi_string_idx(rdi, type->built_in.name_string_idx), str8_lit(t), 0)); \
} while (0)
TestStdint("uint8_t", 1, "unsigned char");
TestStdint("uint16_t", 2, "unsigned short");
TestStdint("uint32_t", 4, "unsigned int");
TestStdint("uint64_t", 8, "long unsigned int");
TestStdint("int8_t", 1, "char");
TestStdint("int16_t", 2, "short");
TestStdint("int32_t", 4, "int");
TestStdint("int64_t", 8, "long int");
#undef TestStdint
dw_writer_end(&writer);
}
T_EndTest;
T_BeginTest(d2r_general) T_BeginTest(d2r_general)
{ {
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);
dw_writer_tag_begin(writer, DW_TagKind_CompileUnit); {
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Producer, "Test"); dw_writer_tag_begin(writer, DW_TagKind_CompileUnit);
// declare char type dw_writer_push_attrib_stringf(writer, DW_AttribKind_Producer, "Test");
DW_WriterTag *char_type = dw_writer_tag_begin(writer, DW_TagKind_BaseType); // declare char type
dw_writer_push_attrib_sint(writer, DW_AttribKind_ByteSize, 1); DW_WriterTag *char_type = dw_writer_tag_begin(writer, DW_TagKind_BaseType);
dw_writer_push_attrib_enum(writer, DW_AttribKind_Encoding, DW_ATE_SignedChar); dw_writer_push_attrib_sint(writer, DW_AttribKind_ByteSize, 1);
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "char"); dw_writer_push_attrib_enum(writer, DW_AttribKind_Encoding, DW_ATE_SignedChar);
dw_writer_tag_end(writer); dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "char");
// declare function
dw_writer_tag_begin(writer, DW_TagKind_SubProgram);
dw_writer_push_attrib_address(writer, DW_AttribKind_LowPc, 0x140173f9);
dw_writer_push_attrib_address(writer, DW_AttribKind_HighPc, 0x14017474b);
dw_writer_push_attrib_flag(writer, DW_AttribKind_External, 1);
dw_writer_push_attrib_flag(writer, DW_AttribKind_Prototyped, 1);
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "FooBar");
// declare variable
dw_writer_tag_begin(writer, DW_TagKind_Variable);
dw_writer_push_attrib_expression(writer, DW_AttribKind_Location, &(DW_ExprEnc)DW_ExprEnc_Op(Reg7), 1);
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "TestLocal");
dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, char_type);
dw_writer_tag_end(writer); dw_writer_tag_end(writer);
dw_writer_tag_end(writer); // declare function
dw_writer_tag_begin(writer, DW_TagKind_SubProgram);
dw_writer_push_attrib_address(writer, DW_AttribKind_LowPc, 0x140173f9);
dw_writer_push_attrib_address(writer, DW_AttribKind_HighPc, 0x14017474b);
dw_writer_push_attrib_flag(writer, DW_AttribKind_External, 1);
dw_writer_push_attrib_flag(writer, DW_AttribKind_Prototyped, 1);
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "FooBar");
// declare variable
dw_writer_tag_begin(writer, DW_TagKind_Variable);
dw_writer_push_attrib_expressionv(writer, DW_AttribKind_Location, DW_ExprEnc_Op(Reg7));
dw_writer_push_attrib_stringf(writer, DW_AttribKind_Name, "TestLocal");
dw_writer_push_attrib_ref(writer, DW_AttribKind_Type, char_type);
dw_writer_tag_end(writer);
dw_writer_tag_end(writer);
}
RDI_Parsed *rdi = d2r_rdi_from_dwarf_writer(scratch.arena, writer); RDI_Parsed *rdi = d2r_rdi_from_dwarf_writer(scratch.arena, writer);
RDI_Procedure *proc_name = rdi_procedure_from_name_cstr(rdi, "FooBar"); RDI_Procedure *proc = rdi_procedure_from_name_cstr(rdi, "FooBar");
T_Ok(proc_name); T_Ok(proc);
T_Ok(proc->link_flags == RDI_LinkFlag_External);
String8 proc_name = str8_from_rdi_string_idx(rdi, proc->name_string_idx);
T_Ok(str8_match(proc_name, str8_lit("FooBar"), 0));
RDI_Scope *root_scope = rdi_root_scope_from_procedure(rdi, proc);
T_Ok(root_scope);
T_Ok(root_scope->local_count == 1);
RDI_Local *test_local = rdi_element_from_name_idx(rdi, Locals, root_scope->local_first + 0);
T_Ok(test_local);
T_Ok(test_local->kind == RDI_LocalKind_Variable);
String8 test_local_name = str8_from_rdi_string_idx(rdi, test_local->name_string_idx);
T_Ok(str8_match(test_local_name, str8_lit("TestLocal"), 0));
RDI_TypeNode *test_local_type = rdi_element_from_name_idx(rdi, TypeNodes, test_local->type_idx);
T_Ok(test_local_type);
T_Ok(test_local_type->kind == RDI_TypeKind_Alias);
T_Ok(test_local_type->flags == 0);
String8 alias_name = str8_from_rdi_string_idx(rdi, test_local_type->user_defined.name_string_idx);
T_Ok(str8_match(alias_name, str8_lit("char"), 0));
RDI_TypeNode *char_type = rdi_element_from_name_idx(rdi, TypeNodes, test_local_type->user_defined.direct_type_idx);
T_Ok(char_type);
T_Ok(char_type->kind == RDI_TypeKind_Char8);
T_Ok(char_type->flags == 0);
T_Ok(char_type->byte_size == 1);
String8 char_type_name = str8_from_rdi_string_idx(rdi, char_type->built_in.name_string_idx);
T_Ok(str8_match(char_type_name, str8_lit("Char8"), 0));
dw_writer_end(&writer); dw_writer_end(&writer);
} }