start dwarf -> rdi cleanup; eliminate some assertions-as-validation, remove incorrect assumption that line info addresses are vaddrs (they seem to be voffs)

This commit is contained in:
Ryan Fleury
2025-11-10 15:06:52 -08:00
parent efb4731ace
commit f396b2eaa3
11 changed files with 1433 additions and 1250 deletions
+2 -2
View File
@@ -46,8 +46,8 @@ load_paths =
commands =
{
//- rjf: [raddbg]
.f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg meta telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
// .f1 = { .win = "raddbg_stable --ipc kill_all && build radbin debug telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
// .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg meta telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.f1 = { .win = "raddbg_stable --ipc kill_all && build radbin debug telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
//- rjf: [raddbg wsl]
// .f1 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
+3 -3
View File
@@ -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;
+222 -222
View File
@@ -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);
}
} 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);
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;
default: { InvalidPath; } break;
} 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;
}
}
// 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;
}
@@ -1601,7 +1601,7 @@ internal String8
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_Input *input, Arch arch, DW_CompUni
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,7 +1730,7 @@ dw_string_from_attrib_value(Arena *arena, DW_Input *input, Arch arch, DW_CompUni
}
String8 result = str8_list_join(arena, &attrib_fmt, 0);
scratch_end(scratch);
return result;
}
@@ -1750,7 +1750,7 @@ dw_dump_list_from_sections(Arena *arena,
Rng1U64Array segment_vranges = {0};
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_input(scratch.arena, input);
@@ -1780,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
@@ -1820,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);
}
}
@@ -2199,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)
@@ -2207,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};
@@ -2229,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);
}
} 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");
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, insts_str_list.first) { dumpf(" %S\n", n->string); }
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);
}
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;
} 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(" {\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;
}
}
}
+574 -567
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -171,12 +171,12 @@ enum
ELF_ShType_PreinitArray = 16, // Array of ptrs to finish functions
ELF_ShType_Group = 17, // Array of ptrs to pre-init funcs
ELF_ShType_SymtabShndx = 18, // Section contains a section group
ELF_ShType_GNU_IncrementalInputs = 0x6fff4700, // Indices for SHN_XINDEX entries
ELF_ShType_GNU_Attributes = 0x6ffffff5, // Incremental build data
ELF_ShType_GNU_Hash = 0x6ffffff6, // Object attributes
ELF_ShType_GNU_LibList = 0x6ffffff7, // GNU style symbol hash table
ELF_ShType_SUNW_verdef = 0x6ffffffd,
ELF_ShType_SUNW_verneed = 0x6ffffffe, // Versions defined by file
ELF_ShType_SUNW_versym = 0x6fffffff, // Versions needed by file
@@ -216,7 +216,7 @@ enum
ELF_SectionIndex_MIPS_SUndefined = 0xff04,
};
typedef U32 ELF_SectionFlag;
typedef U32 ELF_SectionFlags;
enum
{
ELF_Shf_Write = (1 << 0),
+4 -9
View File
@@ -58,14 +58,11 @@ c2r_rdi_binary_section_flags_from_coff_section_flags(COFF_SectionFlags flags)
internal RDIM_BinarySectionList
c2r_rdi_binary_sections_from_coff_sections(Arena *arena, String8 image_data, String8 string_table, U64 sectab_count, COFF_SectionHeader *sectab)
{
ProfBeginFunction();
RDIM_BinarySectionList binary_sections = {0};
for (U64 isec = 0; isec < sectab_count; ++isec) {
COFF_SectionHeader *coff_sec = &sectab[isec];
RDIM_BinarySection *sec = rdim_binary_section_list_push(arena, &binary_sections);
for EachIndex(idx, sectab_count)
{
COFF_SectionHeader *coff_sec = &sectab[idx];
RDIM_BinarySection *sec = rdim_binary_section_list_push(arena, &binary_sections);
sec->name = coff_name_from_section_header(string_table, coff_sec);
sec->flags = c2r_rdi_binary_section_flags_from_coff_section_flags(coff_sec->flags);
sec->voff_first = coff_sec->voff;
@@ -73,7 +70,5 @@ c2r_rdi_binary_sections_from_coff_sections(Arena *arena, String8 image_data, Str
sec->foff_first = coff_sec->foff;
sec->foff_opl = coff_sec->foff + coff_sec->fsize;
}
ProfEnd();
return binary_sections;
}
File diff suppressed because it is too large Load Diff
+15 -8
View File
@@ -1,7 +1,11 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#pragma once
#ifndef RDI_FROM_DWARF_H
#define RDI_FROM_DWARF_H
////////////////////////////////
//~ rjf: Conversion Stage Inputs
typedef struct D2R_ConvertParams D2R_ConvertParams;
struct D2R_ConvertParams
@@ -15,6 +19,9 @@ struct D2R_ConvertParams
B32 deterministic;
};
////////////////////////////////
//~ rjf: Conversion Helper Types
typedef struct D2R_TypeTable
{
HashTable *ht;
@@ -76,7 +83,7 @@ typedef enum D2R_ValueType
typedef struct D2R_ValueTypeNode
{
D2R_ValueType type;
struct D2R_ValueTypeNode *next;
} D2R_ValueTypeNode;
@@ -104,9 +111,6 @@ internal RDIM_Type * d2r_type_from_offset(D2R_TypeTable *type_table, U64 i
internal RDIM_Type * d2r_type_from_attrib(D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
internal Rng1U64List d2r_range_list_from_tag(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 image_base, DW_Tag tag);
internal RDIM_Type ** d2r_collect_proc_params(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_TagNode *cur_node, U64 *param_count_out);
internal RDI_TypeKind d2r_unsigned_type_kind_from_size(U64 byte_size);
internal RDI_TypeKind d2r_signed_type_kind_from_size(U64 byte_size);
internal RDI_EvalTypeGroup d2r_type_group_from_type_kind(RDI_TypeKind x);
////////////////////////////////
//~ RDIM Bytecode Helpers
@@ -134,15 +138,14 @@ internal void d2r_push_relational_op(Arena *arena, D2R_ValueTypeStack *
internal RDIM_EvalBytecode d2r_bytecode_from_expression(Arena *arena, DW_Input *input, U64 image_base, U64 address_size, Arch arch, DW_ListUnit *addr_lu, String8 expr, DW_CompUnit *cu, D2R_ValueType *result_type_out);
internal RDIM_Location * d2r_transpile_expression(Arena *arena, RDIM_LocationChunkList *locations, DW_Input *input, U64 image_base, U64 address_size, Arch arch, DW_ListUnit *addr_lu, DW_CompUnit *cu, String8 expr);
internal RDIM_Location * d2r_location_from_attrib(Arena *arena, RDIM_LocationChunkList *locations, DW_Input *input, DW_CompUnit *cu, U64 image_base, Arch arch, DW_Tag tag, DW_AttribKind kind);
internal RDIM_LocationCaseList d2r_locset_from_attrib(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Scope *curr_scope, RDIM_LocationChunkList *locations, DW_Input *input, DW_CompUnit *cu, U64 image_base, Arch arch, DW_Tag tag, DW_AttribKind kind);
internal RDIM_LocationCaseList d2r_var_locset_from_tag(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Scope *curr_scope, RDIM_LocationChunkList *locations, DW_Input *input, DW_CompUnit *cu, U64 image_base, Arch arch, DW_Tag tag);
////////////////////////////////
//~ rjf: Compilation Unit / Scope Conversion Helpers
internal D2R_CompUnitContribMap d2r_cu_contrib_map_from_aranges(Arena *arena, DW_Input *input, U64 image_base);
internal RDIM_Rng1U64ChunkList d2r_voff_ranges_from_cu_info_off(D2R_CompUnitContribMap map, U64 info_off);
internal RDIM_Rng1U64ChunkList d2r_voff_ranges_from_cu_info_off(D2R_CompUnitContribMap map, U64 info_off);
internal RDIM_Scope *d2r_push_scope(Arena *arena, RDIM_ScopeChunkList *scopes, U64 scope_chunk_cap, D2R_TagFrame *tag_stack, Rng1U64List ranges);
////////////////////////////////
//~ Tag Iterator
@@ -159,6 +162,8 @@ internal DW_Tag d2r_tag_iterator_parent_tag(D2R_TagIterator *iter);
internal void d2r_flag_converted_tag(DW_TagNode *tag_node);
internal B8 d2r_is_tag_converted(DW_TagNode *tag_node);
internal RDIM_Type *d2r_find_or_convert_type(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Language cu_lang, U64 arch_addr_size, DW_Tag tag, DW_AttribKind kind);
internal void d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Language cu_lang, U64 arch_addr_size, DW_TagNode *root);
internal void d2r_convert_udts(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Language cu_lang, U64 arch_addr_size, DW_TagNode *root);
internal void d2r_convert_symbols(Arena *arena, D2R_TypeTable *type_table, RDIM_Scope *global_scope, DW_Input *input, DW_CompUnit *cu, DW_Language cu_lang, U64 arch_addr_size, U64 image_base, Arch arch, DW_TagNode *root);
@@ -167,3 +172,5 @@ internal void d2r_convert_symbols(Arena *arena, D2R_TypeTable *type_table, RDIM_
//~ rjf: Main Conversion Entry Point
internal RDIM_BakeParams d2r_convert(Arena *arena, D2R_ConvertParams *params);
#endif // RDI_FROM_DWARF_H
+29 -2
View File
@@ -1,9 +1,36 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal RDIM_BinarySectionList
e2r_rdi_binary_sections_from_elf_section_table(Arena *arena, ELF_Shdr64Array shdrs)
internal RDI_BinarySectionFlags
e2r_rdi_binary_section_flags_from_elf(ELF_SectionFlags f)
{
RDI_BinarySectionFlags result = RDI_BinarySectionFlag_Read;
if(f & ELF_Shf_Write)
{
result |= RDI_BinarySectionFlag_Write;
}
if(f & ELF_Shf_ExecInstr)
{
result |= RDI_BinarySectionFlag_Execute;
}
return result;
}
internal RDIM_BinarySectionList
e2r_rdi_binary_sections_from_elf_section_table(Arena *arena, String8 data, ELF_Bin *bin, ELF_Shdr64Array shdrs)
{
RDIM_BinarySectionList result = {0};
U64 base_vaddr = elf_base_addr_from_bin(bin);
for EachIndex(idx, shdrs.count)
{
ELF_Shdr64 *src = &shdrs.v[idx];
RDIM_BinarySection *dst = rdim_binary_section_list_push(arena, &result);
dst->name = elf_name_from_shdr64(data, bin, src);
dst->flags = e2r_rdi_binary_section_flags_from_elf(src->sh_flags);
dst->voff_first = src->sh_addr - base_vaddr;
dst->voff_opl = dst->voff_first + src->sh_size;
dst->foff_first = src->sh_offset;
dst->foff_opl = dst->foff_first + src->sh_size;
}
return result;
}
+2 -1
View File
@@ -4,6 +4,7 @@
#ifndef RDI_FROM_ELF_H
#define RDI_FROM_ELF_H
internal RDIM_BinarySectionList e2r_rdi_binary_sections_from_elf_section_table(Arena *arena, ELF_Shdr64Array shdrs);
internal RDI_BinarySectionFlags e2r_rdi_binary_section_flags_from_elf(ELF_SectionFlags f);
internal RDIM_BinarySectionList e2r_rdi_binary_sections_from_elf_section_table(Arena *arena, String8 data, ELF_Bin *bin, ELF_Shdr64Array shdrs);
#endif // RDI_FROM_ELF_H
+2 -2
View File
@@ -5,7 +5,7 @@
#define RDI_FROM_PDB_H
////////////////////////////////
//~ rjf: Conversion Stage Inputs/Outputs
//~ rjf: Conversion Stage Inputs
typedef struct P2R_ConvertParams P2R_ConvertParams;
struct P2R_ConvertParams
@@ -19,7 +19,7 @@ struct P2R_ConvertParams
};
////////////////////////////////
//~ rjf: Shared Conversion State
//~ rjf: Conversion Helper Types
//- rjf: link name map (voff -> string)