diff --git a/src/dwarf/dwarf.c b/src/dwarf/dwarf.c index e6fa63d0..a010a320 100644 --- a/src/dwarf/dwarf.c +++ b/src/dwarf/dwarf.c @@ -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); } diff --git a/src/dwarf/dwarf.h b/src/dwarf/dwarf.h index b22e1623..7239aefb 100644 --- a/src/dwarf/dwarf.h +++ b/src/dwarf/dwarf.h @@ -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 diff --git a/src/dwarf/dwarf_parse_2.c b/src/dwarf/dwarf_parse_2.c index d4e86ed9..6da9c57a 100644 --- a/src/dwarf/dwarf_parse_2.c +++ b/src/dwarf/dwarf_parse_2.c @@ -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; diff --git a/src/dwarf/dwarf_parse_2.h b/src/dwarf/dwarf_parse_2.h index d8096846..cf69a1fc 100644 --- a/src/dwarf/dwarf_parse_2.h +++ b/src/dwarf/dwarf_parse_2.h @@ -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 diff --git a/src/rdi_from_dwarf/rdi_from_dwarf_2.c b/src/rdi_from_dwarf/rdi_from_dwarf_2.c index f3e9bcd2..17939b5a 100644 --- a/src/rdi_from_dwarf/rdi_from_dwarf_2.c +++ b/src/rdi_from_dwarf/rdi_from_dwarf_2.c @@ -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 //