mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
form value resolution; line table header parsing
This commit is contained in:
+3
-3
@@ -194,7 +194,7 @@ dw_attrib_class_from_attrib_mips(DW_AttribKind k)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal DW_AttribClass
|
internal DW_AttribClass
|
||||||
dw_attrib_class_from_attrib(DW_Version ver, DW_Ext ext, DW_AttribKind k)
|
dw_attrib_class_from_kind(DW_Version ver, DW_Ext ext, DW_AttribKind k)
|
||||||
{
|
{
|
||||||
DW_AttribClass result = DW_AttribClass_Null;
|
DW_AttribClass result = DW_AttribClass_Null;
|
||||||
|
|
||||||
@@ -344,11 +344,11 @@ dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, DW_AttribKind attrib_kind
|
|||||||
// This function's purpose is to find the overlapping class between an
|
// This function's purpose is to find the overlapping class between an
|
||||||
// DW_AttribKind and DW_FormKind.
|
// DW_AttribKind and DW_FormKind.
|
||||||
|
|
||||||
DW_AttribClass attrib_class = dw_attrib_class_from_attrib(ver, ext, attrib_kind);
|
DW_AttribClass attrib_class = dw_attrib_class_from_kind(ver, ext, attrib_kind);
|
||||||
DW_AttribClass form_class = dw_attrib_class_from_form_kind(ver, form_kind);
|
DW_AttribClass form_class = dw_attrib_class_from_form_kind(ver, form_kind);
|
||||||
if(attrib_class == DW_AttribClass_Null || form_class == DW_AttribClass_Null)
|
if(attrib_class == DW_AttribClass_Null || form_class == DW_AttribClass_Null)
|
||||||
{
|
{
|
||||||
attrib_class = dw_attrib_class_from_attrib(DW_Version_Last, ext, attrib_kind);
|
attrib_class = dw_attrib_class_from_kind(DW_Version_Last, ext, attrib_kind);
|
||||||
form_class = dw_attrib_class_from_form_kind(DW_Version_Last, form_kind);
|
form_class = dw_attrib_class_from_form_kind(DW_Version_Last, form_kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -478,7 +478,7 @@ X(GNU_RefAlt, DW_AttribClass_Undefined) \
|
|||||||
X(GNU_StrpAlt, DW_AttribClass_String)
|
X(GNU_StrpAlt, DW_AttribClass_String)
|
||||||
|
|
||||||
typedef U64 DW_FormKind;
|
typedef U64 DW_FormKind;
|
||||||
typedef enum DW_FormEnum
|
typedef enum DW_FormKindEnum
|
||||||
{
|
{
|
||||||
DW_Form_Null,
|
DW_Form_Null,
|
||||||
#define X(_N, _ID) DW_Form_##_N = _ID,
|
#define X(_N, _ID) DW_Form_##_N = _ID,
|
||||||
@@ -487,7 +487,7 @@ typedef enum DW_FormEnum
|
|||||||
DW_Form_V5_XList(X)
|
DW_Form_V5_XList(X)
|
||||||
DW_Form_GNU_XList(X)
|
DW_Form_GNU_XList(X)
|
||||||
#undef X
|
#undef X
|
||||||
} DW_FormEnum;
|
} DW_FormKindEnum;
|
||||||
|
|
||||||
//- Attributes DWARF2
|
//- Attributes DWARF2
|
||||||
|
|
||||||
@@ -1762,7 +1762,7 @@ internal DW_AttribClass dw_attrib_class_from_attrib_llvm (DW_AttribKind k);
|
|||||||
internal DW_AttribClass dw_attrib_class_from_attrib_apple(DW_AttribKind k);
|
internal DW_AttribClass dw_attrib_class_from_attrib_apple(DW_AttribKind k);
|
||||||
internal DW_AttribClass dw_attrib_class_from_attrib_mips (DW_AttribKind k);
|
internal DW_AttribClass dw_attrib_class_from_attrib_mips (DW_AttribKind k);
|
||||||
|
|
||||||
internal DW_AttribClass dw_attrib_class_from_attrib(DW_Version ver, DW_Ext ext, DW_AttribKind v);
|
internal DW_AttribClass dw_attrib_class_from_kind(DW_Version ver, DW_Ext ext, DW_AttribKind v);
|
||||||
|
|
||||||
//- Form Class Encodings
|
//- Form Class Encodings
|
||||||
|
|
||||||
|
|||||||
+59
-19
@@ -246,8 +246,9 @@ internal U64
|
|||||||
dw2_read_form_val(DW2_ParseCtx *ctx, String8 data, U64 off, DW_FormKind form_kind, U64 implicit_const, DW2_FormVal *out)
|
dw2_read_form_val(DW2_ParseCtx *ctx, String8 data, U64 off, DW_FormKind form_kind, U64 implicit_const, DW2_FormVal *out)
|
||||||
{
|
{
|
||||||
U64 start_off = off;
|
U64 start_off = off;
|
||||||
DW2_FormVal val = {0};
|
DW2_FormVal val = {form_kind};
|
||||||
{
|
{
|
||||||
|
//- rjf: read value bytes
|
||||||
U64 bytes_to_read = 0;
|
U64 bytes_to_read = 0;
|
||||||
switch(form_kind)
|
switch(form_kind)
|
||||||
{
|
{
|
||||||
@@ -351,8 +352,7 @@ dw2_read_form_val(DW2_ParseCtx *ctx, String8 data, U64 off, DW_FormKind form_kin
|
|||||||
U64 size = 0;
|
U64 size = 0;
|
||||||
U64 og_read_off = off;
|
U64 og_read_off = off;
|
||||||
off += str8_deserial_read_uleb128(data, off, &size);
|
off += str8_deserial_read_uleb128(data, off, &size);
|
||||||
val.u128.u64[0] = size;
|
val.string = str8_substr(data, r1u64(off, off+size));
|
||||||
val.u128.u64[1] = og_read_off;
|
|
||||||
off += size;
|
off += size;
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
@@ -362,8 +362,7 @@ dw2_read_form_val(DW2_ParseCtx *ctx, String8 data, U64 off, DW_FormKind form_kin
|
|||||||
String8 string = {0};
|
String8 string = {0};
|
||||||
U64 og_read_off = off;
|
U64 og_read_off = off;
|
||||||
off += str8_deserial_read_cstr(data, off, &string);
|
off += str8_deserial_read_cstr(data, off, &string);
|
||||||
val.u128.u64[0] = og_read_off;
|
val.string = string;
|
||||||
val.u128.u64[1] = og_read_off + string.size - 1;
|
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
//- rjf: implicit constants (no reading in .debug_info; value comes from .debug_abbrev)
|
//- rjf: implicit constants (no reading in .debug_info; value comes from .debug_abbrev)
|
||||||
@@ -389,21 +388,41 @@ dw2_read_form_val(DW2_ParseCtx *ctx, String8 data, U64 off, DW_FormKind form_kin
|
|||||||
val.u128.u64[0] = 1;
|
val.u128.u64[0] = 1;
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- rjf: in some cases, resolve numeric values -> strings
|
||||||
|
{
|
||||||
|
switch(form_kind)
|
||||||
|
{
|
||||||
|
default:{}break;
|
||||||
|
case DW_Form_Strx1:
|
||||||
|
case DW_Form_Strx2:
|
||||||
|
case DW_Form_Strx3:
|
||||||
|
case DW_Form_Strx4:
|
||||||
|
case DW_Form_Strx:
|
||||||
|
{
|
||||||
|
// TODO(rjf)
|
||||||
|
}break;
|
||||||
|
case DW_Form_LineStrp:
|
||||||
|
{
|
||||||
|
String8 string_section_data = ctx->raw->sec[DW_Section_LineStr].data;
|
||||||
|
val.string = str8_cstring_capped(string_section_data.str + val.u128.u64[0],
|
||||||
|
string_section_data.str + string_section_data.size);
|
||||||
|
}break;
|
||||||
|
case DW_Form_Strp:
|
||||||
|
case DW_Form_StrpSup:
|
||||||
|
{
|
||||||
|
String8 string_section_data = ctx->raw->sec[DW_Section_Str].data;
|
||||||
|
val.string = str8_cstring_capped(string_section_data.str + val.u128.u64[0],
|
||||||
|
string_section_data.str + string_section_data.size);
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*out = val;
|
*out = val;
|
||||||
U64 bytes_read = (off - start_off);
|
U64 bytes_read = (off - start_off);
|
||||||
return bytes_read;
|
return bytes_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal String8
|
|
||||||
dw2_string_from_form_val(DW2_ParseCtx *ctx, DW2_FormVal val)
|
|
||||||
{
|
|
||||||
String8 section_data = ctx->raw->sec[val.section_kind].data;
|
|
||||||
Rng1U64 range = r1u64(val.u128.u64[0], val.u128.u64[1]);
|
|
||||||
String8 string = str8_substr(section_data, range);
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Tag Parsing
|
//~ rjf: Tag Parsing
|
||||||
|
|
||||||
@@ -490,7 +509,7 @@ dw2_read_tag(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 off, DW2_Tag *ta
|
|||||||
SLLQueuePush(attribs.first, attribs.last, n);
|
SLLQueuePush(attribs.first, attribs.last, n);
|
||||||
attribs.count += 1;
|
attribs.count += 1;
|
||||||
n->v.attrib_kind = attrib_kind;
|
n->v.attrib_kind = attrib_kind;
|
||||||
n->v.form_kind = attrib_form_kind;
|
n->v.val = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
// rjf: no movement, or no attrib kind -> done
|
// rjf: no movement, or no attrib kind -> done
|
||||||
@@ -511,6 +530,21 @@ dw2_read_tag(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 off, DW2_Tag *ta
|
|||||||
return bytes_read;
|
return bytes_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal DW2_Attrib *
|
||||||
|
dw2_attrib_from_kind(DW2_Tag *tag, DW_AttribKind kind)
|
||||||
|
{
|
||||||
|
DW2_Attrib *result = &dw2_attrib_nil;
|
||||||
|
for EachNode(n, DW2_AttribNode, tag->attribs.first)
|
||||||
|
{
|
||||||
|
if(n->v.attrib_kind == kind)
|
||||||
|
{
|
||||||
|
result = &n->v;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Line Table Parsing
|
//~ rjf: Line Table Parsing
|
||||||
|
|
||||||
@@ -695,7 +729,7 @@ dw2_read_line_table_header(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 of
|
|||||||
case DW_Version_5:
|
case DW_Version_5:
|
||||||
{
|
{
|
||||||
//- rjf: read directory & file tables
|
//- rjf: read directory & file tables
|
||||||
for(B32 files = 0, dirs = 1; files <= 1; files = 1, dirs = 0)
|
for(B32 do_files = 0, do_dirs = 1; do_files <= 1; do_files += 1, do_dirs = 0)
|
||||||
{
|
{
|
||||||
// rjf: read header
|
// rjf: read header
|
||||||
U8 entry_formats_count = 0;
|
U8 entry_formats_count = 0;
|
||||||
@@ -703,7 +737,8 @@ dw2_read_line_table_header(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 of
|
|||||||
U64 *entry_formats = push_array(scratch.arena, U64, entry_formats_count*2);
|
U64 *entry_formats = push_array(scratch.arena, U64, entry_formats_count*2);
|
||||||
for EachIndex(idx, entry_formats_count)
|
for EachIndex(idx, entry_formats_count)
|
||||||
{
|
{
|
||||||
off += str8_deserial_read_uleb128(data, off, &entry_formats[idx]);
|
off += str8_deserial_read_uleb128(data, off, &entry_formats[idx*2 + 0]);
|
||||||
|
off += str8_deserial_read_uleb128(data, off, &entry_formats[idx*2 + 1]);
|
||||||
}
|
}
|
||||||
U64 table_count = 0;
|
U64 table_count = 0;
|
||||||
off += str8_deserial_read_uleb128(data, off, &table_count);
|
off += str8_deserial_read_uleb128(data, off, &table_count);
|
||||||
@@ -731,7 +766,7 @@ dw2_read_line_table_header(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 of
|
|||||||
}break;
|
}break;
|
||||||
case DW_LNCT_Path:
|
case DW_LNCT_Path:
|
||||||
{
|
{
|
||||||
entry_out->file_name = dw2_string_from_form_val(ctx, form_val);
|
entry_out->file_name = form_val.string;
|
||||||
}break;
|
}break;
|
||||||
case DW_LNCT_DirectoryIndex:
|
case DW_LNCT_DirectoryIndex:
|
||||||
{
|
{
|
||||||
@@ -751,12 +786,17 @@ dw2_read_line_table_header(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 of
|
|||||||
}break;
|
}break;
|
||||||
case DW_LNCT_LLVM_Source:
|
case DW_LNCT_LLVM_Source:
|
||||||
{
|
{
|
||||||
entry_out->source = dw2_string_from_form_val(ctx, form_val);
|
entry_out->source = form_val.string;
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rjf: store
|
||||||
|
if(0){}
|
||||||
|
else if(do_files) { files = table; }
|
||||||
|
else if(do_dirs) { dirs = table; }
|
||||||
}
|
}
|
||||||
|
|
||||||
}break;
|
}break;
|
||||||
|
|||||||
@@ -59,7 +59,8 @@ struct DW2_ParseCtx
|
|||||||
typedef struct DW2_FormVal DW2_FormVal;
|
typedef struct DW2_FormVal DW2_FormVal;
|
||||||
struct DW2_FormVal
|
struct DW2_FormVal
|
||||||
{
|
{
|
||||||
DW_SectionKind section_kind;
|
DW_FormKind kind;
|
||||||
|
String8 string;
|
||||||
U128 u128;
|
U128 u128;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -67,7 +68,6 @@ typedef struct DW2_Attrib DW2_Attrib;
|
|||||||
struct DW2_Attrib
|
struct DW2_Attrib
|
||||||
{
|
{
|
||||||
DW_AttribKind attrib_kind;
|
DW_AttribKind attrib_kind;
|
||||||
DW_FormKind form_kind;
|
|
||||||
DW2_FormVal val;
|
DW2_FormVal val;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -154,6 +154,11 @@ struct DW2_LineTableHeader
|
|||||||
DW2_LineTableFileArray files;
|
DW2_LineTableFileArray files;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ rjf: Globals
|
||||||
|
|
||||||
|
global read_only DW2_Attrib dw2_attrib_nil = {0};
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Basic Parsing Helpers
|
//~ rjf: Basic Parsing Helpers
|
||||||
|
|
||||||
@@ -174,12 +179,12 @@ internal DW2_AbbrevMap dw2_abbrev_map_from_data(Arena *arena, String8 data, U64
|
|||||||
//~ rjf: Form Value Parsing
|
//~ rjf: Form Value Parsing
|
||||||
|
|
||||||
internal U64 dw2_read_form_val(DW2_ParseCtx *ctx, String8 data, U64 off, DW_FormKind form_kind, U64 implicit_const, DW2_FormVal *out);
|
internal U64 dw2_read_form_val(DW2_ParseCtx *ctx, String8 data, U64 off, DW_FormKind form_kind, U64 implicit_const, DW2_FormVal *out);
|
||||||
internal String8 dw2_string_from_form_val(DW2_ParseCtx *ctx, DW2_FormVal val);
|
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Tag Parsing
|
//~ rjf: Tag Parsing
|
||||||
|
|
||||||
internal U64 dw2_read_tag(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 off, DW2_Tag *tag_out);
|
internal U64 dw2_read_tag(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 off, DW2_Tag *tag_out);
|
||||||
|
internal DW2_Attrib *dw2_attrib_from_kind(DW2_Tag *tag, DW_AttribKind kind);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Line Table Parsing
|
//~ rjf: Line Table Parsing
|
||||||
|
|||||||
@@ -298,6 +298,31 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
|||||||
}
|
}
|
||||||
lane_sync();
|
lane_sync();
|
||||||
|
|
||||||
|
////////////////////////////
|
||||||
|
//- rjf: parse each unit's line table
|
||||||
|
//
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
DW2_ParseCtx *ctx = &unit_parse_ctxs[unit_idx];
|
||||||
|
DW2_Tag *unit_root_tag = &unit_root_tags[unit_idx];
|
||||||
|
DW2_Attrib *stmt_list = dw2_attrib_from_kind(unit_root_tag, DW_AttribKind_StmtList);
|
||||||
|
U64 line_info_off = stmt_list->val.u128.u64[0];
|
||||||
|
DW2_LineTableHeader line_table_header = {0};
|
||||||
|
String8 line_info_data = raw->sec[DW_Section_Line].data;
|
||||||
|
dw2_read_line_table_header(scratch.arena, ctx, line_info_data, line_info_off, &line_table_header);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lane_sync();
|
||||||
|
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
//- rjf: fill result
|
//- rjf: fill result
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user