mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-04 04:48:40 +00:00
dumper for Dwarf
This commit is contained in:
@@ -0,0 +1,266 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind_v2(DW_AttribKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_C) case DW_Attrib_##_N: return _C;
|
||||
DW_AttribKind_ClassFlags_V2_XList(X)
|
||||
#undef X
|
||||
}
|
||||
return DW_AttribClass_Null;
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind_v3(DW_AttribKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_C) case DW_Attrib_##_N: return _C;
|
||||
DW_AttribKind_ClassFlags_V3_XList(X)
|
||||
#undef X
|
||||
}
|
||||
return DW_AttribClass_Null;
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind_v4(DW_AttribKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_C) case DW_Attrib_##_N: return _C;
|
||||
DW_AttribKind_ClassFlags_V4_XList(X)
|
||||
#undef X
|
||||
}
|
||||
return DW_AttribClass_Null;
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind_v5(DW_AttribKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_C) case DW_Attrib_##_N: return _C;
|
||||
DW_AttribKind_ClassFlags_V5_XList(X)
|
||||
#undef X
|
||||
}
|
||||
return DW_AttribClass_Null;
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind_gnu(DW_AttribKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_C) case DW_Attrib_##_N: return _C;
|
||||
DW_AttribKind_ClassFlags_GNU_XList(X)
|
||||
#undef X
|
||||
}
|
||||
return DW_AttribClass_Null;
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind_llvm(DW_AttribKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_C) case DW_Attrib_##_N: return _C;
|
||||
DW_AttribKind_ClassFlags_LLVM_XList(X)
|
||||
#undef X
|
||||
}
|
||||
return DW_AttribClass_Null;
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind_apple(DW_AttribKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_C) case DW_Attrib_##_N: return _C;
|
||||
DW_AttribKind_ClassFlags_APPLE_XList(X)
|
||||
#undef X
|
||||
}
|
||||
return DW_AttribClass_Null;
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind_mips(DW_AttribKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_C) case DW_Attrib_##_N: return _C;
|
||||
DW_AttribKind_ClassFlags_MIPS_XList(X)
|
||||
#undef X
|
||||
}
|
||||
return DW_AttribClass_Null;
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_attrib_kind(DW_Version ver, DW_Ext ext, DW_AttribKind k)
|
||||
{
|
||||
DW_AttribClass result = DW_AttribClass_Null;
|
||||
|
||||
while (ext) {
|
||||
U64 z = 64-clz64(ext);
|
||||
if (z == 0) {
|
||||
break;
|
||||
}
|
||||
U64 flag = 1 << (z-1);
|
||||
ext &= ~flag;
|
||||
|
||||
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;
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
|
||||
if (result != DW_AttribClass_Null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == DW_AttribClass_Null) {
|
||||
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;
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_form_kind(DW_Version ver, DW_FormKind k)
|
||||
{
|
||||
#define X(_N,_C) case DW_Form_##_N: return _C;
|
||||
switch (ver) {
|
||||
case DW_Version_5: {
|
||||
switch (k) {
|
||||
DW_Form_AttribClass_V5_XList(X)
|
||||
}
|
||||
} break;
|
||||
case DW_Version_4: {
|
||||
switch (k) {
|
||||
DW_Form_AttribClass_V4_XList(X)
|
||||
}
|
||||
} break;
|
||||
case DW_Version_3: {
|
||||
switch (k) {
|
||||
DW_Form_AttribClass_V2_XList(X)
|
||||
}
|
||||
} break;
|
||||
case DW_Version_2: {
|
||||
switch (k) {
|
||||
DW_Form_AttribClass_V2_XList(X)
|
||||
}
|
||||
} break;
|
||||
case DW_Version_1: {
|
||||
} break;
|
||||
case DW_Version_Null: break;
|
||||
}
|
||||
#undef X
|
||||
|
||||
return DW_AttribClass_Null;
|
||||
}
|
||||
|
||||
internal B32
|
||||
dw_are_attrib_class_and_form_kind_compatible(DW_Version ver, DW_AttribClass attrib_class, DW_FormKind form_kind)
|
||||
{
|
||||
DW_AttribClass compat_flags = dw_attrib_class_from_form_kind(ver, form_kind);
|
||||
B32 are_compat = (attrib_class & compat_flags) != 0;
|
||||
return are_compat;
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_name_string_from_section_kind(DW_SectionKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_L);
|
||||
DW_SectionKind_XList(X)
|
||||
#undef X
|
||||
}
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_mach_name_string_from_section_kind(DW_SectionKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_M);
|
||||
DW_SectionKind_XList(X)
|
||||
#undef X
|
||||
}
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_dwo_name_string_from_section_kind(DW_SectionKind k)
|
||||
{
|
||||
switch (k) {
|
||||
#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_D);
|
||||
DW_SectionKind_XList(X)
|
||||
#undef X
|
||||
}
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal U64
|
||||
dw_offset_size_from_mode(DW_Mode mode)
|
||||
{
|
||||
U64 result = 0;
|
||||
switch (mode) {
|
||||
case DW_Mode_Null: break;
|
||||
case DW_Mode_32Bit: result = 4; break;
|
||||
case DW_Mode_64Bit: result = 8; break;
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, DW_Language lang, B32 relaxed, DW_AttribKind attrib_kind, DW_FormKind form_kind)
|
||||
{
|
||||
// NOTE(rjf): DWARF's spec specifies two mappings:
|
||||
// (DW_AttribKind) => List(DW_AttribClass)
|
||||
// (DW_FormKind) => List(DW_AttribClass)
|
||||
//
|
||||
// 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 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);
|
||||
form_class = dw_attrib_class_from_form_kind(DW_Version_Last, form_kind);
|
||||
}
|
||||
}
|
||||
|
||||
DW_AttribClass result = DW_AttribClass_Null;
|
||||
if(attrib_class != DW_AttribClass_Null && form_class != DW_AttribClass_Null)
|
||||
{
|
||||
result = DW_AttribClass_Undefined;
|
||||
|
||||
for(U32 i = 0; i < 32; ++i)
|
||||
{
|
||||
U32 n = 1u << i;
|
||||
if((attrib_class & n) != 0 && (form_class & n) != 0)
|
||||
{
|
||||
result = ((DW_AttribClass) n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (attrib_kind != DW_Attrib_Null && form_kind != DW_Form_Null) {
|
||||
//Assert(result != DW_AttribClass_Null && result != DW_AttribClass_Undefined);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+1690
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,225 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
internal String8
|
||||
dw_string_from_expr_op(Arena *arena, DW_Version ver, DW_Ext ext, DW_ExprOp op)
|
||||
{
|
||||
String8 result = {0};
|
||||
|
||||
#define X(_N,...) case DW_ExprOp_##_N: result = str8_lit(Stringify(_N)); goto exit;
|
||||
switch (ext) {
|
||||
case DW_Ext_Null: break;
|
||||
case DW_Ext_LLVM: break;
|
||||
case DW_Ext_APPLE: break;
|
||||
case DW_Ext_MIPS: break;
|
||||
case DW_Ext_GNU: DW_Expr_GNU_XList(X); break;
|
||||
}
|
||||
|
||||
switch (ver) {
|
||||
case DW_Version_5: {
|
||||
switch (op) {
|
||||
DW_Expr_V5_XList(X)
|
||||
}
|
||||
} // fall-through
|
||||
case DW_Version_4: {
|
||||
switch (op) {
|
||||
DW_Expr_V4_XList(X)
|
||||
}
|
||||
} // fall-through
|
||||
case DW_Version_3: {
|
||||
switch (op) {
|
||||
DW_Expr_V3_XList(X)
|
||||
}
|
||||
} // fall-through
|
||||
case DW_Version_2:
|
||||
case DW_Version_1:
|
||||
case DW_Version_Null:
|
||||
break;
|
||||
}
|
||||
#undef X
|
||||
|
||||
result = push_str8f(arena, "%x", op);
|
||||
|
||||
exit:;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_tag_kind(Arena *arena, DW_TagKind kind)
|
||||
{
|
||||
switch (kind) {
|
||||
#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)
|
||||
#undef X
|
||||
}
|
||||
return push_str8f(arena, "%llx", 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));
|
||||
|
||||
while (ext) {
|
||||
U64 z = 64-clz64(ext);
|
||||
if (z == 0) {
|
||||
break;
|
||||
}
|
||||
U64 flag = 1 << (z-1);
|
||||
ext &= ~flag;
|
||||
|
||||
switch (flag) {
|
||||
case DW_Ext_Null: break;
|
||||
case DW_Ext_GNU: switch (kind) { DW_AttribKind_GNU_XList(X) } break;
|
||||
case DW_Ext_LLVM: switch (kind) { DW_AttribKind_LLVM_XList(X) } break;
|
||||
case DW_Ext_APPLE: switch (kind) { DW_AttribKind_APPLE_XList(X) } break;
|
||||
case DW_Ext_MIPS: switch (kind) { DW_AttribKind_MIPS_XList(X) } break;
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ver) {
|
||||
case DW_Version_5: {
|
||||
switch (kind) {
|
||||
DW_AttribKind_V5_XList(X)
|
||||
}
|
||||
} // fall-through
|
||||
case DW_Version_4: {
|
||||
switch (kind) {
|
||||
DW_AttribKind_V4_XList(X)
|
||||
}
|
||||
} // fall-through
|
||||
case DW_Version_3: {
|
||||
switch (kind) {
|
||||
DW_AttribKind_V3_XList(X)
|
||||
}
|
||||
} // fall-through
|
||||
case DW_Version_2: {
|
||||
switch (kind) {
|
||||
DW_AttribKind_V2_XList(X)
|
||||
}
|
||||
} // fall-through
|
||||
case DW_Version_1: {
|
||||
} // fall-through
|
||||
case DW_Version_Null: break;
|
||||
}
|
||||
#undef X
|
||||
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_form_kind(Arena *arena, DW_Version ver, DW_FormKind kind)
|
||||
{
|
||||
#define X(_N,...) case DW_Form_##_N: return str8_lit(Stringify(_N));
|
||||
switch (ver) {
|
||||
case DW_Version_5: {
|
||||
switch (kind) {
|
||||
DW_Form_V5_XList(X)
|
||||
}
|
||||
} // fall-through
|
||||
case DW_Version_4: {
|
||||
switch (kind) {
|
||||
DW_Form_V4_XList(X)
|
||||
}
|
||||
} // fall-through
|
||||
case DW_Version_3:
|
||||
case DW_Version_2: {
|
||||
switch (kind) {
|
||||
DW_Form_V2_XList(X)
|
||||
}
|
||||
} // fall-through
|
||||
case DW_Version_Null: break;
|
||||
}
|
||||
#undef X
|
||||
String8 result = push_str8f(arena, "%x", kind);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_language(Arena *arena, DW_Language kind)
|
||||
{
|
||||
switch (kind) {
|
||||
#define X(_N,_ID) case DW_Language_##_N: return str8_lit(Stringify(_N));
|
||||
DW_Language_XList(X)
|
||||
#undef X
|
||||
}
|
||||
return push_str8f(arena, "%x", kind);
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_std_opcode(Arena *arena, DW_StdOpcode kind)
|
||||
{
|
||||
switch (kind) {
|
||||
#define X(_N,_ID) case DW_StdOpcode_##_N: return str8_lit(Stringify(_N));
|
||||
DW_StdOpcode_XList(X)
|
||||
#undef X
|
||||
}
|
||||
return push_str8f(arena, "%x", kind);
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_ext_opcode(Arena *arena, DW_ExtOpcode kind)
|
||||
{
|
||||
switch (kind) {
|
||||
#define X(_N,_ID) case DW_ExtOpcode_##_N: return str8_lit(Stringify(_N));
|
||||
DW_ExtOpcode_XList(X)
|
||||
#undef X
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
return push_str8f(arena, "%x", kind);
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_loc_list_entry_kind(Arena *arena, DW_LocListEntryKind kind)
|
||||
{
|
||||
NotImplemented;
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_section_kind(Arena *arena, DW_SectionKind kind)
|
||||
{
|
||||
NotImplemented;
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_rng_list_entry_kind(Arena *arena, DW_RngListEntryKind kind)
|
||||
{
|
||||
NotImplemented;
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_register(Arena *arena, Arch arch, U64 reg_id)
|
||||
{
|
||||
String8 reg_str = str8_zero();
|
||||
switch (arch) {
|
||||
case Arch_Null: break;
|
||||
case Arch_x86: {
|
||||
switch (reg_id) {
|
||||
#define X(_N, _ID, ...) case DW_Reg_x86_##_N: reg_str = str8_lit(Stringify(_ID)); break;
|
||||
DW_Regs_X86_XList(X)
|
||||
#undef X
|
||||
}
|
||||
} break;
|
||||
case Arch_x64: {
|
||||
switch (reg_id) {
|
||||
#define X(_N, _ID, ...) case DW_Reg_x64_##_N: reg_str = str8_lit(Stringify(_ID)); break;
|
||||
DW_Regs_X64_XList(X)
|
||||
#undef X
|
||||
}
|
||||
} break;
|
||||
case Arch_arm32: NotImplemented; break;
|
||||
case Arch_arm64: NotImplemented; break;
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
if (reg_str.size == 0) {
|
||||
reg_str = push_str8f(arena, "%#llx", reg_id);
|
||||
}
|
||||
return reg_str;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
internal String8 dw_string_from_expr_op(Arena *arena, DW_ExprOp op);
|
||||
#ifndef DWARF_ENUM_H
|
||||
#define DWARF_ENUM_H
|
||||
|
||||
internal String8 dw_string_from_expr_op(Arena *arena, DW_Version ver, DW_Ext ext, DW_ExprOp op);
|
||||
internal String8 dw_string_from_tag_kind(Arena *arena, DW_TagKind kind);
|
||||
internal String8 dw_string_from_attrib_kind(Arena *arena, DW_AttribKind kind);
|
||||
internal String8 dw_string_from_form_kind(Arena *arena, DW_FormKind kind);
|
||||
internal String8 dw_string_from_attrib_kind(Arena *arena, DW_Version ver, DW_Ext ext, DW_AttribKind kind);
|
||||
internal String8 dw_string_from_form_kind(Arena *arena, DW_Version ver, DW_FormKind kind);
|
||||
|
||||
//internal String8 dw_string_from_register(Arena *arena, Arch arch, U64 reg_id);
|
||||
|
||||
#endif // DWARF_ENUM_H
|
||||
|
||||
|
||||
+51
-51
@@ -9,7 +9,7 @@ dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base)
|
||||
DW_SimpleLoc result = {DW_SimpleLocKind_Empty};
|
||||
|
||||
U8 op = 0;
|
||||
if (based_range_read(base, range, 0, 1, &op)) {
|
||||
if (dw_based_range_read(base, range, 0, 1, &op)) {
|
||||
// step params
|
||||
U64 size_param = 0;
|
||||
B32 is_signed = 0;
|
||||
@@ -48,7 +48,7 @@ dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base)
|
||||
const_n:
|
||||
{
|
||||
U64 x = 0;
|
||||
step_cursor += based_range_read(base, range, step_cursor, size_param, &x);
|
||||
step_cursor += dw_based_range_read(base, range, step_cursor, size_param, &x);
|
||||
|
||||
if (is_signed) {
|
||||
x = extend_sign64(x, size_param);
|
||||
@@ -61,7 +61,7 @@ dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base)
|
||||
case DW_ExprOp_Addr:
|
||||
{
|
||||
U64 offset = 0;
|
||||
step_cursor += based_range_read(base, range, step_cursor, 8, &offset);
|
||||
step_cursor += dw_based_range_read(base, range, step_cursor, 8, &offset);
|
||||
U64 x = text_section_base + offset;
|
||||
result.kind = DW_SimpleLocKind_Address;
|
||||
result.addr = x;
|
||||
@@ -70,7 +70,7 @@ dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base)
|
||||
case DW_ExprOp_ConstU:
|
||||
{
|
||||
U64 x = 0;
|
||||
step_cursor += based_range_read_uleb128(base, range, step_cursor, &x);
|
||||
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &x);
|
||||
result.kind = DW_SimpleLocKind_Address;
|
||||
result.addr = x;
|
||||
} break;
|
||||
@@ -78,7 +78,7 @@ dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base)
|
||||
case DW_ExprOp_ConstS:
|
||||
{
|
||||
U64 x = 0;
|
||||
step_cursor += based_range_read_sleb128(base, range, step_cursor, (S64*)&x);
|
||||
step_cursor += dw_based_range_read_sleb128(base, range, step_cursor, (S64*)&x);
|
||||
result.kind = DW_SimpleLocKind_Address;
|
||||
result.addr = x;
|
||||
} break;
|
||||
@@ -106,7 +106,7 @@ dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base)
|
||||
case DW_ExprOp_RegX:
|
||||
{
|
||||
U64 reg_idx = 0;
|
||||
step_cursor += based_range_read_uleb128(base, range, step_cursor, ®_idx);
|
||||
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, ®_idx);
|
||||
result.kind = DW_SimpleLocKind_Register;
|
||||
result.reg_idx = reg_idx;
|
||||
} break;
|
||||
@@ -117,7 +117,7 @@ dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base)
|
||||
case DW_ExprOp_ImplicitValue:
|
||||
{
|
||||
U64 size = 0;
|
||||
step_cursor += based_range_read_uleb128(base, range, step_cursor, &size);
|
||||
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &size);
|
||||
if (step_cursor + size <= range.max) {
|
||||
result.kind = DW_SimpleLocKind_ValueLong;
|
||||
result.val_long.str = (U8*)base + range.min + step_cursor;
|
||||
@@ -141,15 +141,15 @@ dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base)
|
||||
case DW_ExprOp_Piece:
|
||||
{
|
||||
U64 size = 0;
|
||||
step_cursor += based_range_read_uleb128(base, range, step_cursor, &size);
|
||||
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &size);
|
||||
result.kind = DW_SimpleLocKind_Empty;
|
||||
} break;
|
||||
|
||||
case DW_ExprOp_BitPiece:
|
||||
{
|
||||
U64 bit_size = 0, bit_off = 0;
|
||||
step_cursor += based_range_read_uleb128(base, range, step_cursor, &bit_size);
|
||||
step_cursor += based_range_read_uleb128(base, range, step_cursor, &bit_off);
|
||||
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &bit_size);
|
||||
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &bit_off);
|
||||
result.kind = DW_SimpleLocKind_Empty;
|
||||
} break;
|
||||
|
||||
@@ -222,7 +222,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
|
||||
// decode op
|
||||
U64 op_offset = cursor;
|
||||
U8 op = 0;
|
||||
if (based_range_read(task_base, task_range, op_offset, 1, &op)) {
|
||||
if (dw_based_range_read(task_base, task_range, op_offset, 1, &op)) {
|
||||
U64 after_op_off = cursor + 1;
|
||||
|
||||
// require piece op after 'implicit' location descriptions
|
||||
@@ -267,26 +267,26 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
|
||||
const_n:
|
||||
{
|
||||
U64 x = 0;
|
||||
step_cursor += based_range_read(task_base, task_range, step_cursor, size_param, &x);
|
||||
step_cursor += dw_based_range_read(task_base, task_range, step_cursor, size_param, &x);
|
||||
} break;
|
||||
|
||||
case DW_ExprOp_Addr:
|
||||
{
|
||||
U64 offset = 0;
|
||||
step_cursor += based_range_read(task_base, task_range, step_cursor, 8, &offset);
|
||||
step_cursor += dw_based_range_read(task_base, task_range, step_cursor, 8, &offset);
|
||||
result.flags |= DW_ExprFlag_UsesTextBase;
|
||||
} break;
|
||||
|
||||
case DW_ExprOp_ConstU:
|
||||
{
|
||||
U64 x = 0;
|
||||
step_cursor += based_range_read_uleb128(task_base, task_range, step_cursor, &x);
|
||||
step_cursor += dw_based_range_read_uleb128(task_base, task_range, step_cursor, &x);
|
||||
} break;
|
||||
|
||||
case DW_ExprOp_ConstS:
|
||||
{
|
||||
U64 x = 0;
|
||||
step_cursor += based_range_read_sleb128(task_base, task_range, step_cursor, (S64*)&x);
|
||||
step_cursor += dw_based_range_read_sleb128(task_base, task_range, step_cursor, (S64*)&x);
|
||||
} break;
|
||||
|
||||
|
||||
@@ -295,7 +295,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
|
||||
case DW_ExprOp_FBReg:
|
||||
{
|
||||
S64 offset = 0;
|
||||
step_cursor += based_range_read_sleb128(task_base, task_range, step_cursor, &offset);
|
||||
step_cursor += dw_based_range_read_sleb128(task_base, task_range, step_cursor, &offset);
|
||||
result.flags |= DW_ExprFlag_UsesFrameBase;
|
||||
} break;
|
||||
|
||||
@@ -312,15 +312,15 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
|
||||
case DW_ExprOp_BReg30: case DW_ExprOp_BReg31:
|
||||
{
|
||||
S64 offset = 0;
|
||||
step_cursor += based_range_read_sleb128(task_base, task_range, step_cursor, &offset);
|
||||
step_cursor += dw_based_range_read_sleb128(task_base, task_range, step_cursor, &offset);
|
||||
result.flags |= DW_ExprFlag_UsesRegisters;
|
||||
} break;
|
||||
|
||||
case DW_ExprOp_BRegX:
|
||||
{
|
||||
U64 reg_idx = 0; S64 offset = 0;
|
||||
step_cursor += based_range_read_uleb128(task_base, task_range, step_cursor, ®_idx);
|
||||
step_cursor += based_range_read_sleb128(task_base, task_range, step_cursor, &offset);
|
||||
step_cursor += dw_based_range_read_uleb128(task_base, task_range, step_cursor, ®_idx);
|
||||
step_cursor += dw_based_range_read_sleb128(task_base, task_range, step_cursor, &offset);
|
||||
result.flags |= DW_ExprFlag_UsesRegisters;
|
||||
} break;
|
||||
|
||||
@@ -334,7 +334,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
|
||||
case DW_ExprOp_Pick:
|
||||
{
|
||||
U64 idx = 0;
|
||||
step_cursor += based_range_read(task_base, task_range, step_cursor, 1, &idx);
|
||||
step_cursor += dw_based_range_read(task_base, task_range, step_cursor, 1, &idx);
|
||||
} break;
|
||||
|
||||
case DW_ExprOp_Over:
|
||||
@@ -350,7 +350,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
|
||||
case DW_ExprOp_DerefSize:
|
||||
{
|
||||
U64 size = 0;
|
||||
step_cursor += based_range_read(task_base, task_range, step_cursor, 1, &size);
|
||||
step_cursor += dw_based_range_read(task_base, task_range, step_cursor, 1, &size);
|
||||
result.flags |= DW_ExprFlag_UsesMemory;
|
||||
} break;
|
||||
|
||||
@@ -394,7 +394,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
|
||||
case DW_ExprOp_PlusUConst:
|
||||
{
|
||||
U64 y = 0;
|
||||
step_cursor += based_range_read_uleb128(task_base, task_range, step_cursor, &y);
|
||||
step_cursor += dw_based_range_read_uleb128(task_base, task_range, step_cursor, &y);
|
||||
} break;
|
||||
|
||||
case DW_ExprOp_Shl:
|
||||
@@ -418,7 +418,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
|
||||
case DW_ExprOp_Bra:
|
||||
{
|
||||
S16 d = 0;
|
||||
step_cursor += based_range_read(task_base, task_range, step_cursor, 2, &d);
|
||||
step_cursor += dw_based_range_read(task_base, task_range, step_cursor, 2, &d);
|
||||
result.flags |= DW_ExprFlag_NonLinearFlow;
|
||||
} break;
|
||||
|
||||
@@ -427,7 +427,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
|
||||
callN:
|
||||
{
|
||||
U64 p = 0;
|
||||
step_cursor += based_range_read(task_base, task_range, step_cursor, size_param, &p);
|
||||
step_cursor += dw_based_range_read(task_base, task_range, step_cursor, size_param, &p);
|
||||
result.flags |= DW_ExprFlag_UsesCallResolution|DW_ExprFlag_NonLinearFlow;
|
||||
|
||||
// add to task list
|
||||
@@ -476,7 +476,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
|
||||
case DW_ExprOp_RegX:
|
||||
{
|
||||
U64 reg_idx = 0;
|
||||
step_cursor += based_range_read(task_base, task_range, step_cursor, size_param, ®_idx);
|
||||
step_cursor += dw_based_range_read(task_base, task_range, step_cursor, size_param, ®_idx);
|
||||
last_was_implicit_loc = 1;
|
||||
} break;
|
||||
|
||||
@@ -486,7 +486,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
|
||||
case DW_ExprOp_ImplicitValue:
|
||||
{
|
||||
U64 size = 0;
|
||||
step_cursor += based_range_read(task_base, task_range, step_cursor, size_param, &size);
|
||||
step_cursor += dw_based_range_read(task_base, task_range, step_cursor, size_param, &size);
|
||||
if (step_cursor + size > task_range.max) {
|
||||
result.flags |= DW_ExprFlag_BadData;
|
||||
goto finish;
|
||||
@@ -506,7 +506,7 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
|
||||
case DW_ExprOp_Piece:
|
||||
{
|
||||
U64 size = 0;
|
||||
step_cursor += based_range_read_uleb128(task_base, task_range, step_cursor, &size);
|
||||
step_cursor += dw_based_range_read_uleb128(task_base, task_range, step_cursor, &size);
|
||||
result.flags |= DW_ExprFlag_UsesComposite;
|
||||
|
||||
last_was_implicit_loc = 0;
|
||||
@@ -515,8 +515,8 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
|
||||
case DW_ExprOp_BitPiece:
|
||||
{
|
||||
U64 bit_size = 0; U64 bit_off = 0;
|
||||
step_cursor += based_range_read_uleb128(task_base, task_range, step_cursor, &bit_size);
|
||||
step_cursor += based_range_read_uleb128(task_base, task_range, step_cursor, &bit_off);
|
||||
step_cursor += dw_based_range_read_uleb128(task_base, task_range, step_cursor, &bit_size);
|
||||
step_cursor += dw_based_range_read_uleb128(task_base, task_range, step_cursor, &bit_off);
|
||||
result.flags |= DW_ExprFlag_UsesComposite;
|
||||
|
||||
last_was_implicit_loc = 0;
|
||||
@@ -590,7 +590,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
|
||||
// decode op
|
||||
U64 op_offset = cursor;
|
||||
U8 op = 0;
|
||||
if (based_range_read(base, range, op_offset, 1, &op)) {
|
||||
if (dw_based_range_read(base, range, op_offset, 1, &op)) {
|
||||
U64 after_op_off = cursor + 1;
|
||||
|
||||
// require piece op after 'implicit' location descriptions
|
||||
@@ -639,7 +639,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
|
||||
const_n:
|
||||
{
|
||||
U64 x = 0;
|
||||
step_cursor += based_range_read(base, range, step_cursor, size_param, &x);
|
||||
step_cursor += dw_based_range_read(base, range, step_cursor, size_param, &x);
|
||||
if (is_signed) {
|
||||
x = extend_sign64(x, size_param);
|
||||
}
|
||||
@@ -649,13 +649,13 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
|
||||
case DW_ExprOp_Addr:
|
||||
{
|
||||
U64 offset = 0;
|
||||
step_cursor += based_range_read(base, range, step_cursor, 8, &offset);
|
||||
step_cursor += dw_based_range_read(base, range, step_cursor, 8, &offset);
|
||||
|
||||
// earlier versions of GCC emit TLS offset with DW_ExprOp_Addr.
|
||||
B32 is_text_relative;
|
||||
{
|
||||
U8 next_op = 0;
|
||||
based_range_read_struct(base, range, step_cursor, &next_op);
|
||||
dw_based_range_read_struct(base, range, step_cursor, &next_op);
|
||||
is_text_relative = (next_op != DW_ExprOp_GNU_PushTlsAddress);
|
||||
}
|
||||
|
||||
@@ -677,14 +677,14 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
|
||||
case DW_ExprOp_ConstU:
|
||||
{
|
||||
U64 x = 0;
|
||||
step_cursor += based_range_read_uleb128(base, range, step_cursor, &x);
|
||||
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &x);
|
||||
dw_expr__stack_push(scratch.arena, &stack, x);
|
||||
} break;
|
||||
|
||||
case DW_ExprOp_ConstS:
|
||||
{
|
||||
U64 x = 0;
|
||||
step_cursor += based_range_read_sleb128(base, range, step_cursor, (S64*)&x);
|
||||
step_cursor += dw_based_range_read_sleb128(base, range, step_cursor, (S64*)&x);
|
||||
dw_expr__stack_push(scratch.arena, &stack, x);
|
||||
} break;
|
||||
|
||||
@@ -694,7 +694,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
|
||||
case DW_ExprOp_FBReg:
|
||||
{
|
||||
S64 offset = 0;
|
||||
step_cursor += based_range_read_sleb128(base, range, step_cursor, &offset);
|
||||
step_cursor += dw_based_range_read_sleb128(base, range, step_cursor, &offset);
|
||||
if (config->frame_base != 0) {
|
||||
U64 x = *config->frame_base + offset;
|
||||
dw_expr__stack_push(scratch.arena, &stack, x);
|
||||
@@ -718,7 +718,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
|
||||
case DW_ExprOp_BReg30: case DW_ExprOp_BReg31:
|
||||
{
|
||||
S64 offset = 0;
|
||||
step_cursor += based_range_read_sleb128(base, range, step_cursor, &offset);
|
||||
step_cursor += dw_based_range_read_sleb128(base, range, step_cursor, &offset);
|
||||
U64 reg_idx = op - DW_ExprOp_BReg0;
|
||||
DW_RegsX64 *regs = config->regs;
|
||||
if (regs != 0) {
|
||||
@@ -741,8 +741,8 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
|
||||
case DW_ExprOp_BRegX:
|
||||
{
|
||||
U64 reg_idx = 0; S64 offset = 0;
|
||||
step_cursor += based_range_read_uleb128(base, range, step_cursor, ®_idx);
|
||||
step_cursor += based_range_read_sleb128(base, range, step_cursor, &offset);
|
||||
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, ®_idx);
|
||||
step_cursor += dw_based_range_read_sleb128(base, range, step_cursor, &offset);
|
||||
|
||||
DW_RegsX64 *regs = config->regs;
|
||||
if (regs != 0) {
|
||||
@@ -779,7 +779,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
|
||||
case DW_ExprOp_Pick:
|
||||
{
|
||||
U64 idx = 0;
|
||||
step_cursor += based_range_read(base, range, step_cursor, 1, &idx);
|
||||
step_cursor += dw_based_range_read(base, range, step_cursor, 1, &idx);
|
||||
U64 x = dw_expr__stack_pick(&stack, idx);
|
||||
dw_expr__stack_push(scratch.arena, &stack, x);
|
||||
} break;
|
||||
@@ -832,7 +832,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
|
||||
case DW_ExprOp_DerefSize:
|
||||
{
|
||||
U64 raw_size = 0;
|
||||
step_cursor += based_range_read(base, range, step_cursor, 1, &raw_size);
|
||||
step_cursor += dw_based_range_read(base, range, step_cursor, 1, &raw_size);
|
||||
|
||||
U64 size = ClampTop(raw_size, 8);
|
||||
U64 addr = dw_expr__stack_pop(&stack);
|
||||
@@ -983,7 +983,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
|
||||
case DW_ExprOp_PlusUConst:
|
||||
{
|
||||
U64 y = 0;
|
||||
step_cursor += based_range_read_uleb128(base, range, step_cursor, &y);
|
||||
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &y);
|
||||
U64 z = dw_expr__stack_pop(&stack);
|
||||
U64 x = y + z;
|
||||
dw_expr__stack_push(scratch.arena, &stack, x);
|
||||
@@ -1088,14 +1088,14 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
|
||||
case DW_ExprOp_Skip:
|
||||
{
|
||||
S16 d = 0;
|
||||
step_cursor += based_range_read(base, range, step_cursor, 2, &d);
|
||||
step_cursor += dw_based_range_read(base, range, step_cursor, 2, &d);
|
||||
step_cursor = step_cursor + d;
|
||||
} break;
|
||||
|
||||
case DW_ExprOp_Bra:
|
||||
{
|
||||
S16 d = 0;
|
||||
step_cursor += based_range_read(base, range, step_cursor, 2, &d);
|
||||
step_cursor += dw_based_range_read(base, range, step_cursor, 2, &d);
|
||||
U64 b = dw_expr__stack_pop(&stack);
|
||||
if (b != 0) {
|
||||
step_cursor = step_cursor + d;
|
||||
@@ -1105,7 +1105,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
|
||||
case DW_ExprOp_Call2:
|
||||
{
|
||||
U16 p = 0;
|
||||
step_cursor += based_range_read(base, range, step_cursor, 2, &p);
|
||||
step_cursor += dw_based_range_read(base, range, step_cursor, 2, &p);
|
||||
if (config->call.func != 0) {
|
||||
String8 sub_data = config->call.func(config->call.user_ptr, p);
|
||||
dw_expr__call_push(scratch.arena, &call_stack, sub_data.str, sub_data.size);
|
||||
@@ -1119,7 +1119,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
|
||||
case DW_ExprOp_Call4:
|
||||
{
|
||||
U32 p = 0;
|
||||
step_cursor += based_range_read(base, range, step_cursor, 4, &p);
|
||||
step_cursor += dw_based_range_read(base, range, step_cursor, 4, &p);
|
||||
if (config->call.func != 0) {
|
||||
String8 sub_data = config->call.func(config->call.user_ptr, p);
|
||||
dw_expr__call_push(scratch.arena, &call_stack, sub_data.str, sub_data.size);
|
||||
@@ -1165,7 +1165,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
|
||||
case DW_ExprOp_RegX:
|
||||
{
|
||||
U64 reg_idx = 0;
|
||||
step_cursor += based_range_read(base, range, step_cursor, size_param, ®_idx);
|
||||
step_cursor += dw_based_range_read(base, range, step_cursor, size_param, ®_idx);
|
||||
stashed_loc.kind = DW_SimpleLocKind_Register;
|
||||
stashed_loc.reg_idx = reg_idx;
|
||||
} break;
|
||||
@@ -1176,7 +1176,7 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
|
||||
case DW_ExprOp_ImplicitValue:
|
||||
{
|
||||
U64 size = 0;
|
||||
step_cursor += based_range_read(base, range, step_cursor, size_param, &size);
|
||||
step_cursor += dw_based_range_read(base, range, step_cursor, size_param, &size);
|
||||
if (step_cursor + size <= range.max) {
|
||||
void *data = (U8*)base + range.min + step_cursor;
|
||||
stashed_loc.kind = DW_SimpleLocKind_ValueLong;
|
||||
@@ -1216,13 +1216,13 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
|
||||
case DW_ExprOp_Piece:
|
||||
{
|
||||
U64 size = 0;
|
||||
step_cursor += based_range_read_uleb128(base, range, step_cursor, &size);
|
||||
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &size);
|
||||
bit_size = size*8;
|
||||
} break;
|
||||
case DW_ExprOp_BitPiece:
|
||||
{
|
||||
step_cursor += based_range_read_uleb128(base, range, step_cursor, &bit_size);
|
||||
step_cursor += based_range_read_uleb128(base, range, step_cursor, &bit_off);
|
||||
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &bit_size);
|
||||
step_cursor += dw_based_range_read_uleb128(base, range, step_cursor, &bit_off);
|
||||
is_bit_loc = 1;
|
||||
} break;
|
||||
}
|
||||
|
||||
+310
-288
File diff suppressed because it is too large
Load Diff
+41
-38
@@ -50,6 +50,7 @@ struct DW_AbbrevTable
|
||||
typedef struct DW_Section DW_Section;
|
||||
struct DW_Section
|
||||
{
|
||||
String8 name;
|
||||
String8 data;
|
||||
DW_Mode mode;
|
||||
B32 is_dwo;
|
||||
@@ -201,7 +202,6 @@ struct DW_CompRoot
|
||||
U64 size;
|
||||
DW_CompUnitKind kind;
|
||||
DW_Version version;
|
||||
DW_Ext ext;
|
||||
U64 address_size;
|
||||
U64 abbrev_off;
|
||||
U64 info_off;
|
||||
@@ -228,10 +228,6 @@ struct DW_CompRoot
|
||||
U64 high_pc;
|
||||
DW_AttribValue ranges_attrib_value;
|
||||
U64 base_addr;
|
||||
|
||||
// NOTE(rjf): Line/File Info For This Comp Unit
|
||||
String8Array dir_table;
|
||||
DW_LineVMFileArray file_table;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -314,32 +310,32 @@ struct DW_TagStubList
|
||||
typedef struct DW_LineVMHeader DW_LineVMHeader;
|
||||
struct DW_LineVMHeader
|
||||
{
|
||||
U64 unit_length;
|
||||
U64 unit_opl;
|
||||
U16 version;
|
||||
U8 address_size; // NOTE(nick): duplicates size from the compilation unit but is needed to support stripped exe that just have .debug_line and .debug_line_str.
|
||||
U8 segment_selector_size;
|
||||
U64 header_length;
|
||||
U64 program_off;
|
||||
U8 min_inst_len;
|
||||
U8 max_ops_for_inst;
|
||||
U8 default_is_stmt;
|
||||
S8 line_base;
|
||||
U8 line_range;
|
||||
U8 opcode_base;
|
||||
U64 num_opcode_lens;
|
||||
U8 *opcode_lens;
|
||||
String8Array dir_table;
|
||||
DW_LineVMFileArray file_table;
|
||||
U64 unit_length;
|
||||
U64 unit_opl;
|
||||
DW_Version version;
|
||||
U8 address_size; // Duplicates size from the compilation unit but is needed to support stripped exe that just have .debug_line and .debug_line_str.
|
||||
U8 segment_selector_size;
|
||||
U64 header_length;
|
||||
U64 program_off;
|
||||
U8 min_inst_len;
|
||||
U8 max_ops_for_inst;
|
||||
U8 default_is_stmt;
|
||||
S8 line_base;
|
||||
U8 line_range;
|
||||
U8 opcode_base;
|
||||
U64 num_opcode_lens;
|
||||
U8 *opcode_lens;
|
||||
String8Array dir_table;
|
||||
DW_LineVMFileArray file_table;
|
||||
};
|
||||
|
||||
typedef struct DW_LineVMState DW_LineVMState;
|
||||
struct DW_LineVMState
|
||||
{
|
||||
U64 address; // NOTE(nick): Address of a machine instruction.
|
||||
U32 op_index; // NOTE(nick): This is used by the VLIW instructions to indicate index of operation inside the instruction.
|
||||
U64 address; // Address of a machine instruction.
|
||||
U32 op_index; // This is used by the VLIW instructions to indicate index of operation inside the instruction.
|
||||
|
||||
// NOTE(nick): Line table doesn't contain full path to a file, instead
|
||||
// Line table doesn't contain full path to a file, instead
|
||||
// DWARF encodes path as two indices. First index will point into a directory
|
||||
// table, and second points into a file name table.
|
||||
U32 file_index;
|
||||
@@ -347,10 +343,10 @@ struct DW_LineVMState
|
||||
U32 line;
|
||||
U32 column;
|
||||
|
||||
B32 is_stmt; // NOTE(nick): Indicates that "address" points to place suitable for a breakpoint.
|
||||
B32 basic_block; // NOTE(nick): Indicates that the "address" is inside a basic block.
|
||||
B32 is_stmt; // Indicates that "address" points to place suitable for a breakpoint.
|
||||
B32 basic_block; // Indicates that the "address" is inside a basic block.
|
||||
|
||||
// NOTE(nick): Indicates that "address" points to place where function starts.
|
||||
// Indicates that "address" points to place where function starts.
|
||||
// Usually prologue is the place where compiler emits instructions to
|
||||
// prepare stack for a function.
|
||||
B32 prologue_end;
|
||||
@@ -421,16 +417,23 @@ struct DW_PubStringsTable
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Helpers
|
||||
|
||||
internal U64 dw_hash_from_string(String8 string);
|
||||
internal DW_AttribClass dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, DW_Language lang, DW_AttribKind attrib, DW_FormKind form_kind);
|
||||
internal U64 dw_hash_from_string(String8 string);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Specific Based Range Helpers
|
||||
|
||||
internal U64 dw_based_range_read_length(void *base, Rng1U64 range, U64 offset, U64 *out_value);
|
||||
internal U64 dw_based_range_read_abbrev_tag(void *base, Rng1U64 range, U64 offset, DW_Abbrev *out_abbrev);
|
||||
internal U64 dw_based_range_read_abbrev_attrib_info(void *base, Rng1U64 range, U64 offset, DW_Abbrev *out_abbrev);
|
||||
internal U64 dw_based_range_read_attrib_form_value(void *base, Rng1U64 range, U64 offset, DW_Mode mode, U64 address_size, DW_FormKind form_kind, U64 implicit_const, DW_AttribValue *form_value_out);
|
||||
#define dw_based_range_read_struct(base, range, offset, out) dw_based_range_read(base, range, offset, sizeof(*out), out)
|
||||
|
||||
internal U64 dw_based_range_read(void *base, Rng1U64 range, U64 offset, U64 size, void *out);
|
||||
internal String8 dw_based_range_read_string(void *base, Rng1U64 range, U64 offset);
|
||||
internal void* dw_based_range_ptr(void *base, Rng1U64 range, U64 offset);
|
||||
internal void* dw_based_range_ptr_size(void *base, Rng1U64 range, U64 offset, U64 size);
|
||||
internal U64 dw_based_range_read_uleb128(void *base, Rng1U64 range, U64 offset, U64 *out_value);
|
||||
internal U64 dw_based_range_read_sleb128(void *base, Rng1U64 range, U64 offset, S64 *out_value);
|
||||
internal U64 dw_based_range_read_length(void *base, Rng1U64 range, U64 offset, U64 *out_value);
|
||||
internal U64 dw_based_range_read_abbrev_tag(void *base, Rng1U64 range, U64 offset, DW_Abbrev *out_abbrev);
|
||||
internal U64 dw_based_range_read_abbrev_attrib_info(void *base, Rng1U64 range, U64 offset, DW_Abbrev *out_abbrev);
|
||||
internal U64 dw_based_range_read_attrib_form_value(void *base, Rng1U64 range, U64 offset, DW_Mode mode, U64 address_size, DW_FormKind form_kind, U64 implicit_const, DW_AttribValue *form_value_out);
|
||||
|
||||
internal DW_Mode dw_mode_from_sec(DW_SectionArray *sections, DW_SectionKind kind);
|
||||
internal B32 dw_sec_is_present(DW_SectionArray *sections, DW_SectionKind kind);
|
||||
@@ -473,8 +476,8 @@ internal Rng1U64List dw_range_list_from_high_low_pc_and_ranges_a
|
||||
////////////////////////////////
|
||||
//~ rjf: Tag Parsing
|
||||
|
||||
internal DW_AttribListParseResult dw_parse_attrib_list_from_info_abbrev_offsets(Arena *arena, DW_SectionArray *sections, DW_Version ver, DW_Ext ext, DW_Language lang, U64 address_size, U64 info_off, U64 abbrev_off);
|
||||
internal DW_Tag* dw_tag_from_info_offset(Arena *arena, DW_SectionArray *sections, DW_AbbrevTable abbrev_table, DW_Version ver, DW_Ext ext, DW_Language lang, U64 address_size, U64 info_offset);
|
||||
internal DW_AttribListParseResult dw_parse_attrib_list_from_info_abbrev_offsets(Arena *arena, DW_SectionArray *sections, DW_Version ver, DW_Ext ext, DW_Language lang, U64 address_size, U64 info_off, U64 abbrev_off, B32 relaxed);
|
||||
internal DW_Tag* dw_tag_from_info_offset(Arena *arena, DW_SectionArray *sections, DW_AbbrevTable abbrev_table, DW_Version ver, DW_Ext ext, DW_Language lang, U64 address_size, U64 info_offset, B32 relaxed);
|
||||
internal DW_TagStub dw_stub_from_tag(DW_SectionArray *sections, DW_AttribValueResolveParams resolve_params, DW_Tag *tag);
|
||||
|
||||
//- rjf: line info
|
||||
@@ -484,8 +487,8 @@ internal void dw_line_vm_advance(DW_LineVMState *state, U64 advance, U64 min_ins
|
||||
internal DW_LineSeqNode* dw_push_line_seq(Arena* arena, DW_LineTableParseResult *parsed_tbl);
|
||||
internal DW_LineNode* dw_push_line(Arena *arena, DW_LineTableParseResult *tbl, DW_LineVMState *vm_state, B32 start_of_sequence);
|
||||
internal DW_LineTableParseResult dw_parsed_line_table_from_comp_root(Arena *arena, DW_SectionArray *sections, DW_CompRoot *root);
|
||||
internal U64 dw_read_line_file(void *line_base, Rng1U64 line_rng, U64 line_off, DW_Mode mode, DW_SectionArray *sections, DW_CompRoot *unit, U8 address_size, U64 format_count, Rng1U64 *formats, DW_LineFile *line_file_out);
|
||||
internal U64 dw_read_line_vm_header(Arena *arena, void *line_base, Rng1U64 line_rng, U64 line_off, DW_Mode mode, DW_SectionArray *sections, DW_CompRoot *unit, DW_LineVMHeader *header_out);
|
||||
internal U64 dw_read_line_file(void *line_base, Rng1U64 line_rng, U64 line_off, DW_Mode mode, DW_SectionArray *sections, DW_AttribValueResolveParams resolve_params, U8 address_size, U64 format_count, Rng1U64 *formats, DW_LineFile *line_file_out);
|
||||
internal U64 dw_read_line_vm_header(Arena *arena, void *line_base, Rng1U64 line_rng, U64 line_off, DW_Mode mode, DW_SectionArray *sections, DW_AttribValueResolveParams resolve_params, String8 compile_dir, String8 unit_name, DW_LineVMHeader *header_out);
|
||||
|
||||
#endif // DWARF_PARSE_H
|
||||
|
||||
|
||||
+19
-19
@@ -338,7 +338,7 @@ dw_unwind_parse_pointer_x64(void *frame_base, Rng1U64 frame_range, DW_EhPtrCtx *
|
||||
case DW_EhPtrEnc_UData8: size_param = 8; goto ufixed;
|
||||
ufixed:
|
||||
{
|
||||
based_range_read(frame_base, frame_range, pointer_off, size_param, &raw_pointer);
|
||||
dw_based_range_read(frame_base, frame_range, pointer_off, size_param, &raw_pointer);
|
||||
after_pointer_off = pointer_off + size_param;
|
||||
} break;
|
||||
|
||||
@@ -352,7 +352,7 @@ dw_unwind_parse_pointer_x64(void *frame_base, Rng1U64 frame_range, DW_EhPtrCtx *
|
||||
case DW_EhPtrEnc_SData8:size_param = 8; goto sfixed;
|
||||
sfixed:
|
||||
{
|
||||
based_range_read(frame_base, frame_range, pointer_off, size_param, &raw_pointer);
|
||||
dw_based_range_read(frame_base, frame_range, pointer_off, size_param, &raw_pointer);
|
||||
after_pointer_off = pointer_off + size_param;
|
||||
// sign extension
|
||||
U64 sign_bit = size_param*8 - 1;
|
||||
@@ -363,13 +363,13 @@ dw_unwind_parse_pointer_x64(void *frame_base, Rng1U64 frame_range, DW_EhPtrCtx *
|
||||
|
||||
case DW_EhPtrEnc_ULEB128:
|
||||
{
|
||||
U64 size = based_range_read_uleb128(frame_base, frame_range, pointer_off, &raw_pointer);
|
||||
U64 size = dw_based_range_read_uleb128(frame_base, frame_range, pointer_off, &raw_pointer);
|
||||
after_pointer_off = pointer_off + size;
|
||||
} break;
|
||||
|
||||
case DW_EhPtrEnc_SLEB128:
|
||||
{
|
||||
U64 size = based_range_read_sleb128(frame_base, frame_range, pointer_off,
|
||||
U64 size = dw_based_range_read_sleb128(frame_base, frame_range, pointer_off,
|
||||
(S64*)&raw_pointer);
|
||||
after_pointer_off = pointer_off + size;
|
||||
} break;
|
||||
@@ -415,34 +415,34 @@ dw_unwind_parse_cie_x64(void *base, Rng1U64 range, DW_EhPtrCtx *ptr_ctx, U64 off
|
||||
// get version
|
||||
U64 version_off = off;
|
||||
U8 version = 0;
|
||||
based_range_read(base, range, version_off, 1, &version);
|
||||
dw_based_range_read(base, range, version_off, 1, &version);
|
||||
|
||||
// check version
|
||||
if (version == 1 || version == 3) {
|
||||
|
||||
// read augmentation
|
||||
U64 augmentation_off = version_off + 1;
|
||||
String8 augmentation = based_range_read_string(base, range, augmentation_off);
|
||||
String8 augmentation = dw_based_range_read_string(base, range, augmentation_off);
|
||||
|
||||
// read code align
|
||||
U64 code_align_factor_off = augmentation_off + augmentation.size + 1;
|
||||
U64 code_align_factor = 0;
|
||||
U64 code_align_factor_size = based_range_read_uleb128(base, range, code_align_factor_off, &code_align_factor);
|
||||
U64 code_align_factor_size = dw_based_range_read_uleb128(base, range, code_align_factor_off, &code_align_factor);
|
||||
|
||||
// read data align
|
||||
U64 data_align_factor_off = code_align_factor_off + code_align_factor_size;
|
||||
S64 data_align_factor = 0;
|
||||
U64 data_align_factor_size = based_range_read_sleb128(base, range, data_align_factor_off, &data_align_factor);
|
||||
U64 data_align_factor_size = dw_based_range_read_sleb128(base, range, data_align_factor_off, &data_align_factor);
|
||||
|
||||
// return address register
|
||||
U64 ret_addr_reg_off = data_align_factor_off + data_align_factor_size;
|
||||
U64 after_ret_addr_reg_off = 0;
|
||||
U64 ret_addr_reg = 0;
|
||||
if (version == 1) {
|
||||
based_range_read(base, range, ret_addr_reg_off, 1, &ret_addr_reg);
|
||||
dw_based_range_read(base, range, ret_addr_reg_off, 1, &ret_addr_reg);
|
||||
after_ret_addr_reg_off = ret_addr_reg_off + 1;
|
||||
} else {
|
||||
U64 ret_addr_reg_size = based_range_read_uleb128(base, range, ret_addr_reg_off, &ret_addr_reg);
|
||||
U64 ret_addr_reg_size = dw_based_range_read_uleb128(base, range, ret_addr_reg_off, &ret_addr_reg);
|
||||
after_ret_addr_reg_off = ret_addr_reg_off + ret_addr_reg_size;
|
||||
}
|
||||
|
||||
@@ -459,7 +459,7 @@ dw_unwind_parse_cie_x64(void *base, Rng1U64 range, DW_EhPtrCtx *ptr_ctx, U64 off
|
||||
U64 augmentation_size = 0;
|
||||
if (augmentation.size > 0 && augmentation.str[0] == 'z') {
|
||||
has_augmentation_size = 1;
|
||||
U64 aug_size_size = based_range_read_uleb128(base, range, aug_size_off, &augmentation_size);
|
||||
U64 aug_size_size = dw_based_range_read_uleb128(base, range, aug_size_off, &augmentation_size);
|
||||
after_aug_size_off += aug_size_size;
|
||||
}
|
||||
|
||||
@@ -476,19 +476,19 @@ dw_unwind_parse_cie_x64(void *base, Rng1U64 range, DW_EhPtrCtx *ptr_ctx, U64 off
|
||||
for (U8 *ptr = augmentation.str + 1, *opl = augmentation.str + augmentation.size; ptr < opl; ++ptr) {
|
||||
switch (*ptr) {
|
||||
case 'L': {
|
||||
based_range_read_struct(base, range, aug_data_cursor, &lsda_encoding);
|
||||
dw_based_range_read_struct(base, range, aug_data_cursor, &lsda_encoding);
|
||||
aug_data_cursor += sizeof(lsda_encoding);
|
||||
} break;
|
||||
case 'P': {
|
||||
DW_EhPtrEnc handler_encoding = DW_EhPtrEnc_Omit;
|
||||
based_range_read_struct(base, range, aug_data_cursor, &handler_encoding);
|
||||
dw_based_range_read_struct(base, range, aug_data_cursor, &handler_encoding);
|
||||
|
||||
U64 ptr_off = aug_data_cursor + sizeof(handler_encoding);
|
||||
U64 ptr_size = dw_unwind_parse_pointer_x64(base, range, ptr_ctx, handler_encoding, ptr_off, &handler_ip);
|
||||
aug_data_cursor = ptr_off + ptr_size;
|
||||
} break;
|
||||
case 'R': {
|
||||
based_range_read_struct(base, range, aug_data_cursor, &addr_encoding);
|
||||
dw_based_range_read_struct(base, range, aug_data_cursor, &addr_encoding);
|
||||
aug_data_cursor += sizeof(addr_encoding);
|
||||
} break;
|
||||
default: {
|
||||
@@ -547,7 +547,7 @@ dw_unwind_parse_fde_x64(void *base, Rng1U64 range, DW_EhPtrCtx *ptr_ctx, DW_CIEU
|
||||
if (cie->has_augmentation_size) {
|
||||
// augmentation size
|
||||
U64 augmentation_size = 0;
|
||||
U64 aug_size_size = based_range_read_uleb128(base, range, aug_data_off, &augmentation_size);
|
||||
U64 aug_size_size = dw_based_range_read_uleb128(base, range, aug_data_off, &augmentation_size);
|
||||
U64 after_aug_size_off = aug_data_off + aug_size_size;
|
||||
|
||||
// extract lsda (only thing that can actually be in FDE's augmentation data as far as we know)
|
||||
@@ -863,7 +863,7 @@ dw_unwind_machine_run_to_ip_x64(void *base, Rng1U64 range, DW_CFIMachine *machin
|
||||
DW_CFAControlBits control_bits = 0;
|
||||
|
||||
// decode opcode/operand0
|
||||
if (!based_range_read(base, range, cfi_off, 1, &opcode)) {
|
||||
if (!dw_based_range_read(base, range, cfi_off, 1, &opcode)) {
|
||||
result = 1;
|
||||
goto done;
|
||||
}
|
||||
@@ -897,7 +897,7 @@ dw_unwind_machine_run_to_ip_x64(void *base, Rng1U64 range, DW_CFIMachine *machin
|
||||
} break;
|
||||
default: {
|
||||
if (d <= 8) {
|
||||
based_range_read(base, range, decode_cursor, d, out);
|
||||
dw_based_range_read(base, range, decode_cursor, d, out);
|
||||
o_size = d;
|
||||
}
|
||||
} break;
|
||||
@@ -905,10 +905,10 @@ dw_unwind_machine_run_to_ip_x64(void *base, Rng1U64 range, DW_CFIMachine *machin
|
||||
o_size = dw_unwind_parse_pointer_x64(base, range, ptr_ctx, cie->addr_encoding, decode_cursor, out);
|
||||
} break;
|
||||
case DW_CFADecode_ULEB128: {
|
||||
o_size = based_range_read_uleb128(base, range, decode_cursor, out);
|
||||
o_size = dw_based_range_read_uleb128(base, range, decode_cursor, out);
|
||||
} break;
|
||||
case DW_CFADecode_SLEB128: {
|
||||
o_size = based_range_read_sleb128(base, range, decode_cursor, (S64*)out);
|
||||
o_size = dw_based_range_read_sleb128(base, range, decode_cursor, (S64*)out);
|
||||
} break;
|
||||
}
|
||||
decode_cursor += o_size;
|
||||
|
||||
Reference in New Issue
Block a user