mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-07-27 18:00:12 +00:00
consistency pass over dwarf layer
This commit is contained in:
+33
-33
@@ -70,10 +70,10 @@ dw_reg_pos_from_code(Arch arch, DW_Reg reg_code)
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind_v2(DW_AttribKind k)
|
||||
dw_attrib_class_from_attrib_v2(DW_AttribKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_C) case DW_Attrib_##_N: return _C;
|
||||
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
||||
DW_AttribKind_ClassFlags_V2_XList(X)
|
||||
#undef X
|
||||
}
|
||||
@@ -81,10 +81,10 @@ dw_attrib_class_from_attrib_kind_v2(DW_AttribKind k)
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind_v3(DW_AttribKind k)
|
||||
dw_attrib_class_from_attrib_v3(DW_AttribKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_C) case DW_Attrib_##_N: return _C;
|
||||
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
||||
DW_AttribKind_ClassFlags_V3_XList(X)
|
||||
#undef X
|
||||
}
|
||||
@@ -92,10 +92,10 @@ dw_attrib_class_from_attrib_kind_v3(DW_AttribKind k)
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind_v4(DW_AttribKind k)
|
||||
dw_attrib_class_from_attrib_v4(DW_AttribKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_C) case DW_Attrib_##_N: return _C;
|
||||
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
||||
DW_AttribKind_ClassFlags_V4_XList(X)
|
||||
#undef X
|
||||
}
|
||||
@@ -103,10 +103,10 @@ dw_attrib_class_from_attrib_kind_v4(DW_AttribKind k)
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind_v5(DW_AttribKind k)
|
||||
dw_attrib_class_from_attrib_v5(DW_AttribKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_C) case DW_Attrib_##_N: return _C;
|
||||
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
||||
DW_AttribKind_ClassFlags_V5_XList(X)
|
||||
#undef X
|
||||
}
|
||||
@@ -114,10 +114,10 @@ dw_attrib_class_from_attrib_kind_v5(DW_AttribKind k)
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind_gnu(DW_AttribKind k)
|
||||
dw_attrib_class_from_attrib_gnu(DW_AttribKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_C) case DW_Attrib_##_N: return _C;
|
||||
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
||||
DW_AttribKind_ClassFlags_GNU_XList(X)
|
||||
#undef X
|
||||
}
|
||||
@@ -125,10 +125,10 @@ dw_attrib_class_from_attrib_kind_gnu(DW_AttribKind k)
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind_llvm(DW_AttribKind k)
|
||||
dw_attrib_class_from_attrib_llvm(DW_AttribKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_C) case DW_Attrib_##_N: return _C;
|
||||
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
||||
DW_AttribKind_ClassFlags_LLVM_XList(X)
|
||||
#undef X
|
||||
}
|
||||
@@ -136,10 +136,10 @@ dw_attrib_class_from_attrib_kind_llvm(DW_AttribKind k)
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind_apple(DW_AttribKind k)
|
||||
dw_attrib_class_from_attrib_apple(DW_AttribKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_C) case DW_Attrib_##_N: return _C;
|
||||
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
||||
DW_AttribKind_ClassFlags_APPLE_XList(X)
|
||||
#undef X
|
||||
}
|
||||
@@ -147,10 +147,10 @@ dw_attrib_class_from_attrib_kind_apple(DW_AttribKind k)
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind_mips(DW_AttribKind k)
|
||||
dw_attrib_class_from_attrib_mips(DW_AttribKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_C) case DW_Attrib_##_N: return _C;
|
||||
#define X(_N,_C) case DW_AttribKind_##_N: return _C;
|
||||
DW_AttribKind_ClassFlags_MIPS_XList(X)
|
||||
#undef X
|
||||
}
|
||||
@@ -158,7 +158,7 @@ dw_attrib_class_from_attrib_kind_mips(DW_AttribKind k)
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind(DW_Version ver, DW_Ext ext, DW_AttribKind k)
|
||||
dw_attrib_class_from_attrib(DW_Version ver, DW_Ext ext, DW_AttribKind k)
|
||||
{
|
||||
DW_AttribClass result = DW_AttribClass_Null;
|
||||
|
||||
@@ -172,10 +172,10 @@ dw_attrib_class_from_attrib_kind(DW_Version ver, DW_Ext ext, DW_AttribKind k)
|
||||
|
||||
switch (flag) {
|
||||
case DW_Ext_Null: break;
|
||||
case DW_Ext_GNU: result = dw_attrib_class_from_attrib_kind_gnu(k); break;
|
||||
case DW_Ext_LLVM: result = dw_attrib_class_from_attrib_kind_llvm(k); break;
|
||||
case DW_Ext_APPLE: result = dw_attrib_class_from_attrib_kind_apple(k); break;
|
||||
case DW_Ext_MIPS: result = dw_attrib_class_from_attrib_kind_mips(k); break;
|
||||
case DW_Ext_GNU: result = dw_attrib_class_from_attrib_gnu(k); break;
|
||||
case DW_Ext_LLVM: result = dw_attrib_class_from_attrib_llvm(k); break;
|
||||
case DW_Ext_APPLE: result = dw_attrib_class_from_attrib_apple(k); break;
|
||||
case DW_Ext_MIPS: result = dw_attrib_class_from_attrib_mips(k); break;
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
|
||||
@@ -188,10 +188,10 @@ dw_attrib_class_from_attrib_kind(DW_Version ver, DW_Ext ext, DW_AttribKind k)
|
||||
switch (ver) {
|
||||
case DW_Version_Null: break;
|
||||
case DW_Version_1: AssertAlways(!"DWARF V1 is not supported"); break;
|
||||
case DW_Version_2: result = dw_attrib_class_from_attrib_kind_v2(k); break;
|
||||
case DW_Version_3: result = dw_attrib_class_from_attrib_kind_v3(k); break;
|
||||
case DW_Version_4: result = dw_attrib_class_from_attrib_kind_v4(k); break;
|
||||
case DW_Version_5: result = dw_attrib_class_from_attrib_kind_v5(k); break;
|
||||
case DW_Version_2: result = dw_attrib_class_from_attrib_v2(k); break;
|
||||
case DW_Version_3: result = dw_attrib_class_from_attrib_v3(k); break;
|
||||
case DW_Version_4: result = dw_attrib_class_from_attrib_v4(k); break;
|
||||
case DW_Version_5: result = dw_attrib_class_from_attrib_v5(k); break;
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
}
|
||||
@@ -302,14 +302,14 @@ dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, B32 relaxed, DW_AttribKin
|
||||
// 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_kind(ver, ext, attrib_kind);
|
||||
DW_AttribClass attrib_class = dw_attrib_class_from_attrib(ver, ext, attrib_kind);
|
||||
DW_AttribClass form_class = dw_attrib_class_from_form_kind(ver, form_kind);
|
||||
|
||||
if(relaxed)
|
||||
{
|
||||
if(attrib_class == DW_AttribClass_Null || form_class == DW_AttribClass_Null)
|
||||
{
|
||||
attrib_class = dw_attrib_class_from_attrib_kind(DW_Version_Last, ext, attrib_kind);
|
||||
attrib_class = dw_attrib_class_from_attrib(DW_Version_Last, ext, attrib_kind);
|
||||
form_class = dw_attrib_class_from_form_kind(DW_Version_Last, form_kind);
|
||||
}
|
||||
}
|
||||
@@ -434,11 +434,11 @@ internal String8
|
||||
dw_string_from_tag_kind(Arena *arena, DW_TagKind kind)
|
||||
{
|
||||
switch (kind) {
|
||||
case DW_Tag_Null: return str8_lit("Null");
|
||||
#define X(_N,_ID) case DW_Tag_##_N: return str8_lit(Stringify(_N));
|
||||
DW_Tag_V3_XList(X)
|
||||
DW_Tag_V5_XList(X)
|
||||
DW_Tag_GNU_XList(X)
|
||||
case DW_TagKind_Null: return str8_lit("Null");
|
||||
#define X(_N,_ID) case DW_TagKind_##_N: return str8_lit(Stringify(_N));
|
||||
DW_TagKind_V3_XList(X)
|
||||
DW_TagKind_V5_XList(X)
|
||||
DW_TagKind_GNU_XList(X)
|
||||
#undef X
|
||||
}
|
||||
return push_str8f(arena, "%llx", kind);
|
||||
@@ -447,7 +447,7 @@ dw_string_from_tag_kind(Arena *arena, DW_TagKind kind)
|
||||
internal String8
|
||||
dw_string_from_attrib_kind(Arena *arena, DW_Version ver, DW_Ext ext, DW_AttribKind kind)
|
||||
{
|
||||
#define X(_N,...) case DW_Attrib_##_N: return str8_lit(Stringify(_N));
|
||||
#define X(_N,...) case DW_AttribKind_##_N: return str8_lit(Stringify(_N));
|
||||
|
||||
while (ext) {
|
||||
U64 z = 64-clz64(ext);
|
||||
|
||||
+24
-24
@@ -188,7 +188,7 @@ typedef enum DW_IDCaseKindEnum
|
||||
#undef X
|
||||
} DW_IDCaseKindEnum;
|
||||
|
||||
#define DW_Tag_V3_XList(X) \
|
||||
#define DW_TagKind_V3_XList(X) \
|
||||
X(ArrayType, 0x01) \
|
||||
X(ClassType, 0x02) \
|
||||
X(EntryPoint, 0x03) \
|
||||
@@ -247,7 +247,7 @@ X(ImportedUnit, 0x3d) \
|
||||
X(Condition, 0x3f) \
|
||||
X(SharedType, 0x40)
|
||||
|
||||
#define DW_Tag_V5_XList(X) \
|
||||
#define DW_TagKind_V5_XList(X) \
|
||||
X(TypeUnit, 0x41) \
|
||||
X(RValueReferenceType, 0x42) \
|
||||
X(TemplateAlias, 0x43) \
|
||||
@@ -260,21 +260,21 @@ X(CallSiteParameter, 0x49) \
|
||||
X(SkeletonUnit, 0x4A) \
|
||||
X(ImmutableType, 0x4B)
|
||||
|
||||
#define DW_Tag_GNU_XList(X) \
|
||||
#define DW_TagKind_GNU_XList(X) \
|
||||
X(GNU_CallSite, 0x4109) \
|
||||
X(GNU_CallSiteParameter, 0x410a)
|
||||
|
||||
typedef U64 DW_TagKind;
|
||||
typedef enum DW_TagKindEnum
|
||||
{
|
||||
DW_Tag_Null,
|
||||
#define X(_N,_ID) DW_Tag_##_N = _ID,
|
||||
DW_Tag_V3_XList(X)
|
||||
DW_Tag_V5_XList(X)
|
||||
DW_Tag_GNU_XList(X)
|
||||
DW_TagKind_Null,
|
||||
#define X(_N,_ID) DW_TagKind_##_N = _ID,
|
||||
DW_TagKind_V3_XList(X)
|
||||
DW_TagKind_V5_XList(X)
|
||||
DW_TagKind_GNU_XList(X)
|
||||
#undef X
|
||||
DW_Tag_UserLo = 0x4080,
|
||||
DW_Tag_UserHi = 0xffff
|
||||
DW_TagKind_UserLo = 0x4080,
|
||||
DW_TagKind_UserHi = 0xffff
|
||||
} DW_TagKindEnum;
|
||||
|
||||
//- Attrib Class Encodings
|
||||
@@ -581,7 +581,7 @@ X(Producer, DW_AttribClass_String)
|
||||
X(Prototyped, DW_AttribClass_Flag) \
|
||||
X(ReturnAddr, DW_AttribClass_Block|DW_AttribClass_Const) \
|
||||
X(StartScope, DW_AttribClass_Const) \
|
||||
X(BitStride, DW_AttribClass_Const) /* dwarf-v1 DW_Attrib_stride_size*/ \
|
||||
X(BitStride, DW_AttribClass_Const) /* dwarf-v1 DW_AttribKind_stride_size*/ \
|
||||
X(UpperBound, DW_AttribClass_Const|DW_AttribClass_Reference) \
|
||||
X(AbstractOrigin, DW_AttribClass_Reference) \
|
||||
X(Accessibility, DW_AttribClass_Const) \
|
||||
@@ -1159,8 +1159,8 @@ X(MIPS_AssumedSize, DW_AttribClass_Reference)
|
||||
typedef U32 DW_AttribKind;
|
||||
typedef enum DW_AttribKindEnum
|
||||
{
|
||||
DW_Attrib_Null,
|
||||
#define X(_N,_ID,...) DW_Attrib_##_N = _ID,
|
||||
DW_AttribKind_Null,
|
||||
#define X(_N,_ID,...) DW_AttribKind_##_N = _ID,
|
||||
DW_AttribKind_V2_XList(X)
|
||||
DW_AttribKind_V3_XList(X)
|
||||
DW_AttribKind_V4_XList(X)
|
||||
@@ -1170,8 +1170,8 @@ typedef enum DW_AttribKindEnum
|
||||
DW_AttribKind_APPLE_XList(X)
|
||||
DW_AttribKind_MIPS_XList(X)
|
||||
#undef X
|
||||
DW_Attrib_UserLo = 0x2000,
|
||||
DW_Attrib_UserHi = 0x3fff
|
||||
DW_AttribKind_UserLo = 0x2000,
|
||||
DW_AttribKind_UserHi = 0x3fff
|
||||
} DW_AttribKindEnum;
|
||||
|
||||
#define DW_ATE_XList(X) \
|
||||
@@ -1744,18 +1744,18 @@ internal U64 dw_reg_pos_from_code(Arch arch, DW_Reg reg_code);
|
||||
//- Attrib Class Encodings
|
||||
|
||||
// Speced Encodings
|
||||
internal DW_AttribClass dw_attrib_class_from_attrib_kind_v2(DW_AttribKind k);
|
||||
internal DW_AttribClass dw_attrib_class_from_attrib_kind_v3(DW_AttribKind k);
|
||||
internal DW_AttribClass dw_attrib_class_from_attrib_kind_v4(DW_AttribKind k);
|
||||
internal DW_AttribClass dw_attrib_class_from_attrib_kind_v5(DW_AttribKind k);
|
||||
internal DW_AttribClass dw_attrib_class_from_attrib_v2(DW_AttribKind k);
|
||||
internal DW_AttribClass dw_attrib_class_from_attrib_v3(DW_AttribKind k);
|
||||
internal DW_AttribClass dw_attrib_class_from_attrib_v4(DW_AttribKind k);
|
||||
internal DW_AttribClass dw_attrib_class_from_attrib_v5(DW_AttribKind k);
|
||||
|
||||
// Extensions
|
||||
internal DW_AttribClass dw_attrib_class_from_attrib_kind_gnu (DW_AttribKind k);
|
||||
internal DW_AttribClass dw_attrib_class_from_attrib_kind_llvm (DW_AttribKind k);
|
||||
internal DW_AttribClass dw_attrib_class_from_attrib_kind_apple(DW_AttribKind k);
|
||||
internal DW_AttribClass dw_attrib_class_from_attrib_kind_mips (DW_AttribKind k);
|
||||
internal DW_AttribClass dw_attrib_class_from_attrib_gnu (DW_AttribKind k);
|
||||
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_kind(DW_Version ver, DW_Ext ext, DW_AttribKind v);
|
||||
internal DW_AttribClass dw_attrib_class_from_attrib(DW_Version ver, DW_Ext ext, DW_AttribKind v);
|
||||
|
||||
//- Form Class Encodings
|
||||
|
||||
|
||||
+345
-287
@@ -628,260 +628,7 @@ dw_print_eh_frame(Arena *arena, String8List *out, String8 indent, String8 raw_eh
|
||||
internal void
|
||||
dw_print_debug_info(Arena *arena, String8List *out, String8 indent, DW_Input *input, DW_ListUnitInput lu_input, Arch arch, B32 relaxed)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
|
||||
Rng1U64List cu_ranges = dw_unit_ranges_from_data(scratch.arena, input->sec[DW_Section_Info].data);
|
||||
|
||||
if (cu_ranges.count > 0) {
|
||||
rd_printf("# %S", input->sec[DW_Section_Info].name);
|
||||
rd_indent();
|
||||
}
|
||||
|
||||
U64 comp_idx = 0;
|
||||
for (Rng1U64Node *cu_range_n = cu_ranges.first; cu_range_n != 0; cu_range_n = cu_range_n->next, ++comp_idx) {
|
||||
Temp comp_temp = temp_begin(scratch.arena);
|
||||
|
||||
U64 cu_base = cu_range_n->v.min;
|
||||
Rng1U64 cu_range = cu_range_n->v;
|
||||
DW_CompUnit cu = dw_cu_from_info_off(comp_temp.arena, input, lu_input, cu_range.min, relaxed);
|
||||
|
||||
String8 cu_dir = dw_string_from_attrib (input, &cu, cu.tag, DW_Attrib_CompDir );
|
||||
String8 cu_name = dw_string_from_attrib (input, &cu, cu.tag, DW_Attrib_Name );
|
||||
String8 stmt_list = dw_line_ptr_from_attrib(input, &cu, cu.tag, DW_Attrib_StmtList);
|
||||
|
||||
DW_LineVMHeader line_vm = {0};
|
||||
dw_read_line_vm_header(comp_temp.arena, stmt_list, 0, input, cu_dir, cu_name, cu.address_size, cu.str_offsets_lu, &line_vm);
|
||||
|
||||
// print comp info
|
||||
rd_printf("Compilation Unit #%u", comp_idx);
|
||||
rd_indent();
|
||||
rd_printf("Version: %u", cu.version);
|
||||
rd_printf("Address Size: %llu", cu.address_size);
|
||||
rd_printf("Abbrev Offset: %#llx", cu.abbrev_off);
|
||||
rd_printf("Info Range: %#llx-%#llx (%M)", cu.info_range.min, cu.info_range.max, dim_1u64(cu.info_range));
|
||||
rd_newline();
|
||||
|
||||
// prase tags
|
||||
U32 tag_depth = 0;
|
||||
for (U64 info_off = cu.first_tag_info_off; info_off < cu.info_range.max; ) {
|
||||
Temp tag_temp = temp_begin(scratch.arena);
|
||||
|
||||
U64 tag_info_off = info_off;
|
||||
DW_Tag tag = {0};
|
||||
info_off += dw_read_tag_cu(tag_temp.arena, input, &cu, tag_info_off, &tag);
|
||||
|
||||
String8 tag_str = dw_string_from_tag_kind(tag_temp.arena, tag.kind);
|
||||
rd_printf("<%x><%llx> DW_Tag_%S (Abbrev Number: %llu)", tag_depth, tag_info_off, tag_str, tag.abbrev_id);
|
||||
rd_indent();
|
||||
|
||||
// parse attributes
|
||||
for (DW_AttribNode *attrib_n = tag.attribs.first; attrib_n != 0; attrib_n = attrib_n->next) {
|
||||
Temp attrib_temp = temp_begin(tag_temp.arena);
|
||||
|
||||
DW_Attrib *attrib = &attrib_n->v;
|
||||
|
||||
String8List attrib_list = {0};
|
||||
|
||||
// attribute .debug_info offset
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "<%llx> ", attrib->info_off);
|
||||
|
||||
// attribute kind
|
||||
String8 attrib_kind_str = dw_string_from_attrib_kind(attrib_temp.arena, cu.version, cu.ext, attrib->attrib_kind);
|
||||
if (attrib_kind_str.size == 0) {
|
||||
if (relaxed) {
|
||||
attrib_kind_str = dw_string_from_attrib_kind(attrib_temp.arena, DW_Version_Last, cu.ext, attrib->attrib_kind);
|
||||
}
|
||||
}
|
||||
if (attrib_kind_str.size == 0) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "Unknown(%#x) ", attrib->attrib_kind);
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "DW_Attrib_%-20S ", attrib_kind_str);
|
||||
}
|
||||
|
||||
// form kind
|
||||
String8 form_kind_str = dw_string_from_form_kind(scratch.arena, cu.version, attrib->form_kind);
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "DW_Form_%-15S", form_kind_str);
|
||||
|
||||
DW_AttribClass value_class = dw_value_class_from_attrib(&cu, attrib);
|
||||
switch (value_class) {
|
||||
default: {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unknown value class");
|
||||
} break;
|
||||
case DW_AttribClass_Undefined: {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: undefined value class");
|
||||
} break;
|
||||
case DW_AttribClass_Address: {
|
||||
U64 address = dw_address_from_attrib_ptr(input, &cu, attrib);
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", address);
|
||||
} break;
|
||||
case DW_AttribClass_Block: {
|
||||
String8 block = dw_block_from_attrib_ptr(input, &cu, attrib);
|
||||
String8List block_strs = numeric_str8_list_from_data(attrib_temp.arena, 16, block, 1);
|
||||
String8 block_str = str8_list_join(attrib_temp.arena, &block_strs, &(StringJoin){.sep = str8_lit(", ")});
|
||||
str8_list_push(attrib_temp.arena, &attrib_list, block_str);
|
||||
} break;
|
||||
case DW_AttribClass_Const: {
|
||||
U64 constant = dw_const_u64_from_attrib_ptr(input, &cu, attrib);
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", constant);
|
||||
} break;
|
||||
case DW_AttribClass_ExprLoc: {
|
||||
String8 exprloc = dw_exprloc_from_attrib_ptr(input, &cu, attrib);
|
||||
String8 exprloc_str = dw_format_expression_single_line(attrib_temp.arena, exprloc, cu_base, cu.address_size, arch, cu.version, cu.ext, cu.format);
|
||||
str8_list_push(attrib_temp.arena, &attrib_list, exprloc_str);
|
||||
} break;
|
||||
case DW_AttribClass_Flag: {
|
||||
B32 flag = dw_flag_from_attrib_ptr(input, &cu, attrib);
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%llu (%s)", flag, flag == 0 ? "false" : "true");
|
||||
} break;
|
||||
case DW_AttribClass_LinePtr: {
|
||||
if (attrib->form_kind == DW_Form_SecOffset) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unexpected form %S", dw_string_from_form_kind(attrib_temp.arena, cu.version, attrib->form_kind));
|
||||
}
|
||||
} break;
|
||||
case DW_AttribClass_LocListPtr: {
|
||||
if (attrib->form_kind == DW_Form_SecOffset) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unexpected form %S", dw_string_from_form_kind(attrib_temp.arena, cu.version, attrib->form_kind));
|
||||
}
|
||||
} break;
|
||||
case DW_AttribClass_MacPtr: {
|
||||
if (attrib->form_kind == DW_Form_SecOffset) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "\?\?\?");
|
||||
}
|
||||
} break;
|
||||
case DW_AttribClass_RngListPtr: {
|
||||
if (attrib->form_kind == DW_Form_SecOffset) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "\?\?\?");
|
||||
}
|
||||
} break;
|
||||
case DW_AttribClass_RngList: {
|
||||
if (attrib->form_kind == DW_Form_SecOffset) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "\?\?\?");
|
||||
}
|
||||
} break;
|
||||
case DW_AttribClass_Reference: {
|
||||
if (attrib->form_kind == DW_Form_Ref1 ||
|
||||
attrib->form_kind == DW_Form_Ref2 ||
|
||||
attrib->form_kind == DW_Form_Ref4 ||
|
||||
attrib->form_kind == DW_Form_Ref8 ||
|
||||
attrib->form_kind == DW_Form_RefUData) {
|
||||
U64 info_off = cu.info_range.min + attrib->form.ref;
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "<%llx>", info_off);
|
||||
if (!contains_1u64(cu.info_range, attrib->form.ref)) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "(ERROR: out of bounds reference)");
|
||||
}
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.ref);
|
||||
}
|
||||
} break;
|
||||
case DW_AttribClass_String: {
|
||||
if (attrib->form_kind == DW_Form_Strp) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
|
||||
}
|
||||
String8 string = dw_string_from_attrib_ptr(input, &cu, attrib);
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "(%S)", string);
|
||||
} break;
|
||||
case DW_AttribClass_StrOffsetsPtr: {
|
||||
if (attrib->form_kind == DW_Form_SecOffset) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unexpected form %S", dw_string_from_form_kind(attrib_temp.arena, cu.version, attrib->form_kind));
|
||||
}
|
||||
} break;
|
||||
case DW_AttribClass_AddrPtr: {
|
||||
if (attrib->form_kind == DW_Form_SecOffset) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unexpected form %S", dw_string_from_form_kind(attrib_temp.arena, cu.version, attrib->form_kind));
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
String8 attrib_str = {0};
|
||||
switch (attrib->attrib_kind) {
|
||||
case DW_Attrib_Language: {
|
||||
DW_Language lang = dw_const_u64_from_attrib_ptr(input, &cu, attrib);
|
||||
attrib_str = dw_string_from_language(attrib_temp.arena, lang);
|
||||
} break;
|
||||
case DW_Attrib_DeclFile: {
|
||||
U64 file_idx = dw_const_u64_from_attrib_ptr(input, &cu, attrib);
|
||||
DW_LineFile *file = dw_file_from_attrib_ptr(&cu, &line_vm, attrib);
|
||||
attrib_str = str8_lit("\?\?\?");
|
||||
if (file) {
|
||||
attrib_str = dw_path_from_file(attrib_temp.arena, &line_vm, file);
|
||||
}
|
||||
} break;
|
||||
case DW_Attrib_DeclLine: {
|
||||
U64 line = dw_const_u64_from_attrib_ptr(input, &cu, attrib);
|
||||
attrib_str = push_str8f(attrib_temp.arena, "%llu", line);
|
||||
} break;
|
||||
case DW_Attrib_Inline: {
|
||||
DW_InlKind inl = dw_const_u64_from_attrib_ptr(input, &cu, attrib);
|
||||
attrib_str = dw_string_from_inl(attrib_temp.arena, inl);
|
||||
} break;
|
||||
case DW_Attrib_Accessibility: {
|
||||
DW_AccessKind access = dw_const_u64_from_attrib_ptr(input, &cu, attrib);
|
||||
attrib_str = dw_string_from_access_kind(attrib_temp.arena, access);
|
||||
} break;
|
||||
case DW_Attrib_CallingConvention: {
|
||||
DW_CallingConventionKind calling_convetion = dw_const_u64_from_attrib_ptr(input, &cu, attrib);
|
||||
attrib_str = dw_string_from_calling_convetion(attrib_temp.arena, calling_convetion);
|
||||
} break;
|
||||
case DW_Attrib_Encoding: {
|
||||
DW_ATE encoding = dw_const_u64_from_attrib_ptr(input, &cu, attrib);
|
||||
attrib_str = dw_string_from_attrib_type_encoding(attrib_temp.arena, encoding);
|
||||
} break;
|
||||
}
|
||||
|
||||
if (attrib_str.size) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "(%S)", attrib_str);
|
||||
}
|
||||
String8 print = str8_list_join(attrib_temp.arena, &attrib_list, &(StringJoin){.sep=str8_lit(" ")});
|
||||
rd_printf("%S", print);
|
||||
|
||||
temp_end(attrib_temp);
|
||||
}
|
||||
|
||||
B32 is_ender_tag = tag.abbrev_id == 0;
|
||||
if (tag.has_children) {
|
||||
if (is_ender_tag) {
|
||||
rd_errorf("null-tag cannot have children");
|
||||
}
|
||||
rd_indent();
|
||||
tag_depth += 1;
|
||||
}
|
||||
if (is_ender_tag) {
|
||||
if (tag_depth == 0) {
|
||||
rd_errorf("malformed data detected, too many null tags");
|
||||
} else {
|
||||
rd_unindent();
|
||||
tag_depth -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
rd_unindent();
|
||||
temp_end(tag_temp);
|
||||
}
|
||||
temp_end(comp_temp);
|
||||
|
||||
rd_unindent();
|
||||
rd_newline();
|
||||
}
|
||||
|
||||
if (cu_ranges.count > 0) {
|
||||
rd_unindent();
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
internal void
|
||||
@@ -914,7 +661,7 @@ dw_print_debug_abbrev(Arena *arena, String8List *out, String8 indent, DW_Input *
|
||||
cursor += str8_deserial_read_uleb128(raw_abbrev, cursor, &tag);
|
||||
cursor += str8_deserial_read_struct(raw_abbrev, cursor, &has_children);
|
||||
|
||||
rd_printf("<%llx> %llu DW_Tag_%S %s", id_off, id, dw_string_from_tag_kind(temp.arena, tag), has_children ? "[has children]" : "[no children]");
|
||||
rd_printf("<%llx> %llu DW_TagKind_%S %s", id_off, id, dw_string_from_tag_kind(temp.arena, tag), has_children ? "[has children]" : "[no children]");
|
||||
rd_indent();
|
||||
for (;;) {
|
||||
U64 attrib_off = cursor;
|
||||
@@ -927,7 +674,7 @@ dw_print_debug_abbrev(Arena *arena, String8List *out, String8 indent, DW_Input *
|
||||
}
|
||||
String8 attrib_str = dw_string_from_attrib_kind(temp.arena, DW_Version_Last, DW_Ext_All, attrib_id);
|
||||
String8 form_str = dw_string_from_form_kind(temp.arena, DW_Version_Last, form_id);
|
||||
rd_printf("<%llx> DW_Attrib_%-20S DW_Form_%S", attrib_off, attrib_str, form_str);
|
||||
rd_printf("<%llx> DW_AttribKind_%-20S DW_Form_%S", attrib_off, attrib_str, form_str);
|
||||
}
|
||||
rd_unindent();
|
||||
|
||||
@@ -2146,58 +1893,369 @@ dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 indent, DW_In
|
||||
#endif
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_format(Arena *arena, String8List *out, String8 indent, DW_DumpSubsetFlags subset_flags, DW_Input *input, Arch arch, ExecutableImageKind image_type)
|
||||
internal String8List
|
||||
dw_dump_list_from_sections(Arena *arena, DW_Input *input, Arch arch, ExecutableImageKind image_type, DW_DumpSubsetFlags subset_flags)
|
||||
{
|
||||
String8List strings = {0};
|
||||
String8 indent = str8_lit(" ");
|
||||
#define dump(str) str8_list_push(arena, &strings, (str))
|
||||
#define dumpf(...) str8_list_pushf(arena, &strings, __VA_ARGS__)
|
||||
#define DumpSubset(name) if(subset_flags & DW_DumpSubsetFlag_##name) DeferLoop(dumpf("# %S\n\n", dw_name_title_from_dump_subset_table[DW_DumpSubset_##name]), dump(str8_lit("\n")))
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
|
||||
Rng1U64Array segment_vranges = {0};
|
||||
|
||||
DW_ListUnitInput lu_input = dw_list_unit_input_from_input(scratch.arena, input);
|
||||
Rng1U64List unit_ranges_list = dw_unit_ranges_from_data(scratch.arena, input->sec[DW_Section_Info].data);
|
||||
Rng1U64Array unit_ranges = rng1u64_array_from_list(scratch.arena, &unit_ranges_list);
|
||||
B32 relaxed = 1;
|
||||
|
||||
if (subset_flags & DW_DumpSubsetFlag_DebugInfo) {
|
||||
dw_print_debug_info(arena, out, indent, input, lu_input, arch, relaxed);
|
||||
//////////////////////////////
|
||||
//- rjf: dump .debug_info
|
||||
//
|
||||
DumpSubset(DebugInfo)
|
||||
{
|
||||
for EachIndex(unit_idx, unit_ranges.count)
|
||||
{
|
||||
Temp unit_temp = temp_begin(scratch.arena);
|
||||
|
||||
//- rjf: unpack unit
|
||||
Rng1U64 unit_range = unit_ranges.v[unit_idx];
|
||||
DW_CompUnit unit = dw_cu_from_info_off(unit_temp.arena, input, lu_input, unit_range.min, relaxed);
|
||||
String8 unit_dir = dw_string_from_attrib(input, &unit, unit.tag, DW_AttribKind_CompDir );
|
||||
String8 unit_name = dw_string_from_attrib(input, &unit, unit.tag, DW_AttribKind_Name );
|
||||
String8 stmt_list = dw_line_ptr_from_attrib(input, &unit, unit.tag, DW_AttribKind_StmtList);
|
||||
DW_LineVMHeader line_vm = {0};
|
||||
dw_read_line_vm_header(unit_temp.arena, stmt_list, 0, input, unit_dir, unit_name, unit.address_size, unit.str_offsets_lu, &line_vm);
|
||||
|
||||
//- rjf: log top-level unit info
|
||||
dumpf("unit: // compile_unit[%u]\n{\n", unit_idx);
|
||||
dumpf(" version: %u\n", unit.version);
|
||||
dumpf(" address_size: %I64u\n", unit.address_size);
|
||||
dumpf(" abbrev_off: 0x%I64x\n", unit.abbrev_off);
|
||||
dumpf(" info_range: [0x%I64x, 0x%I64x) // (%M)\n", unit.info_range.min, unit.info_range.max, dim_1u64(unit.info_range));
|
||||
|
||||
//- rjf: log tags
|
||||
S64 tag_depth = 0;
|
||||
for(U64 info_off = unit.first_tag_info_off; info_off < unit.info_range.max;)
|
||||
{
|
||||
// rjf: unpack tag
|
||||
Temp tag_temp = temp_begin(scratch.arena);
|
||||
U64 tag_info_off = info_off;
|
||||
DW_Tag tag = {0};
|
||||
info_off += dw_read_tag_cu(tag_temp.arena, input, &unit, tag_info_off, &tag);
|
||||
|
||||
String8 tag_str = dw_string_from_tag_kind(tag_temp.arena, tag.kind);
|
||||
rd_printf("<%x><%llx> DW_TagKind_%S (Abbrev Number: %llu)", tag_depth, tag_info_off, tag_str, tag.abbrev_id);
|
||||
rd_indent();
|
||||
|
||||
// parse attributes
|
||||
for (DW_AttribNode *attrib_n = tag.attribs.first; attrib_n != 0; attrib_n = attrib_n->next) {
|
||||
Temp attrib_temp = temp_begin(tag_temp.arena);
|
||||
|
||||
DW_Attrib *attrib = &attrib_n->v;
|
||||
|
||||
String8List attrib_list = {0};
|
||||
|
||||
// attribute .debug_info offset
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "<%llx> ", attrib->info_off);
|
||||
|
||||
// attribute kind
|
||||
String8 attrib_kind_str = dw_string_from_attrib_kind(attrib_temp.arena, unit.version, unit.ext, attrib->attrib_kind);
|
||||
if (attrib_kind_str.size == 0) {
|
||||
if (relaxed) {
|
||||
attrib_kind_str = dw_string_from_attrib_kind(attrib_temp.arena, DW_Version_Last, unit.ext, attrib->attrib_kind);
|
||||
}
|
||||
}
|
||||
if (attrib_kind_str.size == 0) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "Unknown(%#x) ", attrib->attrib_kind);
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "DW_AttribKind_%-20S ", attrib_kind_str);
|
||||
}
|
||||
|
||||
// form kind
|
||||
String8 form_kind_str = dw_string_from_form_kind(scratch.arena, unit.version, attrib->form_kind);
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "DW_Form_%-15S", form_kind_str);
|
||||
|
||||
DW_AttribClass value_class = dw_value_class_from_attrib(&unit, attrib);
|
||||
switch (value_class) {
|
||||
default: {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unknown value class");
|
||||
} break;
|
||||
case DW_AttribClass_Undefined: {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: undefined value class");
|
||||
} break;
|
||||
case DW_AttribClass_Address: {
|
||||
U64 address = dw_address_from_attrib_ptr(input, &unit, attrib);
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", address);
|
||||
} break;
|
||||
case DW_AttribClass_Block: {
|
||||
String8 block = dw_block_from_attrib_ptr(input, &unit, attrib);
|
||||
String8List block_strs = numeric_str8_list_from_data(attrib_temp.arena, 16, block, 1);
|
||||
String8 block_str = str8_list_join(attrib_temp.arena, &block_strs, &(StringJoin){.sep = str8_lit(", ")});
|
||||
str8_list_push(attrib_temp.arena, &attrib_list, block_str);
|
||||
} break;
|
||||
case DW_AttribClass_Const: {
|
||||
U64 constant = dw_const_u64_from_attrib_ptr(input, &unit, attrib);
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", constant);
|
||||
} break;
|
||||
case DW_AttribClass_ExprLoc: {
|
||||
String8 exprloc = dw_exprloc_from_attrib_ptr(input, &unit, attrib);
|
||||
String8 exprloc_str = dw_format_expression_single_line(attrib_temp.arena, exprloc, unit_range.min, unit.address_size, arch, unit.version, unit.ext, unit.format);
|
||||
str8_list_push(attrib_temp.arena, &attrib_list, exprloc_str);
|
||||
} break;
|
||||
case DW_AttribClass_Flag: {
|
||||
B32 flag = dw_flag_from_attrib_ptr(input, &unit, attrib);
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%llu (%s)", flag, flag == 0 ? "false" : "true");
|
||||
} break;
|
||||
case DW_AttribClass_LinePtr: {
|
||||
if (attrib->form_kind == DW_Form_SecOffset) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unexpected form %S", dw_string_from_form_kind(attrib_temp.arena, unit.version, attrib->form_kind));
|
||||
}
|
||||
} break;
|
||||
case DW_AttribClass_LocListPtr: {
|
||||
if (attrib->form_kind == DW_Form_SecOffset) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unexpected form %S", dw_string_from_form_kind(attrib_temp.arena, unit.version, attrib->form_kind));
|
||||
}
|
||||
} break;
|
||||
case DW_AttribClass_MacPtr: {
|
||||
if (attrib->form_kind == DW_Form_SecOffset) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "\?\?\?");
|
||||
}
|
||||
} break;
|
||||
case DW_AttribClass_RngListPtr: {
|
||||
if (attrib->form_kind == DW_Form_SecOffset) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "\?\?\?");
|
||||
}
|
||||
} break;
|
||||
case DW_AttribClass_RngList: {
|
||||
if (attrib->form_kind == DW_Form_SecOffset) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "\?\?\?");
|
||||
}
|
||||
} break;
|
||||
case DW_AttribClass_Reference: {
|
||||
if (attrib->form_kind == DW_Form_Ref1 ||
|
||||
attrib->form_kind == DW_Form_Ref2 ||
|
||||
attrib->form_kind == DW_Form_Ref4 ||
|
||||
attrib->form_kind == DW_Form_Ref8 ||
|
||||
attrib->form_kind == DW_Form_RefUData) {
|
||||
U64 info_off = unit.info_range.min + attrib->form.ref;
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "<%llx>", info_off);
|
||||
if (!contains_1u64(unit.info_range, attrib->form.ref)) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "(ERROR: out of bounds reference)");
|
||||
}
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.ref);
|
||||
}
|
||||
} break;
|
||||
case DW_AttribClass_String: {
|
||||
if (attrib->form_kind == DW_Form_Strp) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
|
||||
}
|
||||
String8 string = dw_string_from_attrib_ptr(input, &unit, attrib);
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "(%S)", string);
|
||||
} break;
|
||||
case DW_AttribClass_StrOffsetsPtr: {
|
||||
if (attrib->form_kind == DW_Form_SecOffset) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unexpected form %S", dw_string_from_form_kind(attrib_temp.arena, unit.version, attrib->form_kind));
|
||||
}
|
||||
} break;
|
||||
case DW_AttribClass_AddrPtr: {
|
||||
if (attrib->form_kind == DW_Form_SecOffset) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "%#llx", attrib->form.sec_offset);
|
||||
} else {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "ERROR: unexpected form %S", dw_string_from_form_kind(attrib_temp.arena, unit.version, attrib->form_kind));
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
String8 attrib_str = {0};
|
||||
switch (attrib->attrib_kind) {
|
||||
case DW_AttribKind_Language: {
|
||||
DW_Language lang = dw_const_u64_from_attrib_ptr(input, &unit, attrib);
|
||||
attrib_str = dw_string_from_language(attrib_temp.arena, lang);
|
||||
} break;
|
||||
case DW_AttribKind_DeclFile: {
|
||||
U64 file_idx = dw_const_u64_from_attrib_ptr(input, &unit, attrib);
|
||||
DW_LineFile *file = dw_file_from_attrib_ptr(&unit, &line_vm, attrib);
|
||||
attrib_str = str8_lit("\?\?\?");
|
||||
if (file) {
|
||||
attrib_str = dw_path_from_file(attrib_temp.arena, &line_vm, file);
|
||||
}
|
||||
} break;
|
||||
case DW_AttribKind_DeclLine: {
|
||||
U64 line = dw_const_u64_from_attrib_ptr(input, &unit, attrib);
|
||||
attrib_str = push_str8f(attrib_temp.arena, "%llu", line);
|
||||
} break;
|
||||
case DW_AttribKind_Inline: {
|
||||
DW_InlKind inl = dw_const_u64_from_attrib_ptr(input, &unit, attrib);
|
||||
attrib_str = dw_string_from_inl(attrib_temp.arena, inl);
|
||||
} break;
|
||||
case DW_AttribKind_Accessibility: {
|
||||
DW_AccessKind access = dw_const_u64_from_attrib_ptr(input, &unit, attrib);
|
||||
attrib_str = dw_string_from_access_kind(attrib_temp.arena, access);
|
||||
} break;
|
||||
case DW_AttribKind_CallingConvention: {
|
||||
DW_CallingConventionKind calling_convetion = dw_const_u64_from_attrib_ptr(input, &unit, attrib);
|
||||
attrib_str = dw_string_from_calling_convetion(attrib_temp.arena, calling_convetion);
|
||||
} break;
|
||||
case DW_AttribKind_Encoding: {
|
||||
DW_ATE encoding = dw_const_u64_from_attrib_ptr(input, &unit, attrib);
|
||||
attrib_str = dw_string_from_attrib_type_encoding(attrib_temp.arena, encoding);
|
||||
} break;
|
||||
}
|
||||
|
||||
if (attrib_str.size) {
|
||||
str8_list_pushf(attrib_temp.arena, &attrib_list, "(%S)", attrib_str);
|
||||
}
|
||||
String8 print = str8_list_join(attrib_temp.arena, &attrib_list, &(StringJoin){.sep=str8_lit(" ")});
|
||||
rd_printf("%S", print);
|
||||
|
||||
temp_end(attrib_temp);
|
||||
}
|
||||
|
||||
B32 is_ender_tag = tag.abbrev_id == 0;
|
||||
if (tag.has_children) {
|
||||
if (is_ender_tag) {
|
||||
rd_errorf("null-tag cannot have children");
|
||||
}
|
||||
rd_indent();
|
||||
tag_depth += 1;
|
||||
}
|
||||
if (is_ender_tag) {
|
||||
if (tag_depth == 0) {
|
||||
rd_errorf("malformed data detected, too many null tags");
|
||||
} else {
|
||||
rd_unindent();
|
||||
tag_depth -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
rd_unindent();
|
||||
temp_end(tag_temp);
|
||||
}
|
||||
temp_end(unit_temp);
|
||||
dumpf("} // compile_unit[/%u]\n\n", unit_idx);
|
||||
}
|
||||
}
|
||||
if (subset_flags & DW_DumpSubsetFlag_DebugAbbrev) {
|
||||
dw_print_debug_abbrev(arena, out, indent, input);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: dump .debug_abbrev
|
||||
//
|
||||
DumpSubset(DebugAbbrev)
|
||||
{
|
||||
// dw_print_debug_abbrev(arena, out, indent, input);
|
||||
}
|
||||
if (subset_flags & DW_DumpSubsetFlag_DebugLine) {
|
||||
dw_print_debug_line(arena, out, indent, input, lu_input, relaxed);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: dump .debug_line
|
||||
//
|
||||
DumpSubset(DebugLine)
|
||||
{
|
||||
// dw_print_debug_line(arena, out, indent, input, lu_input, relaxed);
|
||||
}
|
||||
if (subset_flags & DW_DumpSubsetFlag_DebugStr) {
|
||||
dw_print_debug_str(arena, out, indent, input);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: dump .debug_str
|
||||
//
|
||||
DumpSubset(DebugStr)
|
||||
{
|
||||
// dw_print_debug_str(arena, out, indent, input);
|
||||
}
|
||||
if (subset_flags & DW_DumpSubsetFlag_DebugLoc) {
|
||||
dw_print_debug_loc(arena, out, indent, input, arch, image_type, relaxed);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: dump .debug_loc
|
||||
//
|
||||
DumpSubset(DebugLoc)
|
||||
{
|
||||
// dw_print_debug_loc(arena, out, indent, input, arch, image_type, relaxed);
|
||||
}
|
||||
if (subset_flags & DW_DumpSubsetFlag_DebugRanges) {
|
||||
dw_print_debug_ranges(arena, out, indent, input, arch, image_type, relaxed);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: dump .debug_ranges
|
||||
//
|
||||
DumpSubset(DebugRanges)
|
||||
{
|
||||
// dw_print_debug_ranges(arena, out, indent, input, arch, image_type, relaxed);
|
||||
}
|
||||
if (subset_flags & DW_DumpSubsetFlag_DebugARanges) {
|
||||
dw_print_debug_aranges(arena, out, indent, input);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: dump .debug_aranges
|
||||
//
|
||||
DumpSubset(DebugARanges)
|
||||
{
|
||||
// dw_print_debug_aranges(arena, out, indent, input);
|
||||
}
|
||||
if (subset_flags & DW_DumpSubsetFlag_DebugAddr) {
|
||||
dw_print_debug_addr(arena, out, indent, input);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: dump .debug_addr
|
||||
//
|
||||
DumpSubset(DebugAddr)
|
||||
{
|
||||
// dw_print_debug_addr(arena, out, indent, input);
|
||||
}
|
||||
if (subset_flags & DW_DumpSubsetFlag_DebugLocLists) {
|
||||
dw_print_debug_loclists(arena, out, indent, input, segment_vranges, arch);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: dump .debug_loclists
|
||||
//
|
||||
DumpSubset(DebugLocLists)
|
||||
{
|
||||
// dw_print_debug_loclists(arena, out, indent, input, segment_vranges, arch);
|
||||
}
|
||||
if (subset_flags & DW_DumpSubsetFlag_DebugRngLists) {
|
||||
dw_print_debug_rnglists(arena, out, indent, input, segment_vranges);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: dump .debug_rnglists
|
||||
//
|
||||
DumpSubset(DebugRngLists)
|
||||
{
|
||||
// dw_print_debug_rnglists(arena, out, indent, input, segment_vranges);
|
||||
}
|
||||
if (subset_flags & DW_DumpSubsetFlag_DebugPubNames) {
|
||||
dw_print_debug_pubnames(arena, out, indent, input);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: dump .debug_pubnames
|
||||
//
|
||||
DumpSubset(DebugPubNames)
|
||||
{
|
||||
// dw_print_debug_pubnames(arena, out, indent, input);
|
||||
}
|
||||
if (subset_flags & DW_DumpSubsetFlag_DebugPubTypes) {
|
||||
dw_print_debug_pubtypes(arena, out, indent, input);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: dump .debug_pubtypes
|
||||
//
|
||||
DumpSubset(DebugPubTypes)
|
||||
{
|
||||
// dw_print_debug_pubtypes(arena, out, indent, input);
|
||||
}
|
||||
if (subset_flags & DW_DumpSubsetFlag_DebugLineStr) {
|
||||
dw_print_debug_line_str(arena, out, indent, input);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: dump .debug_linestr
|
||||
//
|
||||
DumpSubset(DebugLineStr)
|
||||
{
|
||||
// dw_print_debug_line_str(arena, out, indent, input);
|
||||
}
|
||||
if (subset_flags & DW_DumpSubsetFlag_DebugStrOffsets) {
|
||||
dw_print_debug_str_offsets(arena, out, indent, input);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: dump .debug_stroffs
|
||||
//
|
||||
DumpSubset(DebugStrOffsets)
|
||||
{
|
||||
// dw_print_debug_str_offsets(arena, out, indent, input);
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
#undef DumpSubset
|
||||
#undef dumpf
|
||||
#undef dump
|
||||
return strings;
|
||||
}
|
||||
|
||||
@@ -72,6 +72,6 @@ internal void dw_print_debug_pubnames (Arena *arena, String8List *out, String8
|
||||
internal void dw_print_debug_pubtypes (Arena *arena, String8List *out, String8 indent, DW_Input *input);
|
||||
internal void dw_print_debug_line_str (Arena *arena, String8List *out, String8 indent, DW_Input *input);
|
||||
internal void dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 indent, DW_Input *input);
|
||||
internal void dw_format(Arena *arena, String8List *out, String8 indent, DW_DumpSubsetFlags subset_flags, DW_Input *input, Arch arch, ExecutableImageKind image_type);
|
||||
internal String8List dw_dump_list_from_sections(Arena *arena, DW_Input *input, Arch arch, ExecutableImageKind image_type, DW_DumpSubsetFlags subset_flags);
|
||||
|
||||
#endif // DWARF_DUMP_H
|
||||
|
||||
+20
-20
@@ -1837,10 +1837,10 @@ dw_attrib_from_tag(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind k
|
||||
{
|
||||
DW_Attrib *attrib = dw_attrib_from_tag_(tag, kind);
|
||||
|
||||
if (attrib->attrib_kind == DW_Attrib_Null) {
|
||||
if (attrib->attrib_kind == DW_AttribKind_Null) {
|
||||
if (cu && cu->tag_ht) {
|
||||
DW_Attrib *ao_attrib = dw_attrib_from_tag_(tag, DW_Attrib_AbstractOrigin);
|
||||
if (ao_attrib->attrib_kind == DW_Attrib_AbstractOrigin) {
|
||||
DW_Attrib *ao_attrib = dw_attrib_from_tag_(tag, DW_AttribKind_AbstractOrigin);
|
||||
if (ao_attrib->attrib_kind == DW_AttribKind_AbstractOrigin) {
|
||||
DW_Reference ref = dw_interp_ref(input, cu, ao_attrib->form_kind, ao_attrib->form);
|
||||
DW_TagNode *ref_tag = dw_tag_node_from_info_off(ref.cu, ref.info_off);
|
||||
attrib = dw_attrib_from_tag_(ref_tag->tag, kind);
|
||||
@@ -1855,7 +1855,7 @@ internal B32
|
||||
dw_tag_has_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind)
|
||||
{
|
||||
DW_Attrib *attrib = dw_attrib_from_tag(input, cu, tag, kind);
|
||||
B32 has_attrib = attrib->attrib_kind != DW_Attrib_Null;
|
||||
B32 has_attrib = attrib->attrib_kind != DW_AttribKind_Null;
|
||||
return has_attrib;
|
||||
}
|
||||
|
||||
@@ -1940,18 +1940,18 @@ dw_file_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_LineVMHeader *line_vm,
|
||||
internal B32
|
||||
dw_try_byte_size_from_tag(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, U64 *byte_size_out)
|
||||
{
|
||||
B32 has_byte_size = dw_tag_has_attrib(input, cu, tag, DW_Attrib_ByteSize);
|
||||
B32 has_bit_size = dw_tag_has_attrib(input, cu, tag, DW_Attrib_BitSize );
|
||||
B32 has_byte_size = dw_tag_has_attrib(input, cu, tag, DW_AttribKind_ByteSize);
|
||||
B32 has_bit_size = dw_tag_has_attrib(input, cu, tag, DW_AttribKind_BitSize );
|
||||
|
||||
if (has_byte_size && has_bit_size) {
|
||||
Assert(!"ill formated byte size");
|
||||
}
|
||||
|
||||
if (has_byte_size) {
|
||||
*byte_size_out = dw_const_u64_from_attrib(input, cu, tag, DW_Attrib_ByteSize);
|
||||
*byte_size_out = dw_const_u64_from_attrib(input, cu, tag, DW_AttribKind_ByteSize);
|
||||
return 1;
|
||||
} else if (has_bit_size) {
|
||||
U64 bit_size = dw_const_u64_from_attrib(input, cu, tag, DW_Attrib_BitSize);
|
||||
U64 bit_size = dw_const_u64_from_attrib(input, cu, tag, DW_AttribKind_BitSize);
|
||||
*byte_size_out = bit_size / 8;
|
||||
return 1;
|
||||
}
|
||||
@@ -1985,13 +1985,13 @@ dw_u64_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind k
|
||||
DW_Attrib *attrib = dw_attrib_from_tag(input, cu, tag, kind);
|
||||
DW_AttribClass attrib_class = dw_value_class_from_attrib(cu, attrib);
|
||||
if (attrib_class == DW_AttribClass_Const || attrib_class == DW_AttribClass_Block) {
|
||||
if (dw_tag_has_attrib(input, cu, tag, DW_Attrib_Type)) {
|
||||
if (dw_tag_has_attrib(input, cu, tag, DW_AttribKind_Type)) {
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
DW_Reference type_ref = dw_ref_from_attrib(input, cu, tag, DW_Attrib_Type);
|
||||
DW_Reference type_ref = dw_ref_from_attrib(input, cu, tag, DW_AttribKind_Type);
|
||||
DW_Tag type_tag = {0};
|
||||
dw_read_tag_cu(scratch.arena, input, type_ref.cu, type_ref.info_off, &type_tag);
|
||||
U64 type_byte_size = dw_byte_size_from_tag(input, cu, type_tag);
|
||||
DW_ATE type_encoding = dw_const_u64_from_attrib(input, type_ref.cu, type_tag, DW_Attrib_Encoding);
|
||||
DW_ATE type_encoding = dw_const_u64_from_attrib(input, type_ref.cu, type_tag, DW_AttribKind_Encoding);
|
||||
if (type_encoding == DW_ATE_Unsigned || type_encoding == DW_ATE_UnsignedChar) {
|
||||
result = dw_interp_const64(type_byte_size, type_encoding, attrib->form_kind, attrib->form);
|
||||
}
|
||||
@@ -2121,15 +2121,15 @@ dw_cu_from_info_off(Arena *arena, DW_Input *input, DW_ListUnitInput lu_input, U6
|
||||
dw_read_tag(arena, data, cursor, range.min, abbrev_table, abbrev_data, version, format, address_size, &cu_tag);
|
||||
|
||||
// TODO: handle these unit types
|
||||
Assert(cu_tag.kind != DW_Tag_SkeletonUnit);
|
||||
Assert(cu_tag.kind != DW_Tag_TypeUnit);
|
||||
Assert(cu_tag.kind != DW_TagKind_SkeletonUnit);
|
||||
Assert(cu_tag.kind != DW_TagKind_TypeUnit);
|
||||
|
||||
if (cu_tag.kind == DW_Tag_CompileUnit || cu_tag.kind == DW_Tag_PartialUnit) {
|
||||
if (cu_tag.kind == DW_TagKind_CompileUnit || cu_tag.kind == DW_TagKind_PartialUnit) {
|
||||
// fetch attribs for list sections
|
||||
DW_Attrib *addr_base_attrib = dw_attrib_from_tag(0, 0, cu_tag, DW_Attrib_AddrBase );
|
||||
DW_Attrib *str_offsets_base_attrib = dw_attrib_from_tag(0, 0, cu_tag, DW_Attrib_StrOffsetsBase);
|
||||
DW_Attrib *rnglists_base_attrib = dw_attrib_from_tag(0, 0, cu_tag, DW_Attrib_RngListsBase );
|
||||
DW_Attrib *loclists_base_attrib = dw_attrib_from_tag(0, 0, cu_tag, DW_Attrib_LocListsBase );
|
||||
DW_Attrib *addr_base_attrib = dw_attrib_from_tag(0, 0, cu_tag, DW_AttribKind_AddrBase );
|
||||
DW_Attrib *str_offsets_base_attrib = dw_attrib_from_tag(0, 0, cu_tag, DW_AttribKind_StrOffsetsBase);
|
||||
DW_Attrib *rnglists_base_attrib = dw_attrib_from_tag(0, 0, cu_tag, DW_AttribKind_RngListsBase );
|
||||
DW_Attrib *loclists_base_attrib = dw_attrib_from_tag(0, 0, cu_tag, DW_AttribKind_LocListsBase );
|
||||
|
||||
// interp attribs as section offsets
|
||||
U64 addr_sec_off = dw_interp_sec_offset(addr_base_attrib->form_kind, addr_base_attrib->form );
|
||||
@@ -2150,7 +2150,7 @@ dw_cu_from_info_off(Arena *arena, DW_Input *input, DW_ListUnitInput lu_input, U6
|
||||
DW_ListUnit *loclists_lu = loclists_lu_idx < lu_input.loclist_count ? &lu_input.loclists[loclists_lu_idx] : 0;
|
||||
|
||||
// find compile unit base address
|
||||
DW_Attrib *low_pc_attrib = dw_attrib_from_tag(0, 0, cu_tag, DW_Attrib_LowPc);
|
||||
DW_Attrib *low_pc_attrib = dw_attrib_from_tag(0, 0, cu_tag, DW_AttribKind_LowPc);
|
||||
U64 low_pc = dw_interp_address(address_size, max_U64, addr_lu, low_pc_attrib->form_kind, low_pc_attrib->form);
|
||||
|
||||
// fill out compile unit
|
||||
@@ -2195,7 +2195,7 @@ dw_tag_tree_from_data(Arena *arena, String8 info_data, String8 abbrev_data, DW_C
|
||||
*cursor += tag_size;
|
||||
|
||||
// is this sentinel tag?
|
||||
if (tag.kind == DW_Tag_Null) {
|
||||
if (tag.kind == DW_TagKind_Null) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user