d2r2: finished first pass of type conversion; sketched out structure for symbol/unit conversion; plugged everything in

This commit is contained in:
Ryan Fleury
2026-04-27 16:07:07 -07:00
parent ffa41c0a98
commit c6b733de20
4 changed files with 559 additions and 20 deletions
+1 -1
View File
@@ -379,7 +379,7 @@ dw2_read_form_val(DW2_ParseCtx *ctx, String8 data, U64 off, DW_FormKind form_kin
U64 bytes_read = str8_deserial_read_uleb128(data, off, &size);
val.u128.u64[0] = og_read_off + bytes_read;
val.u128.u64[1] = size;
off += bytes_read;
off += size + bytes_read;
}break;
//- rjf: flag present
+1
View File
@@ -60,6 +60,7 @@ struct DW2_ParseCtx
// it can from context.
DW_Version version;
DW_Format format;
DW_Ext ext;
U64 addr_size;
DW2_AbbrevMap *abbrev_map;
DW2_StrOffsetsTable *str_offsets_table;
+3
View File
@@ -956,7 +956,10 @@ rb_thread_entry_point(void *p)
{
bake_params = push_array(arena, RDIM_BakeParams, 1);
rdim_bake_params_concat_in_place(bake_params, &pdb_bake_params);
#if 0
rdim_bake_params_concat_in_place(bake_params, &dwarf_bake_params);
#endif
rdim_bake_params_concat_in_place(bake_params, &dwarf_bake_params_2);
for EachNode(n, RDIM_BakeParamsNode, first_rdi_bake_params)
{
rdim_bake_params_concat_in_place(bake_params, &n->v);
+554 -19
View File
@@ -12,6 +12,7 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
RDIM_BinarySectionList binary_sections = params->binary_sections;
Arch arch = params->arch;
U64 base_vaddr = params->base_vaddr;
U64 arch_addr_size = byte_size_from_arch(arch);
////////////////////////////
//- rjf: determine acceptable address range
@@ -992,7 +993,7 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
}
lane_sync_u64(&builtin_types, 0);
lane_sync_u64(&builtin_type_from_kind_map, 0);
#define d2r2_type_from_builtin_kind(k) ((RDI_TypeKind_FirstBuiltIn <= (k) && (k) <= RDI_TypeKind_LastBuiltIn) ? builtin_types[k - RDI_TypeKind_FirstBuiltIn] : 0)
#define d2r2_type_from_builtin_kind(k) ((RDI_TypeKind_FirstBuiltIn <= (k) && (k) <= RDI_TypeKind_LastBuiltIn) ? builtin_type_from_kind_map[k - RDI_TypeKind_FirstBuiltIn] : builtin_type_from_kind_map[RDI_TypeKind_Void])
////////////////////////////
//- rjf: predict the total number of tags in all units
@@ -1124,19 +1125,31 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
// rjf: record top-level info about this tag tree
if(t_start_off == t->off && t == &start_task)
{
is_type_tag_tree = (tag.kind == DW_TagKind_ArrayType || tag.kind == DW_TagKind_ClassType ||
tag.kind == DW_TagKind_EnumerationType || tag.kind == DW_TagKind_PointerType ||
tag.kind == DW_TagKind_ReferenceType || tag.kind == DW_TagKind_StringType ||
tag.kind == DW_TagKind_StructureType || tag.kind == DW_TagKind_SubroutineType ||
tag.kind == DW_TagKind_Typedef || tag.kind == DW_TagKind_UnionType ||
tag.kind == DW_TagKind_PtrToMemberType || tag.kind == DW_TagKind_SetType ||
tag.kind == DW_TagKind_SubrangeType || tag.kind == DW_TagKind_BaseType ||
tag.kind == DW_TagKind_ConstType || tag.kind == DW_TagKind_FileType ||
tag.kind == DW_TagKind_PackedType || tag.kind == DW_TagKind_VolatileType ||
tag.kind == DW_TagKind_RestrictType || tag.kind == DW_TagKind_InterfaceType ||
tag.kind == DW_TagKind_UnspecifiedType || tag.kind == DW_TagKind_SharedType ||
tag.kind == DW_TagKind_RValueReferenceType || tag.kind == DW_TagKind_CoarrayType ||
tag.kind == DW_TagKind_DynamicType || tag.kind == DW_TagKind_AtomicType ||
is_type_tag_tree = (tag.kind == DW_TagKind_ArrayType ||
tag.kind == DW_TagKind_ClassType ||
tag.kind == DW_TagKind_EnumerationType ||
tag.kind == DW_TagKind_PointerType ||
tag.kind == DW_TagKind_ReferenceType ||
tag.kind == DW_TagKind_StringType ||
tag.kind == DW_TagKind_StructureType ||
tag.kind == DW_TagKind_SubroutineType ||
tag.kind == DW_TagKind_Typedef ||
tag.kind == DW_TagKind_UnionType ||
tag.kind == DW_TagKind_PtrToMemberType ||
tag.kind == DW_TagKind_SetType ||
tag.kind == DW_TagKind_BaseType ||
tag.kind == DW_TagKind_ConstType ||
tag.kind == DW_TagKind_FileType ||
tag.kind == DW_TagKind_PackedType ||
tag.kind == DW_TagKind_VolatileType ||
tag.kind == DW_TagKind_RestrictType ||
tag.kind == DW_TagKind_InterfaceType ||
tag.kind == DW_TagKind_UnspecifiedType ||
tag.kind == DW_TagKind_SharedType ||
tag.kind == DW_TagKind_RValueReferenceType ||
tag.kind == DW_TagKind_CoarrayType ||
tag.kind == DW_TagKind_DynamicType ||
tag.kind == DW_TagKind_AtomicType ||
tag.kind == DW_TagKind_ImmutableType);
}
@@ -1418,8 +1431,8 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
{
TypeDepChain *c = push_array(scratch.arena, TypeDepChain, 1);
c->type_idx = type_tag_node->order_idx;
SLLStackPush(type_dep_chains[type_tag_node->order_idx], c);
type_dep_chains_counts[type_tag_node->order_idx] += 1;
SLLStackPush(type_dep_chains[root_type_idx], c);
type_dep_chains_counts[root_type_idx] += 1;
}
// rjf: unpack unit
@@ -1489,6 +1502,29 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
//- rjf: build all types - build types w/ 1 dependency (leaves) first, then 2, 3, etc.,
// to ensure dependencies always travel backwards
//
// NOTE: * DWARF vs RDI Array Type Graph *
//
// For example lets take following decl:
//
// int (*foo[2])[3];
//
// This compiles to in DWARF:
//
// foo -> DW_TAG_ArrayType -> (A0) DW_TAG_Subrange [2]
// \
// -> (B0) DW_TAG_PointerType -> (A1) DW_TAG_ArrayType -> DW_TAG_Subrange [3]
// \
// -> (B1) DW_TAG_BaseType (int)
//
// RDI expects:
//
// foo -> Array[2] -> Pointer -> Array[3] -> int
//
// Note that DWARF forks the graph on DW_TAG_ArrayType to describe array ranges in branch A and
// in branch B describes array type which might be a struct, pointer, base type, or any other type tag.
// However, in RDI we have a simple list of type nodes and to convert we need to append type nodes from
// B to A.
//
RDIM_TypeChunkList *all_types = 0;
RDIM_Type **type_from_idx_map = 0;
{
@@ -1496,6 +1532,7 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
{
all_types = push_array(scratch.arena, RDIM_TypeChunkList, 1);
type_from_idx_map = push_array(scratch.arena, RDIM_Type *, type_count);
rdim_type_chunk_list_concat_in_place(all_types, builtin_types);
}
lane_sync_u64(&all_types, 0);
lane_sync_u64(&type_from_idx_map, 0);
@@ -1509,16 +1546,25 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
// find this lane's next dependency restriction
U64 next_max_chain_count = max_U64;
RDIM_TypeChunkList lane_types = {0};
U64 lane_types_chunk_count = 256;
for EachInRange(type_idx, range)
{
// rjf: if this type has a higher chain count than the current,
// but it is lower than our next maximum chain count, collect it,
// so we will hit
//
// if this type has a lower chain count than the current,
// we should've already built it from a previous pass.
//
if(type_dep_chains_counts[type_idx] > max_chain_count)
{
next_max_chain_count = Min(type_dep_chains_counts[type_idx], next_max_chain_count);
continue;
}
else if(type_dep_chains_counts[type_idx] < max_chain_count)
{
continue;
}
Temp temp = temp_begin(scratch2.arena);
// rjf: idx -> type tag node
@@ -1532,13 +1578,332 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
// rjf: parse root-level tag
DW2_Tag tag = {0};
dw2_read_tag(temp.arena, unit_parse_ctx, raw->sec[DW_Section_Info].data, info_off, &tag);
U64 tag_info_size = dw2_read_tag(temp.arena, unit_parse_ctx, raw->sec[DW_Section_Info].data, info_off, &tag);
// rjf: extract common attributes
DW2_Attrib *name_attrib = &dw2_attrib_nil;
DW2_Attrib *direct_type_attrib = &dw2_attrib_nil;
DW2_Attrib *bitsize_attrib = &dw2_attrib_nil;
DW2_Attrib *bytesize_attrib = &dw2_attrib_nil;
DW2_Attrib *encoding_attrib = &dw2_attrib_nil;
DW2_Attrib *decl_attrib = &dw2_attrib_nil;
//
// TODO(rjf): if a DW_AttribKing_GNU_Vector is found on an DW_TagKind_ArrayType,
// then: @native_vector_support extract byte size from the base type tag
// and convert to U256, U512, S256 and S512
//
for EachNode(n, DW2_AttribNode, tag.attribs.first)
{
switch(n->v.attrib_kind)
{
default:{}break;
#define Case(dst_name, src_name) case DW_AttribKind_##src_name:{dst_name##_attrib = &n->v;}break
Case(name, Name);
Case(direct_type, Type);
Case(bitsize, BitSize);
Case(bytesize, ByteSize);
Case(encoding, Encoding);
Case(decl, Declaration);
#undef Case
}
}
// rjf: unpack common attributes
String8 name = name_attrib->val.string;
DW_ATE encoding = encoding_attrib->val.u128.u64[0];
RDIM_Type *direct_type = d2r2_type_from_builtin_kind(RDI_TypeKind_Void);
U64 bitsize = 0;
B32 is_decl = (decl_attrib != &dw2_attrib_nil);
{
// rjf: unpack direct type
if(direct_type_attrib != &dw2_attrib_nil)
{
U64 direct_type_info_off = dw2_reference_info_off_from_form_val(unit_parse_ctx, &direct_type_attrib->val);
U64 direct_type_unit_idx = unit_idx;
if(!contains_1u64(unit_info_tag_range, direct_type_info_off))
{
Rng1U64Array unit_info_tag_ranges_array = {unit_info_tag_ranges, unit_count};
U64 new_unit_num = rng1u64_array_num_from_value__binary_search(&unit_info_tag_ranges_array, direct_type_info_off);
direct_type_unit_idx = (new_unit_num > 0 ? new_unit_num-1 : unit_idx);
}
UnitTypeMap *direct_type_unit_type_map = &unit_type_maps[direct_type_unit_idx];
U64 info_off_hash = u64_hash_from_str8(str8_struct(&direct_type_info_off));
U64 info_off_slot_idx = info_off_hash%direct_type_unit_type_map->slots_count;
U64 direct_type_hash = 0;
for(UnitTypeNode *n = direct_type_unit_type_map->slots[info_off_slot_idx]; n != 0; n = n->next)
{
if(n->src_info_off == direct_type_info_off)
{
direct_type_hash = n->dst_hash;
break;
}
}
U64 unique_type_tag_slot_idx = direct_type_hash%unique_type_tag_slots_count;
for(UniqueTypeTagNode *n = unique_type_tag_slots[unique_type_tag_slot_idx]; n != 0; n = n->next)
{
if(n->hash == direct_type_hash)
{
direct_type = type_from_idx_map[n->order_idx];
break;
}
}
}
// rjf: unpack bit/byte sizes
if(bitsize_attrib != &dw2_attrib_nil)
{
bitsize = bitsize_attrib->val.u128.u64[0];
}
else if(bytesize_attrib != &dw2_attrib_nil)
{
bitsize = bytesize_attrib->val.u128.u64[0]*8;
}
}
// rjf: convert type
RDIM_Type *dst_type = 0;
RDI_TypeKind rdi_type_kind = RDI_TypeKind_NULL;
RDI_TypeModifierFlags rdi_type_modifier_flags = 0;
switch(tag.kind)
{
// TODO(rjf)
default:{}break;
case DW_TagKind_ClassType: rdi_type_kind = is_decl ? RDI_TypeKind_IncompleteClass : RDI_TypeKind_Class; goto struct_type;
case DW_TagKind_StructureType: rdi_type_kind = is_decl ? RDI_TypeKind_IncompleteStruct : RDI_TypeKind_Struct; goto struct_type;
case DW_TagKind_UnionType: rdi_type_kind = is_decl ? RDI_TypeKind_IncompleteUnion : RDI_TypeKind_Union; goto struct_type;
struct_type:;
{
dst_type = rdim_type_chunk_list_push(arena, &lane_types, lane_types_chunk_count);
dst_type->kind = rdi_type_kind;
dst_type->name = name;
dst_type->byte_size = bitsize/8;
}break;
case DW_TagKind_EnumerationType:
{
dst_type = rdim_type_chunk_list_push(arena, &lane_types, lane_types_chunk_count);
dst_type->kind = is_decl ? RDI_TypeKind_IncompleteEnum : RDI_TypeKind_Enum;
dst_type->name = name;
dst_type->direct_type = direct_type;
dst_type->byte_size = (direct_type != 0 ? direct_type->byte_size : bitsize/8);
}break;
case DW_TagKind_SubroutineType:
{
}break;
case DW_TagKind_Typedef:
{
dst_type = rdim_type_chunk_list_push(arena, &lane_types, lane_types_chunk_count);
dst_type->kind = RDI_TypeKind_Alias;
dst_type->name = name;
dst_type->direct_type = direct_type;
dst_type->byte_size = (direct_type ? direct_type->byte_size : 0);
}break;
case DW_TagKind_BaseType:
{
if(0){}
#define CaseA(rdi_type_kind_, encoding_) else if(encoding == (encoding_)) { rdi_type_kind = (rdi_type_kind_); }
#define CaseB(rdi_type_kind_, encoding_, bit_size_) else if(encoding == (encoding_) && bitsize == (bit_size_)) { rdi_type_kind = (rdi_type_kind_); }
#define CaseC(rdi_type_kind_, encoding_, name_) /* assumes x64/arm64 */ else if(encoding == (encoding_) && str8_match(name, str8_lit(name_), 0)) { rdi_type_kind = (rdi_type_kind_); }
#define CaseD(rdi_type_kind_, encoding_, name_, bit_size_) else if(encoding == (encoding_) && bitsize == (bit_size_) && str8_match(name, str8_lit(name_), 0)) { rdi_type_kind = (rdi_type_kind_); }
CaseA(RDI_TypeKind_NULL, DW_ATE_Null)
CaseA(RDI_TypeKind_Void, DW_ATE_Address)
CaseA(RDI_TypeKind_Bool, DW_ATE_Boolean)
CaseB(RDI_TypeKind_ComplexF32, DW_ATE_ComplexFloat, 32)
CaseB(RDI_TypeKind_ComplexF64, DW_ATE_ComplexFloat, 64)
CaseB(RDI_TypeKind_ComplexF80, DW_ATE_ComplexFloat, 80)
CaseB(RDI_TypeKind_ComplexF128, DW_ATE_ComplexFloat, 128)
CaseC(RDI_TypeKind_F80, DW_ATE_Float, "__float80")
CaseC(RDI_TypeKind_F128, DW_ATE_Float, "__float128")
CaseC(RDI_TypeKind_F16, DW_ATE_Float, "_Float16")
CaseC(RDI_TypeKind_BF16, DW_ATE_Float, "__bf16")
CaseB(RDI_TypeKind_F16, DW_ATE_Float, 16)
CaseB(RDI_TypeKind_F32, DW_ATE_Float, 32)
CaseB(RDI_TypeKind_F48, DW_ATE_Float, 48)
CaseB(RDI_TypeKind_F64, DW_ATE_Float, 64)
CaseB(RDI_TypeKind_F80, DW_ATE_Float, 80)
CaseB(RDI_TypeKind_F96, DW_ATE_Float, 96)
CaseB(RDI_TypeKind_F128, DW_ATE_Float, 128)
CaseD(RDI_TypeKind_Char8, DW_ATE_Signed, "wchar_t", 8)
CaseD(RDI_TypeKind_Char16, DW_ATE_Signed, "wchar_t", 16)
CaseD(RDI_TypeKind_Char32, DW_ATE_Signed, "wchar_t", 32)
CaseB(RDI_TypeKind_S8, DW_ATE_Signed, 8)
CaseB(RDI_TypeKind_S16, DW_ATE_Signed, 16)
CaseB(RDI_TypeKind_S32, DW_ATE_Signed, 32)
CaseB(RDI_TypeKind_S64, DW_ATE_Signed, 64)
CaseB(RDI_TypeKind_S128, DW_ATE_Signed, 128)
CaseB(RDI_TypeKind_S256, DW_ATE_Signed, 256)
CaseB(RDI_TypeKind_S512, DW_ATE_Signed, 512)
CaseB(RDI_TypeKind_U8, DW_ATE_Unsigned, 8)
CaseB(RDI_TypeKind_U16, DW_ATE_Unsigned, 16)
CaseB(RDI_TypeKind_U32, DW_ATE_Unsigned, 32)
CaseB(RDI_TypeKind_U64, DW_ATE_Unsigned, 64)
CaseB(RDI_TypeKind_U128, DW_ATE_Unsigned, 128)
CaseB(RDI_TypeKind_U256, DW_ATE_Unsigned, 256)
CaseB(RDI_TypeKind_U512, DW_ATE_Unsigned, 512)
CaseB(RDI_TypeKind_UChar8, DW_ATE_UnsignedChar, 8)
CaseB(RDI_TypeKind_UChar8, DW_ATE_Utf, 8)
CaseB(RDI_TypeKind_UChar16, DW_ATE_UnsignedChar, 16)
CaseB(RDI_TypeKind_UChar16, DW_ATE_Utf, 16)
CaseB(RDI_TypeKind_UChar32, DW_ATE_UnsignedChar, 32)
CaseB(RDI_TypeKind_UChar32, DW_ATE_Utf, 32)
CaseB(RDI_TypeKind_Decimal32, DW_ATE_DecimalFloat, 32)
CaseB(RDI_TypeKind_Decimal64, DW_ATE_DecimalFloat, 64)
CaseB(RDI_TypeKind_Decimal128, DW_ATE_DecimalFloat, 128)
#undef CaseA
#undef CaseB
#undef CaseC
#undef CaseD
dst_type = rdim_type_chunk_list_push(arena, &lane_types, lane_types_chunk_count);
dst_type->kind = RDI_TypeKind_Alias;
dst_type->name = name;
dst_type->direct_type = d2r2_type_from_builtin_kind(rdi_type_kind);
dst_type->byte_size = bitsize/8;
}break;
case DW_TagKind_PointerType: rdi_type_kind = RDI_TypeKind_Ptr; goto ptr_or_ref_type;
case DW_TagKind_ReferenceType: rdi_type_kind = RDI_TypeKind_LRef; goto ptr_or_ref_type;
case DW_TagKind_RValueReferenceType: rdi_type_kind = RDI_TypeKind_RRef; goto ptr_or_ref_type;
ptr_or_ref_type:;
{
dst_type = rdim_type_chunk_list_push(arena, &lane_types, lane_types_chunk_count);
dst_type->kind = rdi_type_kind;
dst_type->direct_type = direct_type;
dst_type->byte_size = arch_addr_size;
}break;
case DW_TagKind_RestrictType:
{
rdi_type_modifier_flags = RDI_TypeModifierFlag_Restrict;
}goto basic_type_operators;
case DW_TagKind_VolatileType:
{
rdi_type_modifier_flags = RDI_TypeModifierFlag_Volatile;
}goto basic_type_operators;
case DW_TagKind_ConstType:
{
rdi_type_modifier_flags = RDI_TypeModifierFlag_Const;
}goto basic_type_operators;
basic_type_operators:;
{
dst_type = rdim_type_chunk_list_push(arena, &lane_types, lane_types_chunk_count);
dst_type->kind = RDI_TypeKind_Modifier;
dst_type->flags = rdi_type_modifier_flags;
dst_type->direct_type = direct_type;
dst_type->byte_size = (direct_type ? direct_type->byte_size : 0);
}break;
case DW_TagKind_ArrayType:
if(tag.has_children)
{
// rjf: parse array type children; extract dimensions (each one gets a SubrangeType)
typedef struct ArrayDimensionNode ArrayDimensionNode;
struct ArrayDimensionNode
{
ArrayDimensionNode *next;
U64 count;
};
ArrayDimensionNode *top_dimension = 0;
{
U64 tag_children_off = info_off + tag_info_size;
S64 depth = 1;
for(U64 off = tag_children_off; contains_1u64(unit_info_tag_range, off) && depth > 0;)
{
U64 start_off = off;
DW2_Tag child_tag = {0};
off += dw2_read_tag(temp.arena, unit_parse_ctx, raw->sec[DW_Section_Info].data, off, &child_tag);
if(child_tag.kind == DW_TagKind_SubrangeType)
{
// rjf: extract bounds attribs
DW2_Attrib *lower_bound_attrib = &dw2_attrib_nil;
DW2_Attrib *upper_bound_attrib = &dw2_attrib_nil;
DW2_Attrib *count_attrib = &dw2_attrib_nil;
for(DW2_AttribNode *n = child_tag.attribs.first;
n != 0 && (lower_bound_attrib == &dw2_attrib_nil || (upper_bound_attrib == &dw2_attrib_nil && count_attrib == &dw2_attrib_nil));
n = n->next)
{
if(n->v.attrib_kind == DW_AttribKind_LowerBound)
{
lower_bound_attrib = &n->v;
}
else if(n->v.attrib_kind == DW_AttribKind_UpperBound)
{
upper_bound_attrib = &n->v;
}
else if(n->v.attrib_kind == DW_AttribKind_Count)
{
count_attrib = &n->v;
}
}
// rjf: resolve lower bound
U64 lower_bound = 0;
{
if(dw_is_form_kind_ref(unit_parse_ctx->version, unit_parse_ctx->ext, lower_bound_attrib->val.kind))
{
log_infof("[.debug_info@%I64x] Array type lower bound is a variable; this is not currently supported.\n", start_off);
}
else
{
lower_bound = lower_bound_attrib->val.u128.u64[0];
}
}
// rjf: resolve upper bound
U64 upper_bound = 0;
{
if(count_attrib != &dw2_attrib_nil)
{
upper_bound = lower_bound + count_attrib->val.u128.u64[0];
}
else if(upper_bound_attrib != &dw2_attrib_nil)
{
if(dw_is_form_kind_ref(unit_parse_ctx->version, unit_parse_ctx->ext, upper_bound_attrib->val.kind))
{
log_infof("[.debug_info@%I64x] Array type upper bound is a variable; this is not currently supported.\n", start_off);
}
else
{
upper_bound = upper_bound_attrib->val.u128.u64[0];
upper_bound += 1; // NOTE(rjf): turn to exclusive range
}
}
}
// rjf: push node
ArrayDimensionNode *dim_n = push_array(temp.arena, ArrayDimensionNode, 1);
SLLStackPush(top_dimension, dim_n);
dim_n->count = (upper_bound - lower_bound);
}
if(child_tag.has_children)
{
depth += 1;
}
else if(child_tag.kind == DW_TagKind_Null)
{
depth -= 1;
}
if(off == start_off)
{
break;
}
}
}
// rjf: create array type operators for each dimension
RDIM_Type *array_direct_type = direct_type;
for EachNode(dim_n, ArrayDimensionNode, top_dimension)
{
RDIM_Type *array_type = rdim_type_chunk_list_push(arena, &lane_types, lane_types_chunk_count);
array_type->kind = RDI_TypeKind_Array;
array_type->byte_size = array_direct_type ? array_direct_type->byte_size*dim_n->count : 0;
array_type->direct_type = array_direct_type;
array_direct_type = array_type;
}
// rjf: final destination type -> the final array dimension type
dst_type = array_direct_type;
}break;
}
// rjf: store type in type-from-idx table
type_from_idx_map[type_idx] = dst_type;
temp_end(temp);
}
@@ -1580,16 +1945,186 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
}
lane_sync_u64(&next_max_chain_count, 0);
//- rjf: update max chain count
max_chain_count = next_max_chain_count;
scratch_end(scratch2);
}
}
lane_sync();
////////////////////////////
//- rjf: convert all units / symbols
//
RDIM_UnitChunkList *all_units = 0;
RDIM_Unit **unit_from_idx_map = 0;
ProfScope("convert all units / symbols")
{
if(lane_idx() == 0)
{
all_units = push_array(scratch.arena, RDIM_UnitChunkList, 1);
unit_from_idx_map = push_array(scratch.arena, RDIM_Unit *, unit_count);
for EachIndex(unit_idx, unit_count)
{
unit_from_idx_map[unit_idx] = rdim_unit_chunk_list_push(arena, all_units, unit_count);
}
}
lane_sync_u64(&all_units, 0);
lane_sync_u64(&unit_from_idx_map, 0);
U64 unit_take_idx_ = 0;
U64 *unit_take_idx_ptr = &unit_take_idx_;
lane_sync_u64(&unit_take_idx_ptr, 0);
for(;;)
{
U64 unit_idx = ins_atomic_u64_inc_eval(unit_take_idx_ptr) - 1;
if(unit_idx >= unit_count)
{
break;
}
//- rjf: unpack unit info
DW2_ParseCtx *unit_parse_ctx = &unit_parse_ctxs[unit_idx];
Rng1U64 unit_info_tag_range = unit_info_tag_ranges[unit_idx];
RDIM_Unit *dst_unit = unit_from_idx_map[unit_idx];
//- rjf: unpack unit's root tag
DW2_Tag *unit_root_tag = &unit_root_tags[unit_idx];
DW2_Attrib *name_attrib = &dw2_attrib_nil;
DW2_Attrib *comp_dir_attrib = &dw2_attrib_nil;
DW2_Attrib *producer_attrib = &dw2_attrib_nil;
DW2_Attrib *lang_attrib = &dw2_attrib_nil;
for EachNode(n, DW2_AttribNode, unit_root_tag->attribs.first)
{
switch(n->v.attrib_kind)
{
default:{}break;
#define Case(dst, src) case DW_AttribKind_##src:{dst##_attrib = &n->v;}break
Case(name, Name);
Case(comp_dir, CompDir);
Case(producer, Producer);
Case(lang, Language);
#undef Case
}
}
//- rjf: unpack attributes
String8 unit_name = name_attrib->val.string;
String8 unit_comp_dir = comp_dir_attrib->val.string;
String8 unit_producer = producer_attrib->val.string;
RDI_Language unit_lang = RDI_Language_NULL;
{
DW_Language dw_lang = lang_attrib->val.u128.u64[0];
switch(dw_lang)
{
default:{}break;
case DW_Language_C89:
case DW_Language_C99:
case DW_Language_C11:
case DW_Language_C:
{
unit_lang = RDI_Language_C;
}break;
case DW_Language_CPlusPlus03:
case DW_Language_CPlusPlus11:
case DW_Language_CPlusPlus14:
case DW_Language_CPlusPlus:
{
unit_lang = RDI_Language_CPlusPlus;
}break;
}
}
//- rjf: fill top-level unit info
{
dst_unit->unit_name = unit_name;
dst_unit->compiler_name = unit_producer;
// TODO(rjf): dst_unit->source_file = ???;
// TODO(rjf): dst_unit->object_file = ???;
// TODO(rjf): dst_unit->archive_file = ???;
dst_unit->build_path = unit_comp_dir;
dst_unit->language = unit_lang;
dst_unit->line_table = unit_line_tables[unit_idx];
}
//- rjf: produce all unit symbols
for(U64 off = unit_info_tag_range.min; off < unit_info_tag_range.max;)
{
Temp scratch2 = scratch_begin(&scratch.arena, 1);
U64 start_off = off;
//- rjf: parse tag
DW2_Tag tag = {0};
off += dw2_read_tag(scratch2.arena, unit_parse_ctx, raw->sec[DW_Section_Info].data, off, &tag);
//- rjf: gather attributes from tag
DW2_Attrib *name_attrib = &dw2_attrib_nil;
for EachNode(n, DW2_AttribNode, tag.attribs.first)
{
switch(n->v.attrib_kind)
{
default:{}break;
#define Case(dst, src) case DW_AttribKind_##src:{dst##_attrib = &n->v;}break
Case(name, Name);
#undef Case
}
}
//- rjf: unpack attributes
String8 name = name_attrib->val.string;
//- rjf: produce symbols from tag
switch(tag.kind)
{
default:{}break;
//- rjf: subprograms (procedures)
case DW_TagKind_SubProgram:
{
RDIM_Symbol *procedure = rdim_symbol_chunk_list_push(arena, &dst_unit->procedures, 512);
procedure->name = name;
}break;
//- rjf: inline site
case DW_TagKind_InlinedSubroutine:
{
}break;
//- rjf: variables
case DW_TagKind_Variable:
case DW_TagKind_FormalParameter:
{
}break;
//- rjf: lexical blocks (scopes)
case DW_TagKind_LexicalBlock:
{
}break;
}
scratch_end(scratch2);
if(off == start_off)
{
break;
}
}
}
}
////////////////////////////
//- rjf: fill result
//
RDIM_BakeParams result = {0};
{
// TODO(rjf)
result.subset_flags = params->subset_flags;
// TODO(rjf): result.top_level_info = *top_level_info;
// TODO(rjf): result.binary_sections = *binary_sections;
result.units = *all_units;
result.types = *all_types;
result.src_files = *all_src_files;
result.line_tables = *all_line_tables;
}
#undef d2r2_type_from_builtin_kind