mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
detect variable length array in upper bound and lower bound
This commit is contained in:
@@ -256,6 +256,25 @@ dw_are_attrib_class_and_form_kind_compatible(DW_Version ver, DW_AttribClass attr
|
||||
return are_compat;
|
||||
}
|
||||
|
||||
internal B32
|
||||
dw_is_form_kind_ref(DW_Version ver, DW_Ext ext, DW_FormKind form_kind)
|
||||
{
|
||||
B32 is_ref = 0;
|
||||
if (form_kind == DW_Form_RefAddr ||
|
||||
form_kind == DW_Form_Ref1 ||
|
||||
form_kind == DW_Form_Ref2 ||
|
||||
form_kind == DW_Form_Ref4 ||
|
||||
form_kind == DW_Form_Ref8 ||
|
||||
form_kind == DW_Form_RefUData) {
|
||||
is_ref = 1;
|
||||
} else {
|
||||
if (ext == DW_Ext_GNU) {
|
||||
is_ref = DW_Form_GNU_RefAlt;
|
||||
}
|
||||
}
|
||||
return is_ref;
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_name_string_from_section_kind(DW_SectionKind k)
|
||||
{
|
||||
|
||||
@@ -1724,6 +1724,8 @@ internal DW_AttribClass dw_attrib_class_from_form_kind(DW_Version ver, DW_FormKi
|
||||
|
||||
internal B32 dw_are_attrib_class_and_form_kind_compatible(DW_Version ver, DW_AttribClass attrib_class, DW_FormKind form_kind);
|
||||
|
||||
internal B32 dw_is_form_kind_ref(DW_Version ver, DW_Ext ext, DW_FormKind form_kind);
|
||||
|
||||
//- Section Names
|
||||
|
||||
internal String8 dw_name_string_from_section_kind (DW_SectionKind k);
|
||||
|
||||
+18
-2
@@ -1139,7 +1139,7 @@ dw_interp_ref(DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form f
|
||||
form_kind == DW_Form_Ref4 || form_kind == DW_Form_Ref8 ||
|
||||
form_kind == DW_Form_RefUData) {
|
||||
ref.cu = cu;
|
||||
ref.info_off = form.ref;
|
||||
ref.info_off = cu->info_range.min + form.ref;
|
||||
} else if (form_kind == DW_Form_RefAddr) {
|
||||
NotImplemented;
|
||||
} else if (form_kind == DW_Form_RefSig8) {
|
||||
@@ -2009,6 +2009,22 @@ dw_u64_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind k
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
dw_is_attrib_var_ref(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib)
|
||||
{
|
||||
B32 is_var_ref = 0;
|
||||
if (dw_is_form_kind_ref(cu->version, cu->ext, attrib->form_kind)) {
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
DW_Reference ref = dw_ref_from_attrib(input, cu, attrib);
|
||||
DW_Tag ref_tag = {0};
|
||||
if (dw_read_tag_cu(scratch.arena, input, ref.cu, ref.info_off, &ref_tag)) {
|
||||
is_var_ref = ref_tag.kind == DW_TagKind_Variable;
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
return is_var_ref;
|
||||
}
|
||||
|
||||
internal DW_CompUnit
|
||||
dw_cu_from_info_off(Arena *arena, DW_Input *input, DW_ListUnitInput lu_input, U64 offset, B32 relaxed)
|
||||
{
|
||||
@@ -2164,7 +2180,7 @@ dw_cu_from_info_off(Arena *arena, DW_Input *input, DW_ListUnitInput lu_input, U6
|
||||
cu.address_size = address_size;
|
||||
cu.abbrev_off = abbrev_base;
|
||||
cu.info_range = range;
|
||||
cu.first_tag_info_off = range.min + cursor;
|
||||
cu.first_tag_info_off = cursor;
|
||||
cu.abbrev_table = abbrev_table;
|
||||
cu.abbrev_data = abbrev_data;
|
||||
cu.addr_lu = addr_lu;
|
||||
|
||||
@@ -317,7 +317,7 @@ typedef struct DW_PubStringsTable
|
||||
typedef struct DW_Reference
|
||||
{
|
||||
DW_CompUnit *cu;
|
||||
U64 info_off;
|
||||
U64 info_off; // global .debug_info offset
|
||||
} DW_Reference;
|
||||
|
||||
////////////////////////////////
|
||||
@@ -521,6 +521,8 @@ internal DW_Reference dw_ref_from_tag_attrib_kind (DW_Input *input, DW_Co
|
||||
internal DW_LocList dw_loclist_from_tag_attrib_kind (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal Rng1U64List dw_rnglist_from_tag_attrib_kind (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
|
||||
internal B32 dw_is_attrib_var_ref(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
|
||||
// compile unit
|
||||
|
||||
internal DW_CompUnit dw_cu_from_info_off(Arena *arena, DW_Input *input, DW_ListUnitInput lu_input, U64 offset, B32 relaxed);
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
// TODO:
|
||||
//
|
||||
// [ ] Currently converter relies on clang's -gdwarf-aranges to generate compile unit ranges,
|
||||
// however it is optional and in case it is missing converter has to generate the ranges from scopes.
|
||||
// [ ] Error handling
|
||||
////////////////////////////////
|
||||
|
||||
thread_static D2R_Log g_d2r_log;
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
@@ -2092,6 +2090,8 @@ d2r_convert_types(Arena *arena,
|
||||
type->direct_type = direct_type;
|
||||
} break;
|
||||
case DW_TagKind_ArrayType: {
|
||||
B32 error = 1;
|
||||
|
||||
// * DWARF vs RDI Array Type Graph *
|
||||
//
|
||||
// For example lets take following decl:
|
||||
@@ -2118,15 +2118,19 @@ d2r_convert_types(Arena *arena,
|
||||
struct SubrangeNode *subrange_stack = 0;
|
||||
for (DW_TagNode *n = tag_node->first_child; n != 0; n = n->sibling) {
|
||||
if (n->tag.kind != DW_TagKind_SubrangeType) {
|
||||
// TODO: error handling
|
||||
AssertAlways(!"unexpected tag");
|
||||
continue;
|
||||
d2r_log("[%llx] while scanning for DW_TagKind_SubrangeType found an unexpected child tag %S @ %llx\n", tag.info_off, dw_string_from_tag_kind(g_d2r_log.arena, n->tag.kind), n->tag.info_off);
|
||||
goto array_type_exit;
|
||||
}
|
||||
|
||||
// resolve lower bound
|
||||
U64 lower_bound = 0;
|
||||
if (dw_tag_has_attrib(input, cu, n->tag, DW_AttribKind_LowerBound)) {
|
||||
B32 is_vla = dw_is_attrib_var_ref(input, cu, dw_attrib_from_tag(input, cu, n->tag, DW_AttribKind_LowerBound));
|
||||
if (is_vla) {
|
||||
d2r_log("[%llx] TODO: lower bound is a variable\n", n->tag.info_off);
|
||||
} else {
|
||||
lower_bound = dw_u64_from_attrib(input, cu, n->tag, DW_AttribKind_LowerBound);
|
||||
}
|
||||
} else {
|
||||
lower_bound = dw_pick_default_lower_bound(cu_lang);
|
||||
}
|
||||
@@ -2137,9 +2141,14 @@ d2r_convert_types(Arena *arena,
|
||||
U64 count = dw_u64_from_attrib(input, cu, n->tag, DW_AttribKind_Count);
|
||||
upper_bound = lower_bound + count;
|
||||
} else if (dw_tag_has_attrib(input, cu, n->tag, DW_AttribKind_UpperBound)) {
|
||||
B32 is_vla = dw_is_attrib_var_ref(input, cu, dw_attrib_from_tag(input, cu, n->tag, DW_AttribKind_UpperBound));
|
||||
if (is_vla) {
|
||||
d2r_log("[%llx] TODO: upper bound is a variable\n", n->tag.info_off);
|
||||
goto array_type_exit;
|
||||
} else {
|
||||
upper_bound = dw_u64_from_attrib(input, cu, n->tag, DW_AttribKind_UpperBound);
|
||||
// turn upper bound into exclusive range
|
||||
upper_bound += 1;
|
||||
upper_bound += 1; // turn upper bound into exclusive range
|
||||
}
|
||||
} else {
|
||||
// zero sized array
|
||||
}
|
||||
@@ -2167,6 +2176,15 @@ d2r_convert_types(Arena *arena,
|
||||
direct_type = t;
|
||||
}
|
||||
|
||||
error = 0;
|
||||
array_type_exit:;
|
||||
|
||||
// in case of an error, assign null to the array type
|
||||
if (error) {
|
||||
Assert(d2r_type_from_offset(type_table, tag.info_off) == 0); // this should the first time this type is being parsed
|
||||
hash_table_push_u64_raw(arena, type_table->ht, tag.info_off, type_table->builtin_types[RDI_TypeKind_NULL]);
|
||||
}
|
||||
|
||||
d2r_tag_iterator_skip_children(it);
|
||||
} break;
|
||||
case DW_TagKind_SubrangeType: {
|
||||
@@ -2577,6 +2595,8 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
if (lane_idx() == 0) {
|
||||
g_d2r_log.arena = arena_alloc();
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
ProfBegin("compute exe hash");
|
||||
@@ -2787,9 +2807,6 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
|
||||
|
||||
DW_CompUnit *cu = &cu_arr[cu_idx];
|
||||
|
||||
// parse and build tag tree
|
||||
DW_TagTree tag_tree = dw_tag_tree_from_cu(comp_temp.arena, &input, cu);
|
||||
|
||||
// skip DWO
|
||||
{
|
||||
if (cu->dwo_id) { goto next_cu; }
|
||||
@@ -2801,6 +2818,9 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
|
||||
if (gnu_dwo_name.size) { goto next_cu; }
|
||||
}
|
||||
|
||||
// parse and build tag tree
|
||||
DW_TagTree tag_tree = dw_tag_tree_from_cu(comp_temp.arena, &input, cu);
|
||||
|
||||
// build (info offset -> tag) hash table to resolve tags with abstract origin
|
||||
cu->tag_ht = dw_make_tag_hash_table(comp_temp.arena, tag_tree);
|
||||
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef struct D2R_Log
|
||||
{
|
||||
Arena *arena;
|
||||
String8List v;
|
||||
} D2R_Log;
|
||||
|
||||
#define d2r_log(...) str8_list_pushf(g_d2r_log.arena, &g_d2r_log.v, __FILE__ ":" Stringify(__LINE__) " " __VA_ARGS__)
|
||||
|
||||
typedef struct D2R_ConvertParams D2R_ConvertParams;
|
||||
struct D2R_ConvertParams
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user