mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-10-09 09:25:41 +00:00
revert DWARF changes to commit bda3a71379
This commit is contained in:
+72
-74
@@ -73,10 +73,10 @@ internal U64
|
||||
dw_reg_count_from_arch(Arch arch)
|
||||
{
|
||||
switch (arch) {
|
||||
default: { NotImplemented; } // fall-through
|
||||
case Arch_Null: return 0;
|
||||
case Arch_x86: return DW_RegX86_Last;
|
||||
case Arch_x64: return DW_RegX64_Last;
|
||||
default: { NotImplemented; } // fall-through
|
||||
case Arch_Null: return 0;
|
||||
case Arch_x86: return DW_RegX86_Last;
|
||||
case Arch_x64: return DW_RegX64_Last;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,10 +98,10 @@ internal U64
|
||||
dw_sp_from_arch(Arch arch)
|
||||
{
|
||||
switch (arch) {
|
||||
default: NotImplemented;
|
||||
case Arch_Null: return 0;
|
||||
case Arch_x86: return DW_RegX86_Esp;
|
||||
case Arch_x64: return DW_RegX64_Rsp;
|
||||
default: NotImplemented;
|
||||
case Arch_Null: return 0;
|
||||
case Arch_x86: return DW_RegX86_Esp;
|
||||
case Arch_x64: return DW_RegX64_Rsp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ dw_attrib_class_from_attrib_mips(DW_AttribKind k)
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_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;
|
||||
|
||||
@@ -278,64 +278,58 @@ 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;
|
||||
B32 are_compat = (attrib_class & compat_flags) != 0;
|
||||
return are_compat;
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_name_string_from_section_kind(DW_SectionKind k)
|
||||
{
|
||||
String8 result = {0};
|
||||
switch(k)
|
||||
{
|
||||
#define X(_N,_L,_M,_D) case DW_Section_##_N:{result = str8_lit(_L);}break;
|
||||
switch (k) {
|
||||
#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_L);
|
||||
DW_SectionKind_XList(X)
|
||||
#undef X
|
||||
}
|
||||
return result;
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_mach_name_string_from_section_kind(DW_SectionKind k)
|
||||
{
|
||||
String8 result = {0};
|
||||
switch(k)
|
||||
{
|
||||
#define X(_N,_L,_M,_D) case DW_Section_##_N:{result = str8_lit(_M);}break;
|
||||
switch (k) {
|
||||
#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_M);
|
||||
DW_SectionKind_XList(X)
|
||||
#undef X
|
||||
}
|
||||
return result;
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_dwo_name_string_from_section_kind(DW_SectionKind k)
|
||||
{
|
||||
String8 result = {0};
|
||||
switch(k)
|
||||
{
|
||||
#define X(_N,_L,_M,_D) case DW_Section_##_N:{result = str8_lit(_D);}break;
|
||||
switch (k) {
|
||||
#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_D);
|
||||
DW_SectionKind_XList(X)
|
||||
#undef X
|
||||
}
|
||||
return result;
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal U64
|
||||
dw_size_from_format(DW_Format format)
|
||||
{
|
||||
U64 result = 0;
|
||||
switch(format)
|
||||
{
|
||||
default:{}break;
|
||||
switch (format) {
|
||||
case DW_Format_Null: break;
|
||||
case DW_Format_32Bit: result = 4; break;
|
||||
case DW_Format_64Bit: result = 8; break;
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal DW_AttribClass
|
||||
dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, DW_AttribKind attrib_kind, DW_FormKind form_kind)
|
||||
dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, B32 relaxed, DW_AttribKind attrib_kind, DW_FormKind form_kind)
|
||||
{
|
||||
// NOTE(rjf): DWARF's spec specifies two mappings:
|
||||
// (DW_AttribKind) => List(DW_AttribClass)
|
||||
@@ -344,12 +338,16 @@ dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, DW_AttribKind attrib_kind
|
||||
// This function's purpose is to find the overlapping class between an
|
||||
// DW_AttribKind and DW_FormKind.
|
||||
|
||||
DW_AttribClass attrib_class = dw_attrib_class_from_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(attrib_class == DW_AttribClass_Null || form_class == DW_AttribClass_Null)
|
||||
|
||||
if(relaxed)
|
||||
{
|
||||
attrib_class = dw_attrib_class_from_kind(DW_Version_Last, ext, attrib_kind);
|
||||
form_class = dw_attrib_class_from_form_kind(DW_Version_Last, form_kind);
|
||||
if(attrib_class == DW_AttribClass_Null || form_class == DW_AttribClass_Null)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
DW_AttribClass result = DW_AttribClass_Null;
|
||||
@@ -430,11 +428,11 @@ dw_operand_count_from_expr_op(DW_ExprOp op)
|
||||
switch (op) {
|
||||
#define X(_N, _ID, _OPER_COUNT, _POP_COUNT, _PUSH_COUNT) case _ID: return _OPER_COUNT;
|
||||
DW_Expr_V3_XList(X)
|
||||
DW_Expr_V4_XList(X)
|
||||
DW_Expr_V5_XList(X)
|
||||
DW_Expr_GNU_XList(X)
|
||||
DW_Expr_V4_XList(X)
|
||||
DW_Expr_V5_XList(X)
|
||||
DW_Expr_GNU_XList(X)
|
||||
#undef X
|
||||
default: { NotImplemented; } break;
|
||||
default: { NotImplemented; } break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -445,11 +443,11 @@ dw_pop_count_from_expr_op(DW_ExprOp op)
|
||||
switch (op) {
|
||||
#define X(_N, _ID, _OPER_COUNT, _POP_COUNT, _PUSH_COUNT) case _ID: return _POP_COUNT;
|
||||
DW_Expr_V3_XList(X)
|
||||
DW_Expr_V4_XList(X)
|
||||
DW_Expr_V5_XList(X)
|
||||
DW_Expr_GNU_XList(X)
|
||||
DW_Expr_V4_XList(X)
|
||||
DW_Expr_V5_XList(X)
|
||||
DW_Expr_GNU_XList(X)
|
||||
#undef X
|
||||
default: { NotImplemented; } break;
|
||||
default: { NotImplemented; } break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -460,11 +458,11 @@ dw_push_count_from_expr_op(DW_ExprOp op)
|
||||
switch (op) {
|
||||
#define X(_N, _ID, _OPER_COUNT, _POP_COUNT, _PUSH_COUNT) case _ID: return _PUSH_COUNT;
|
||||
DW_Expr_V3_XList(X)
|
||||
DW_Expr_V4_XList(X)
|
||||
DW_Expr_V5_XList(X)
|
||||
DW_Expr_GNU_XList(X)
|
||||
DW_Expr_V4_XList(X)
|
||||
DW_Expr_V5_XList(X)
|
||||
DW_Expr_GNU_XList(X)
|
||||
#undef X
|
||||
default: { NotImplemented; } break;
|
||||
default: { NotImplemented; } break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -476,7 +474,7 @@ dw_operand_count_from_cfa_opcode(DW_CFA_Opcode opcode)
|
||||
#define X(_N, _ID, ...) case _ID: { local_persist DW_CFA_OperandType t[] = { DW_CFA_OperandType_Null, __VA_ARGS__ }; return ArrayCount(t)-1; }
|
||||
DW_CFA_Kind_XList(X)
|
||||
#undef X
|
||||
default: { NotImplemented; } break;
|
||||
default: { NotImplemented; } break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -486,21 +484,21 @@ dw_is_cfa_expr_opcode_invalid(DW_ExprOp opcode)
|
||||
{
|
||||
B32 is_invalid = 0;
|
||||
switch (opcode) {
|
||||
case DW_ExprOp_Addrx:
|
||||
case DW_ExprOp_Call2:
|
||||
case DW_ExprOp_Call4:
|
||||
case DW_ExprOp_CallRef:
|
||||
case DW_ExprOp_ConstType:
|
||||
case DW_ExprOp_Constx:
|
||||
case DW_ExprOp_Convert:
|
||||
case DW_ExprOp_DerefType:
|
||||
case DW_ExprOp_RegvalType:
|
||||
case DW_ExprOp_Reinterpret:
|
||||
case DW_ExprOp_PushObjectAddress:
|
||||
case DW_ExprOp_CallFrameCfa: {
|
||||
is_invalid = 1;
|
||||
} break;
|
||||
default: break;
|
||||
case DW_ExprOp_Addrx:
|
||||
case DW_ExprOp_Call2:
|
||||
case DW_ExprOp_Call4:
|
||||
case DW_ExprOp_CallRef:
|
||||
case DW_ExprOp_ConstType:
|
||||
case DW_ExprOp_Constx:
|
||||
case DW_ExprOp_Convert:
|
||||
case DW_ExprOp_DerefType:
|
||||
case DW_ExprOp_RegvalType:
|
||||
case DW_ExprOp_Reinterpret:
|
||||
case DW_ExprOp_PushObjectAddress:
|
||||
case DW_ExprOp_CallFrameCfa: {
|
||||
is_invalid = 1;
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
return is_invalid;
|
||||
}
|
||||
@@ -510,14 +508,14 @@ dw_is_new_row_cfa_opcode(DW_CFA_Opcode opcode)
|
||||
{
|
||||
B32 is_new_row_op = 0;
|
||||
switch (opcode) {
|
||||
case DW_CFA_SetLoc:
|
||||
case DW_CFA_AdvanceLoc:
|
||||
case DW_CFA_AdvanceLoc1:
|
||||
case DW_CFA_AdvanceLoc2:
|
||||
case DW_CFA_AdvanceLoc4: {
|
||||
is_new_row_op = 1;
|
||||
} break;
|
||||
default: break;
|
||||
case DW_CFA_SetLoc:
|
||||
case DW_CFA_AdvanceLoc:
|
||||
case DW_CFA_AdvanceLoc1:
|
||||
case DW_CFA_AdvanceLoc2:
|
||||
case DW_CFA_AdvanceLoc4: {
|
||||
is_new_row_op = 1;
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
return is_new_row_op;
|
||||
}
|
||||
@@ -529,7 +527,7 @@ dw_operand_types_from_cfa_op(DW_CFA_Opcode opcode)
|
||||
#define X(_N, _ID, ...) case _ID: { local_persist DW_CFA_OperandType t[] = { DW_CFA_OperandType_Null, __VA_ARGS__ }; return &t[0] + 1; }
|
||||
DW_CFA_Kind_XList(X)
|
||||
#undef X
|
||||
default: { NotImplemented; } break;
|
||||
default: { NotImplemented; } break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -541,9 +539,9 @@ internal String8
|
||||
dw_string_from_format(DW_Format format)
|
||||
{
|
||||
switch (format) {
|
||||
case DW_Format_Null: return str8_zero();
|
||||
case DW_Format_32Bit: return str8_lit("DWARF32");
|
||||
case DW_Format_64Bit: return str8_lit("DWARF64");
|
||||
case DW_Format_Null: return str8_zero();
|
||||
case DW_Format_32Bit: return str8_lit("DWARF32");
|
||||
case DW_Format_64Bit: return str8_lit("DWARF64");
|
||||
}
|
||||
return str8_zero();
|
||||
}
|
||||
@@ -826,7 +824,7 @@ dw_string_from_cfa_opcode(DW_CFA_Opcode opcode)
|
||||
#define X(_NAME, _ID, ...) case _ID: return str8_lit(Stringify(_NAME));
|
||||
DW_CFA_Kind_XList(X)
|
||||
#undef X
|
||||
default: InvalidPath; break;
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
+7
-7
@@ -478,7 +478,7 @@ X(GNU_RefAlt, DW_AttribClass_Undefined) \
|
||||
X(GNU_StrpAlt, DW_AttribClass_String)
|
||||
|
||||
typedef U64 DW_FormKind;
|
||||
typedef enum DW_FormKindEnum
|
||||
typedef enum DW_FormEnum
|
||||
{
|
||||
DW_Form_Null,
|
||||
#define X(_N, _ID) DW_Form_##_N = _ID,
|
||||
@@ -487,7 +487,7 @@ typedef enum DW_FormKindEnum
|
||||
DW_Form_V5_XList(X)
|
||||
DW_Form_GNU_XList(X)
|
||||
#undef X
|
||||
} DW_FormKindEnum;
|
||||
} DW_FormEnum;
|
||||
|
||||
//- Attributes DWARF2
|
||||
|
||||
@@ -1582,9 +1582,9 @@ typedef enum DW_ExprOpEnum
|
||||
{
|
||||
#define X(_N, _ID, _OPER_COUNT, _POP_COUNT, _PUSH_COUNT) DW_ExprOp_##_N = _ID,
|
||||
DW_Expr_V3_XList(X)
|
||||
DW_Expr_V4_XList(X)
|
||||
DW_Expr_V5_XList(X)
|
||||
DW_Expr_GNU_XList(X)
|
||||
DW_Expr_V4_XList(X)
|
||||
DW_Expr_V5_XList(X)
|
||||
DW_Expr_GNU_XList(X)
|
||||
#undef X
|
||||
} DW_ExprOpEnum;
|
||||
|
||||
@@ -1762,7 +1762,7 @@ internal DW_AttribClass dw_attrib_class_from_attrib_llvm (DW_AttribKind k);
|
||||
internal DW_AttribClass dw_attrib_class_from_attrib_apple(DW_AttribKind k);
|
||||
internal DW_AttribClass dw_attrib_class_from_attrib_mips (DW_AttribKind k);
|
||||
|
||||
internal DW_AttribClass dw_attrib_class_from_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
|
||||
|
||||
@@ -1782,7 +1782,7 @@ internal U64 dw_size_from_format(DW_Format format);
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal DW_AttribClass dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, DW_AttribKind attrib, DW_FormKind form_kind);
|
||||
internal DW_AttribClass dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, B32 relaxed, DW_AttribKind attrib, DW_FormKind form_kind);
|
||||
|
||||
internal U64 dw_pick_default_lower_bound(DW_Language lang);
|
||||
|
||||
|
||||
@@ -23,14 +23,14 @@ dw_is_dwarf_present_coff_section_table(String8 string_table, U64 section_count,
|
||||
return is_dwarf_present;
|
||||
}
|
||||
|
||||
internal DW_Raw
|
||||
dw_raw_from_coff_section_table(Arena *arena,
|
||||
String8 raw_image,
|
||||
String8 string_table,
|
||||
U64 section_count,
|
||||
COFF_SectionHeader *section_table)
|
||||
internal DW_Input
|
||||
dw_input_from_coff_section_table(Arena *arena,
|
||||
String8 raw_image,
|
||||
String8 string_table,
|
||||
U64 section_count,
|
||||
COFF_SectionHeader *section_table)
|
||||
{
|
||||
DW_Raw input = {0};
|
||||
DW_Input input = {0};
|
||||
B32 sect_status[ArrayCount(input.sec)] = {0};
|
||||
|
||||
for (U64 i = 0; i < section_count; ++i) {
|
||||
@@ -51,6 +51,7 @@ dw_raw_from_coff_section_table(Arena *arena,
|
||||
} else {
|
||||
sect_status[s] = 1;
|
||||
DW_Section *d = &input.sec[s];
|
||||
d->name = push_str8_copy(arena, name);
|
||||
d->data = str8_substr(raw_image, raw_data_range);
|
||||
d->is_dwo = is_dwo;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#define DWARF_COFF_H
|
||||
|
||||
internal B32 dw_is_dwarf_present_coff_section_table(String8 string_table, U64 section_count, COFF_SectionHeader *section_table);
|
||||
internal DW_Raw dw_raw_from_coff_section_table(Arena *arena, String8 raw_image, String8 string_table, U64 section_count, COFF_SectionHeader *section_table);
|
||||
internal DW_Input dw_input_from_coff_section_table(Arena *arena, String8 raw_image, String8 string_table, U64 section_count, COFF_SectionHeader *section_table);
|
||||
|
||||
#endif // DWARF_COFF_H
|
||||
|
||||
|
||||
+240
-239
@@ -211,13 +211,13 @@ dw_string_list_from_expression(Arena *arena, String8 raw_data, U64 cu_base, U64
|
||||
} break;
|
||||
case DW_ExprOp_CallRef: {
|
||||
U64 x = 0;
|
||||
cursor += dw_str8_deserial_read_fmt_uint(raw_data, cursor, format, &x);
|
||||
cursor += str8_deserial_read_dwarf_uint(raw_data, cursor, format, &x);
|
||||
op_value = push_str8f(scratch.arena, "%llu", x);
|
||||
} break;
|
||||
case DW_ExprOp_ImplicitPointer:
|
||||
case DW_ExprOp_GNU_ImplicitPointer: {
|
||||
U64 info_off = 0;
|
||||
cursor += dw_str8_deserial_read_fmt_uint(raw_data, cursor, format, &info_off);
|
||||
cursor += str8_deserial_read_dwarf_uint(raw_data, cursor, format, &info_off);
|
||||
S64 ptr = 0;
|
||||
cursor += str8_deserial_read_sleb128(raw_data, cursor, &ptr);
|
||||
|
||||
@@ -350,7 +350,7 @@ dw_string_list_from_cfi_program(Arena *arena,
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
String8List list = {0};
|
||||
|
||||
|
||||
U64 reg_max = dw_reg_count_from_arch(arch);
|
||||
U64 pc = pc_begin;
|
||||
for (U64 cursor = 0, inst_size; cursor < program.size; cursor += inst_size) {
|
||||
@@ -362,134 +362,134 @@ dw_string_list_from_cfi_program(Arena *arena,
|
||||
str8_list_pushf(arena, &list, "ERROR: failed to unpack CFA instruction @ 0x%I64", cursor);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// error check operands
|
||||
DW_CFA_OperandType *operand_types = dw_operand_types_from_cfa_op(inst.opcode);
|
||||
U64 operand_count = dw_operand_count_from_cfa_opcode(inst.opcode);
|
||||
for EachIndex(operand_idx, operand_count) {
|
||||
switch (operand_types[operand_idx]) {
|
||||
case DW_CFA_OperandType_Null: break;
|
||||
case DW_CFA_OperandType_Value: break;
|
||||
case DW_CFA_OperandType_Register: {
|
||||
if (inst.operands[operand_idx].u64 >= reg_max) {
|
||||
str8_list_pushf(arena, &list, "ERROR: DW_CFA_%S @ 0x%I64x has an invalid register",
|
||||
dw_string_from_cfa_opcode(inst.opcode),
|
||||
cursor);
|
||||
case DW_CFA_OperandType_Null: break;
|
||||
case DW_CFA_OperandType_Value: break;
|
||||
case DW_CFA_OperandType_Register: {
|
||||
if (inst.operands[operand_idx].u64 >= reg_max) {
|
||||
str8_list_pushf(arena, &list, "ERROR: DW_CFA_%S @ 0x%I64x has an invalid register",
|
||||
dw_string_from_cfa_opcode(inst.opcode),
|
||||
cursor);
|
||||
}
|
||||
} break;
|
||||
case DW_CFA_OperandType_Expression: {
|
||||
DW_Expr expr = dw_expr_from_data(scratch.arena, format, cie->address_size, inst.operands[operand_idx].block);
|
||||
for EachNode(inst, DW_ExprInst, expr.first) {
|
||||
if (dw_is_cfa_expr_opcode_invalid(inst->opcode)) {
|
||||
String8 expr_opcode_str = dw_string_from_expr_op(scratch.arena, ver, ext, inst->opcode);
|
||||
str8_list_pushf(arena, &list, "ERROR: Exrepssion in DW_CFA_%S @ 0x%I64x has an invalid opcode DW_ExprOp_%S", expr_opcode_str);
|
||||
}
|
||||
} break;
|
||||
case DW_CFA_OperandType_Expression: {
|
||||
DW_Expr expr = dw_expr_from_data(scratch.arena, format, cie->address_size, inst.operands[operand_idx].block);
|
||||
for EachNode(inst, DW_ExprInst, expr.first) {
|
||||
if (dw_is_cfa_expr_opcode_invalid(inst->opcode)) {
|
||||
String8 expr_opcode_str = dw_string_from_expr_op(scratch.arena, ver, ext, inst->opcode);
|
||||
str8_list_pushf(arena, &list, "ERROR: Exrepssion in DW_CFA_%S @ 0x%I64x has an invalid opcode DW_ExprOp_%S", expr_opcode_str);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
} break;
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// format operands
|
||||
String8 operand_str = str8_lit("???");
|
||||
switch (inst.opcode) {
|
||||
case DW_CFA_Nop: { operand_str = str8_zero(); } break;
|
||||
case DW_CFA_SetLoc: {
|
||||
operand_str = str8f(arena, "0x%X", inst.operands[0].u64);
|
||||
pc = inst.operands[0].u64;
|
||||
} break;
|
||||
case DW_CFA_AdvanceLoc1: {
|
||||
U64 delta = inst.operands[0].u64;
|
||||
pc += delta;
|
||||
operand_str = str8f(arena, "%+u `PC 0x%I64x`", delta, pc);
|
||||
} break;
|
||||
case DW_CFA_AdvanceLoc2: {
|
||||
U64 delta = inst.operands[0].u64;
|
||||
pc += delta;
|
||||
operand_str = str8f(arena, "%+u `PC 0x%I64x`", delta, pc);
|
||||
} break;
|
||||
case DW_CFA_AdvanceLoc4: {
|
||||
U64 delta = inst.operands[0].u64;
|
||||
pc += delta;
|
||||
operand_str = str8f(arena, "%+u `PC 0x%I64x`", delta, pc);
|
||||
} break;
|
||||
case DW_CFA_OffsetExt: {
|
||||
U64 reg = inst.operands[0].u64;
|
||||
S64 offset = (S64)inst.operands[1].u64;
|
||||
operand_str = dw_string_from_reg_off(arena, arch, reg, offset);
|
||||
} break;
|
||||
case DW_CFA_RestoreExt: { operand_str = str8_zero(); } break;
|
||||
case DW_CFA_Undefined: {
|
||||
operand_str = str8f(arena, "%I64u", inst.operands[0].u64);
|
||||
} break;
|
||||
case DW_CFA_SameValue: {
|
||||
operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, 0);
|
||||
} break;
|
||||
case DW_CFA_Register: {
|
||||
operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, inst.operands[1].u64);
|
||||
} break;
|
||||
case DW_CFA_RememberState: { operand_str = str8_zero(); } break;
|
||||
case DW_CFA_RestoreState: { operand_str = str8_zero(); } break;
|
||||
case DW_CFA_DefCfa: {
|
||||
operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, inst.operands[1].u64);
|
||||
} break;
|
||||
case DW_CFA_DefCfaRegister: {
|
||||
operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, 0);
|
||||
} break;
|
||||
case DW_CFA_DefCfaOffset: {
|
||||
operand_str = str8f(arena, "+%I64u", inst.operands[0].u64);
|
||||
} break;
|
||||
case DW_CFA_DefCfaExpr: {
|
||||
operand_str = dw_string_from_expression(arena, inst.operands[0].block, cu_base, cie->address_size, arch, ver, ext, format);
|
||||
} break;
|
||||
case DW_CFA_Expr: {
|
||||
String8 reg_str = dw_string_from_reg_off(scratch.arena, arch, inst.operands[0].u64, 0);
|
||||
String8 expr_str = dw_string_from_expression(scratch.arena, inst.operands[1].block, cu_base, cie->address_size, arch, ver, ext, format);
|
||||
operand_str = str8f(arena, "%S expression %S", reg_str, expr_str);
|
||||
} break;
|
||||
case DW_CFA_OffsetExtSf: {
|
||||
operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, inst.operands[1].s64);
|
||||
} break;
|
||||
case DW_CFA_DefCfaSf: {
|
||||
operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, inst.operands[1].s64);
|
||||
} break;
|
||||
case DW_CFA_DefCfaOffsetSf: { operand_str = str8_zero(); } break;
|
||||
case DW_CFA_ValOffset: {
|
||||
operand_str = str8f(arena, "value 0x%llx, offset %+I64d", inst.operands[0].u64, inst.operands[1].u64);
|
||||
} break;
|
||||
case DW_CFA_ValOffsetSf: {
|
||||
operand_str = str8f(arena, "value %llu, offset %+I64d", inst.operands[0].u64, inst.operands[1].s64);
|
||||
} break;
|
||||
case DW_CFA_ValExpr: {
|
||||
String8 expr_str = dw_string_from_expression(scratch.arena, inst.operands[1].block, cu_base, cie->address_size, arch, ver, ext, format);
|
||||
operand_str = str8f(arena, "value +%I64u, expression %S", inst.operands[0].u64, expr_str);
|
||||
} break;
|
||||
case DW_CFA_AdvanceLoc: {
|
||||
U64 delta = inst.operands[0].u64;
|
||||
pc += delta;
|
||||
operand_str = str8f(arena, "+%I64u `PC 0x%I64x`", delta, pc);
|
||||
} break;
|
||||
case DW_CFA_Offset: {
|
||||
U64 reg = inst.operands[0].u64;
|
||||
S64 offset = (S64)inst.operands[1].u64;
|
||||
operand_str = dw_string_from_reg_off(arena, arch, reg, offset);
|
||||
} break;
|
||||
case DW_CFA_Restore: {
|
||||
operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, 0);
|
||||
} break;
|
||||
default: {
|
||||
str8_list_pushf(arena, &list, "ERROR: unknown CFA opcode 0x%I64u", inst.opcode);
|
||||
} goto exit;
|
||||
case DW_CFA_Nop: { operand_str = str8_zero(); } break;
|
||||
case DW_CFA_SetLoc: {
|
||||
operand_str = str8f(arena, "0x%X", inst.operands[0].u64);
|
||||
pc = inst.operands[0].u64;
|
||||
} break;
|
||||
case DW_CFA_AdvanceLoc1: {
|
||||
U64 delta = inst.operands[0].u64;
|
||||
pc += delta;
|
||||
operand_str = str8f(arena, "%+u `PC 0x%I64x`", delta, pc);
|
||||
} break;
|
||||
case DW_CFA_AdvanceLoc2: {
|
||||
U64 delta = inst.operands[0].u64;
|
||||
pc += delta;
|
||||
operand_str = str8f(arena, "%+u `PC 0x%I64x`", delta, pc);
|
||||
} break;
|
||||
case DW_CFA_AdvanceLoc4: {
|
||||
U64 delta = inst.operands[0].u64;
|
||||
pc += delta;
|
||||
operand_str = str8f(arena, "%+u `PC 0x%I64x`", delta, pc);
|
||||
} break;
|
||||
case DW_CFA_OffsetExt: {
|
||||
U64 reg = inst.operands[0].u64;
|
||||
S64 offset = (S64)inst.operands[1].u64;
|
||||
operand_str = dw_string_from_reg_off(arena, arch, reg, offset);
|
||||
} break;
|
||||
case DW_CFA_RestoreExt: { operand_str = str8_zero(); } break;
|
||||
case DW_CFA_Undefined: {
|
||||
operand_str = str8f(arena, "%I64u", inst.operands[0].u64);
|
||||
} break;
|
||||
case DW_CFA_SameValue: {
|
||||
operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, 0);
|
||||
} break;
|
||||
case DW_CFA_Register: {
|
||||
operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, inst.operands[1].u64);
|
||||
} break;
|
||||
case DW_CFA_RememberState: { operand_str = str8_zero(); } break;
|
||||
case DW_CFA_RestoreState: { operand_str = str8_zero(); } break;
|
||||
case DW_CFA_DefCfa: {
|
||||
operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, inst.operands[1].u64);
|
||||
} break;
|
||||
case DW_CFA_DefCfaRegister: {
|
||||
operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, 0);
|
||||
} break;
|
||||
case DW_CFA_DefCfaOffset: {
|
||||
operand_str = str8f(arena, "+%I64u", inst.operands[0].u64);
|
||||
} break;
|
||||
case DW_CFA_DefCfaExpr: {
|
||||
operand_str = dw_string_from_expression(arena, inst.operands[0].block, cu_base, cie->address_size, arch, ver, ext, format);
|
||||
} break;
|
||||
case DW_CFA_Expr: {
|
||||
String8 reg_str = dw_string_from_reg_off(scratch.arena, arch, inst.operands[0].u64, 0);
|
||||
String8 expr_str = dw_string_from_expression(scratch.arena, inst.operands[1].block, cu_base, cie->address_size, arch, ver, ext, format);
|
||||
operand_str = str8f(arena, "%S expression %S", reg_str, expr_str);
|
||||
} break;
|
||||
case DW_CFA_OffsetExtSf: {
|
||||
operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, inst.operands[1].s64);
|
||||
} break;
|
||||
case DW_CFA_DefCfaSf: {
|
||||
operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, inst.operands[1].s64);
|
||||
} break;
|
||||
case DW_CFA_DefCfaOffsetSf: { operand_str = str8_zero(); } break;
|
||||
case DW_CFA_ValOffset: {
|
||||
operand_str = str8f(arena, "value 0x%llx, offset %+I64d", inst.operands[0].u64, inst.operands[1].u64);
|
||||
} break;
|
||||
case DW_CFA_ValOffsetSf: {
|
||||
operand_str = str8f(arena, "value %llu, offset %+I64d", inst.operands[0].u64, inst.operands[1].s64);
|
||||
} break;
|
||||
case DW_CFA_ValExpr: {
|
||||
String8 expr_str = dw_string_from_expression(scratch.arena, inst.operands[1].block, cu_base, cie->address_size, arch, ver, ext, format);
|
||||
operand_str = str8f(arena, "value +%I64u, expression %S", inst.operands[0].u64, expr_str);
|
||||
} break;
|
||||
case DW_CFA_AdvanceLoc: {
|
||||
U64 delta = inst.operands[0].u64;
|
||||
pc += delta;
|
||||
operand_str = str8f(arena, "+%I64u `PC 0x%I64x`", delta, pc);
|
||||
} break;
|
||||
case DW_CFA_Offset: {
|
||||
U64 reg = inst.operands[0].u64;
|
||||
S64 offset = (S64)inst.operands[1].u64;
|
||||
operand_str = dw_string_from_reg_off(arena, arch, reg, offset);
|
||||
} break;
|
||||
case DW_CFA_Restore: {
|
||||
operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, 0);
|
||||
} break;
|
||||
default: {
|
||||
str8_list_pushf(arena, &list, "ERROR: unknown CFA opcode 0x%I64u", inst.opcode);
|
||||
} goto exit;
|
||||
}
|
||||
|
||||
|
||||
if (operand_str.size) {
|
||||
str8_list_pushf(arena, &list, "DW_CFA_%S: %S", dw_string_from_cfa_opcode(inst.opcode), operand_str);
|
||||
} else {
|
||||
str8_list_pushf(arena, &list, "DW_CFA_%S", dw_string_from_cfa_opcode(inst.opcode));
|
||||
}
|
||||
}
|
||||
|
||||
exit:;
|
||||
|
||||
exit:;
|
||||
scratch_end(scratch);
|
||||
return list;
|
||||
}
|
||||
@@ -499,10 +499,10 @@ dw_string_from_cfa(Arena *arena, Arch arch, U64 address_size, DW_Version version
|
||||
{
|
||||
String8 cfa_str = str8_lit("???");
|
||||
switch (cfa.rule) {
|
||||
case DW_CFA_Rule_Null: {} break;
|
||||
case DW_CFA_Rule_RegOff: { cfa_str = dw_string_from_reg_off(arena, arch, cfa.reg, cfa.off); } break;
|
||||
case DW_CFA_Rule_Expression: { cfa_str = dw_string_from_expression(arena, cfa.expr, max_U64, address_size, arch, version, ext, format); } break;
|
||||
default: { InvalidPath; } break;
|
||||
case DW_CFA_Rule_Null: {} break;
|
||||
case DW_CFA_Rule_RegOff: { cfa_str = dw_string_from_reg_off(arena, arch, cfa.reg, cfa.off); } break;
|
||||
case DW_CFA_Rule_Expression: { cfa_str = dw_string_from_expression(arena, cfa.expr, max_U64, address_size, arch, version, ext, format); } break;
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
return cfa_str;
|
||||
}
|
||||
@@ -517,40 +517,40 @@ dw_string_from_cfi_row(Arena *arena, Arch arch, U64 address_size, DW_Version ver
|
||||
DW_CFI_Register *cfi_reg = &row->regs[reg_idx];
|
||||
String8 rule_str = str8_lit("???");
|
||||
switch (cfi_reg->rule) {
|
||||
case DW_CFI_RegisterRule_Undefined: {
|
||||
rule_str = str8f(scratch.arena, "Undefined(%S)", dw_string_from_reg(scratch.arena, arch, cfi_reg->n));
|
||||
} break;
|
||||
case DW_CFI_RegisterRule_SameValue: {
|
||||
rule_str = str8_zero();
|
||||
} break;
|
||||
case DW_CFI_RegisterRule_Offset: {
|
||||
rule_str = str8f(scratch.arena, "[CFA%+I64d]", cfi_reg->n);
|
||||
} break;
|
||||
case DW_CFI_RegisterRule_ValOffset: {
|
||||
rule_str = str8f(scratch.arena, "Val(CFA%+I64d)", cfi_reg->n);
|
||||
} break;
|
||||
case DW_CFI_RegisterRule_Register: {
|
||||
rule_str = str8f(scratch.arena, "Register(%S)", dw_string_from_reg(scratch.arena, arch, cfi_reg->n));
|
||||
} break;
|
||||
case DW_CFI_RegisterRule_Expression: {
|
||||
rule_str = str8f(scratch.arena, "Expression(%S)", dw_string_from_expression(scratch.arena, cfi_reg->expr, max_U64, address_size, arch, version, ext, format));
|
||||
} break;
|
||||
case DW_CFI_RegisterRule_ValExpression: {
|
||||
rule_str = str8f(scratch.arena, "ValExpression(%S)", dw_string_from_expression(scratch.arena, cfi_reg->expr, max_U64, address_size, arch, version, ext, format));
|
||||
} break;
|
||||
case DW_CFI_RegisterRule_Architectural: {
|
||||
rule_str = str8_lit("???");
|
||||
} break;
|
||||
default: { InvalidPath; } break;
|
||||
case DW_CFI_RegisterRule_Undefined: {
|
||||
rule_str = str8f(scratch.arena, "Undefined(%S)", dw_string_from_reg(scratch.arena, arch, cfi_reg->n));
|
||||
} break;
|
||||
case DW_CFI_RegisterRule_SameValue: {
|
||||
rule_str = str8_zero();
|
||||
} break;
|
||||
case DW_CFI_RegisterRule_Offset: {
|
||||
rule_str = str8f(scratch.arena, "[CFA%+I64d]", cfi_reg->n);
|
||||
} break;
|
||||
case DW_CFI_RegisterRule_ValOffset: {
|
||||
rule_str = str8f(scratch.arena, "Val(CFA%+I64d)", cfi_reg->n);
|
||||
} break;
|
||||
case DW_CFI_RegisterRule_Register: {
|
||||
rule_str = str8f(scratch.arena, "Register(%S)", dw_string_from_reg(scratch.arena, arch, cfi_reg->n));
|
||||
} break;
|
||||
case DW_CFI_RegisterRule_Expression: {
|
||||
rule_str = str8f(scratch.arena, "Expression(%S)", dw_string_from_expression(scratch.arena, cfi_reg->expr, max_U64, address_size, arch, version, ext, format));
|
||||
} break;
|
||||
case DW_CFI_RegisterRule_ValExpression: {
|
||||
rule_str = str8f(scratch.arena, "ValExpression(%S)", dw_string_from_expression(scratch.arena, cfi_reg->expr, max_U64, address_size, arch, version, ext, format));
|
||||
} break;
|
||||
case DW_CFI_RegisterRule_Architectural: {
|
||||
rule_str = str8_lit("???");
|
||||
} break;
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
|
||||
|
||||
if (rule_str.size) {
|
||||
str8_list_pushf(scratch.arena, &cfi_regs_list, "%S: %S", dw_string_from_reg(scratch.arena, arch, reg_idx), rule_str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String8 string = str8_list_join(arena, &cfi_regs_list, &(StringJoin){.sep=str8_lit(", ")});
|
||||
|
||||
|
||||
scratch_end(scratch);
|
||||
return string;
|
||||
}
|
||||
@@ -680,7 +680,7 @@ dw_print_eh_frame(Arena *arena, String8List *out, String8 indent, String8 raw_eh
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_loc(Arena *arena, String8List *out, String8 indent, DW_Raw *input, Arch arch, ExecutableImageKind image_type, B32 relaxed)
|
||||
dw_print_debug_loc(Arena *arena, String8List *out, String8 indent, DW_Input *input, Arch arch, ExecutableImageKind image_type, B32 relaxed)
|
||||
{
|
||||
#if 0
|
||||
DW_Section info = input->sec[DW_Section_Info];
|
||||
@@ -827,7 +827,7 @@ dw_print_debug_loc(Arena *arena, String8List *out, String8 indent, DW_Raw *input
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_ranges(Arena *arena, String8List *out, String8 indent, DW_Raw *input, Arch arch, ExecutableImageKind image_type, B32 relaxed)
|
||||
dw_print_debug_ranges(Arena *arena, String8List *out, String8 indent, DW_Input *input, Arch arch, ExecutableImageKind image_type, B32 relaxed)
|
||||
{
|
||||
NotImplemented;
|
||||
#if 0
|
||||
@@ -933,7 +933,7 @@ dw_print_debug_ranges(Arena *arena, String8List *out, String8 indent, DW_Raw *in
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_aranges(Arena *arena, String8List *out, String8 indent, DW_Raw *input)
|
||||
dw_print_debug_aranges(Arena *arena, String8List *out, String8 indent, DW_Input *input)
|
||||
{
|
||||
NotImplemented;
|
||||
#if 0
|
||||
@@ -1022,7 +1022,7 @@ dw_print_debug_aranges(Arena *arena, String8List *out, String8 indent, DW_Raw *i
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_addr(Arena *arena, String8List *out, String8 indent, DW_Raw *input)
|
||||
dw_print_debug_addr(Arena *arena, String8List *out, String8 indent, DW_Input *input)
|
||||
{
|
||||
NotImplemented;
|
||||
#if 0
|
||||
@@ -1131,7 +1131,7 @@ dw_based_range_read_address(void *base, Rng1U64 range, U64 offset, Rng1U64Array
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_loclists(Arena *arena, String8List *out, String8 indent, DW_Raw *input, Rng1U64Array segment_virtual_ranges, Arch arch)
|
||||
dw_print_debug_loclists(Arena *arena, String8List *out, String8 indent, DW_Input *input, Rng1U64Array segment_virtual_ranges, Arch arch)
|
||||
{
|
||||
NotImplemented;
|
||||
#if 0
|
||||
@@ -1284,7 +1284,7 @@ dw_print_debug_loclists(Arena *arena, String8List *out, String8 indent, DW_Raw *
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_rnglists(Arena *arena, String8List *out, String8 indent, DW_Raw *input, Rng1U64Array segment_ranges)
|
||||
dw_print_debug_rnglists(Arena *arena, String8List *out, String8 indent, DW_Input *input, Rng1U64Array segment_ranges)
|
||||
{
|
||||
NotImplemented;
|
||||
#if 0
|
||||
@@ -1423,7 +1423,7 @@ dw_print_debug_rnglists(Arena *arena, String8List *out, String8 indent, DW_Raw *
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_format_string_table(Arena *arena, String8List *out, String8 indent, DW_Raw *input, DW_SectionKind sec)
|
||||
dw_format_string_table(Arena *arena, String8List *out, String8 indent, DW_Input *input, DW_SectionKind sec)
|
||||
{
|
||||
NotImplemented;
|
||||
#if 0
|
||||
@@ -1485,19 +1485,19 @@ dw_format_string_table(Arena *arena, String8List *out, String8 indent, DW_Raw *i
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_pubnames(Arena *arena, String8List *out, String8 indent, DW_Raw *input)
|
||||
dw_print_debug_pubnames(Arena *arena, String8List *out, String8 indent, DW_Input *input)
|
||||
{
|
||||
dw_format_string_table(arena, out, indent, input, DW_Section_PubNames);
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_pubtypes(Arena *arena, String8List *out, String8 indent, DW_Raw *input)
|
||||
dw_print_debug_pubtypes(Arena *arena, String8List *out, String8 indent, DW_Input *input)
|
||||
{
|
||||
dw_format_string_table(arena, out, indent, input, DW_Section_PubTypes);
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_line_str(Arena *arena, String8List *out, String8 indent, DW_Raw *input)
|
||||
dw_print_debug_line_str(Arena *arena, String8List *out, String8 indent, DW_Input *input)
|
||||
{
|
||||
NotImplemented;
|
||||
#if 0
|
||||
@@ -1527,7 +1527,7 @@ dw_print_debug_line_str(Arena *arena, String8List *out, String8 indent, DW_Raw *
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 indent, DW_Raw *input)
|
||||
dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 indent, DW_Input *input)
|
||||
{
|
||||
NotImplemented;
|
||||
#if 0
|
||||
@@ -1598,10 +1598,10 @@ dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 indent, DW_Ra
|
||||
//~ rjf: Dump Entry Point
|
||||
|
||||
internal String8
|
||||
dw_string_from_attrib_value(Arena *arena, DW_Raw *input, Arch arch, DW_CompUnit *unit, DW_LineVMHeader *line_vm, DW_Attrib *attrib)
|
||||
dw_string_from_attrib_value(Arena *arena, DW_Input *input, Arch arch, DW_CompUnit *unit, DW_LineVMHeader *line_vm, DW_Attrib *attrib)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
|
||||
|
||||
String8List attrib_fmt = {0};
|
||||
|
||||
// rjf: log attrib's value based on vlass
|
||||
@@ -1722,7 +1722,7 @@ dw_string_from_attrib_value(Arena *arena, DW_Raw *input, Arch arch, DW_CompUnit
|
||||
enum_info = dw_string_from_attrib_type_encoding(scratch.arena, encoding);
|
||||
}break;
|
||||
}
|
||||
|
||||
|
||||
if(enum_info.size)
|
||||
{
|
||||
str8_list_pushf(scratch.arena, &attrib_fmt, " `%S`", enum_info);
|
||||
@@ -1730,14 +1730,14 @@ dw_string_from_attrib_value(Arena *arena, DW_Raw *input, Arch arch, DW_CompUnit
|
||||
}
|
||||
|
||||
String8 result = str8_list_join(arena, &attrib_fmt, 0);
|
||||
|
||||
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8List
|
||||
dw_dump_list_from_sections(Arena *arena,
|
||||
DW_Raw *input,
|
||||
DW_Input *input,
|
||||
Arch arch,
|
||||
DW_DumpSubsetFlags subset_flags)
|
||||
{
|
||||
@@ -1748,17 +1748,18 @@ dw_dump_list_from_sections(Arena *arena,
|
||||
#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_raw(scratch.arena, input);
|
||||
|
||||
DW_ListUnitInput lu_input = dw_list_unit_input_from_input(scratch.arena, input);
|
||||
B32 relaxed = 1;
|
||||
|
||||
DW_CompUnit *cu_arr;
|
||||
{
|
||||
DW_ListUnitInput lu_input = dw_list_unit_input_from_raw(scratch.arena, input);
|
||||
DW_ListUnitInput lu_input = dw_list_unit_input_from_input(scratch.arena, input);
|
||||
Rng1U64List cu_range_list = dw_unit_ranges_from_data(scratch.arena, input->sec[DW_Section_Info].data);
|
||||
Rng1U64Array cu_ranges = rng1u64_array_from_list(scratch.arena, &cu_range_list);
|
||||
cu_arr = push_array(scratch.arena, DW_CompUnit, cu_ranges.count);
|
||||
for EachIndex(cu_idx, cu_ranges.count)
|
||||
{
|
||||
cu_arr[cu_idx] = dw_cu_from_info_off(scratch.arena, input, lu_input, cu_ranges.v[cu_idx].min);
|
||||
cu_arr[cu_idx] = dw_cu_from_info_off(scratch.arena, input, lu_input, cu_ranges.v[cu_idx].min, relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1779,7 +1780,7 @@ dw_dump_list_from_sections(Arena *arena,
|
||||
String8 unit_dir = dw_string_from_tag_attrib_kind(input, unit, unit->tag, DW_AttribKind_CompDir );
|
||||
String8 unit_name = dw_string_from_tag_attrib_kind(input, unit, unit->tag, DW_AttribKind_Name );
|
||||
String8 stmt_list = dw_line_ptr_from_tag_attrib_kind(input, unit, unit->tag, DW_AttribKind_StmtList);
|
||||
DW_LineVMHeader line_vm = {0};
|
||||
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
|
||||
@@ -1819,25 +1820,25 @@ dw_dump_list_from_sections(Arena *arena,
|
||||
temp_end(attrib_temp);
|
||||
}
|
||||
value_max_size = Min(120, value_max_size);
|
||||
|
||||
|
||||
// log
|
||||
for EachNode(attrib_n, DW_AttribNode, tag.attribs.first)
|
||||
{
|
||||
DW_Attrib *attrib = &attrib_n->v;
|
||||
|
||||
|
||||
Temp attrib_temp = temp_begin(tag_temp.arena);
|
||||
|
||||
|
||||
String8 attrib_kind_str = dw_string_from_attrib_kind(attrib_temp.arena, unit->version, unit->ext, attrib->attrib_kind);
|
||||
String8 form_kind_str = dw_string_from_form_kind(attrib_temp.arena, unit->version, attrib->form_kind);
|
||||
String8 value_str = dw_string_from_attrib_value(attrib_temp.arena, input, arch, unit, &line_vm, attrib);
|
||||
|
||||
|
||||
dumpf("%S attrib: { kind: %S, %.*sform_kind: %S, %.*svalue: %S, %.*s} // info_off: 0x%I64x\n",
|
||||
tag_indent,
|
||||
attrib_kind_str, attrib_name_max_size - attrib_kind_str.size, indent.str,
|
||||
form_kind_str, form_kind_max_size - form_kind_str.size, indent.str,
|
||||
value_str, value_str.size < value_max_size ? value_max_size - value_str.size: 0, indent.str,
|
||||
attrib->info_off, unit_idx, tag_idx);
|
||||
|
||||
tag_indent,
|
||||
attrib_kind_str, attrib_name_max_size - attrib_kind_str.size, indent.str,
|
||||
form_kind_str, form_kind_max_size - form_kind_str.size, indent.str,
|
||||
value_str, value_str.size < value_max_size ? value_max_size - value_str.size: 0, indent.str,
|
||||
attrib->info_off, unit_idx, tag_idx);
|
||||
|
||||
temp_end(attrib_temp);
|
||||
}
|
||||
}
|
||||
@@ -2198,7 +2199,7 @@ dw_dump_list_from_sections(Arena *arena,
|
||||
dumpf(" { 0x%08I64x %llu \"%S\" }\n", cursor, string.size, string);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
//~ dump .debug_frame
|
||||
DumpSubset(DebugFrame)
|
||||
@@ -2206,7 +2207,7 @@ dw_dump_list_from_sections(Arena *arena,
|
||||
HashTable *cie_ht = hash_table_init(scratch.arena, 0x2000);
|
||||
String8 debug_frame = input->sec[DW_Section_Frame].data;
|
||||
U64 addr_size = byte_size_from_arch(arch);
|
||||
|
||||
|
||||
// make offset -> CIE hash table
|
||||
for (U64 cursor = 0, desc_size; cursor < debug_frame.size; cursor += desc_size) {
|
||||
DW_DescriptorEntry desc = {0};
|
||||
@@ -2228,71 +2229,71 @@ dw_dump_list_from_sections(Arena *arena,
|
||||
desc_size = dw_parse_descriptor_entry_header(debug_frame, cursor, &desc);
|
||||
String8 raw_desc = str8_substr(debug_frame, desc.entry_range);
|
||||
switch (desc.type) {
|
||||
case DW_DescriptorEntryType_Null: {} break;
|
||||
case DW_DescriptorEntryType_CIE: {
|
||||
DW_CIE cie = {0};
|
||||
if (dw_parse_cie(raw_desc, desc.format, arch, &cie)) {
|
||||
String8List init_insts_str_list = dw_string_list_from_cfi_program(scratch.arena, 0, arch, DW_Version_5, DW_Ext_All, cie.format, 0, &cie, dw_decode_ptr_debug_frame, &cie, cie.insts);
|
||||
|
||||
dumpf("CIE: // entry range: %r\n", desc.entry_range);
|
||||
dumpf("{\n");
|
||||
dumpf(" Format: %S\n", dw_string_from_format(desc.format));
|
||||
dumpf(" Version: %u\n", cie.version);
|
||||
dumpf(" Aug string: \"%S\"\n", cie.aug_string);
|
||||
dumpf(" Code align: %I64u\n", cie.code_align_factor);
|
||||
dumpf(" Data align: %I64d\n", cie.data_align_factor);
|
||||
dumpf(" Return addr reg: %u\n", cie.ret_addr_reg);
|
||||
if (cie.version > DW_Version_3) {
|
||||
dumpf(" Address size: %u\n", cie.address_size);
|
||||
dumpf(" Segment selector size: %u\n", cie.segment_selector_size);
|
||||
}
|
||||
dumpf(" Initial Insturction:\n");
|
||||
dumpf(" {\n");
|
||||
for EachNode(n, String8Node, init_insts_str_list.first) { dumpf(" %S\n", n->string); }
|
||||
dumpf(" }\n");
|
||||
dumpf("}\n");
|
||||
} else {
|
||||
dumpf("ERROR: unable to parse CIE @ %I64x\n", desc.entry_range.min);
|
||||
case DW_DescriptorEntryType_Null: {} break;
|
||||
case DW_DescriptorEntryType_CIE: {
|
||||
DW_CIE cie = {0};
|
||||
if (dw_parse_cie(raw_desc, desc.format, arch, &cie)) {
|
||||
String8List init_insts_str_list = dw_string_list_from_cfi_program(scratch.arena, 0, arch, DW_Version_5, DW_Ext_All, cie.format, 0, &cie, dw_decode_ptr_debug_frame, &cie, cie.insts);
|
||||
|
||||
dumpf("CIE: // entry range: %r\n", desc.entry_range);
|
||||
dumpf("{\n");
|
||||
dumpf(" Format: %S\n", dw_string_from_format(desc.format));
|
||||
dumpf(" Version: %u\n", cie.version);
|
||||
dumpf(" Aug string: \"%S\"\n", cie.aug_string);
|
||||
dumpf(" Code align: %I64u\n", cie.code_align_factor);
|
||||
dumpf(" Data align: %I64d\n", cie.data_align_factor);
|
||||
dumpf(" Return addr reg: %u\n", cie.ret_addr_reg);
|
||||
if (cie.version > DW_Version_3) {
|
||||
dumpf(" Address size: %u\n", cie.address_size);
|
||||
dumpf(" Segment selector size: %u\n", cie.segment_selector_size);
|
||||
}
|
||||
} break;
|
||||
case DW_DescriptorEntryType_FDE: {
|
||||
DW_DescriptorEntry cie_desc = {0};
|
||||
U64 cie_desc_size = dw_parse_descriptor_entry_header(debug_frame, desc.cie_pointer, &cie_desc);
|
||||
String8 cie_data = str8_substr(debug_frame, cie_desc.entry_range);
|
||||
DW_CIE cie = {0};
|
||||
dw_parse_cie(cie_data, cie_desc.format, arch, &cie);
|
||||
|
||||
DW_FDE fde = {0};
|
||||
if (dw_parse_fde(raw_desc, desc.format, &cie, &fde)) {
|
||||
DW_Version version = DW_Version_5;
|
||||
DW_Ext ext = DW_Ext_All;
|
||||
String8List insts_str_list = dw_string_list_from_cfi_program(scratch.arena, 0, arch, version, ext, fde.format, fde.pc_range.min, &cie, dw_decode_ptr_debug_frame, &cie, fde.insts);
|
||||
dumpf("FDE: // entry range: %r\n", desc.entry_range);
|
||||
dumpf("{\n");
|
||||
{
|
||||
dumpf(" Format: %S\n", dw_string_from_format(fde.format));
|
||||
dumpf(" CIE pointer: 0x%I64x\n", fde.cie_pointer);
|
||||
dumpf(" PC range: %r\n", fde.pc_range);
|
||||
dumpf(" Instructions:\n");
|
||||
dumpf(" {\n");
|
||||
for EachNode(n, String8Node, insts_str_list.first) { dumpf(" %S\n", n->string); }
|
||||
dumpf(" }\n");
|
||||
}
|
||||
dumpf(" Unwind:\n");
|
||||
dumpf(" Initial Insturction:\n");
|
||||
dumpf(" {\n");
|
||||
for EachNode(n, String8Node, init_insts_str_list.first) { dumpf(" %S\n", n->string); }
|
||||
dumpf(" }\n");
|
||||
dumpf("}\n");
|
||||
} else {
|
||||
dumpf("ERROR: unable to parse CIE @ %I64x\n", desc.entry_range.min);
|
||||
}
|
||||
} break;
|
||||
case DW_DescriptorEntryType_FDE: {
|
||||
DW_DescriptorEntry cie_desc = {0};
|
||||
U64 cie_desc_size = dw_parse_descriptor_entry_header(debug_frame, desc.cie_pointer, &cie_desc);
|
||||
String8 cie_data = str8_substr(debug_frame, cie_desc.entry_range);
|
||||
DW_CIE cie = {0};
|
||||
dw_parse_cie(cie_data, cie_desc.format, arch, &cie);
|
||||
|
||||
DW_FDE fde = {0};
|
||||
if (dw_parse_fde(raw_desc, desc.format, &cie, &fde)) {
|
||||
DW_Version version = DW_Version_5;
|
||||
DW_Ext ext = DW_Ext_All;
|
||||
String8List insts_str_list = dw_string_list_from_cfi_program(scratch.arena, 0, arch, version, ext, fde.format, fde.pc_range.min, &cie, dw_decode_ptr_debug_frame, &cie, fde.insts);
|
||||
dumpf("FDE: // entry range: %r\n", desc.entry_range);
|
||||
dumpf("{\n");
|
||||
{
|
||||
dumpf(" Format: %S\n", dw_string_from_format(fde.format));
|
||||
dumpf(" CIE pointer: 0x%I64x\n", fde.cie_pointer);
|
||||
dumpf(" PC range: %r\n", fde.pc_range);
|
||||
dumpf(" Instructions:\n");
|
||||
dumpf(" {\n");
|
||||
DW_CFI_Unwind *cfi_unwind = dw_cfi_unwind_init(scratch.arena, arch, &cie, &fde, dw_decode_ptr_debug_frame, &cie);
|
||||
do {
|
||||
String8 cfa_str = dw_string_from_cfa(scratch.arena, arch, cie.address_size, version, ext, fde.format, cfi_unwind->row->cfa);
|
||||
String8 cfi_regs_str = dw_string_from_cfi_row(scratch.arena, arch, cie.address_size, version, ext, fde.format, cfi_unwind->row);
|
||||
dumpf(" { PC: 0x%I64x, CFA: %-7S, Rules: { %S }\n", cfi_unwind->pc, cfa_str, cfi_regs_str);
|
||||
} while (dw_cfi_next_row(scratch.arena, cfi_unwind));
|
||||
for EachNode(n, String8Node, insts_str_list.first) { dumpf(" %S\n", n->string); }
|
||||
dumpf(" }\n");
|
||||
|
||||
dumpf("}\n");
|
||||
} else {
|
||||
dumpf("ERROR: unable to parse FDE @ %I64x\n", desc.entry_range.min);
|
||||
}
|
||||
} break;
|
||||
dumpf(" Unwind:\n");
|
||||
dumpf(" {\n");
|
||||
DW_CFI_Unwind *cfi_unwind = dw_cfi_unwind_init(scratch.arena, arch, &cie, &fde, dw_decode_ptr_debug_frame, &cie);
|
||||
do {
|
||||
String8 cfa_str = dw_string_from_cfa(scratch.arena, arch, cie.address_size, version, ext, fde.format, cfi_unwind->row->cfa);
|
||||
String8 cfi_regs_str = dw_string_from_cfi_row(scratch.arena, arch, cie.address_size, version, ext, fde.format, cfi_unwind->row);
|
||||
dumpf(" { PC: 0x%I64x, CFA: %-7S, Rules: { %S }\n", cfi_unwind->pc, cfa_str, cfi_regs_str);
|
||||
} while (dw_cfi_next_row(scratch.arena, cfi_unwind));
|
||||
dumpf(" }\n");
|
||||
|
||||
dumpf("}\n");
|
||||
} else {
|
||||
dumpf("ERROR: unable to parse FDE @ %I64x\n", desc.entry_range.min);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-11
@@ -70,21 +70,21 @@ internal String8 dw_string_from_cfi_row(Arena *arena, Arch arch, U64 address_siz
|
||||
|
||||
#if 0
|
||||
internal void dw_print_eh_frame (Arena *arena, String8List *out, String8 indent, String8 raw_eh_frame, Arch arch, DW_Version ver, DW_Ext ext, EH_PtrCtx *ptr_ctx);
|
||||
internal void dw_print_debug_loc (Arena *arena, String8List *out, String8 indent, DW_Raw *input, Arch arch, ExecutableImageKind image_type, B32 relaxed);
|
||||
internal void dw_print_debug_ranges (Arena *arena, String8List *out, String8 indent, DW_Raw *input, Arch arch, ExecutableImageKind image_type, B32 relaxed);
|
||||
internal void dw_print_debug_aranges (Arena *arena, String8List *out, String8 indent, DW_Raw *input);
|
||||
internal void dw_print_debug_addr (Arena *arena, String8List *out, String8 indent, DW_Raw *input);
|
||||
internal void dw_print_debug_loclists (Arena *arena, String8List *out, String8 indent, DW_Raw *input, Rng1U64Array segment_vranges, Arch arch);
|
||||
internal void dw_print_debug_rnglists (Arena *arena, String8List *out, String8 indent, DW_Raw *input, Rng1U64Array segment_vranges);
|
||||
internal void dw_print_debug_pubnames (Arena *arena, String8List *out, String8 indent, DW_Raw *input);
|
||||
internal void dw_print_debug_pubtypes (Arena *arena, String8List *out, String8 indent, DW_Raw *input);
|
||||
internal void dw_print_debug_line_str (Arena *arena, String8List *out, String8 indent, DW_Raw *input);
|
||||
internal void dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 indent, DW_Raw *input);
|
||||
internal void dw_print_debug_loc (Arena *arena, String8List *out, String8 indent, DW_Input *input, Arch arch, ExecutableImageKind image_type, B32 relaxed);
|
||||
internal void dw_print_debug_ranges (Arena *arena, String8List *out, String8 indent, DW_Input *input, Arch arch, ExecutableImageKind image_type, B32 relaxed);
|
||||
internal void dw_print_debug_aranges (Arena *arena, String8List *out, String8 indent, DW_Input *input);
|
||||
internal void dw_print_debug_addr (Arena *arena, String8List *out, String8 indent, DW_Input *input);
|
||||
internal void dw_print_debug_loclists (Arena *arena, String8List *out, String8 indent, DW_Input *input, Rng1U64Array segment_vranges, Arch arch);
|
||||
internal void dw_print_debug_rnglists (Arena *arena, String8List *out, String8 indent, DW_Input *input, Rng1U64Array segment_vranges);
|
||||
internal void dw_print_debug_pubnames (Arena *arena, String8List *out, String8 indent, DW_Input *input);
|
||||
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);
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Dump Entry Point
|
||||
|
||||
internal String8List dw_dump_list_from_sections(Arena *arena, DW_Raw *input, Arch arch, DW_DumpSubsetFlags subset_flags);
|
||||
internal String8List dw_dump_list_from_sections(Arena *arena, DW_Input *input, Arch arch, DW_DumpSubsetFlags subset_flags);
|
||||
|
||||
#endif // DWARF_DUMP_H
|
||||
|
||||
@@ -27,10 +27,10 @@ dw_is_dwarf_present_from_elf_bin(String8 data, ELF_Bin *bin)
|
||||
#define SINFL_IMPLEMENTATION
|
||||
#include "third_party/sinfl/sinfl.h"
|
||||
|
||||
internal DW_Raw
|
||||
dw_raw_from_elf_bin(Arena *arena, String8 data, ELF_Bin *bin)
|
||||
internal DW_Input
|
||||
dw_input_from_elf_bin(Arena *arena, String8 data, ELF_Bin *bin)
|
||||
{
|
||||
DW_Raw result = {0};
|
||||
DW_Input result = {0};
|
||||
B32 is_section_present[ArrayCount(result.sec)] = {0};
|
||||
for(U64 section_idx = 1; section_idx < bin->shdrs.count; section_idx += 1)
|
||||
{
|
||||
@@ -106,6 +106,7 @@ dw_raw_from_elf_bin(Arena *arena, String8 data, ELF_Bin *bin)
|
||||
//- rjf: store
|
||||
is_section_present[section_kind] = 1;
|
||||
DW_Section *d = &result.sec[section_kind];
|
||||
d->name = push_str8_copy(arena, section_name);
|
||||
d->data = section_data__uncompressed;
|
||||
d->is_dwo = is_dwo;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
#define DWARF_ELF_H
|
||||
|
||||
internal B32 dw_is_dwarf_present_from_elf_bin(String8 raw_image, ELF_Bin *bin);
|
||||
internal DW_Raw dw_raw_from_elf_bin(Arena *arena, String8 raw_image, ELF_Bin *bin);
|
||||
internal DW_Input dw_input_from_elf_bin(Arena *arena, String8 raw_image, ELF_Bin *bin);
|
||||
|
||||
#endif // DWARF_ELF_H
|
||||
|
||||
@@ -15,3 +15,4 @@ typedef struct DW_CallFrameInfo
|
||||
internal DW_CallFrameInfo dw_call_frame_info_from_data(Arena *arena, Arch arch, U64 rebase, String8 debug_frame);
|
||||
|
||||
#endif // DWARF_HELP_H
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "dwarf/dwarf.c"
|
||||
#include "dwarf/dwarf_expr.c"
|
||||
#include "dwarf/dwarf_parse.c"
|
||||
#include "dwarf/dwarf_parse_2.c"
|
||||
#include "dwarf/dwarf_coff.c"
|
||||
#include "dwarf/dwarf_elf.c"
|
||||
#include "dwarf/dwarf_unwind.c"
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "dwarf/dwarf.h"
|
||||
#include "dwarf/dwarf_expr.h"
|
||||
#include "dwarf/dwarf_parse.h"
|
||||
#include "dwarf/dwarf_parse_2.h"
|
||||
#include "dwarf/dwarf_coff.h"
|
||||
#include "dwarf/dwarf_elf.h"
|
||||
#include "dwarf/dwarf_unwind.h"
|
||||
|
||||
+791
-658
File diff suppressed because it is too large
Load Diff
+133
-140
@@ -4,60 +4,54 @@
|
||||
#ifndef DWARF_PARSE_H
|
||||
#define DWARF_PARSE_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Raw DWARF Info Bundle
|
||||
|
||||
typedef struct DW_Section DW_Section;
|
||||
struct DW_Section
|
||||
typedef struct DW_Section
|
||||
{
|
||||
String8 name;
|
||||
String8 data;
|
||||
B32 is_dwo;
|
||||
};
|
||||
B32 is_dwo;
|
||||
} DW_Section;
|
||||
|
||||
typedef struct DW_Raw DW_Raw;
|
||||
struct DW_Raw
|
||||
typedef struct DW_Input
|
||||
{
|
||||
DW_Section sec[DW_Section_Count];
|
||||
};
|
||||
DW_Section sup[DW_Section_Count];
|
||||
} DW_Input;
|
||||
|
||||
typedef struct DW_ListUnit DW_ListUnit;
|
||||
struct DW_ListUnit
|
||||
typedef struct DW_ListUnit
|
||||
{
|
||||
DW_Version version;
|
||||
U64 address_size;
|
||||
U64 segment_selector_size;
|
||||
U64 entry_size;
|
||||
String8 entries;
|
||||
};
|
||||
U64 address_size;
|
||||
U64 segment_selector_size;
|
||||
U64 entry_size;
|
||||
String8 entries;
|
||||
} DW_ListUnit;
|
||||
|
||||
typedef struct DW_ListUnitInput DW_ListUnitInput;
|
||||
struct DW_ListUnitInput
|
||||
typedef struct DW_ListUnitInput
|
||||
{
|
||||
U64 addr_count;
|
||||
U64 str_offset_count;
|
||||
U64 rnglist_count;
|
||||
U64 loclist_count;
|
||||
Rng1U64Array addr_ranges;
|
||||
Rng1U64Array str_offset_ranges;
|
||||
Rng1U64Array rnglist_ranges;
|
||||
Rng1U64Array loclist_ranges;
|
||||
DW_ListUnit *addrs;
|
||||
DW_ListUnit *str_offsets;
|
||||
DW_ListUnit *rnglists;
|
||||
DW_ListUnit *loclists;
|
||||
};
|
||||
U64 addr_count;
|
||||
U64 str_offset_count;
|
||||
U64 rnglist_count;
|
||||
U64 loclist_count;
|
||||
Rng1U64Array addr_ranges;
|
||||
Rng1U64Array str_offset_ranges;
|
||||
Rng1U64Array rnglist_ranges;
|
||||
Rng1U64Array loclist_ranges;
|
||||
DW_ListUnit *addrs;
|
||||
DW_ListUnit *str_offsets;
|
||||
DW_ListUnit *rnglists;
|
||||
DW_ListUnit *loclists;
|
||||
} DW_ListUnitInput;
|
||||
|
||||
typedef struct DW_AbbrevTableEntry DW_AbbrevTableEntry;
|
||||
struct DW_AbbrevTableEntry
|
||||
typedef struct DW_AbbrevTableEntry
|
||||
{
|
||||
U64 id;
|
||||
U64 off;
|
||||
};
|
||||
} DW_AbbrevTableEntry;
|
||||
|
||||
typedef struct DW_AbbrevTable DW_AbbrevTable;
|
||||
struct DW_AbbrevTable
|
||||
{
|
||||
U64 count;
|
||||
U64 count;
|
||||
DW_AbbrevTableEntry *entries;
|
||||
};
|
||||
|
||||
@@ -69,8 +63,7 @@ typedef enum DW_AbbrevKind
|
||||
DW_Abbrev_AttribSequenceEnd,
|
||||
DW_Abbrev_DIEBegin,
|
||||
DW_Abbrev_DIEEnd,
|
||||
}
|
||||
DW_AbbrevKind;
|
||||
} DW_AbbrevKind;
|
||||
|
||||
typedef U32 DW_AbbrevFlags;
|
||||
enum
|
||||
@@ -79,15 +72,14 @@ enum
|
||||
DW_AbbrevFlag_HasChildren = (1 << 1),
|
||||
};
|
||||
|
||||
typedef struct DW_Abbrev DW_Abbrev;
|
||||
struct DW_Abbrev
|
||||
typedef struct DW_Abbrev
|
||||
{
|
||||
DW_AbbrevKind kind;
|
||||
U64 sub_kind;
|
||||
U64 id;
|
||||
U64 const_value;
|
||||
DW_AbbrevKind kind;
|
||||
U64 sub_kind;
|
||||
U64 id;
|
||||
U64 const_value;
|
||||
DW_AbbrevFlags flags;
|
||||
};
|
||||
} DW_Abbrev;
|
||||
|
||||
typedef union DW_Form
|
||||
{
|
||||
@@ -108,78 +100,71 @@ typedef union DW_Form
|
||||
U64 rnglistx;
|
||||
U64 ptr;
|
||||
U64 implicit_const;
|
||||
}
|
||||
DW_Form;
|
||||
} DW_Form;
|
||||
|
||||
typedef struct DW_Attrib DW_Attrib;
|
||||
struct DW_Attrib
|
||||
typedef struct DW_Attrib
|
||||
{
|
||||
U64 info_off;
|
||||
DW_AttribKind attrib_kind;
|
||||
DW_FormKind form_kind;
|
||||
DW_Form form;
|
||||
};
|
||||
U64 info_off;
|
||||
U64 abbrev_off;
|
||||
U64 abbrev_id;
|
||||
DW_AttribKind attrib_kind;
|
||||
DW_FormKind form_kind;
|
||||
DW_Form form;
|
||||
} DW_Attrib;
|
||||
|
||||
typedef struct DW_AttribNode DW_AttribNode;
|
||||
struct DW_AttribNode
|
||||
typedef struct DW_AttribNode
|
||||
{
|
||||
DW_AttribNode *next;
|
||||
DW_Attrib v;
|
||||
};
|
||||
struct DW_AttribNode *next;
|
||||
DW_Attrib v;
|
||||
} DW_AttribNode;
|
||||
|
||||
typedef struct DW_AttribList DW_AttribList;
|
||||
struct DW_AttribList
|
||||
typedef struct DW_AttribList
|
||||
{
|
||||
DW_AttribNode *first;
|
||||
DW_AttribNode *last;
|
||||
U64 count;
|
||||
};
|
||||
U64 count;
|
||||
} DW_AttribList;
|
||||
|
||||
typedef struct DW_Tag DW_Tag;
|
||||
struct DW_Tag
|
||||
typedef struct DW_Tag
|
||||
{
|
||||
B32 has_children;
|
||||
U64 abbrev_id;
|
||||
DW_TagKind kind;
|
||||
DW_AttribList attribs;
|
||||
U64 info_off;
|
||||
U8 v[1];
|
||||
};
|
||||
B32 has_children;
|
||||
U64 abbrev_id;
|
||||
DW_TagKind kind;
|
||||
DW_AttribList attribs;
|
||||
U64 info_off;
|
||||
U8 v[1];
|
||||
} DW_Tag;
|
||||
|
||||
typedef struct DW_TagNode DW_TagNode;
|
||||
struct DW_TagNode
|
||||
typedef struct DW_TagNode
|
||||
{
|
||||
DW_Tag tag;
|
||||
DW_TagNode *sibling;
|
||||
DW_TagNode *first_child;
|
||||
DW_TagNode *last_child;
|
||||
};
|
||||
DW_Tag tag;
|
||||
struct DW_TagNode *sibling;
|
||||
struct DW_TagNode *first_child;
|
||||
struct DW_TagNode *last_child;
|
||||
} DW_TagNode;
|
||||
|
||||
typedef struct DW_Loc DW_Loc;
|
||||
struct DW_Loc
|
||||
typedef struct DW_Loc
|
||||
{
|
||||
Rng1U64 range;
|
||||
String8 expr;
|
||||
};
|
||||
} DW_Loc;
|
||||
|
||||
typedef struct DW_LocNode DW_LocNode;
|
||||
struct DW_LocNode
|
||||
typedef struct DW_LocNode
|
||||
{
|
||||
DW_LocNode *next;
|
||||
DW_Loc v;
|
||||
};
|
||||
DW_Loc v;
|
||||
struct DW_LocNode *next;
|
||||
} DW_LocNode;
|
||||
|
||||
typedef struct DW_LocList DW_LocList;
|
||||
struct DW_LocList
|
||||
typedef struct DW_LocList
|
||||
{
|
||||
U64 count;
|
||||
DW_LocNode *first;
|
||||
DW_LocNode *last;
|
||||
U64 count;
|
||||
};
|
||||
} DW_LocList;
|
||||
|
||||
typedef struct DW_CompUnit DW_CompUnit;
|
||||
struct DW_CompUnit
|
||||
typedef struct DW_CompUnit
|
||||
{
|
||||
B32 relaxed;
|
||||
DW_Ext ext;
|
||||
DW_CompUnitKind kind;
|
||||
DW_Version version;
|
||||
@@ -198,7 +183,7 @@ struct DW_CompUnit
|
||||
U64 dwo_id;
|
||||
DW_Tag tag;
|
||||
HashTable *tag_ht;
|
||||
};
|
||||
} DW_CompUnit;
|
||||
|
||||
typedef struct DW_TagTree
|
||||
{
|
||||
@@ -343,12 +328,12 @@ typedef union DW_ExprOperand
|
||||
U16 u16;
|
||||
U32 u32;
|
||||
U64 u64;
|
||||
|
||||
|
||||
S8 s8;
|
||||
S16 s16;
|
||||
S32 s32;
|
||||
S64 s64;
|
||||
|
||||
|
||||
String8 block;
|
||||
} DW_ExprOperand;
|
||||
|
||||
@@ -446,10 +431,18 @@ typedef struct DW_CFA_InstList
|
||||
#define DW_DECODE_PTR(name) U64 name(String8 data, void *ud, U64 *ptr_out)
|
||||
typedef DW_DECODE_PTR(DW_DecodePtr);
|
||||
|
||||
// hasher
|
||||
|
||||
internal U64 dw_hash_from_string(String8 string);
|
||||
|
||||
// deserial helpers
|
||||
|
||||
internal U64 dw_str8_deserial_read_packed_size(String8 string, U64 off, U64 *size_out);
|
||||
internal U64 dw_str8_deserial_read_fmt_uint(String8 string, U64 off, DW_Format format, U64 *uint_out);
|
||||
internal U64 str8_deserial_read_dwarf_packed_size(String8 string, U64 off, U64 *size_out);
|
||||
internal U64 str8_deserial_read_dwarf_uint (String8 string, U64 off, DW_Format format, U64 *uint_out);
|
||||
internal U64 str8_deserial_read_uleb128 (String8 string, U64 off, U64 *value_out);
|
||||
internal U64 str8_deserial_read_sleb128 (String8 string, U64 off, S64 *value_out);
|
||||
internal U64 str8_deserial_read_uleb128_array(Arena *arena, String8 string, U64 off, U64 count, U64 **arr_out);
|
||||
internal U64 str8_deserial_read_sleb128_array(Arena *arena, String8 string, U64 off, U64 count, S64 **arr_out);
|
||||
|
||||
internal Rng1U64List dw_unit_ranges_from_data(Arena *arena, String8 data);
|
||||
|
||||
@@ -459,7 +452,7 @@ internal U64 dw_read_list_unit_header_addr (String8 unit_data, DW_ListUnit
|
||||
internal U64 dw_read_list_unit_header_str_offsets(String8 unit_data, DW_ListUnit *lu_out);
|
||||
internal U64 dw_read_list_unit_header_list (String8 unit_data, DW_ListUnit *lu_out);
|
||||
|
||||
internal DW_ListUnitInput dw_list_unit_input_from_raw(Arena *arena, DW_Raw *input);
|
||||
internal DW_ListUnitInput dw_list_unit_input_from_input(Arena *arena, DW_Input *input);
|
||||
|
||||
internal U64 dw_offset_from_list_unit(DW_ListUnit *lu, U64 index);
|
||||
internal U64 dw_addr_from_list_unit (DW_ListUnit *lu, U64 index);
|
||||
@@ -475,7 +468,7 @@ internal U64 dw_abbrev_offset_from_abbrev_id(DW_AbbrevTable table, U6
|
||||
|
||||
internal U64 dw_read_form(String8 data, U64 off, DW_Version version, DW_Format unit_format, U64 address_size, DW_FormKind form_kind, U64 implicit_const, DW_Form *form_out);
|
||||
internal U64 dw_read_tag (Arena *arena, String8 tag_data, U64 tag_off, U64 tag_base, DW_AbbrevTable abbrev_table, String8 abbrev_data, DW_Version version, DW_Format unit_format, U64 address_size, DW_Tag *tag_out);
|
||||
internal U64 dw_read_tag_cu(Arena *arena, DW_Raw *input, DW_CompUnit *cu, U64 info_off, DW_Tag *tag_out);
|
||||
internal U64 dw_read_tag_cu(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 info_off, DW_Tag *tag_out);
|
||||
|
||||
// attrib interp
|
||||
|
||||
@@ -488,56 +481,56 @@ internal S64 dw_interp_const_s64 (DW_FormKind form_kind, DW_Form form)
|
||||
internal S32 dw_interp_const_s32 (DW_FormKind form_kind, DW_Form form);
|
||||
internal B32 dw_interp_flag (DW_FormKind form_kind, DW_Form form);
|
||||
internal U64 dw_interp_address (U64 address_size, U64 base_addr, DW_ListUnit *addr_xlist, DW_FormKind form_kind, DW_Form form);
|
||||
internal String8 dw_interp_block (DW_Raw *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form);
|
||||
internal String8 dw_interp_string (DW_Raw *input, DW_Format unit_format, DW_ListUnit *str_offsets, DW_FormKind form_kind, DW_Form form);
|
||||
internal String8 dw_interp_line_ptr (DW_Raw *input, DW_FormKind form_kind, DW_Form form);
|
||||
internal String8 dw_interp_block (DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form);
|
||||
internal String8 dw_interp_string (DW_Input *input, DW_Format unit_format, DW_ListUnit *str_offsets, DW_FormKind form_kind, DW_Form form);
|
||||
internal String8 dw_interp_line_ptr (DW_Input *input, DW_FormKind form_kind, DW_Form form);
|
||||
internal DW_LineFile * dw_interp_file (DW_LineVMHeader *line_vm, DW_FormKind form_kind, DW_Form form);
|
||||
internal DW_Reference dw_interp_ref (DW_Raw *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form);
|
||||
internal DW_LocList dw_interp_loclist (Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form);
|
||||
internal Rng1U64List dw_interp_rnglist (Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form);
|
||||
internal DW_Reference dw_interp_ref (DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form);
|
||||
internal DW_LocList dw_interp_loclist (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form);
|
||||
internal Rng1U64List dw_interp_rnglist (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form);
|
||||
|
||||
internal String8 dw_exprloc_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal U128 dw_const_u128_from_attrib(DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal U64 dw_const_u64_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal U32 dw_const_u32_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal S64 dw_const_s64_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal S32 dw_const_s32_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal B32 dw_flag_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal U64 dw_address_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal String8 dw_block_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal String8 dw_string_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal String8 dw_line_ptr_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal String8 dw_exprloc_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal U128 dw_const_u128_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal U64 dw_const_u64_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal U32 dw_const_u32_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal S64 dw_const_s64_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal S32 dw_const_s32_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal B32 dw_flag_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal U64 dw_address_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal String8 dw_block_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal String8 dw_string_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal String8 dw_line_ptr_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal DW_LineFile * dw_file_from_attrib (DW_CompUnit *cu, DW_LineVMHeader *line_vm, DW_Attrib *attrib);
|
||||
internal DW_Reference dw_ref_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal DW_LocList dw_loclist_from_attrib (Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal Rng1U64List dw_rnglist_from_attrib (Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal DW_Reference dw_ref_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal DW_LocList dw_loclist_from_attrib (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal Rng1U64List dw_rnglist_from_attrib (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
|
||||
internal String8 dw_exprloc_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal U128 dw_const_u128_from_tag_attrib_kind(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal U64 dw_const_u64_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal U32 dw_const_u32_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal B32 dw_flag_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal U64 dw_address_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal String8 dw_block_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal String8 dw_string_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal String8 dw_line_ptr_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal String8 dw_line_ptr_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal DW_LineFile * dw_file_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_LineVMHeader *line_vm, DW_Tag tag, DW_AttribKind kind);
|
||||
internal DW_Reference dw_ref_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal DW_LocList dw_loclist_from_tag_attrib_kind (Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal Rng1U64List dw_rnglist_from_tag_attrib_kind (Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal String8 dw_exprloc_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal U128 dw_const_u128_from_tag_attrib_kind(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal U64 dw_const_u64_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal U32 dw_const_u32_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal B32 dw_flag_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal U64 dw_address_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal String8 dw_block_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal String8 dw_string_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal String8 dw_line_ptr_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal String8 dw_line_ptr_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal DW_LineFile * dw_file_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_LineVMHeader *line_vm, DW_Tag tag, DW_AttribKind kind);
|
||||
internal DW_Reference dw_ref_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal DW_LocList dw_loclist_from_tag_attrib_kind (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal Rng1U64List dw_rnglist_from_tag_attrib_kind (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
|
||||
// compile unit
|
||||
|
||||
internal DW_CompUnit dw_cu_from_info_off(Arena *arena, DW_Raw *input, DW_ListUnitInput lu_input, U64 offset);
|
||||
internal DW_TagTree dw_tag_tree_from_cu(Arena *arena, DW_Raw *input, DW_CompUnit *cu);
|
||||
internal DW_CompUnit dw_cu_from_info_off(Arena *arena, DW_Input *input, DW_ListUnitInput lu_input, U64 offset, B32 relaxed);
|
||||
internal DW_TagTree dw_tag_tree_from_cu(Arena *arena, DW_Input *input, DW_CompUnit *cu);
|
||||
internal HashTable * dw_make_tag_hash_table(Arena *arena, DW_TagTree tag_tree);
|
||||
internal DW_TagNode * dw_tag_node_from_info_off(DW_CompUnit *cu, U64 info_off);
|
||||
|
||||
// line info
|
||||
|
||||
internal U64 dw_read_line_file(String8 line_data, U64 line_off, DW_Raw *input, DW_Version unit_version, DW_Format unit_format, DW_Ext ext, U64 address_size, DW_ListUnit *str_offsets, U64 enc_count, U64 *enc_arr, DW_LineFile *line_file_out);
|
||||
internal U64 dw_read_line_vm_header(Arena *arena, String8 line_data, U64 line_off, DW_Raw *input, String8 cu_dir, String8 cu_name, U8 cu_address_size, DW_ListUnit *cu_str_offsets, DW_LineVMHeader *header_out);
|
||||
internal U64 dw_read_line_file(String8 line_data, U64 line_off, DW_Input *input, DW_Version unit_version, DW_Format unit_format, DW_Ext ext, U64 address_size, DW_ListUnit *str_offsets, U64 enc_count, U64 *enc_arr, DW_LineFile *line_file_out);
|
||||
internal U64 dw_read_line_vm_header(Arena *arena, String8 line_data, U64 line_off, DW_Input *input, String8 cu_dir, String8 cu_name, U8 cu_address_size, DW_ListUnit *cu_str_offsets, DW_LineVMHeader *header_out);
|
||||
internal void dw_line_vm_reset(DW_LineVMState *state, B32 default_is_stmt);
|
||||
internal void dw_line_vm_advance(DW_LineVMState *state, U64 advance, U64 min_inst_len, U64 max_ops_for_inst);
|
||||
internal DW_LineSeqNode * dw_push_line_seq(Arena* arena, DW_LineTableParseResult *parsed_tbl);
|
||||
@@ -545,11 +538,11 @@ internal DW_LineNode * dw_push_line(Arena *arena, DW_LineTableParseResult *tb
|
||||
internal String8 dw_path_from_file(Arena *arena, DW_LineVMHeader *vm, DW_LineFile *file);
|
||||
internal String8 dw_path_from_file_idx(Arena *arena, DW_LineVMHeader *vm, U64 file_idx);
|
||||
|
||||
internal DW_LineTableParseResult dw_parsed_line_table_from_data(Arena *arena, String8 unit_data, DW_Raw *input, String8 cu_dir, String8 cu_name, U8 cu_address_size, DW_ListUnit *cu_str_offsets);
|
||||
internal DW_LineTableParseResult dw_parsed_line_table_from_data(Arena *arena, String8 unit_data, DW_Input *input, String8 cu_dir, String8 cu_name, U8 cu_address_size, DW_ListUnit *cu_str_offsets);
|
||||
|
||||
// helper for .debug_pubtypes and .debug_pubnames
|
||||
|
||||
internal DW_PubStringsTable dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Raw *input, DW_SectionKind section_kind);
|
||||
internal DW_PubStringsTable dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Input *input, DW_SectionKind section_kind);
|
||||
|
||||
// expression
|
||||
|
||||
|
||||
+3
-2
@@ -8,8 +8,8 @@
|
||||
//~ Dump Subset Types
|
||||
|
||||
#define EH_DumpSubset_XList \
|
||||
X(EhFrameHdr, eh_frame_hdr, ".eh_frame_hdr") \
|
||||
X(EhFrame, eh_frame, ".eh_frame")
|
||||
X(EhFrameHdr, eh_frame_hdr, ".eh_frame_hdr") \
|
||||
X(EhFrame, eh_frame, ".eh_frame")
|
||||
|
||||
typedef enum EH_DumpSubset {
|
||||
#define X(name, name_lower, title) EH_DumpSubset_##name,
|
||||
@@ -45,3 +45,4 @@ read_only global String8 eh_name_title_from_dump_subset_table[] =
|
||||
internal String8List eh_dump_list_from_data(Arena *arena, Arch arch, U64 eh_frame_hdr_vaddr, U64 eh_frame_vaddr, String8 eh_frame_hdr, String8 eh_frame, EH_DumpSubsetFlags subset_flags);
|
||||
|
||||
#endif // EH_FRAME_DUMP_H
|
||||
|
||||
|
||||
+136
-136
@@ -5,69 +5,69 @@ internal U64
|
||||
eh_parse_ptr(String8 frame_base, U64 off, U64 pc, EH_PtrCtx *ptr_ctx, EH_PtrEnc encoding, U64 *ptr_out)
|
||||
{
|
||||
U64 ptr_off = off;
|
||||
|
||||
|
||||
if (encoding == EH_PtrEnc_Omit) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// align read offset as needed
|
||||
if (encoding == EH_PtrEnc_Aligned) {
|
||||
ptr_off = AlignPow2(ptr_off, ptr_ctx->ptr_align);
|
||||
encoding = EH_PtrEnc_Ptr;
|
||||
}
|
||||
|
||||
|
||||
// decode pointer value
|
||||
U64 decode_size = 0;
|
||||
U64 raw_ptr_size = 0;
|
||||
U64 raw_ptr = 0;
|
||||
switch (encoding & EH_PtrEnc_TypeMask) {
|
||||
default: { InvalidPath; } break;
|
||||
|
||||
case EH_PtrEnc_Ptr : { raw_ptr_size = 8; } goto ufixed;
|
||||
case EH_PtrEnc_UData2: { raw_ptr_size = 2; } goto ufixed;
|
||||
case EH_PtrEnc_UData4: { raw_ptr_size = 4; } goto ufixed;
|
||||
case EH_PtrEnc_UData8: { raw_ptr_size = 8; } goto ufixed;
|
||||
ufixed: {
|
||||
decode_size += str8_deserial_read(frame_base, ptr_off, &raw_ptr, raw_ptr_size, raw_ptr_size);
|
||||
} break;
|
||||
|
||||
// TODO: Signed is actually just a flag that indicates this int is negavite.
|
||||
// There shouldn't be a read for Signed.
|
||||
// For instance, (EH_PtrEnc_UData2 | EH_PtrEnc_Signed) == EH_PtrEnc_SData etc.
|
||||
case EH_PtrEnc_Signed: { raw_ptr_size = 8; } goto sfixed;
|
||||
|
||||
case EH_PtrEnc_SData2: { raw_ptr_size = 2; } goto sfixed;
|
||||
case EH_PtrEnc_SData4: { raw_ptr_size = 4; } goto sfixed;
|
||||
case EH_PtrEnc_SData8: { raw_ptr_size = 8; } goto sfixed;
|
||||
sfixed: {
|
||||
decode_size += str8_deserial_read(frame_base, ptr_off, &raw_ptr, raw_ptr_size, raw_ptr_size);
|
||||
raw_ptr = extend_sign64(raw_ptr, raw_ptr_size);
|
||||
} break;
|
||||
|
||||
case EH_PtrEnc_ULEB128: { decode_size += str8_deserial_read_uleb128(frame_base, ptr_off, &raw_ptr); } break;
|
||||
case EH_PtrEnc_SLEB128: { decode_size += str8_deserial_read_sleb128(frame_base, ptr_off, (S64*)&raw_ptr); } break;
|
||||
}
|
||||
default: { InvalidPath; } break;
|
||||
|
||||
case EH_PtrEnc_Ptr : { raw_ptr_size = 8; } goto ufixed;
|
||||
case EH_PtrEnc_UData2: { raw_ptr_size = 2; } goto ufixed;
|
||||
case EH_PtrEnc_UData4: { raw_ptr_size = 4; } goto ufixed;
|
||||
case EH_PtrEnc_UData8: { raw_ptr_size = 8; } goto ufixed;
|
||||
ufixed: {
|
||||
decode_size += str8_deserial_read(frame_base, ptr_off, &raw_ptr, raw_ptr_size, raw_ptr_size);
|
||||
} break;
|
||||
|
||||
// TODO: Signed is actually just a flag that indicates this int is negavite.
|
||||
// There shouldn't be a read for Signed.
|
||||
// For instance, (EH_PtrEnc_UData2 | EH_PtrEnc_Signed) == EH_PtrEnc_SData etc.
|
||||
case EH_PtrEnc_Signed: { raw_ptr_size = 8; } goto sfixed;
|
||||
|
||||
case EH_PtrEnc_SData2: { raw_ptr_size = 2; } goto sfixed;
|
||||
case EH_PtrEnc_SData4: { raw_ptr_size = 4; } goto sfixed;
|
||||
case EH_PtrEnc_SData8: { raw_ptr_size = 8; } goto sfixed;
|
||||
sfixed: {
|
||||
decode_size += str8_deserial_read(frame_base, ptr_off, &raw_ptr, raw_ptr_size, raw_ptr_size);
|
||||
raw_ptr = extend_sign64(raw_ptr, raw_ptr_size);
|
||||
} break;
|
||||
|
||||
case EH_PtrEnc_ULEB128: { decode_size += str8_deserial_read_uleb128(frame_base, ptr_off, &raw_ptr); } break;
|
||||
case EH_PtrEnc_SLEB128: { decode_size += str8_deserial_read_sleb128(frame_base, ptr_off, (S64*)&raw_ptr); } break;
|
||||
}
|
||||
|
||||
// apply relative bases
|
||||
if (decode_size > 0) {
|
||||
U64 ptr = raw_ptr;
|
||||
switch (encoding & EH_PtrEnc_ModifierMask) {
|
||||
case 0: break;
|
||||
case EH_PtrEnc_PcRel: { ptr = pc + raw_ptr; } break;
|
||||
case EH_PtrEnc_TextRel: { ptr = ptr_ctx->text_vaddr + raw_ptr; } break;
|
||||
case EH_PtrEnc_DataRel: { ptr = ptr_ctx->data_vaddr + raw_ptr; } break;
|
||||
case EH_PtrEnc_FuncRel: {
|
||||
Assert(!"TODO: need a sample to verify implementation");
|
||||
ptr = ptr_ctx->func_vaddr + raw_ptr;
|
||||
} break;
|
||||
default: { InvalidPath; } break;
|
||||
case 0: break;
|
||||
case EH_PtrEnc_PcRel: { ptr = pc + raw_ptr; } break;
|
||||
case EH_PtrEnc_TextRel: { ptr = ptr_ctx->text_vaddr + raw_ptr; } break;
|
||||
case EH_PtrEnc_DataRel: { ptr = ptr_ctx->data_vaddr + raw_ptr; } break;
|
||||
case EH_PtrEnc_FuncRel: {
|
||||
Assert(!"TODO: need a sample to verify implementation");
|
||||
ptr = ptr_ctx->func_vaddr + raw_ptr;
|
||||
} break;
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
|
||||
|
||||
if (ptr_out) {
|
||||
*ptr_out = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return decode_size;
|
||||
}
|
||||
|
||||
@@ -76,49 +76,49 @@ eh_parse_frame_hdr(String8 data, U64 address_size, EH_PtrCtx *ptr_ctx)
|
||||
{
|
||||
EH_FrameHdr header = {0};
|
||||
U64 cursor = 0;
|
||||
|
||||
|
||||
U64 version_size = str8_deserial_read_struct(data, cursor, &header.version);
|
||||
if (version_size == 0) { goto exit; }
|
||||
cursor += version_size;
|
||||
|
||||
|
||||
if (header.version == 1) {
|
||||
U64 eh_frame_ptr_enc_size = str8_deserial_read_struct(data, cursor, &header.eh_frame_ptr_enc);
|
||||
if (eh_frame_ptr_enc_size == 0) { goto exit; }
|
||||
cursor += eh_frame_ptr_enc_size;
|
||||
|
||||
|
||||
U64 fde_count_enc_size = str8_deserial_read_struct(data, cursor, &header.fde_count_enc);
|
||||
if (fde_count_enc_size == 0) { goto exit; }
|
||||
cursor += fde_count_enc_size;
|
||||
|
||||
|
||||
U64 table_enc_size = str8_deserial_read_struct(data, cursor, &header.table_enc);
|
||||
if (table_enc_size == 0) { goto exit; }
|
||||
cursor += table_enc_size;
|
||||
|
||||
|
||||
cursor += eh_parse_ptr(data, cursor, cursor, ptr_ctx, header.eh_frame_ptr_enc, &header.eh_frame_ptr);
|
||||
cursor += eh_parse_ptr(data, cursor, cursor, ptr_ctx, header.fde_count_enc, &header.fde_count);
|
||||
|
||||
|
||||
switch (header.table_enc & EH_PtrEnc_TypeMask) {
|
||||
case EH_PtrEnc_Ptr: { header.field_byte_size = address_size; } break;
|
||||
case EH_PtrEnc_ULEB128: { InvalidPath; } break; // TODO: when loading module convert these to UData8
|
||||
case EH_PtrEnc_UData2: { header.field_byte_size = 2; } break;
|
||||
case EH_PtrEnc_UData4: { header.field_byte_size = 4; } break;
|
||||
case EH_PtrEnc_UData8: { header.field_byte_size = 8; } break;
|
||||
case EH_PtrEnc_Signed: { header.field_byte_size = address_size; } break;
|
||||
case EH_PtrEnc_SLEB128: { InvalidPath; } break; // TODO: when loading module convert these to UData8
|
||||
case EH_PtrEnc_SData2: { header.field_byte_size = 2; } break;
|
||||
case EH_PtrEnc_SData4: { header.field_byte_size = 4; } break;
|
||||
case EH_PtrEnc_SData8: { header.field_byte_size = 8; } break;
|
||||
default: { InvalidPath; } break;
|
||||
case EH_PtrEnc_Ptr: { header.field_byte_size = address_size; } break;
|
||||
case EH_PtrEnc_ULEB128: { InvalidPath; } break; // TODO: when loading module convert these to UData8
|
||||
case EH_PtrEnc_UData2: { header.field_byte_size = 2; } break;
|
||||
case EH_PtrEnc_UData4: { header.field_byte_size = 4; } break;
|
||||
case EH_PtrEnc_UData8: { header.field_byte_size = 8; } break;
|
||||
case EH_PtrEnc_Signed: { header.field_byte_size = address_size; } break;
|
||||
case EH_PtrEnc_SLEB128: { InvalidPath; } break; // TODO: when loading module convert these to UData8
|
||||
case EH_PtrEnc_SData2: { header.field_byte_size = 2; } break;
|
||||
case EH_PtrEnc_SData4: { header.field_byte_size = 4; } break;
|
||||
case EH_PtrEnc_SData8: { header.field_byte_size = 8; } break;
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
header.entry_byte_size = header.field_byte_size * 2;
|
||||
|
||||
|
||||
header.table = str8_skip(data, cursor);
|
||||
AssertAlways(header.table.size == header.entry_byte_size * header.fde_count);
|
||||
} else {
|
||||
Assert(0 && "unknown version");
|
||||
}
|
||||
|
||||
exit:;
|
||||
|
||||
exit:;
|
||||
return header;
|
||||
}
|
||||
|
||||
@@ -130,9 +130,9 @@ eh_parse_aug_data(String8 aug_string, String8 aug_data, U64 pc, EH_PtrCtx *ptr_c
|
||||
// On 32bit arch it is a 4-byte and on 64-bit 8-byte value.
|
||||
// Reference: https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html
|
||||
// Reference doc doesn't clarify structure for EH Data though
|
||||
|
||||
|
||||
U64 cursor = 0;
|
||||
|
||||
|
||||
U64 aug_data_size = 0;
|
||||
EH_AugFlags aug_flags = 0;
|
||||
EH_PtrEnc lsda_encoding = EH_PtrEnc_Omit;
|
||||
@@ -141,30 +141,30 @@ eh_parse_aug_data(String8 aug_string, String8 aug_data, U64 pc, EH_PtrCtx *ptr_c
|
||||
U64 handler_ip = 0;
|
||||
if (str8_match(str8_prefix(aug_string, 1), str8_lit("z"), 0)) {
|
||||
cursor = str8_deserial_read_uleb128(aug_data, cursor, &aug_data_size);
|
||||
|
||||
|
||||
for (U8 *ptr = aug_string.str+1; ptr < (aug_string.str+aug_string.size); ptr += 1) {
|
||||
switch (*ptr) {
|
||||
case 'L': {
|
||||
cursor += str8_deserial_read_struct(aug_data, cursor, &lsda_encoding);
|
||||
aug_flags |= EH_AugFlag_HasLSDA;
|
||||
} break;
|
||||
case 'P': {
|
||||
cursor += str8_deserial_read_struct(aug_data, cursor, &handler_encoding);
|
||||
cursor += eh_parse_ptr(aug_data, cursor, pc + cursor, ptr_ctx, handler_encoding, &handler_ip);
|
||||
aug_flags |= EH_AugFlag_HasHandler;
|
||||
} break;
|
||||
case 'R': {
|
||||
cursor += str8_deserial_read_struct(aug_data, cursor, &addr_encoding);
|
||||
aug_flags |= EH_AugFlag_HasAddrEnc;
|
||||
} break;
|
||||
case 'S': {
|
||||
aug_flags |= EH_AugFlag_SignalFrame;
|
||||
} break;
|
||||
default: { Assert(!"failed to parse augmentation string"); goto exit; } break;
|
||||
case 'L': {
|
||||
cursor += str8_deserial_read_struct(aug_data, cursor, &lsda_encoding);
|
||||
aug_flags |= EH_AugFlag_HasLSDA;
|
||||
} break;
|
||||
case 'P': {
|
||||
cursor += str8_deserial_read_struct(aug_data, cursor, &handler_encoding);
|
||||
cursor += eh_parse_ptr(aug_data, cursor, pc + cursor, ptr_ctx, handler_encoding, &handler_ip);
|
||||
aug_flags |= EH_AugFlag_HasHandler;
|
||||
} break;
|
||||
case 'R': {
|
||||
cursor += str8_deserial_read_struct(aug_data, cursor, &addr_encoding);
|
||||
aug_flags |= EH_AugFlag_HasAddrEnc;
|
||||
} break;
|
||||
case 'S': {
|
||||
aug_flags |= EH_AugFlag_SignalFrame;
|
||||
} break;
|
||||
default: { Assert(!"failed to parse augmentation string"); goto exit; } break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (aug_out) {
|
||||
aug_out->handler_ip = handler_ip;
|
||||
aug_out->handler_encoding = handler_encoding;
|
||||
@@ -173,8 +173,8 @@ eh_parse_aug_data(String8 aug_string, String8 aug_data, U64 pc, EH_PtrCtx *ptr_c
|
||||
aug_out->flags = aug_flags;
|
||||
aug_out->size = aug_data_size;
|
||||
}
|
||||
|
||||
exit:;
|
||||
|
||||
exit:;
|
||||
U64 parse_size = cursor;
|
||||
return parse_size;
|
||||
}
|
||||
@@ -185,24 +185,24 @@ eh_parse_descriptor_entry_header(String8 data, U64 off, DW_DescriptorEntry *desc
|
||||
U32 first_four_bytes = 0;
|
||||
str8_deserial_read_struct(data, off, &first_four_bytes);
|
||||
DW_Format format = first_four_bytes == max_U32 ? DW_Format_64Bit : DW_Format_32Bit;
|
||||
|
||||
|
||||
U64 length = 0;
|
||||
U64 length_size = dw_str8_deserial_read_packed_size(data, off, &length);
|
||||
U64 length_size = str8_deserial_read_dwarf_packed_size(data, off, &length);
|
||||
if (length_size == 0) { goto exit; }
|
||||
|
||||
|
||||
Rng1U64 entry_range = rng_1u64(off, off + length_size + length);
|
||||
String8 entry_data = str8_substr(data, entry_range);
|
||||
U64 id = 0;
|
||||
U64 id_size = dw_str8_deserial_read_fmt_uint(entry_data, length_size, format, &id);
|
||||
U64 id_size = str8_deserial_read_dwarf_uint(entry_data, length_size, format, &id);
|
||||
if (id_size == 0) { goto exit; }
|
||||
|
||||
|
||||
desc_out->format = format;
|
||||
desc_out->type = (id == 0) ? DW_DescriptorEntryType_CIE : DW_DescriptorEntryType_FDE;
|
||||
desc_out->entry_range = entry_range;
|
||||
desc_out->cie_pointer = id;
|
||||
desc_out->cie_pointer_off = off + length_size;
|
||||
|
||||
exit:;
|
||||
|
||||
exit:;
|
||||
return length + length_size;
|
||||
}
|
||||
|
||||
@@ -211,17 +211,17 @@ eh_parse_cie(String8 data, DW_Format format, Arch arch, U64 pc, EH_PtrCtx *ptr_c
|
||||
{
|
||||
B32 is_parsed = 0;
|
||||
U64 cursor = format == DW_Format_32Bit ? 4 : 12;
|
||||
|
||||
|
||||
U64 cie_id = 0;
|
||||
U64 cie_id_size = dw_str8_deserial_read_fmt_uint(data, cursor, format, &cie_id);
|
||||
U64 cie_id_size = str8_deserial_read_dwarf_uint(data, cursor, format, &cie_id);
|
||||
if (cie_id_size == 0) { goto exit; }
|
||||
cursor += cie_id_size;
|
||||
|
||||
|
||||
U8 version = 0;
|
||||
U64 version_size = str8_deserial_read_struct(data, cursor, &version);
|
||||
if (version_size == 0) { goto exit; }
|
||||
cursor += version_size;
|
||||
|
||||
|
||||
String8 aug_string = {0};
|
||||
String8 aug_data = {0};
|
||||
EH_Augmentation aug = {0};
|
||||
@@ -232,33 +232,33 @@ eh_parse_cie(String8 data, DW_Format format, Arch arch, U64 pc, EH_PtrCtx *ptr_c
|
||||
U64 aug_string_size = str8_deserial_read_cstr(data, cursor, &aug_string);
|
||||
if (aug_string_size == 0) { goto exit; }
|
||||
cursor += aug_string_size;
|
||||
|
||||
|
||||
U64 eh_data = 0;
|
||||
if (str8_match(aug_string, str8_lit("eh"), 0)) {
|
||||
U64 arch_byte_size = byte_size_from_arch(arch);
|
||||
cursor += str8_deserial_read(data, cursor, &eh_data, arch_byte_size, arch_byte_size);
|
||||
}
|
||||
|
||||
|
||||
U64 code_align_factor_size = str8_deserial_read_uleb128(data, cursor, &code_align_factor);
|
||||
if (code_align_factor_size == 0) { goto exit; }
|
||||
cursor += code_align_factor_size;
|
||||
|
||||
|
||||
U64 data_align_factor_size = str8_deserial_read_sleb128(data, cursor, &data_align_factor);
|
||||
if (data_align_factor_size == 0) { goto exit; }
|
||||
cursor += data_align_factor_size;
|
||||
|
||||
|
||||
ret_addr_reg = 0;
|
||||
U64 ret_addr_reg_size = str8_deserial_read(data, cursor, &ret_addr_reg, sizeof(U8), sizeof(U8));
|
||||
if (ret_addr_reg_size == 0) { goto exit; }
|
||||
cursor += ret_addr_reg_size;
|
||||
|
||||
|
||||
U64 aug_data_size = eh_parse_aug_data(aug_string, str8_skip(data, cursor), pc + cursor, ptr_ctx, &aug);
|
||||
aug_data = str8_substr(data, r1u64(cursor, cursor + aug.size));
|
||||
cursor += aug_data_size;
|
||||
} else {
|
||||
Assert(0 && "unexpected version");
|
||||
}
|
||||
|
||||
|
||||
cie_out->insts = str8_skip(data, cursor);
|
||||
cie_out->aug_string = aug_string;
|
||||
cie_out->aug_data = aug_data;
|
||||
@@ -269,11 +269,11 @@ eh_parse_cie(String8 data, DW_Format format, Arch arch, U64 pc, EH_PtrCtx *ptr_c
|
||||
cie_out->version = version;
|
||||
cie_out->address_size = byte_size_from_arch(arch);
|
||||
cie_out->segment_selector_size = 0;
|
||||
|
||||
|
||||
cie_out->ext[EH_CIE_Ext_LSDAEnc] = EH_PtrEnc_Omit;
|
||||
cie_out->ext[EH_CIE_Ext_AddrEnc] = EH_PtrEnc_Omit;
|
||||
cie_out->ext[EH_CIE_Ext_HandlerEnc] = EH_PtrEnc_Omit;
|
||||
|
||||
|
||||
if (aug.flags & EH_AugFlag_HasLSDA) {
|
||||
cie_out->ext[EH_CIE_Ext_LSDAEnc] = aug.lsda_encoding;
|
||||
}
|
||||
@@ -284,9 +284,9 @@ eh_parse_cie(String8 data, DW_Format format, Arch arch, U64 pc, EH_PtrCtx *ptr_c
|
||||
cie_out->ext[EH_CIE_Ext_HandlerEnc] = aug.handler_encoding;
|
||||
cie_out->ext[EH_CIE_Ext_HandlerIp ] = aug.handler_ip;
|
||||
}
|
||||
|
||||
|
||||
is_parsed = 1;
|
||||
exit:;
|
||||
exit:;
|
||||
return is_parsed;
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ eh_parse_fde(String8 data, DW_Format format, U64 pc, DW_CIE *cie, EH_PtrCtx *ptr
|
||||
{
|
||||
B32 is_parsed = 0;
|
||||
U64 cursor = format == DW_Format_32Bit ? 8 : 20;
|
||||
|
||||
|
||||
U64 pc_begin = 0;
|
||||
U64 pc_delta = 0;
|
||||
EH_PtrEnc addr_enc = cie->ext[EH_CIE_Ext_AddrEnc];
|
||||
@@ -303,21 +303,21 @@ eh_parse_fde(String8 data, DW_Format format, U64 pc, DW_CIE *cie, EH_PtrCtx *ptr
|
||||
U64 pc_begin_size = eh_parse_ptr(data, cursor, pc + cursor, ptr_ctx, addr_enc, &pc_begin);
|
||||
if (pc_begin_size == 0) { goto exit; }
|
||||
cursor += pc_begin_size;
|
||||
|
||||
|
||||
U64 pc_delta_size = eh_parse_ptr(data, cursor, pc + cursor, ptr_ctx, addr_enc & EH_PtrEnc_TypeMask, &pc_delta);
|
||||
if (pc_delta_size == 0) { goto exit; }
|
||||
cursor += pc_delta_size;
|
||||
}
|
||||
|
||||
|
||||
if (cursor + cie->aug_data.size > data.size) { goto exit; }
|
||||
cursor += cie->aug_data.size;
|
||||
|
||||
|
||||
fde_out->format = format;
|
||||
fde_out->pc_range = rng_1u64(pc_begin, pc_begin + pc_delta);
|
||||
fde_out->insts = str8_skip(data, cursor);
|
||||
|
||||
|
||||
is_parsed = 1;
|
||||
exit:;
|
||||
exit:;
|
||||
return is_parsed;
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ eh_find_nearest_fde(EH_FrameHdr header, EH_PtrCtx *ptr_ctx, U64 pc)
|
||||
{
|
||||
U64 fde_addr = max_U64;
|
||||
U64 fde_idx = max_U64;
|
||||
|
||||
|
||||
if (header.version == 1) {
|
||||
if (header.fde_count > 0) {
|
||||
U64 first = 0;
|
||||
@@ -339,7 +339,7 @@ eh_find_nearest_fde(EH_FrameHdr header, EH_PtrCtx *ptr_ctx, U64 pc)
|
||||
if (first > pc) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
U64 last_off = header.table.size - header.entry_byte_size;
|
||||
U64 last = 0;
|
||||
U64 last_size = eh_parse_ptr(header.table, last_off, ptr_ctx->pc_vaddr + last_off, ptr_ctx, header.table_enc, &last);
|
||||
@@ -348,7 +348,7 @@ eh_find_nearest_fde(EH_FrameHdr header, EH_PtrCtx *ptr_ctx, U64 pc)
|
||||
fde_idx = header.fde_count - 1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
U64 l = 0;
|
||||
U64 r = header.fde_count - 1;
|
||||
while (l <= r) {
|
||||
@@ -366,12 +366,12 @@ eh_find_nearest_fde(EH_FrameHdr header, EH_PtrCtx *ptr_ctx, U64 pc)
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fde_idx = l > 0 ? l-1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
exit:;
|
||||
|
||||
exit:;
|
||||
if (fde_idx < header.fde_count) {
|
||||
U64 fde_addr_off = (fde_idx * header.entry_byte_size) + header.field_byte_size;
|
||||
U64 fde_addr_size = eh_parse_ptr(header.table, fde_addr_off, ptr_ctx->pc_vaddr + fde_addr_off, ptr_ctx, header.table_enc, &fde_addr);
|
||||
@@ -390,7 +390,7 @@ internal String8
|
||||
eh_frame_hdr_from_call_frame_info(Arena *arena, U64 fde_count, U64 *fde_offsets, DW_FDE *fde)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
|
||||
|
||||
// make .eh_frame_hdr
|
||||
String8List srl = {0};
|
||||
str8_serial_begin(scratch.arena, &srl);
|
||||
@@ -400,14 +400,14 @@ eh_frame_hdr_from_call_frame_info(Arena *arena, U64 fde_count, U64 *fde_offsets,
|
||||
str8_serial_push_u8(scratch.arena, &srl, EH_PtrEnc_UData8); // table encoding
|
||||
str8_serial_push_u64(scratch.arena, &srl, fde_count); // fde_count
|
||||
String8 header = str8_serial_end(scratch.arena, &srl);
|
||||
|
||||
|
||||
// alloc buffer for output
|
||||
U64 buffer_size = header.size + sizeof(EH_FrameHdrEntry) * fde_count;
|
||||
U8 *buffer = push_array(arena, U8, buffer_size);
|
||||
|
||||
|
||||
// copy header
|
||||
MemoryCopyStr8(buffer, header);
|
||||
|
||||
|
||||
// write the table
|
||||
EH_FrameHdrEntry *table = (EH_FrameHdrEntry *)(buffer + header.size);
|
||||
for EachIndex(fde_idx, fde_count) {
|
||||
@@ -415,7 +415,7 @@ eh_frame_hdr_from_call_frame_info(Arena *arena, U64 fde_count, U64 *fde_offsets,
|
||||
table[fde_idx].fde_offset = fde_offsets[fde_idx];
|
||||
}
|
||||
radsort(table, fde_count, eh_frame_hdr_entry_sort);
|
||||
|
||||
|
||||
String8 eh_frame_hdr = str8(buffer, buffer_size);
|
||||
scratch_end(scratch);
|
||||
return eh_frame_hdr;
|
||||
@@ -432,16 +432,16 @@ internal String8
|
||||
eh_string_from_ptr_enc_type(EH_PtrEnc type)
|
||||
{
|
||||
switch (type) {
|
||||
case EH_PtrEnc_Ptr: return str8_lit("Ptr");
|
||||
case EH_PtrEnc_ULEB128: return str8_lit("ULEB128");
|
||||
case EH_PtrEnc_UData2: return str8_lit("UData2");
|
||||
case EH_PtrEnc_UData4: return str8_lit("UData4");
|
||||
case EH_PtrEnc_UData8: return str8_lit("UData8");
|
||||
case EH_PtrEnc_Signed: return str8_lit("Signed");
|
||||
case EH_PtrEnc_SLEB128: return str8_lit("SLEB128");
|
||||
case EH_PtrEnc_SData2: return str8_lit("SData2");
|
||||
case EH_PtrEnc_SData4: return str8_lit("SData4");
|
||||
case EH_PtrEnc_SData8: return str8_lit("SData8");
|
||||
case EH_PtrEnc_Ptr: return str8_lit("Ptr");
|
||||
case EH_PtrEnc_ULEB128: return str8_lit("ULEB128");
|
||||
case EH_PtrEnc_UData2: return str8_lit("UData2");
|
||||
case EH_PtrEnc_UData4: return str8_lit("UData4");
|
||||
case EH_PtrEnc_UData8: return str8_lit("UData8");
|
||||
case EH_PtrEnc_Signed: return str8_lit("Signed");
|
||||
case EH_PtrEnc_SLEB128: return str8_lit("SLEB128");
|
||||
case EH_PtrEnc_SData2: return str8_lit("SData2");
|
||||
case EH_PtrEnc_SData4: return str8_lit("SData4");
|
||||
case EH_PtrEnc_SData8: return str8_lit("SData8");
|
||||
}
|
||||
return str8_zero();
|
||||
}
|
||||
@@ -450,11 +450,11 @@ internal String8
|
||||
eh_string_from_ptr_enc_modifier(EH_PtrEnc modifier)
|
||||
{
|
||||
switch (modifier) {
|
||||
case EH_PtrEnc_PcRel: return str8_lit("PcRel");
|
||||
case EH_PtrEnc_TextRel: return str8_lit("TextRel");
|
||||
case EH_PtrEnc_DataRel: return str8_lit("DataRel");
|
||||
case EH_PtrEnc_FuncRel: return str8_lit("FuncRel");
|
||||
case EH_PtrEnc_Aligned: return str8_lit("Aligned");
|
||||
case EH_PtrEnc_PcRel: return str8_lit("PcRel");
|
||||
case EH_PtrEnc_TextRel: return str8_lit("TextRel");
|
||||
case EH_PtrEnc_DataRel: return str8_lit("DataRel");
|
||||
case EH_PtrEnc_FuncRel: return str8_lit("FuncRel");
|
||||
case EH_PtrEnc_Aligned: return str8_lit("Aligned");
|
||||
}
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ enum
|
||||
EH_PtrEnc_SData2 = 0x0A, // Signed 16-bit value
|
||||
EH_PtrEnc_SData4 = 0x0B, // Signed 32-bit value
|
||||
EH_PtrEnc_SData8 = 0x0C, // Signed 64-bit value
|
||||
|
||||
|
||||
EH_PtrEnc_TypeMask = 0x0F,
|
||||
};
|
||||
|
||||
@@ -31,7 +31,7 @@ enum
|
||||
EH_PtrEnc_DataRel = 0x30, // Value is relative to the .got or .eh_frame_hdr section.
|
||||
EH_PtrEnc_FuncRel = 0x40, // Value is relative to the function.
|
||||
EH_PtrEnc_Aligned = 0x50, // Value is aligned to an address unit sized boundary.
|
||||
|
||||
|
||||
EH_PtrEnc_ModifierMask = 0x70,
|
||||
};
|
||||
|
||||
@@ -104,7 +104,7 @@ typedef struct EH_DecodePtrCtx
|
||||
EH_PtrEnc addr_enc;
|
||||
EH_PtrCtx *ptr_ctx;
|
||||
} EH_DecodePtrCtx;
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal U64 eh_parse_ptr(String8 frame_base, U64 off, U64 pc, EH_PtrCtx *ptr_ctx, EH_PtrEnc encoding, U64 *ptr_out);
|
||||
@@ -123,3 +123,4 @@ internal String8 eh_string_from_ptr_enc_modifier(EH_PtrEnc modifier);
|
||||
internal String8 eh_string_from_ptr_enc(Arena *arena, EH_PtrEnc enc);
|
||||
|
||||
#endif // EH_FRAME_H
|
||||
|
||||
|
||||
Reference in New Issue
Block a user