form value resolution; line table header parsing

This commit is contained in:
Ryan Fleury
2025-11-11 17:24:12 -08:00
parent faee02f763
commit 2a76093e17
5 changed files with 98 additions and 28 deletions
+3 -3
View File
@@ -194,7 +194,7 @@ 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 k)
dw_attrib_class_from_kind(DW_Version ver, DW_Ext ext, DW_AttribKind k)
{
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
// 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);
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);
}
+3 -3
View File
@@ -478,7 +478,7 @@ X(GNU_RefAlt, DW_AttribClass_Undefined) \
X(GNU_StrpAlt, DW_AttribClass_String)
typedef U64 DW_FormKind;
typedef enum DW_FormEnum
typedef enum DW_FormKindEnum
{
DW_Form_Null,
#define X(_N, _ID) DW_Form_##_N = _ID,
@@ -487,7 +487,7 @@ typedef enum DW_FormEnum
DW_Form_V5_XList(X)
DW_Form_GNU_XList(X)
#undef X
} DW_FormEnum;
} DW_FormKindEnum;
//- 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_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
+59 -19
View File
@@ -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)
{
U64 start_off = off;
DW2_FormVal val = {0};
DW2_FormVal val = {form_kind};
{
//- rjf: read value bytes
U64 bytes_to_read = 0;
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 og_read_off = off;
off += str8_deserial_read_uleb128(data, off, &size);
val.u128.u64[0] = size;
val.u128.u64[1] = og_read_off;
val.string = str8_substr(data, r1u64(off, off+size));
off += size;
}break;
@@ -362,8 +362,7 @@ dw2_read_form_val(DW2_ParseCtx *ctx, String8 data, U64 off, DW_FormKind form_kin
String8 string = {0};
U64 og_read_off = off;
off += str8_deserial_read_cstr(data, off, &string);
val.u128.u64[0] = og_read_off;
val.u128.u64[1] = og_read_off + string.size - 1;
val.string = string;
}break;
//- 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;
}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;
U64 bytes_read = (off - start_off);
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
@@ -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);
attribs.count += 1;
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
@@ -511,6 +530,21 @@ dw2_read_tag(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 off, DW2_Tag *ta
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
@@ -695,7 +729,7 @@ dw2_read_line_table_header(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 of
case DW_Version_5:
{
//- 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
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);
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;
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;
case DW_LNCT_Path:
{
entry_out->file_name = dw2_string_from_form_val(ctx, form_val);
entry_out->file_name = form_val.string;
}break;
case DW_LNCT_DirectoryIndex:
{
@@ -751,12 +786,17 @@ dw2_read_line_table_header(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 of
}break;
case DW_LNCT_LLVM_Source:
{
entry_out->source = dw2_string_from_form_val(ctx, form_val);
entry_out->source = form_val.string;
}break;
}
}
}
}
// rjf: store
if(0){}
else if(do_files) { files = table; }
else if(do_dirs) { dirs = table; }
}
}break;
+8 -3
View File
@@ -59,7 +59,8 @@ struct DW2_ParseCtx
typedef struct DW2_FormVal DW2_FormVal;
struct DW2_FormVal
{
DW_SectionKind section_kind;
DW_FormKind kind;
String8 string;
U128 u128;
};
@@ -67,7 +68,6 @@ typedef struct DW2_Attrib DW2_Attrib;
struct DW2_Attrib
{
DW_AttribKind attrib_kind;
DW_FormKind form_kind;
DW2_FormVal val;
};
@@ -154,6 +154,11 @@ struct DW2_LineTableHeader
DW2_LineTableFileArray files;
};
////////////////////////////////
//~ rjf: Globals
global read_only DW2_Attrib dw2_attrib_nil = {0};
////////////////////////////////
//~ 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
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
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
+25
View File
@@ -298,6 +298,31 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
}
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
//