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 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
View File
@@ -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
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) 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;
+8 -3
View File
@@ -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
+25
View File
@@ -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
// //