mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
checkpoint on multi-lane / simplified dwarf parsing/conversion; fix incorrect assumption of relative in radbin
This commit is contained in:
+1302
-1302
File diff suppressed because it is too large
Load Diff
@@ -23,14 +23,14 @@ dw_is_dwarf_present_coff_section_table(String8 string_table, U64 section_count,
|
||||
return is_dwarf_present;
|
||||
}
|
||||
|
||||
internal DW_Input
|
||||
internal DW_Raw
|
||||
dw_input_from_coff_section_table(Arena *arena,
|
||||
String8 raw_image,
|
||||
String8 string_table,
|
||||
U64 section_count,
|
||||
COFF_SectionHeader *section_table)
|
||||
{
|
||||
DW_Input input = {0};
|
||||
DW_Raw input = {0};
|
||||
B32 sect_status[ArrayCount(input.sec)] = {0};
|
||||
|
||||
for (U64 i = 0; i < section_count; ++i) {
|
||||
|
||||
@@ -5,7 +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_Input dw_input_from_coff_section_table(Arena *arena, String8 raw_image, String8 string_table, U64 section_count, COFF_SectionHeader *section_table);
|
||||
internal DW_Raw 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
|
||||
|
||||
|
||||
+287
-287
@@ -110,118 +110,118 @@ dw_string_list_from_cfi_program(Arena *arena,
|
||||
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%I64x, offset %+I64d", inst.operands[0].u64, inst.operands[1].u64);
|
||||
} break;
|
||||
case DW_CFA_ValOffsetSf: {
|
||||
operand_str = str8f(arena, "value %I64u, 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%I64x, offset %+I64d", inst.operands[0].u64, inst.operands[1].u64);
|
||||
} break;
|
||||
case DW_CFA_ValOffsetSf: {
|
||||
operand_str = str8f(arena, "value %I64u, 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) {
|
||||
@@ -231,7 +231,7 @@ dw_string_list_from_cfi_program(Arena *arena,
|
||||
}
|
||||
}
|
||||
|
||||
exit:;
|
||||
exit:;
|
||||
scratch_end(scratch);
|
||||
return list;
|
||||
}
|
||||
@@ -566,10 +566,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;
|
||||
}
|
||||
@@ -584,31 +584,31 @@ 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_register(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_register(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_register(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_register(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) {
|
||||
@@ -633,7 +633,7 @@ dw_single_line_string_from_expression(Arena *arena, String8 raw_data, U64 cu_bas
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_attrib_value(Arena *arena, DW_Input *input, Arch arch, DW_CompUnit *cu, DW_LineVM *line_vm, DW_Attrib *attrib)
|
||||
dw_string_from_attrib_value(Arena *arena, DW_Raw *input, Arch arch, DW_CompUnit *cu, DW_LineVM *line_vm, DW_Attrib *attrib)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
|
||||
@@ -778,7 +778,7 @@ dw_string_from_attrib_value(Arena *arena, DW_Input *input, Arch arch, DW_CompUni
|
||||
internal
|
||||
DW_PRINTER(dw_print_abbrev)
|
||||
{
|
||||
DW_Input *input = dumper->input;
|
||||
DW_Raw *input = dumper->input;
|
||||
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
DW_Section abbrev = input->sec[DW_Section_Abbrev];
|
||||
@@ -842,7 +842,7 @@ DW_PRINTER(dw_print_abbrev)
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_tag(Arena *arena, String8List *strings, int indent, Arch arch, DW_Input *input, DW_CompUnit *cu, DW_LineVM *line_vm, DW_TagNode *root)
|
||||
dw_print_tag(Arena *arena, String8List *strings, int indent, Arch arch, DW_Raw *input, DW_CompUnit *cu, DW_LineVM *line_vm, DW_TagNode *root)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
|
||||
@@ -897,7 +897,7 @@ dw_print_tag(Arena *arena, String8List *strings, int indent, Arch arch, DW_Input
|
||||
internal
|
||||
DW_PRINTER(dw_print_info)
|
||||
{
|
||||
DW_Input *input = dumper->input;
|
||||
DW_Raw *input = dumper->input;
|
||||
Arch arch = dumper->arch;
|
||||
HashTable *line_vm_map = dw_get_line_vm_map(dumper);
|
||||
Rng1U64Array cu_ranges = dw_get_info_ranges(dumper);
|
||||
@@ -941,7 +941,7 @@ DW_PRINTER(dw_print_info)
|
||||
|
||||
DW_PRINTER(dw_print_line)
|
||||
{
|
||||
DW_Input *input = dumper->input;
|
||||
DW_Raw *input = dumper->input;
|
||||
B32 is_verbose = dumper->is_verbose;
|
||||
DW_CompUnit *cu_arr = dw_get_cu_arr(dumper);
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
@@ -1007,13 +1007,13 @@ DW_PRINTER(dw_print_line)
|
||||
{
|
||||
DW_LineFile *file = &vm->header.file_table.v[file_idx];
|
||||
dw_printf("{ %-4I64u %-8I64u %-8I64u %016I64x-%016I64x %-8I64u %-20S }\n",
|
||||
file_idx,
|
||||
file->dir_idx,
|
||||
file->time_stamp,
|
||||
file->md5.u64[1],
|
||||
file->md5.u64[0],
|
||||
file->size,
|
||||
file->path);
|
||||
file_idx,
|
||||
file->dir_idx,
|
||||
file->time_stamp,
|
||||
file->md5.u64[1],
|
||||
file->md5.u64[0],
|
||||
file->size,
|
||||
file->path);
|
||||
}
|
||||
}
|
||||
dw_unindent();
|
||||
@@ -1049,75 +1049,75 @@ DW_PRINTER(dw_print_line)
|
||||
// print operands
|
||||
switch(vm->opcode)
|
||||
{
|
||||
default:
|
||||
{
|
||||
if(vm->opcode >= vm->header.opcode_base)
|
||||
default:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "advance line by %I64d, advance address by %I64d", vm->line_advance, vm->addr_advance);
|
||||
}
|
||||
else
|
||||
if(vm->opcode >= vm->header.opcode_base)
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "advance line by %I64d, advance address by %I64d", vm->line_advance, vm->addr_advance);
|
||||
}
|
||||
else
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "skipping %I64x unknown opcodes", vm->header.opcode_lens[vm->opcode - 1]);
|
||||
}
|
||||
}break;
|
||||
case DW_StdOpcode_Copy:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "skipping %I64x unknown opcodes", vm->header.opcode_lens[vm->opcode - 1]);
|
||||
}
|
||||
}break;
|
||||
case DW_StdOpcode_Copy:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "Line = %I64u, Column = %I64u, Address = %#I64x", vm->state.line, vm->state.column, vm->state.address);
|
||||
}break;
|
||||
case DW_StdOpcode_AdvancePc:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "advance %#I64x ; current address %#I64x", vm->operands[0].u64, vm->state.address);
|
||||
}break;
|
||||
case DW_StdOpcode_AdvanceLine:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "advance %I64d ; current line %I64u", vm->operands[0].s64, vm->state.line);
|
||||
}break;
|
||||
case DW_StdOpcode_SetFile:
|
||||
{
|
||||
DW_LineFile *file = dw_line_vm_find_file(vm, vm->state.file_index);
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%I64u \"%S\"", vm->state.file_index, dw_path_from_file(opcode_temp.arena, vm->header.dir_table, file));
|
||||
}break;
|
||||
case DW_StdOpcode_SetColumn:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%I64u", vm->state.column);
|
||||
}break;
|
||||
case DW_StdOpcode_NegateStmt:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "is_stmt = %u", vm->state.is_stmt);
|
||||
}break;
|
||||
case DW_StdOpcode_SetBasicBlock:
|
||||
{
|
||||
}break;
|
||||
case DW_StdOpcode_ConstAddPc:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%I64d ; address %#I64x", vm->advance, vm->state.address);
|
||||
}break;
|
||||
case DW_StdOpcode_FixedAdvancePc:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%I64u", vm->operands[0].u64);
|
||||
}break;
|
||||
case DW_StdOpcode_SetPrologueEnd:
|
||||
{
|
||||
}break;
|
||||
case DW_StdOpcode_SetEpilogueBegin:
|
||||
{
|
||||
}break;
|
||||
case DW_StdOpcode_SetIsa:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%I64u", vm->state.isa);
|
||||
}break;
|
||||
case DW_StdOpcode_ExtendedOpcode:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%S*", dw_string_from_ext_opcode(opcode_temp.arena, vm->ext_opcode));
|
||||
//str8_list_pushf(opcode_temp.arena, &opcode_fmt, "length: %u", length);
|
||||
switch(vm->ext_opcode)
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "Line = %I64u, Column = %I64u, Address = %#I64x", vm->state.line, vm->state.column, vm->state.address);
|
||||
}break;
|
||||
case DW_StdOpcode_AdvancePc:
|
||||
{
|
||||
case DW_ExtOpcode_EndSequence: {} break;
|
||||
case DW_ExtOpcode_SetAddress: { str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%#I64x", vm->operands[0].u64); } break;
|
||||
case DW_ExtOpcode_DefineFile: { str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%S Dir: %I64u, Time: %I64u, Size: %I64u",
|
||||
vm->operands[0].string, vm->operands[1].u64, vm->operands[2].u64, vm->operands[3].u64); } break;
|
||||
case DW_ExtOpcode_SetDiscriminator: { str8_list_pushf(arena, &opcode_fmt, "%I64u", vm->state.discriminator); }break;
|
||||
}
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "advance %#I64x ; current address %#I64x", vm->operands[0].u64, vm->state.address);
|
||||
}break;
|
||||
case DW_StdOpcode_AdvanceLine:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "advance %I64d ; current line %I64u", vm->operands[0].s64, vm->state.line);
|
||||
}break;
|
||||
case DW_StdOpcode_SetFile:
|
||||
{
|
||||
DW_LineFile *file = dw_line_vm_find_file(vm, vm->state.file_index);
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%I64u \"%S\"", vm->state.file_index, dw_path_from_file(opcode_temp.arena, vm->header.dir_table, file));
|
||||
}break;
|
||||
case DW_StdOpcode_SetColumn:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%I64u", vm->state.column);
|
||||
}break;
|
||||
case DW_StdOpcode_NegateStmt:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "is_stmt = %u", vm->state.is_stmt);
|
||||
}break;
|
||||
case DW_StdOpcode_SetBasicBlock:
|
||||
{
|
||||
}break;
|
||||
case DW_StdOpcode_ConstAddPc:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%I64d ; address %#I64x", vm->advance, vm->state.address);
|
||||
}break;
|
||||
case DW_StdOpcode_FixedAdvancePc:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%I64u", vm->operands[0].u64);
|
||||
}break;
|
||||
case DW_StdOpcode_SetPrologueEnd:
|
||||
{
|
||||
}break;
|
||||
case DW_StdOpcode_SetEpilogueBegin:
|
||||
{
|
||||
}break;
|
||||
case DW_StdOpcode_SetIsa:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%I64u", vm->state.isa);
|
||||
}break;
|
||||
case DW_StdOpcode_ExtendedOpcode:
|
||||
{
|
||||
str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%S*", dw_string_from_ext_opcode(opcode_temp.arena, vm->ext_opcode));
|
||||
//str8_list_pushf(opcode_temp.arena, &opcode_fmt, "length: %u", length);
|
||||
switch(vm->ext_opcode)
|
||||
{
|
||||
case DW_ExtOpcode_EndSequence: {} break;
|
||||
case DW_ExtOpcode_SetAddress: { str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%#I64x", vm->operands[0].u64); } break;
|
||||
case DW_ExtOpcode_DefineFile: { str8_list_pushf(opcode_temp.arena, &opcode_fmt, "%S Dir: %I64u, Time: %I64u, Size: %I64u",
|
||||
vm->operands[0].string, vm->operands[1].u64, vm->operands[2].u64, vm->operands[3].u64); } break;
|
||||
case DW_ExtOpcode_SetDiscriminator: { str8_list_pushf(arena, &opcode_fmt, "%I64u", vm->state.discriminator); }break;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
|
||||
@@ -1163,7 +1163,7 @@ DW_PRINTER(dw_print_line)
|
||||
|
||||
DW_PRINTER(dw_print_strings)
|
||||
{
|
||||
DW_Input *input = dumper->input;
|
||||
DW_Raw *input = dumper->input;
|
||||
String8 data = input->sec[DW_Section_Str].data;
|
||||
for (U64 cursor = 0, read_size = 0; cursor < data.size; cursor += read_size) {
|
||||
String8 string = {0};
|
||||
@@ -1174,7 +1174,7 @@ DW_PRINTER(dw_print_strings)
|
||||
|
||||
DW_PRINTER(dw_print_frame)
|
||||
{
|
||||
DW_Input *input = dumper->input;
|
||||
DW_Raw *input = dumper->input;
|
||||
Arch arch = dumper->arch;
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
HashTable *cie_ht = hash_table_init(scratch.arena, 0x2000);
|
||||
@@ -1202,71 +1202,71 @@ DW_PRINTER(dw_print_frame)
|
||||
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);
|
||||
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);
|
||||
|
||||
dw_printf("CIE: // entry range: %r\n", desc.entry_range);
|
||||
dw_printf("{\n");
|
||||
dw_printf(" Format: %S\n", dw_string_from_format(desc.format));
|
||||
dw_printf(" Version: %u\n", cie.version);
|
||||
dw_printf(" Aug string: \"%S\"\n", cie.aug_string);
|
||||
dw_printf(" Code align: %I64u\n", cie.code_align_factor);
|
||||
dw_printf(" Data align: %I64d\n", cie.data_align_factor);
|
||||
dw_printf(" Return addr reg: %u\n", cie.ret_addr_reg);
|
||||
if (cie.version > DW_Version_3) {
|
||||
dw_printf(" Address size: %u\n", cie.address_size);
|
||||
dw_printf(" Segment selector size: %u\n", cie.segment_selector_size);
|
||||
}
|
||||
dw_printf(" Initial Insturction:\n");
|
||||
dw_printf(" {\n");
|
||||
for EachNode(n, String8Node, init_insts_str_list.first) { dw_printf(" %S\n", n->string); }
|
||||
dw_printf(" }\n");
|
||||
dw_printf("}\n");
|
||||
} else {
|
||||
dw_printf("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);
|
||||
dw_printf("FDE: // entry range: %r\n", desc.entry_range);
|
||||
dw_printf("{\n");
|
||||
{
|
||||
dw_printf(" Format: %S\n", dw_string_from_format(fde.format));
|
||||
dw_printf(" CIE pointer: 0x%I64x\n", fde.cie_pointer);
|
||||
dw_printf(" PC range: %r\n", fde.pc_range);
|
||||
dw_printf(" Instructions:\n");
|
||||
dw_printf("CIE: // entry range: %r\n", desc.entry_range);
|
||||
dw_printf("{\n");
|
||||
dw_printf(" Format: %S\n", dw_string_from_format(desc.format));
|
||||
dw_printf(" Version: %u\n", cie.version);
|
||||
dw_printf(" Aug string: \"%S\"\n", cie.aug_string);
|
||||
dw_printf(" Code align: %I64u\n", cie.code_align_factor);
|
||||
dw_printf(" Data align: %I64d\n", cie.data_align_factor);
|
||||
dw_printf(" Return addr reg: %u\n", cie.ret_addr_reg);
|
||||
if (cie.version > DW_Version_3) {
|
||||
dw_printf(" Address size: %u\n", cie.address_size);
|
||||
dw_printf(" Segment selector size: %u\n", cie.segment_selector_size);
|
||||
}
|
||||
dw_printf(" Initial Insturction:\n");
|
||||
dw_printf(" {\n");
|
||||
for EachNode(n, String8Node, insts_str_list.first) { dw_printf(" %S\n", n->string); }
|
||||
for EachNode(n, String8Node, init_insts_str_list.first) { dw_printf(" %S\n", n->string); }
|
||||
dw_printf(" }\n");
|
||||
dw_printf("}\n");
|
||||
} else {
|
||||
dw_printf("ERROR: unable to parse CIE @ %I64x\n", desc.entry_range.min);
|
||||
}
|
||||
dw_printf(" Unwind:\n");
|
||||
dw_printf(" {\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);
|
||||
dw_printf(" { 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));
|
||||
dw_printf(" }\n");
|
||||
} 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_printf("}\n");
|
||||
} else {
|
||||
dw_printf("ERROR: unable to parse FDE @ %I64x\n", desc.entry_range.min);
|
||||
}
|
||||
} break;
|
||||
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);
|
||||
dw_printf("FDE: // entry range: %r\n", desc.entry_range);
|
||||
dw_printf("{\n");
|
||||
{
|
||||
dw_printf(" Format: %S\n", dw_string_from_format(fde.format));
|
||||
dw_printf(" CIE pointer: 0x%I64x\n", fde.cie_pointer);
|
||||
dw_printf(" PC range: %r\n", fde.pc_range);
|
||||
dw_printf(" Instructions:\n");
|
||||
dw_printf(" {\n");
|
||||
for EachNode(n, String8Node, insts_str_list.first) { dw_printf(" %S\n", n->string); }
|
||||
dw_printf(" }\n");
|
||||
}
|
||||
dw_printf(" Unwind:\n");
|
||||
dw_printf(" {\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);
|
||||
dw_printf(" { 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));
|
||||
dw_printf(" }\n");
|
||||
|
||||
dw_printf("}\n");
|
||||
} else {
|
||||
dw_printf("ERROR: unable to parse FDE @ %I64x\n", desc.entry_range.min);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1275,7 +1275,7 @@ DW_PRINTER(dw_print_frame)
|
||||
internal
|
||||
DW_PRINTER(dw_print_debug_loc)
|
||||
{
|
||||
DW_Input *input = dumper->input;
|
||||
DW_Raw *input = dumper->input;
|
||||
DW_TagTree *tag_trees = dw_get_tag_trees(dumper);
|
||||
DW_Section info = input->sec[DW_Section_Info];
|
||||
DW_Section loc = input->sec[DW_Section_Loc];
|
||||
@@ -1397,7 +1397,7 @@ DW_PRINTER(dw_print_debug_loc)
|
||||
|
||||
#if 0
|
||||
internal void
|
||||
dw_print_debug_ranges(Arena *arena, String8List *out, String8 g_dw_indent, DW_Input *input, Arch arch, ExecutableImageKind image_type, B32 relaxed)
|
||||
dw_print_debug_ranges(Arena *arena, String8List *out, String8 g_dw_indent, DW_Raw *input, Arch arch, ExecutableImageKind image_type, B32 relaxed)
|
||||
{
|
||||
NotImplemented;
|
||||
#if 0
|
||||
@@ -1503,7 +1503,7 @@ dw_print_debug_ranges(Arena *arena, String8List *out, String8 g_dw_indent, DW_In
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_aranges(Arena *arena, String8List *out, String8 g_dw_indent, DW_Input *input)
|
||||
dw_print_debug_aranges(Arena *arena, String8List *out, String8 g_dw_indent, DW_Raw *input)
|
||||
{
|
||||
NotImplemented;
|
||||
#if 0
|
||||
@@ -1592,7 +1592,7 @@ dw_print_debug_aranges(Arena *arena, String8List *out, String8 g_dw_indent, DW_I
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_addr(Arena *arena, String8List *out, String8 g_dw_indent, DW_Input *input)
|
||||
dw_print_debug_addr(Arena *arena, String8List *out, String8 g_dw_indent, DW_Raw *input)
|
||||
{
|
||||
NotImplemented;
|
||||
#if 0
|
||||
@@ -1701,7 +1701,7 @@ dw_based_range_read_address(void *base, Rng1U64 range, U64 offset, Rng1U64Array
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_loclists(Arena *arena, String8List *out, String8 g_dw_indent, DW_Input *input, Rng1U64Array segment_virtual_ranges, Arch arch)
|
||||
dw_print_debug_loclists(Arena *arena, String8List *out, String8 g_dw_indent, DW_Raw *input, Rng1U64Array segment_virtual_ranges, Arch arch)
|
||||
{
|
||||
NotImplemented;
|
||||
#if 0
|
||||
@@ -1854,7 +1854,7 @@ dw_print_debug_loclists(Arena *arena, String8List *out, String8 g_dw_indent, DW_
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_rnglists(Arena *arena, String8List *out, String8 g_dw_indent, DW_Input *input, Rng1U64Array segment_ranges)
|
||||
dw_print_debug_rnglists(Arena *arena, String8List *out, String8 g_dw_indent, DW_Raw *input, Rng1U64Array segment_ranges)
|
||||
{
|
||||
NotImplemented;
|
||||
#if 0
|
||||
@@ -1993,7 +1993,7 @@ dw_print_debug_rnglists(Arena *arena, String8List *out, String8 g_dw_indent, DW_
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_format_string_table(Arena *arena, String8List *out, String8 g_dw_indent, DW_Input *input, DW_SectionKind sec)
|
||||
dw_format_string_table(Arena *arena, String8List *out, String8 g_dw_indent, DW_Raw *input, DW_SectionKind sec)
|
||||
{
|
||||
NotImplemented;
|
||||
#if 0
|
||||
@@ -2055,19 +2055,19 @@ dw_format_string_table(Arena *arena, String8List *out, String8 g_dw_indent, DW_I
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_pubnames(Arena *arena, String8List *out, String8 g_dw_indent, DW_Input *input)
|
||||
dw_print_debug_pubnames(Arena *arena, String8List *out, String8 g_dw_indent, DW_Raw *input)
|
||||
{
|
||||
dw_format_string_table(arena, out, g_dw_indent, input, DW_Section_PubNames);
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_pubtypes(Arena *arena, String8List *out, String8 g_dw_indent, DW_Input *input)
|
||||
dw_print_debug_pubtypes(Arena *arena, String8List *out, String8 g_dw_indent, DW_Raw *input)
|
||||
{
|
||||
dw_format_string_table(arena, out, g_dw_indent, input, DW_Section_PubTypes);
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_line_str(Arena *arena, String8List *out, String8 g_dw_indent, DW_Input *input)
|
||||
dw_print_debug_line_str(Arena *arena, String8List *out, String8 g_dw_indent, DW_Raw *input)
|
||||
{
|
||||
NotImplemented;
|
||||
#if 0
|
||||
@@ -2097,7 +2097,7 @@ dw_print_debug_line_str(Arena *arena, String8List *out, String8 g_dw_indent, DW_
|
||||
}
|
||||
|
||||
internal void
|
||||
dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 g_dw_indent, DW_Input *input)
|
||||
dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 g_dw_indent, DW_Raw *input)
|
||||
{
|
||||
NotImplemented;
|
||||
#if 0
|
||||
@@ -2180,7 +2180,7 @@ read_only struct {
|
||||
|
||||
internal String8List
|
||||
dw_dump_list_from_sections(Arena *arena,
|
||||
DW_Input *input,
|
||||
DW_Raw *input,
|
||||
Arch arch,
|
||||
DW_SectionFlags subset_flags,
|
||||
B32 is_verbose)
|
||||
|
||||
+13
-13
@@ -18,7 +18,7 @@ typedef struct DW_Dumper
|
||||
Arch arch;
|
||||
B32 is_relaxed;
|
||||
B32 is_verbose;
|
||||
DW_Input *input;
|
||||
DW_Raw *input;
|
||||
DW_DumperCacheFlags cache_flags;
|
||||
struct {
|
||||
Rng1U64Array info_ranges;
|
||||
@@ -46,28 +46,28 @@ internal String8List dw_string_list_from_cfi_program(Arena *arena, U64 cu_base,
|
||||
internal String8List dw_string_list_from_expression (Arena *arena, String8 raw_data, U64 cu_base, U64 addr_size, Arch arch, DW_Version ver, DW_Ext ext, DW_Format format);
|
||||
|
||||
internal String8 dw_string_from_reg_off (Arena *arena, Arch arch, DW_Reg reg_idx, S64 reg_off);
|
||||
internal String8 dw_string_from_attrib_value(Arena *arena, DW_Input *input, Arch arch, DW_CompUnit *cu, DW_LineVM *line_vm, DW_Attrib *attrib);
|
||||
internal String8 dw_string_from_attrib_value(Arena *arena, DW_Raw *input, Arch arch, DW_CompUnit *cu, DW_LineVM *line_vm, DW_Attrib *attrib);
|
||||
internal String8 dw_string_from_expression (Arena *arena, String8 expr, U64 cu_base, U64 addr_size, Arch arch, DW_Version ver, DW_Ext ext, DW_Format format);
|
||||
internal String8 dw_string_from_cfa (Arena *arena, Arch arch, U64 address_size, DW_Version version, DW_Ext ext, DW_Format format, DW_CFA cfa);
|
||||
internal String8 dw_string_from_cfi_row (Arena *arena, Arch arch, U64 address_size, DW_Version version, DW_Ext ext, DW_Format format, DW_CFI_Row *row);
|
||||
|
||||
#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_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);
|
||||
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);
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Dump Entry Point
|
||||
|
||||
internal String8List dw_dump_list_from_sections(Arena *arena, DW_Input *input, Arch arch, DW_SectionFlags dump_sections, B32 is_verbose);
|
||||
internal String8List dw_dump_list_from_sections(Arena *arena, DW_Raw *input, Arch arch, DW_SectionFlags dump_sections, B32 is_verbose);
|
||||
|
||||
#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_Input
|
||||
internal DW_Raw
|
||||
dw_input_from_elf_bin(Arena *arena, String8 data, ELF_Bin *bin)
|
||||
{
|
||||
DW_Input result = {0};
|
||||
DW_Raw result = {0};
|
||||
B32 is_section_present[ArrayCount(result.sec)] = {0};
|
||||
for(U64 section_idx = 1; section_idx < bin->shdrs.count; section_idx += 1)
|
||||
{
|
||||
|
||||
@@ -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_Input dw_input_from_elf_bin(Arena *arena, String8 raw_image, ELF_Bin *bin);
|
||||
internal DW_Raw dw_input_from_elf_bin(Arena *arena, String8 raw_image, ELF_Bin *bin);
|
||||
|
||||
#endif // DWARF_ELF_H
|
||||
|
||||
@@ -10,5 +10,6 @@
|
||||
#include "dwarf/dwarf_dump.c"
|
||||
#include "dwarf/dwarf_help.c"
|
||||
#include "dwarf/dwarf_writer.c"
|
||||
#include "dwarf/dwarf_parse_2.c"
|
||||
#include "dwarf/eh_frame.c"
|
||||
#include "dwarf/eh_dump.c"
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "dwarf/dwarf_dump.h"
|
||||
#include "dwarf/dwarf_help.h"
|
||||
#include "dwarf/dwarf_writer.h"
|
||||
#include "dwarf/dwarf_parse_2.h"
|
||||
#include "dwarf/eh_frame.h"
|
||||
#include "dwarf/eh_dump.h"
|
||||
|
||||
|
||||
+426
-426
File diff suppressed because it is too large
Load Diff
+47
-47
@@ -11,11 +11,11 @@ typedef struct DW_Section
|
||||
B32 is_dwo;
|
||||
} DW_Section;
|
||||
|
||||
typedef struct DW_Input
|
||||
typedef struct DW_Raw
|
||||
{
|
||||
DW_Section sec[DW_Section_Count];
|
||||
DW_Section sup[DW_Section_Count];
|
||||
} DW_Input;
|
||||
DW_Section sec[DW_Section_COUNT];
|
||||
DW_Section sup[DW_Section_COUNT];
|
||||
} DW_Raw;
|
||||
|
||||
typedef struct DW_ListUnit
|
||||
{
|
||||
@@ -432,7 +432,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_input(Arena *arena, DW_Input *input);
|
||||
internal DW_ListUnitInput dw_list_unit_input_from_input(Arena *arena, DW_Raw *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);
|
||||
@@ -448,8 +448,8 @@ internal U64 dw_abbrev_offset_from_abbrev_id(DW_AbbrevTable table, U6
|
||||
// form and tag
|
||||
|
||||
internal B32 dw_read_form (String8 data, DW_Version version, DW_Format unit_format, U64 address_size, DW_FormKind form_kind, S64 implicit_const, DW_Form *form_out, U64 *bytes_read_out);
|
||||
internal U64 dw_read_tag (Arena *arena, DW_Input *input, DW_AbbrevTable abbrev_table, DW_Version version, DW_Format format, U64 address_size, Rng1U64 cu_info_range, U64 tag_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);
|
||||
internal U64 dw_read_tag (Arena *arena, DW_Raw *input, DW_AbbrevTable abbrev_table, DW_Version version, DW_Format format, U64 address_size, Rng1U64 cu_info_range, U64 tag_info_off, 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);
|
||||
|
||||
// attrib interp
|
||||
|
||||
@@ -462,58 +462,58 @@ internal S64 dw_interp_const_s64 (DW_Form form);
|
||||
internal S32 dw_interp_const_s32 (DW_Form form);
|
||||
internal B32 dw_interp_flag (DW_Form form);
|
||||
internal U64 dw_interp_address (U64 address_size, U64 base_addr, DW_ListUnit *addr_xlist, DW_Form form);
|
||||
internal String8 dw_interp_block (DW_Input *input, DW_CompUnit *cu, DW_Form form);
|
||||
internal String8 dw_interp_string (DW_Input *input, DW_Format unit_format, DW_ListUnit *str_offsets, DW_Form form);
|
||||
internal String8 dw_interp_line_ptr (DW_Input *input, DW_Form form);
|
||||
internal String8 dw_interp_block (DW_Raw *input, DW_CompUnit *cu, DW_Form form);
|
||||
internal String8 dw_interp_string (DW_Raw *input, DW_Format unit_format, DW_ListUnit *str_offsets, DW_Form form);
|
||||
internal String8 dw_interp_line_ptr (DW_Raw *input, DW_Form form);
|
||||
internal DW_LineFile * dw_interp_file (DW_LineVM *line_vm, DW_Form form);
|
||||
internal DW_Reference dw_interp_ref (DW_Input *input, DW_CompUnit *cu, DW_Form form);
|
||||
internal DW_LocList dw_interp_loclist (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Form form);
|
||||
internal Rng1U64List dw_interp_rnglist (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Form form);
|
||||
internal DW_Reference dw_interp_ref (DW_Raw *input, DW_CompUnit *cu, DW_Form form);
|
||||
internal DW_LocList dw_interp_loclist (Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_Form form);
|
||||
internal Rng1U64List dw_interp_rnglist (Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_Form form);
|
||||
|
||||
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 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 DW_LineFile * dw_file_from_attrib (DW_CompUnit *cu, DW_LineVM *line_vm, 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 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 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_LineVM *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);
|
||||
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_LineVM *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 B32 dw_is_attrib_var_ref(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
internal B32 dw_is_attrib_var_ref(DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib);
|
||||
|
||||
// compile unit
|
||||
|
||||
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 DW_CompUnit dw_cu_from_info_off(Arena *arena, DW_Raw *input, DW_ListUnitInput lu_input, U64 offset, B32 relaxed);
|
||||
internal DW_TagTree dw_tag_tree_from_cu(Arena *arena, DW_Raw *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 VM
|
||||
|
||||
internal U64 dw_read_line_vm_header(Arena *arena, DW_Input *input, String8 cu_stmt_list, String8 cu_dir, String8 cu_name, U8 cu_address_size, DW_ListUnit *cu_str_offsets, DW_LineVMHeader *header_out);
|
||||
internal DW_LineVM * dw_line_vm_init(DW_Input *input, DW_CompUnit *cu);
|
||||
internal U64 dw_read_line_vm_header(Arena *arena, DW_Raw *input, String8 cu_stmt_list, String8 cu_dir, String8 cu_name, U8 cu_address_size, DW_ListUnit *cu_str_offsets, DW_LineVMHeader *header_out);
|
||||
internal DW_LineVM * dw_line_vm_init(DW_Raw *input, DW_CompUnit *cu);
|
||||
internal void dw_line_vm_release(DW_LineVM *vm);
|
||||
internal void dw_line_vm_advance(DW_LineVM *vm, U64 advance);
|
||||
internal B32 dw_line_vm_step(DW_LineVM *vm);
|
||||
@@ -522,7 +522,7 @@ internal String8 dw_path_from_file(Arena *arena, String8Array dir_table, D
|
||||
|
||||
// helper for .debug_pubtypes and .debug_pubnames
|
||||
|
||||
internal DW_PubStringsTable dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Input *input, DW_SectionKind section_kind);
|
||||
internal DW_PubStringsTable dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Raw *input, DW_SectionKind section_kind);
|
||||
|
||||
// expression
|
||||
|
||||
|
||||
@@ -775,6 +775,7 @@ dw2_read_line_table_header(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 of
|
||||
case DW_LNCT_TimeStamp:
|
||||
{
|
||||
entry_out->modify_time = form_val.u128.u64[0];
|
||||
entry_out->flags |= DW2_LineTableFileFlag_HasModifyTime;
|
||||
}break;
|
||||
case DW_LNCT_Size:
|
||||
{
|
||||
@@ -783,6 +784,7 @@ dw2_read_line_table_header(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 of
|
||||
case DW_LNCT_MD5:
|
||||
{
|
||||
entry_out->md5.u128 = form_val.u128;
|
||||
entry_out->flags |= DW2_LineTableFileFlag_HasMD5;
|
||||
}break;
|
||||
case DW_LNCT_LLVM_Source:
|
||||
{
|
||||
|
||||
@@ -100,10 +100,18 @@ struct DW2_Tag
|
||||
////////////////////////////////
|
||||
//~ rjf: Line Info
|
||||
|
||||
typedef U32 DW2_LineTableFileFlags;
|
||||
enum
|
||||
{
|
||||
DW2_LineTableFileFlag_HasMD5 = (1<<0),
|
||||
DW2_LineTableFileFlag_HasModifyTime = (1<<1),
|
||||
};
|
||||
|
||||
typedef struct DW2_LineTableFile DW2_LineTableFile;
|
||||
struct DW2_LineTableFile
|
||||
{
|
||||
String8 file_name;
|
||||
DW2_LineTableFileFlags flags;
|
||||
U64 dir_idx;
|
||||
U64 modify_time;
|
||||
U64 file_size;
|
||||
@@ -154,6 +162,23 @@ struct DW2_LineTableHeader
|
||||
DW2_LineTableFileArray files;
|
||||
};
|
||||
|
||||
typedef struct DW2_LineVMRegs DW2_LineVMRegs;
|
||||
struct DW2_LineVMRegs
|
||||
{
|
||||
U64 address;
|
||||
U64 vliw_op_index;
|
||||
U64 file_index;
|
||||
U64 line;
|
||||
U64 column;
|
||||
B32 is_stmt;
|
||||
B32 basic_block;
|
||||
B32 end_sequence;
|
||||
B32 prologue_end;
|
||||
B32 epilogue_begin;
|
||||
U64 isa;
|
||||
U64 discriminator;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
|
||||
+430
-430
@@ -24,12 +24,12 @@ dw_size_from_sint(S64 v)
|
||||
{
|
||||
DW_IntEnc enc = dw_int_enc_from_sint(v);
|
||||
switch (enc) {
|
||||
case DW_IntEnc_Null: break;
|
||||
case DW_IntEnc_1Byte: return 1;
|
||||
case DW_IntEnc_2Byte: return 2;
|
||||
case DW_IntEnc_4Byte: return 4;
|
||||
case DW_IntEnc_LEB128: return dw_size_from_sleb128(v);
|
||||
default: InvalidPath; break;
|
||||
case DW_IntEnc_Null: break;
|
||||
case DW_IntEnc_1Byte: return 1;
|
||||
case DW_IntEnc_2Byte: return 2;
|
||||
case DW_IntEnc_4Byte: return 4;
|
||||
case DW_IntEnc_LEB128: return dw_size_from_sleb128(v);
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -39,12 +39,12 @@ dw_size_from_uint(U64 v)
|
||||
{
|
||||
DW_IntEnc enc = dw_int_enc_from_uint(v);
|
||||
switch (enc) {
|
||||
case DW_IntEnc_Null: break;
|
||||
case DW_IntEnc_1Byte: return 1;
|
||||
case DW_IntEnc_2Byte: return 2;
|
||||
case DW_IntEnc_4Byte: return 4;
|
||||
case DW_IntEnc_LEB128: return dw_size_from_uleb128(v);
|
||||
default: InvalidPath; break;
|
||||
case DW_IntEnc_Null: break;
|
||||
case DW_IntEnc_1Byte: return 1;
|
||||
case DW_IntEnc_2Byte: return 2;
|
||||
case DW_IntEnc_4Byte: return 4;
|
||||
case DW_IntEnc_LEB128: return dw_size_from_uleb128(v);
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -163,132 +163,132 @@ dw_serial_push_form(Arena *arena, String8List *srl, DW_Version version, DW_Forma
|
||||
{
|
||||
U64 start_off = srl->total_size;
|
||||
switch (form.reader.kind) {
|
||||
case DW_Form_Addr: {
|
||||
str8_serial_push_string(arena, srl, form.reader.addr);
|
||||
} break;
|
||||
case DW_Form_Block1:
|
||||
case DW_Form_Block2:
|
||||
case DW_Form_Block4: {
|
||||
str8_serial_push_string(arena, srl, form.reader.block);
|
||||
} break;
|
||||
case DW_Form_Data1:
|
||||
case DW_Form_Data2:
|
||||
case DW_Form_Data4:
|
||||
case DW_Form_Data8: {
|
||||
str8_serial_push_string(arena, srl, form.reader.data);
|
||||
} break;
|
||||
case DW_Form_String: {
|
||||
str8_serial_push_cstr(arena, srl, form.reader.string);
|
||||
} break;
|
||||
case DW_Form_Block: {
|
||||
dw_serial_push_uleb128(arena, srl, form.reader.block.size);
|
||||
str8_serial_push_string(arena, srl, form.reader.block);
|
||||
} break;
|
||||
case DW_Form_Flag: {
|
||||
str8_serial_push_u8(arena, srl, form.reader.flag);
|
||||
} break;
|
||||
case DW_Form_SData: {
|
||||
dw_serial_push_sleb128(arena, srl, form.reader.sdata);
|
||||
} break;
|
||||
case DW_Form_Strp: {
|
||||
dw_serial_push_uint(arena, srl, format, form.reader.sec_offset);
|
||||
} break;
|
||||
case DW_Form_UData: {
|
||||
dw_serial_push_uleb128(arena, srl, form.reader.udata);
|
||||
} break;
|
||||
case DW_Form_RefAddr: {
|
||||
if (version < DW_Version_3) {
|
||||
Assert(address_size <= sizeof(form.reader.ref));
|
||||
str8_serial_push_string(arena, srl, str8((U8 *)&form.reader.ref, address_size));
|
||||
} else {
|
||||
case DW_Form_Addr: {
|
||||
str8_serial_push_string(arena, srl, form.reader.addr);
|
||||
} break;
|
||||
case DW_Form_Block1:
|
||||
case DW_Form_Block2:
|
||||
case DW_Form_Block4: {
|
||||
str8_serial_push_string(arena, srl, form.reader.block);
|
||||
} break;
|
||||
case DW_Form_Data1:
|
||||
case DW_Form_Data2:
|
||||
case DW_Form_Data4:
|
||||
case DW_Form_Data8: {
|
||||
str8_serial_push_string(arena, srl, form.reader.data);
|
||||
} break;
|
||||
case DW_Form_String: {
|
||||
str8_serial_push_cstr(arena, srl, form.reader.string);
|
||||
} break;
|
||||
case DW_Form_Block: {
|
||||
dw_serial_push_uleb128(arena, srl, form.reader.block.size);
|
||||
str8_serial_push_string(arena, srl, form.reader.block);
|
||||
} break;
|
||||
case DW_Form_Flag: {
|
||||
str8_serial_push_u8(arena, srl, form.reader.flag);
|
||||
} break;
|
||||
case DW_Form_SData: {
|
||||
dw_serial_push_sleb128(arena, srl, form.reader.sdata);
|
||||
} break;
|
||||
case DW_Form_Strp: {
|
||||
dw_serial_push_uint(arena, srl, format, form.reader.sec_offset);
|
||||
} break;
|
||||
case DW_Form_UData: {
|
||||
dw_serial_push_uleb128(arena, srl, form.reader.udata);
|
||||
} break;
|
||||
case DW_Form_RefAddr: {
|
||||
if (version < DW_Version_3) {
|
||||
Assert(address_size <= sizeof(form.reader.ref));
|
||||
str8_serial_push_string(arena, srl, str8((U8 *)&form.reader.ref, address_size));
|
||||
} else {
|
||||
dw_serial_push_uint(arena, srl, format, form.reader.ref);
|
||||
}
|
||||
} break;
|
||||
case DW_Form_Ref1: {
|
||||
str8_serial_push_u8(arena, srl, (U8)form.reader.ref);
|
||||
} break;
|
||||
case DW_Form_Ref2: {
|
||||
str8_serial_push_u16(arena, srl, (U16)form.reader.ref);
|
||||
} break;
|
||||
case DW_Form_Ref4: {
|
||||
str8_serial_push_u32(arena, srl, (U32)form.reader.ref);
|
||||
} break;
|
||||
case DW_Form_Ref8: {
|
||||
if (form.writer.ref->info_off == 0) {
|
||||
// reserve 8 bytes
|
||||
void *value = str8_serial_push_u64(arena, srl, 0);
|
||||
|
||||
// push fixup
|
||||
dw_writer_fixup_list_push(arena, fixups, (DW_WriterFixup){ .ptr = value, .tag = form.writer.ref });
|
||||
}
|
||||
} break;
|
||||
case DW_Form_RefUData: {
|
||||
dw_serial_push_uleb128(arena, srl, form.reader.ref);
|
||||
} break;
|
||||
case DW_Form_Indirect: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_Form_SecOffset: {
|
||||
dw_serial_push_uint(arena, srl, format, form.reader.sec_offset);
|
||||
} break;
|
||||
case DW_Form_ExprLoc: {
|
||||
dw_serial_push_uleb128(arena, srl, form.reader.exprloc.size);
|
||||
str8_serial_push_string(arena, srl, form.reader.exprloc);
|
||||
} break;
|
||||
case DW_Form_FlagPresent: {
|
||||
} break;
|
||||
case DW_Form_RefSig8: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_Form_Strx:
|
||||
case DW_Form_Addrx:
|
||||
case DW_Form_RngListx:
|
||||
case DW_Form_LocListx: {
|
||||
dw_serial_push_uleb128(arena, srl, form.reader.xval);
|
||||
} break;
|
||||
case DW_Form_RefSup4: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_Form_StrpSup: {
|
||||
dw_serial_push_uint(arena, srl, format, form.reader.strp_sup);
|
||||
} break;
|
||||
case DW_Form_Data16: {
|
||||
str8_serial_push_string(arena, srl, form.reader.data);
|
||||
} break;
|
||||
case DW_Form_LineStrp: {
|
||||
dw_serial_push_uint(arena, srl, format, form.reader.sec_offset);
|
||||
} break;
|
||||
case DW_Form_ImplicitConst: {
|
||||
// value is stored in the abbrev entry
|
||||
} break;
|
||||
case DW_Form_RefSup8: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_Form_Strx1:
|
||||
case DW_Form_Addrx1: {
|
||||
str8_serial_push_u8(arena, srl, (U8)form.reader.xval);
|
||||
} break;
|
||||
case DW_Form_Strx2:
|
||||
case DW_Form_Addrx2: {
|
||||
str8_serial_push_u16(arena, srl, (U16)form.reader.xval);
|
||||
} break;
|
||||
case DW_Form_Strx3:
|
||||
case DW_Form_Addrx3: {
|
||||
str8_serial_push_string(arena, srl, str8((U8 *)&form.reader.xval, 3));
|
||||
} break;
|
||||
case DW_Form_Strx4:
|
||||
case DW_Form_Addrx4: {
|
||||
str8_serial_push_u32(arena, srl, (U32)form.reader.xval);
|
||||
} break;
|
||||
|
||||
case DW_Form_GNU_StrpAlt: {
|
||||
dw_serial_push_uint(arena, srl, format, form.reader.sec_offset);
|
||||
} break;
|
||||
case DW_Form_GNU_RefAlt: {
|
||||
dw_serial_push_uint(arena, srl, format, form.reader.ref);
|
||||
}
|
||||
} break;
|
||||
case DW_Form_Ref1: {
|
||||
str8_serial_push_u8(arena, srl, (U8)form.reader.ref);
|
||||
} break;
|
||||
case DW_Form_Ref2: {
|
||||
str8_serial_push_u16(arena, srl, (U16)form.reader.ref);
|
||||
} break;
|
||||
case DW_Form_Ref4: {
|
||||
str8_serial_push_u32(arena, srl, (U32)form.reader.ref);
|
||||
} break;
|
||||
case DW_Form_Ref8: {
|
||||
if (form.writer.ref->info_off == 0) {
|
||||
// reserve 8 bytes
|
||||
void *value = str8_serial_push_u64(arena, srl, 0);
|
||||
} break;
|
||||
|
||||
// push fixup
|
||||
dw_writer_fixup_list_push(arena, fixups, (DW_WriterFixup){ .ptr = value, .tag = form.writer.ref });
|
||||
}
|
||||
} break;
|
||||
case DW_Form_RefUData: {
|
||||
dw_serial_push_uleb128(arena, srl, form.reader.ref);
|
||||
} break;
|
||||
case DW_Form_Indirect: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_Form_SecOffset: {
|
||||
dw_serial_push_uint(arena, srl, format, form.reader.sec_offset);
|
||||
} break;
|
||||
case DW_Form_ExprLoc: {
|
||||
dw_serial_push_uleb128(arena, srl, form.reader.exprloc.size);
|
||||
str8_serial_push_string(arena, srl, form.reader.exprloc);
|
||||
} break;
|
||||
case DW_Form_FlagPresent: {
|
||||
} break;
|
||||
case DW_Form_RefSig8: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_Form_Strx:
|
||||
case DW_Form_Addrx:
|
||||
case DW_Form_RngListx:
|
||||
case DW_Form_LocListx: {
|
||||
dw_serial_push_uleb128(arena, srl, form.reader.xval);
|
||||
} break;
|
||||
case DW_Form_RefSup4: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_Form_StrpSup: {
|
||||
dw_serial_push_uint(arena, srl, format, form.reader.strp_sup);
|
||||
} break;
|
||||
case DW_Form_Data16: {
|
||||
str8_serial_push_string(arena, srl, form.reader.data);
|
||||
} break;
|
||||
case DW_Form_LineStrp: {
|
||||
dw_serial_push_uint(arena, srl, format, form.reader.sec_offset);
|
||||
} break;
|
||||
case DW_Form_ImplicitConst: {
|
||||
// value is stored in the abbrev entry
|
||||
} break;
|
||||
case DW_Form_RefSup8: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_Form_Strx1:
|
||||
case DW_Form_Addrx1: {
|
||||
str8_serial_push_u8(arena, srl, (U8)form.reader.xval);
|
||||
} break;
|
||||
case DW_Form_Strx2:
|
||||
case DW_Form_Addrx2: {
|
||||
str8_serial_push_u16(arena, srl, (U16)form.reader.xval);
|
||||
} break;
|
||||
case DW_Form_Strx3:
|
||||
case DW_Form_Addrx3: {
|
||||
str8_serial_push_string(arena, srl, str8((U8 *)&form.reader.xval, 3));
|
||||
} break;
|
||||
case DW_Form_Strx4:
|
||||
case DW_Form_Addrx4: {
|
||||
str8_serial_push_u32(arena, srl, (U32)form.reader.xval);
|
||||
} break;
|
||||
|
||||
case DW_Form_GNU_StrpAlt: {
|
||||
dw_serial_push_uint(arena, srl, format, form.reader.sec_offset);
|
||||
} break;
|
||||
case DW_Form_GNU_RefAlt: {
|
||||
dw_serial_push_uint(arena, srl, format, form.reader.ref);
|
||||
} break;
|
||||
|
||||
default: InvalidPath; break;
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
return srl->total_size - start_off;
|
||||
}
|
||||
@@ -371,26 +371,26 @@ dw_writer_push_attrib(DW_Writer *writer, DW_AttribKind kind, DW_WriterForm form)
|
||||
for (DW_AttribClass f = attrib_class; f != 0; f &= f - 1) {
|
||||
DW_AttribClass v = f & -f;
|
||||
switch (v) {
|
||||
case DW_AttribClass_Null: { is_enc_legal = (form.kind == DW_WriterFormKind_Null); } break;
|
||||
case DW_AttribClass_Undefined: { is_enc_legal = 0; } break;
|
||||
case DW_AttribClass_Address: { is_enc_legal = (form.kind == DW_WriterFormKind_Address); } break;
|
||||
case DW_AttribClass_Block: { is_enc_legal = (form.kind == DW_WriterFormKind_Block); } break;
|
||||
case DW_AttribClass_Const: { is_enc_legal = (form.kind == DW_WriterFormKind_SInt ||
|
||||
form.kind == DW_WriterFormKind_UInt ||
|
||||
form.kind == DW_WriterFormKind_Implicit); } break;
|
||||
case DW_AttribClass_ExprLoc: { is_enc_legal = (form.kind == DW_WriterFormKind_ExprLoc); } break;
|
||||
case DW_AttribClass_Flag: { is_enc_legal = (form.kind == DW_WriterFormKind_Flag); } break;
|
||||
case DW_AttribClass_LinePtr: { is_enc_legal = (form.kind == DW_WriterFormKind_LinePtr); } break;
|
||||
case DW_AttribClass_LocListPtr: { is_enc_legal = 0; /* TODO */ } break;
|
||||
case DW_AttribClass_MacPtr: { is_enc_legal = (form.kind == DW_WriterFormKind_MacPtr); } break;
|
||||
case DW_AttribClass_RngListPtr: { is_enc_legal = (form.kind == DW_WriterFormKind_RngListPtr); } break;
|
||||
case DW_AttribClass_Reference: { is_enc_legal = (form.kind == DW_WriterFormKind_Ref); } break;
|
||||
case DW_AttribClass_String: { is_enc_legal = (form.kind == DW_WriterFormKind_String); } break;
|
||||
case DW_AttribClass_LocList: { is_enc_legal = 0; /* TODO */ } break;
|
||||
case DW_AttribClass_RngList: { is_enc_legal = 0; /* TODO */ } break;
|
||||
case DW_AttribClass_StrOffsetsPtr: { is_enc_legal = 0; /* TODO */ } break;
|
||||
case DW_AttribClass_AddrPtr: { is_enc_legal = 0; /* TODO */ } break;
|
||||
default: { InvalidPath; } break;
|
||||
case DW_AttribClass_Null: { is_enc_legal = (form.kind == DW_WriterFormKind_Null); } break;
|
||||
case DW_AttribClass_Undefined: { is_enc_legal = 0; } break;
|
||||
case DW_AttribClass_Address: { is_enc_legal = (form.kind == DW_WriterFormKind_Address); } break;
|
||||
case DW_AttribClass_Block: { is_enc_legal = (form.kind == DW_WriterFormKind_Block); } break;
|
||||
case DW_AttribClass_Const: { is_enc_legal = (form.kind == DW_WriterFormKind_SInt ||
|
||||
form.kind == DW_WriterFormKind_UInt ||
|
||||
form.kind == DW_WriterFormKind_Implicit); } break;
|
||||
case DW_AttribClass_ExprLoc: { is_enc_legal = (form.kind == DW_WriterFormKind_ExprLoc); } break;
|
||||
case DW_AttribClass_Flag: { is_enc_legal = (form.kind == DW_WriterFormKind_Flag); } break;
|
||||
case DW_AttribClass_LinePtr: { is_enc_legal = (form.kind == DW_WriterFormKind_LinePtr); } break;
|
||||
case DW_AttribClass_LocListPtr: { is_enc_legal = 0; /* TODO */ } break;
|
||||
case DW_AttribClass_MacPtr: { is_enc_legal = (form.kind == DW_WriterFormKind_MacPtr); } break;
|
||||
case DW_AttribClass_RngListPtr: { is_enc_legal = (form.kind == DW_WriterFormKind_RngListPtr); } break;
|
||||
case DW_AttribClass_Reference: { is_enc_legal = (form.kind == DW_WriterFormKind_Ref); } break;
|
||||
case DW_AttribClass_String: { is_enc_legal = (form.kind == DW_WriterFormKind_String); } break;
|
||||
case DW_AttribClass_LocList: { is_enc_legal = 0; /* TODO */ } break;
|
||||
case DW_AttribClass_RngList: { is_enc_legal = 0; /* TODO */ } break;
|
||||
case DW_AttribClass_StrOffsetsPtr: { is_enc_legal = 0; /* TODO */ } break;
|
||||
case DW_AttribClass_AddrPtr: { is_enc_legal = 0; /* TODO */ } break;
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
if (is_enc_legal) { break; }
|
||||
}
|
||||
@@ -533,67 +533,67 @@ dw_data_from_line_insts(Arena *arena, U8 address_size, DW_LineInstList insts)
|
||||
|
||||
str8_serial_push_struct(scratch.arena, &srl, &inst->opcode);
|
||||
switch (inst->opcode) {
|
||||
case DW_StdOpcode_Copy: {} break;
|
||||
case DW_StdOpcode_AdvancePc: {
|
||||
dw_serial_push_uleb128(arena, &srl, inst->advance_pc);
|
||||
} break;
|
||||
case DW_StdOpcode_AdvanceLine: {
|
||||
dw_serial_push_sleb128(arena, &srl, inst->advance_line);
|
||||
} break;
|
||||
case DW_StdOpcode_SetFile: {
|
||||
dw_serial_push_uleb128(arena, &srl, inst->set_file->file_idx);
|
||||
} break;
|
||||
case DW_StdOpcode_SetColumn: {
|
||||
dw_serial_push_uleb128(arena, &srl, inst->set_column);
|
||||
} break;
|
||||
case DW_StdOpcode_NegateStmt: {} break;
|
||||
case DW_StdOpcode_SetBasicBlock: {} break;
|
||||
case DW_StdOpcode_ConstAddPc: {} break;
|
||||
case DW_StdOpcode_FixedAdvancePc: {
|
||||
str8_serial_push_u16(arena, &srl, inst->fixed_advance_pc);
|
||||
} break;
|
||||
case DW_StdOpcode_SetPrologueEnd: {} break;
|
||||
case DW_StdOpcode_SetEpilogueBegin: {} break;
|
||||
case DW_StdOpcode_SetIsa: {
|
||||
dw_serial_push_uleb128(arena, &srl, inst->set_isa);
|
||||
} break;
|
||||
case DW_StdOpcode_ExtendedOpcode: {
|
||||
// get ext size
|
||||
U64 ext_size = 0;
|
||||
switch (inst->ext) {
|
||||
case DW_ExtOpcode_EndSequence: { ext_size = 0; } break;
|
||||
case DW_ExtOpcode_SetAddress: { ext_size = address_size; } break;
|
||||
case DW_ExtOpcode_DefineFile: {
|
||||
NotImplemented;
|
||||
case DW_StdOpcode_Copy: {} break;
|
||||
case DW_StdOpcode_AdvancePc: {
|
||||
dw_serial_push_uleb128(arena, &srl, inst->advance_pc);
|
||||
} break;
|
||||
case DW_ExtOpcode_SetDiscriminator: {
|
||||
ext_size = dw_size_from_uleb128(inst->set_discriminator);
|
||||
case DW_StdOpcode_AdvanceLine: {
|
||||
dw_serial_push_sleb128(arena, &srl, inst->advance_line);
|
||||
} break;
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
ext_size += sizeof(DW_ExtOpcode);
|
||||
case DW_StdOpcode_SetFile: {
|
||||
dw_serial_push_uleb128(arena, &srl, inst->set_file->file_idx);
|
||||
} break;
|
||||
case DW_StdOpcode_SetColumn: {
|
||||
dw_serial_push_uleb128(arena, &srl, inst->set_column);
|
||||
} break;
|
||||
case DW_StdOpcode_NegateStmt: {} break;
|
||||
case DW_StdOpcode_SetBasicBlock: {} break;
|
||||
case DW_StdOpcode_ConstAddPc: {} break;
|
||||
case DW_StdOpcode_FixedAdvancePc: {
|
||||
str8_serial_push_u16(arena, &srl, inst->fixed_advance_pc);
|
||||
} break;
|
||||
case DW_StdOpcode_SetPrologueEnd: {} break;
|
||||
case DW_StdOpcode_SetEpilogueBegin: {} break;
|
||||
case DW_StdOpcode_SetIsa: {
|
||||
dw_serial_push_uleb128(arena, &srl, inst->set_isa);
|
||||
} break;
|
||||
case DW_StdOpcode_ExtendedOpcode: {
|
||||
// get ext size
|
||||
U64 ext_size = 0;
|
||||
switch (inst->ext) {
|
||||
case DW_ExtOpcode_EndSequence: { ext_size = 0; } break;
|
||||
case DW_ExtOpcode_SetAddress: { ext_size = address_size; } break;
|
||||
case DW_ExtOpcode_DefineFile: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_ExtOpcode_SetDiscriminator: {
|
||||
ext_size = dw_size_from_uleb128(inst->set_discriminator);
|
||||
} break;
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
ext_size += sizeof(DW_ExtOpcode);
|
||||
|
||||
// write ext header
|
||||
dw_serial_push_uleb128(arena, &srl, ext_size);
|
||||
str8_serial_push_struct(arena, &srl, &inst->ext);
|
||||
// write ext header
|
||||
dw_serial_push_uleb128(arena, &srl, ext_size);
|
||||
str8_serial_push_struct(arena, &srl, &inst->ext);
|
||||
|
||||
// write ext operands
|
||||
switch (inst->ext) {
|
||||
case DW_ExtOpcode_EndSequence: {} break;
|
||||
case DW_ExtOpcode_SetAddress: {
|
||||
str8_serial_push_string(arena, &srl, str8_copy(arena, str8((U8 *)&inst->set_address, address_size)));
|
||||
// write ext operands
|
||||
switch (inst->ext) {
|
||||
case DW_ExtOpcode_EndSequence: {} break;
|
||||
case DW_ExtOpcode_SetAddress: {
|
||||
str8_serial_push_string(arena, &srl, str8_copy(arena, str8((U8 *)&inst->set_address, address_size)));
|
||||
} break;
|
||||
case DW_ExtOpcode_DefineFile: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_ExtOpcode_SetDiscriminator: {
|
||||
dw_serial_push_uleb128(arena, &srl, inst->set_discriminator);
|
||||
} break;
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
} break;
|
||||
case DW_ExtOpcode_DefineFile: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_ExtOpcode_SetDiscriminator: {
|
||||
dw_serial_push_uleb128(arena, &srl, inst->set_discriminator);
|
||||
} break;
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
} break;
|
||||
// special opcode
|
||||
default: { } break;
|
||||
// special opcode
|
||||
default: { } break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -694,104 +694,104 @@ dw_lower_attrib_forms(DW_Writer *writer, DW_WriterTag *tag)
|
||||
{
|
||||
for EachNode(attrib, DW_WriterAttrib, tag->first_attrib) {
|
||||
switch (attrib->form.writer.kind) {
|
||||
case DW_WriterFormKind_Null: {} break;
|
||||
case DW_WriterFormKind_Flag: {
|
||||
attrib->form.reader.kind = DW_Form_Flag;
|
||||
attrib->form.reader.flag = attrib->form.writer.flag;
|
||||
} break;
|
||||
case DW_WriterFormKind_SInt: {
|
||||
switch (dw_int_enc_from_sint(attrib->form.writer.sint)) {
|
||||
case DW_IntEnc_Null: attrib->form.reader.kind = 0; break;
|
||||
case DW_IntEnc_1Byte: {
|
||||
attrib->form.reader.kind = DW_Form_Data1;
|
||||
attrib->form.reader.data = str8((U8 *)&attrib->form.writer.sint, sizeof(S8));
|
||||
case DW_WriterFormKind_Null: {} break;
|
||||
case DW_WriterFormKind_Flag: {
|
||||
attrib->form.reader.kind = DW_Form_Flag;
|
||||
attrib->form.reader.flag = attrib->form.writer.flag;
|
||||
} break;
|
||||
case DW_IntEnc_2Byte: {
|
||||
attrib->form.reader.kind = DW_Form_Data2;
|
||||
attrib->form.reader.data = str8((U8 *)&attrib->form.writer.sint, sizeof(S16));
|
||||
} break;
|
||||
case DW_IntEnc_4Byte: {
|
||||
attrib->form.reader.kind = DW_Form_Data4;
|
||||
attrib->form.reader.data = str8((U8 *)&attrib->form.writer.sint, sizeof(U32));
|
||||
} break;
|
||||
case DW_IntEnc_LEB128: {
|
||||
attrib->form.reader.kind = DW_Form_SData;
|
||||
attrib->form.reader.sdata = attrib->form.writer.sint;
|
||||
} break;
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
} break;
|
||||
case DW_WriterFormKind_UInt: {
|
||||
attrib->form.reader.kind = DW_Form_UData;
|
||||
attrib->form.reader.udata = attrib->form.writer.uint;
|
||||
} break;
|
||||
case DW_WriterFormKind_Address: {
|
||||
Assert(writer->address_size <= sizeof(attrib->form.writer.address));
|
||||
attrib->form.reader.kind = DW_Form_Addr;
|
||||
attrib->form.reader.addr = push_str8_copy(writer->arena, str8((U8 *)&attrib->form.writer.address, writer->address_size));
|
||||
} break;
|
||||
case DW_WriterFormKind_Ref: {
|
||||
if (attrib->form.writer.ref->info_off == 0) {
|
||||
attrib->form.reader.kind = DW_Form_Ref8;
|
||||
} else {
|
||||
switch (dw_int_enc_from_uint(attrib->form.writer.ref->info_off)) {
|
||||
case DW_IntEnc_Null: break;
|
||||
case DW_IntEnc_1Byte: {
|
||||
attrib->form.reader.kind = DW_Form_Ref1;
|
||||
attrib->form.reader.ref = (U8)attrib->form.writer.ref->info_off;
|
||||
} break;
|
||||
case DW_IntEnc_2Byte: {
|
||||
attrib->form.reader.kind = DW_Form_Ref2;
|
||||
attrib->form.reader.ref = (U16)attrib->form.writer.ref->info_off;
|
||||
} break;
|
||||
case DW_IntEnc_4Byte: {
|
||||
attrib->form.reader.kind = DW_Form_Ref4;
|
||||
attrib->form.reader.ref = (U32)attrib->form.writer.ref->info_off;
|
||||
} break;
|
||||
case DW_IntEnc_LEB128: {
|
||||
attrib->form.reader.kind = DW_Form_RefUData;
|
||||
attrib->form.reader.ref = attrib->form.writer.ref->info_off;
|
||||
} break;
|
||||
default: InvalidPath; break;
|
||||
case DW_WriterFormKind_SInt: {
|
||||
switch (dw_int_enc_from_sint(attrib->form.writer.sint)) {
|
||||
case DW_IntEnc_Null: attrib->form.reader.kind = 0; break;
|
||||
case DW_IntEnc_1Byte: {
|
||||
attrib->form.reader.kind = DW_Form_Data1;
|
||||
attrib->form.reader.data = str8((U8 *)&attrib->form.writer.sint, sizeof(S8));
|
||||
} break;
|
||||
case DW_IntEnc_2Byte: {
|
||||
attrib->form.reader.kind = DW_Form_Data2;
|
||||
attrib->form.reader.data = str8((U8 *)&attrib->form.writer.sint, sizeof(S16));
|
||||
} break;
|
||||
case DW_IntEnc_4Byte: {
|
||||
attrib->form.reader.kind = DW_Form_Data4;
|
||||
attrib->form.reader.data = str8((U8 *)&attrib->form.writer.sint, sizeof(U32));
|
||||
} break;
|
||||
case DW_IntEnc_LEB128: {
|
||||
attrib->form.reader.kind = DW_Form_SData;
|
||||
attrib->form.reader.sdata = attrib->form.writer.sint;
|
||||
} break;
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case DW_WriterFormKind_LinePtr: {
|
||||
attrib->form.reader.kind = DW_Form_SecOffset;
|
||||
attrib->form.reader.sec_offset = attrib->form.writer.line_ptr;
|
||||
} break;
|
||||
case DW_WriterFormKind_MacPtr: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_WriterFormKind_RngListPtr: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_WriterFormKind_Data: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_WriterFormKind_Block: {
|
||||
attrib->form.reader.block = attrib->form.writer.block;
|
||||
switch (attrib->form.writer.block.size) {
|
||||
case 0 : break;
|
||||
case 1 : attrib->form.reader.kind = DW_Form_Block1; break;
|
||||
case 2 : attrib->form.reader.kind = DW_Form_Block2; break;
|
||||
case 4 : attrib->form.reader.kind = DW_Form_Block4; break;
|
||||
default: attrib->form.reader.kind = DW_Form_Block; break;
|
||||
}
|
||||
} break;
|
||||
case DW_WriterFormKind_String: {
|
||||
attrib->form.reader.kind = DW_Form_String;
|
||||
attrib->form.reader.string = attrib->form.writer.string;
|
||||
} break;
|
||||
case DW_WriterFormKind_ExprLoc: {
|
||||
attrib->form.reader.kind = DW_Form_ExprLoc;
|
||||
attrib->form.reader.exprloc = attrib->form.writer.exprloc;
|
||||
} break;
|
||||
case DW_WriterFormKind_Implicit: {
|
||||
attrib->form.reader.kind = DW_Form_ImplicitConst;
|
||||
attrib->form.reader.implicit_const = attrib->form.writer.implicit;
|
||||
} break;
|
||||
default: { InvalidPath; } break;
|
||||
} break;
|
||||
case DW_WriterFormKind_UInt: {
|
||||
attrib->form.reader.kind = DW_Form_UData;
|
||||
attrib->form.reader.udata = attrib->form.writer.uint;
|
||||
} break;
|
||||
case DW_WriterFormKind_Address: {
|
||||
Assert(writer->address_size <= sizeof(attrib->form.writer.address));
|
||||
attrib->form.reader.kind = DW_Form_Addr;
|
||||
attrib->form.reader.addr = push_str8_copy(writer->arena, str8((U8 *)&attrib->form.writer.address, writer->address_size));
|
||||
} break;
|
||||
case DW_WriterFormKind_Ref: {
|
||||
if (attrib->form.writer.ref->info_off == 0) {
|
||||
attrib->form.reader.kind = DW_Form_Ref8;
|
||||
} else {
|
||||
switch (dw_int_enc_from_uint(attrib->form.writer.ref->info_off)) {
|
||||
case DW_IntEnc_Null: break;
|
||||
case DW_IntEnc_1Byte: {
|
||||
attrib->form.reader.kind = DW_Form_Ref1;
|
||||
attrib->form.reader.ref = (U8)attrib->form.writer.ref->info_off;
|
||||
} break;
|
||||
case DW_IntEnc_2Byte: {
|
||||
attrib->form.reader.kind = DW_Form_Ref2;
|
||||
attrib->form.reader.ref = (U16)attrib->form.writer.ref->info_off;
|
||||
} break;
|
||||
case DW_IntEnc_4Byte: {
|
||||
attrib->form.reader.kind = DW_Form_Ref4;
|
||||
attrib->form.reader.ref = (U32)attrib->form.writer.ref->info_off;
|
||||
} break;
|
||||
case DW_IntEnc_LEB128: {
|
||||
attrib->form.reader.kind = DW_Form_RefUData;
|
||||
attrib->form.reader.ref = attrib->form.writer.ref->info_off;
|
||||
} break;
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case DW_WriterFormKind_LinePtr: {
|
||||
attrib->form.reader.kind = DW_Form_SecOffset;
|
||||
attrib->form.reader.sec_offset = attrib->form.writer.line_ptr;
|
||||
} break;
|
||||
case DW_WriterFormKind_MacPtr: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_WriterFormKind_RngListPtr: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_WriterFormKind_Data: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_WriterFormKind_Block: {
|
||||
attrib->form.reader.block = attrib->form.writer.block;
|
||||
switch (attrib->form.writer.block.size) {
|
||||
case 0 : break;
|
||||
case 1 : attrib->form.reader.kind = DW_Form_Block1; break;
|
||||
case 2 : attrib->form.reader.kind = DW_Form_Block2; break;
|
||||
case 4 : attrib->form.reader.kind = DW_Form_Block4; break;
|
||||
default: attrib->form.reader.kind = DW_Form_Block; break;
|
||||
}
|
||||
} break;
|
||||
case DW_WriterFormKind_String: {
|
||||
attrib->form.reader.kind = DW_Form_String;
|
||||
attrib->form.reader.string = attrib->form.writer.string;
|
||||
} break;
|
||||
case DW_WriterFormKind_ExprLoc: {
|
||||
attrib->form.reader.kind = DW_Form_ExprLoc;
|
||||
attrib->form.reader.exprloc = attrib->form.writer.exprloc;
|
||||
} break;
|
||||
case DW_WriterFormKind_Implicit: {
|
||||
attrib->form.reader.kind = DW_Form_ImplicitConst;
|
||||
attrib->form.reader.implicit_const = attrib->form.writer.implicit;
|
||||
} break;
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -833,128 +833,128 @@ dw_writer_emit_tag(DW_Writer *writer, DW_WriterTag *tag)
|
||||
String8List *debug_info = &writer->sections[DW_Section_Info].srl;
|
||||
for EachNode(attrib, DW_WriterAttrib, tag->first_attrib) {
|
||||
switch (attrib->form.reader.kind) {
|
||||
case DW_Form_Addr: {
|
||||
str8_serial_push_string(writer->arena, debug_info, attrib->form.reader.addr);
|
||||
} break;
|
||||
case DW_Form_Block1:
|
||||
case DW_Form_Block2:
|
||||
case DW_Form_Block4: {
|
||||
str8_serial_push_string(writer->arena, debug_info, attrib->form.reader.block);
|
||||
} break;
|
||||
case DW_Form_Data1:
|
||||
case DW_Form_Data2:
|
||||
case DW_Form_Data4:
|
||||
case DW_Form_Data8: {
|
||||
str8_serial_push_string(writer->arena, debug_info, attrib->form.reader.data);
|
||||
} break;
|
||||
case DW_Form_String: {
|
||||
str8_serial_push_cstr(writer->arena, debug_info, attrib->form.reader.string);
|
||||
} break;
|
||||
case DW_Form_Flag: {
|
||||
str8_serial_push_u8(writer->arena, debug_info, attrib->form.reader.flag);
|
||||
} break;
|
||||
case DW_Form_SData: {
|
||||
dw_serial_push_sleb128(writer->arena, debug_info, attrib->form.reader.sdata);
|
||||
} break;
|
||||
case DW_Form_Strp: {
|
||||
dw_serial_push_uint(writer->arena, debug_info, writer->format, attrib->form.reader.sec_offset);
|
||||
} break;
|
||||
case DW_Form_UData: {
|
||||
dw_serial_push_uleb128(writer->arena, debug_info, attrib->form.reader.udata);
|
||||
} break;
|
||||
case DW_Form_RefAddr: {
|
||||
if (writer->version < DW_Version_3) {
|
||||
Assert(writer->address_size <= sizeof(attrib->form.reader.ref));
|
||||
str8_serial_push_string(writer->arena, debug_info, str8((U8 *)&attrib->form.reader.ref, writer->address_size));
|
||||
} else {
|
||||
case DW_Form_Addr: {
|
||||
str8_serial_push_string(writer->arena, debug_info, attrib->form.reader.addr);
|
||||
} break;
|
||||
case DW_Form_Block1:
|
||||
case DW_Form_Block2:
|
||||
case DW_Form_Block4: {
|
||||
str8_serial_push_string(writer->arena, debug_info, attrib->form.reader.block);
|
||||
} break;
|
||||
case DW_Form_Data1:
|
||||
case DW_Form_Data2:
|
||||
case DW_Form_Data4:
|
||||
case DW_Form_Data8: {
|
||||
str8_serial_push_string(writer->arena, debug_info, attrib->form.reader.data);
|
||||
} break;
|
||||
case DW_Form_String: {
|
||||
str8_serial_push_cstr(writer->arena, debug_info, attrib->form.reader.string);
|
||||
} break;
|
||||
case DW_Form_Flag: {
|
||||
str8_serial_push_u8(writer->arena, debug_info, attrib->form.reader.flag);
|
||||
} break;
|
||||
case DW_Form_SData: {
|
||||
dw_serial_push_sleb128(writer->arena, debug_info, attrib->form.reader.sdata);
|
||||
} break;
|
||||
case DW_Form_Strp: {
|
||||
dw_serial_push_uint(writer->arena, debug_info, writer->format, attrib->form.reader.sec_offset);
|
||||
} break;
|
||||
case DW_Form_UData: {
|
||||
dw_serial_push_uleb128(writer->arena, debug_info, attrib->form.reader.udata);
|
||||
} break;
|
||||
case DW_Form_RefAddr: {
|
||||
if (writer->version < DW_Version_3) {
|
||||
Assert(writer->address_size <= sizeof(attrib->form.reader.ref));
|
||||
str8_serial_push_string(writer->arena, debug_info, str8((U8 *)&attrib->form.reader.ref, writer->address_size));
|
||||
} else {
|
||||
dw_serial_push_uint(writer->arena, debug_info, writer->format, attrib->form.reader.ref);
|
||||
}
|
||||
} break;
|
||||
case DW_Form_Ref1: {
|
||||
str8_serial_push_u8(writer->arena, debug_info, (U8)attrib->form.reader.ref);
|
||||
} break;
|
||||
case DW_Form_Ref2: {
|
||||
str8_serial_push_u16(writer->arena, debug_info, (U16)attrib->form.reader.ref);
|
||||
} break;
|
||||
case DW_Form_Ref4: {
|
||||
str8_serial_push_u32(writer->arena, debug_info, (U32)attrib->form.reader.ref);
|
||||
} break;
|
||||
case DW_Form_Ref8: {
|
||||
if (attrib->form.writer.ref->info_off == 0) {
|
||||
// reserve 8 bytes
|
||||
void *value = str8_serial_push_u64(writer->arena, debug_info, 0);
|
||||
|
||||
// push fixup
|
||||
dw_writer_fixup_list_push(writer->arena, &writer->fixups, (DW_WriterFixup){ .tag = attrib->form.writer.ref, .ptr = value });
|
||||
}
|
||||
} break;
|
||||
case DW_Form_RefUData: {
|
||||
dw_serial_push_uleb128(writer->arena, debug_info, attrib->form.reader.ref);
|
||||
} break;
|
||||
case DW_Form_Indirect: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_Form_SecOffset: {
|
||||
dw_serial_push_uint(writer->arena, debug_info, writer->format, attrib->form.reader.sec_offset);
|
||||
} break;
|
||||
case DW_Form_ExprLoc: {
|
||||
dw_serial_push_uleb128(writer->arena, debug_info, attrib->form.reader.exprloc.size);
|
||||
str8_serial_push_string(writer->arena, debug_info, attrib->form.reader.exprloc);
|
||||
} break;
|
||||
case DW_Form_FlagPresent: {
|
||||
} break;
|
||||
case DW_Form_RefSig8: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_Form_Strx:
|
||||
case DW_Form_Addrx:
|
||||
case DW_Form_RngListx:
|
||||
case DW_Form_LocListx: {
|
||||
dw_serial_push_uleb128(writer->arena, debug_info, attrib->form.reader.xval);
|
||||
} break;
|
||||
case DW_Form_RefSup4: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_Form_StrpSup: {
|
||||
dw_serial_push_uint(writer->arena, debug_info, writer->format, attrib->form.reader.strp_sup);
|
||||
} break;
|
||||
case DW_Form_Data16: {
|
||||
str8_serial_push_string(writer->arena, debug_info, attrib->form.reader.data);
|
||||
} break;
|
||||
case DW_Form_LineStrp: {
|
||||
dw_serial_push_uint(writer->arena, debug_info, writer->format, attrib->form.reader.sec_offset);
|
||||
} break;
|
||||
case DW_Form_ImplicitConst: {
|
||||
// value is stored in the abbrev entry
|
||||
} break;
|
||||
case DW_Form_RefSup8: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_Form_Strx1:
|
||||
case DW_Form_Addrx1: {
|
||||
str8_serial_push_u8(writer->arena, debug_info, (U8)attrib->form.reader.xval);
|
||||
} break;
|
||||
case DW_Form_Strx2:
|
||||
case DW_Form_Addrx2: {
|
||||
str8_serial_push_u16(writer->arena, debug_info, (U16)attrib->form.reader.xval);
|
||||
} break;
|
||||
case DW_Form_Strx3:
|
||||
case DW_Form_Addrx3: {
|
||||
str8_serial_push_string(writer->arena, debug_info, str8((U8 *)&attrib->form.reader.xval, 3));
|
||||
} break;
|
||||
case DW_Form_Strx4:
|
||||
case DW_Form_Addrx4: {
|
||||
str8_serial_push_u32(writer->arena, debug_info, (U32)attrib->form.reader.xval);
|
||||
} break;
|
||||
|
||||
case DW_Form_GNU_StrpAlt: {
|
||||
dw_serial_push_uint(writer->arena, debug_info, writer->format, attrib->form.reader.sec_offset);
|
||||
} break;
|
||||
case DW_Form_GNU_RefAlt: {
|
||||
dw_serial_push_uint(writer->arena, debug_info, writer->format, attrib->form.reader.ref);
|
||||
}
|
||||
} break;
|
||||
case DW_Form_Ref1: {
|
||||
str8_serial_push_u8(writer->arena, debug_info, (U8)attrib->form.reader.ref);
|
||||
} break;
|
||||
case DW_Form_Ref2: {
|
||||
str8_serial_push_u16(writer->arena, debug_info, (U16)attrib->form.reader.ref);
|
||||
} break;
|
||||
case DW_Form_Ref4: {
|
||||
str8_serial_push_u32(writer->arena, debug_info, (U32)attrib->form.reader.ref);
|
||||
} break;
|
||||
case DW_Form_Ref8: {
|
||||
if (attrib->form.writer.ref->info_off == 0) {
|
||||
// reserve 8 bytes
|
||||
void *value = str8_serial_push_u64(writer->arena, debug_info, 0);
|
||||
} break;
|
||||
|
||||
// push fixup
|
||||
dw_writer_fixup_list_push(writer->arena, &writer->fixups, (DW_WriterFixup){ .tag = attrib->form.writer.ref, .ptr = value });
|
||||
}
|
||||
} break;
|
||||
case DW_Form_RefUData: {
|
||||
dw_serial_push_uleb128(writer->arena, debug_info, attrib->form.reader.ref);
|
||||
} break;
|
||||
case DW_Form_Indirect: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_Form_SecOffset: {
|
||||
dw_serial_push_uint(writer->arena, debug_info, writer->format, attrib->form.reader.sec_offset);
|
||||
} break;
|
||||
case DW_Form_ExprLoc: {
|
||||
dw_serial_push_uleb128(writer->arena, debug_info, attrib->form.reader.exprloc.size);
|
||||
str8_serial_push_string(writer->arena, debug_info, attrib->form.reader.exprloc);
|
||||
} break;
|
||||
case DW_Form_FlagPresent: {
|
||||
} break;
|
||||
case DW_Form_RefSig8: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_Form_Strx:
|
||||
case DW_Form_Addrx:
|
||||
case DW_Form_RngListx:
|
||||
case DW_Form_LocListx: {
|
||||
dw_serial_push_uleb128(writer->arena, debug_info, attrib->form.reader.xval);
|
||||
} break;
|
||||
case DW_Form_RefSup4: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_Form_StrpSup: {
|
||||
dw_serial_push_uint(writer->arena, debug_info, writer->format, attrib->form.reader.strp_sup);
|
||||
} break;
|
||||
case DW_Form_Data16: {
|
||||
str8_serial_push_string(writer->arena, debug_info, attrib->form.reader.data);
|
||||
} break;
|
||||
case DW_Form_LineStrp: {
|
||||
dw_serial_push_uint(writer->arena, debug_info, writer->format, attrib->form.reader.sec_offset);
|
||||
} break;
|
||||
case DW_Form_ImplicitConst: {
|
||||
// value is stored in the abbrev entry
|
||||
} break;
|
||||
case DW_Form_RefSup8: {
|
||||
NotImplemented;
|
||||
} break;
|
||||
case DW_Form_Strx1:
|
||||
case DW_Form_Addrx1: {
|
||||
str8_serial_push_u8(writer->arena, debug_info, (U8)attrib->form.reader.xval);
|
||||
} break;
|
||||
case DW_Form_Strx2:
|
||||
case DW_Form_Addrx2: {
|
||||
str8_serial_push_u16(writer->arena, debug_info, (U16)attrib->form.reader.xval);
|
||||
} break;
|
||||
case DW_Form_Strx3:
|
||||
case DW_Form_Addrx3: {
|
||||
str8_serial_push_string(writer->arena, debug_info, str8((U8 *)&attrib->form.reader.xval, 3));
|
||||
} break;
|
||||
case DW_Form_Strx4:
|
||||
case DW_Form_Addrx4: {
|
||||
str8_serial_push_u32(writer->arena, debug_info, (U32)attrib->form.reader.xval);
|
||||
} break;
|
||||
|
||||
case DW_Form_GNU_StrpAlt: {
|
||||
dw_serial_push_uint(writer->arena, debug_info, writer->format, attrib->form.reader.sec_offset);
|
||||
} break;
|
||||
case DW_Form_GNU_RefAlt: {
|
||||
dw_serial_push_uint(writer->arena, debug_info, writer->format, attrib->form.reader.ref);
|
||||
} break;
|
||||
|
||||
default: InvalidPath; break;
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1017,7 +1017,7 @@ dw_writer_emit(DW_Writer *writer)
|
||||
for EachNode(file, DW_WriterFile, writer->line.first_file) {
|
||||
String8 path = str8_chop_last_slash(file->path);
|
||||
if (path.size == 0) {
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
if ( ! hash_table_search_string_u64(dir_ht, path, &file->dir_idx)) {
|
||||
// @dir_idx
|
||||
@@ -1253,7 +1253,7 @@ dw_writer_emit_to_obj(DW_Writer *writer, OBJ *obj)
|
||||
dw_writer_emit(writer);
|
||||
|
||||
// push obj sections
|
||||
OBJ_Section *sections[DW_Section_Count] = {0};
|
||||
OBJ_Section *sections[DW_Section_COUNT] = {0};
|
||||
for EachElement(i, writer->sections) {
|
||||
if (writer->sections[i].srl.total_size) {
|
||||
sections[i] = obj_push_section(obj, dw_name_string_from_section_kind(i), OBJ_SectionFlag_Read|OBJ_SectionFlag_Write);
|
||||
|
||||
@@ -240,7 +240,7 @@ typedef struct DW_Writer
|
||||
|
||||
// Emit
|
||||
DW_WriterFixupList fixups;
|
||||
DW_WriterSection sections[DW_Section_Count];
|
||||
DW_WriterSection sections[DW_Section_COUNT];
|
||||
DW_WriterAttribChunkList attrib_chunk_list;
|
||||
DW_WriterTagChunkList tag_chunk_list;
|
||||
} DW_Writer;
|
||||
|
||||
@@ -285,6 +285,7 @@ switch(arch)
|
||||
{
|
||||
default:{}break;
|
||||
case RDI_Arch_X64:{result = 8;}break;
|
||||
case RDI_Arch_X86:{result = 4;}break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -133,6 +133,7 @@ typedef enum RDI_ArchEnum
|
||||
{
|
||||
RDI_Arch_NULL = 0,
|
||||
RDI_Arch_X64 = 1,
|
||||
RDI_Arch_X86 = 2,
|
||||
} RDI_ArchEnum;
|
||||
|
||||
typedef RDI_U8 RDI_RegCode;
|
||||
@@ -578,6 +579,7 @@ X(RDI_U64, idx)\
|
||||
#define RDI_Arch_XList \
|
||||
X(NULL)\
|
||||
X(X64)\
|
||||
X(X86)\
|
||||
|
||||
#define RDI_RegCodeX64_XList \
|
||||
X(nil, 0)\
|
||||
|
||||
+128
-2
@@ -77,7 +77,14 @@ rb_thread_entry_point(void *p)
|
||||
//////////////////////////
|
||||
//- rjf: possibly relative -> absolute path
|
||||
//
|
||||
String8 input_file_path = path_normalized_from_string(arena, str8f(arena, "%S/%S", working_directory, n->string));
|
||||
String8 input_file_path = n->string;
|
||||
{
|
||||
PathStyle path_style = path_style_from_str8(n->string);
|
||||
if(path_style == PathStyle_Relative)
|
||||
{
|
||||
input_file_path = path_normalized_from_string(arena, str8f(arena, "%S/%S", working_directory, n->string));
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
//- rjf: do thin analysis of file
|
||||
@@ -654,6 +661,7 @@ rb_thread_entry_point(void *p)
|
||||
B32 convert_done = 0;
|
||||
RDIM_BakeParams pdb_bake_params = {0};
|
||||
RDIM_BakeParams dwarf_bake_params = {0};
|
||||
RDIM_BakeParams dwarf_bake_params_2 = {0};
|
||||
typedef struct RDIM_BakeParamsNode RDIM_BakeParamsNode;
|
||||
struct RDIM_BakeParamsNode
|
||||
{
|
||||
@@ -756,6 +764,124 @@ rb_thread_entry_point(void *p)
|
||||
convert_params.is_parse_relaxed = 1; // TODO: switch
|
||||
}
|
||||
ProfScope("convert") dwarf_bake_params = d2r_convert(arena, &convert_params);
|
||||
|
||||
// rjf: convert [2]
|
||||
D2R2_ConvertParams convert_params_2 = {0};
|
||||
{
|
||||
B32 got_exe = 0;
|
||||
B32 got_dbg = 0;
|
||||
String8 exe_name = {0};
|
||||
String8 exe_data = {0};
|
||||
ExecutableImageKind exe_kind = ExecutableImageKind_Null;
|
||||
String8 dbg_name = {0};
|
||||
String8 dbg_data = {0};
|
||||
if(!got_exe && !got_dbg)
|
||||
{
|
||||
for(RB_FileNode *n = input_files_from_format_table[RB_FileFormat_PE].first; n != 0; n = n->next)
|
||||
{
|
||||
if(n->v->format_flags & RB_FileFormatFlag_HasDWARF)
|
||||
{
|
||||
got_exe = 1;
|
||||
got_dbg = 1;
|
||||
dbg_name = n->v->path;
|
||||
dbg_data = n->v->data;
|
||||
exe_name = n->v->path;
|
||||
exe_data = n->v->data;
|
||||
exe_kind = ExecutableImageKind_CoffPe;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!got_exe)
|
||||
{
|
||||
for(RB_FileNode *n = input_files_from_format_table[RB_FileFormat_ELF32].first; n != 0; n = n->next)
|
||||
{
|
||||
got_exe = 1;
|
||||
exe_name = n->v->path;
|
||||
exe_data = n->v->data;
|
||||
exe_kind = ExecutableImageKind_Elf32;
|
||||
if(!(n->v->format_flags & RB_FileFormatFlag_HasDWARF))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!got_exe)
|
||||
{
|
||||
for(RB_FileNode *n = input_files_from_format_table[RB_FileFormat_ELF64].first; n != 0; n = n->next)
|
||||
{
|
||||
got_exe = 1;
|
||||
exe_name = n->v->path;
|
||||
exe_data = n->v->data;
|
||||
exe_kind = ExecutableImageKind_Elf64;
|
||||
if(!(n->v->format_flags & RB_FileFormatFlag_HasDWARF))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!got_dbg)
|
||||
{
|
||||
for(RB_FileNode *n = input_files_from_format_table[RB_FileFormat_ELF32].first; n != 0; n = n->next)
|
||||
{
|
||||
if(n->v->format_flags & RB_FileFormatFlag_HasDWARF)
|
||||
{
|
||||
got_dbg = 1;
|
||||
dbg_name = n->v->path;
|
||||
dbg_data = n->v->data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!got_dbg)
|
||||
{
|
||||
for(RB_FileNode *n = input_files_from_format_table[RB_FileFormat_ELF64].first; n != 0; n = n->next)
|
||||
{
|
||||
if(n->v->format_flags & RB_FileFormatFlag_HasDWARF)
|
||||
{
|
||||
got_dbg = 1;
|
||||
dbg_name = n->v->path;
|
||||
dbg_data = n->v->data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch(exe_kind)
|
||||
{
|
||||
default:{}break;
|
||||
case ExecutableImageKind_CoffPe:
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, exe_data);
|
||||
String8 raw_sections = str8_substr(exe_data, pe.section_table_range);
|
||||
COFF_SectionHeader *section_table = str8_deserial_get_raw_ptr(raw_sections, 0, sizeof(COFF_SectionHeader) * pe.section_count);
|
||||
String8 string_table = str8_substr(exe_data, pe.string_table_range);
|
||||
convert_params_2.arch = pe.arch;
|
||||
convert_params_2.base_vaddr = pe.image_base;
|
||||
convert_params_2.raw = dw_input_from_coff_section_table(scratch.arena, exe_data, string_table, pe.section_count, section_table);
|
||||
convert_params_2.path_style = PathStyle_WindowsAbsolute;
|
||||
convert_params_2.binary_sections = c2r_rdi_binary_sections_from_coff_sections(arena, exe_data, string_table, pe.section_count, section_table);
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
case ExecutableImageKind_Elf32:
|
||||
case ExecutableImageKind_Elf64:
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
ELF_Bin bin = elf_bin_from_data(scratch.arena, dbg_data);
|
||||
convert_params_2.arch = arch_from_elf_machine(bin.hdr.e_machine);
|
||||
convert_params_2.base_vaddr = elf_base_addr_from_bin(&bin);
|
||||
convert_params_2.raw = dw_input_from_elf_bin(scratch.arena, dbg_data, &bin);
|
||||
convert_params_2.path_style = PathStyle_UnixAbsolute;
|
||||
convert_params_2.binary_sections = e2r_rdi_binary_sections_from_elf_section_table(arena, bin.shdrs);
|
||||
scratch_end(scratch);
|
||||
} break;
|
||||
}
|
||||
convert_params_2.exe_name = exe_name;
|
||||
convert_params_2.exe_data = exe_data;
|
||||
convert_params_2.subset_flags = subset_flags;
|
||||
convert_params_2.deterministic = cmd_line_has_flag(cmdline, str8_lit("deterministic"));
|
||||
}
|
||||
ProfScope("convert [2]") dwarf_bake_params_2 = d2r2_convert(arena, &convert_params_2);
|
||||
}
|
||||
|
||||
//- rjf: PDB inputs => PDB -> RDI conversion
|
||||
@@ -1277,7 +1403,7 @@ rb_thread_entry_point(void *p)
|
||||
PE_BinInfo pe = {0};
|
||||
ELF_Bin elf = {0};
|
||||
COFF_FileHeaderInfo coff_obj = {0};
|
||||
DW_Input dw = {0};
|
||||
DW_Raw dw = {0};
|
||||
U64 eh_frame_hdr_vaddr = 0;
|
||||
U64 eh_frame_vaddr = 0;
|
||||
String8 eh_frame_hdr = {0};
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "rdi_from_elf/rdi_from_elf.h"
|
||||
#include "rdi_from_pdb/rdi_from_pdb.h"
|
||||
#include "rdi_from_dwarf/rdi_from_dwarf.h"
|
||||
#include "rdi_from_dwarf/rdi_from_dwarf_2.h"
|
||||
#include "radbin/radbin.h"
|
||||
|
||||
//- rjf: [c]
|
||||
@@ -66,6 +67,7 @@
|
||||
#include "rdi_from_elf/rdi_from_elf.c"
|
||||
#include "rdi_from_pdb/rdi_from_pdb.c"
|
||||
#include "rdi_from_dwarf/rdi_from_dwarf.c"
|
||||
#include "rdi_from_dwarf/rdi_from_dwarf_2.c"
|
||||
#include "radbin/radbin.c"
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
@@ -309,6 +309,7 @@ RDI_ArchTable:
|
||||
{
|
||||
{NULL 0 0}
|
||||
{X64 1 8}
|
||||
{X86 2 4}
|
||||
}
|
||||
|
||||
@table(name value)
|
||||
|
||||
@@ -717,7 +717,7 @@ d2r_push_relational_op(Arena *arena, D2R_ValueTypeStack *stack, RDIM_EvalBytecod
|
||||
|
||||
internal RDIM_EvalBytecode
|
||||
d2r_bytecode_from_expression(Arena *arena,
|
||||
DW_Input *input,
|
||||
DW_Raw *input,
|
||||
U64 image_base,
|
||||
Arch arch,
|
||||
DW_ListUnit *addr_lu,
|
||||
@@ -1312,7 +1312,7 @@ d2r_bytecode_from_expression(Arena *arena,
|
||||
}
|
||||
|
||||
internal RDIM_Location
|
||||
d2r_transpile_expression(Arena *arena, DW_Input *input, U64 image_base, Arch arch, DW_ListUnit *addr_lu, DW_CompUnit *cu, String8 expr)
|
||||
d2r_transpile_expression(Arena *arena, DW_Raw *input, U64 image_base, Arch arch, DW_ListUnit *addr_lu, DW_CompUnit *cu, String8 expr)
|
||||
{
|
||||
RDIM_Location loc = {0};
|
||||
if (expr.size) {
|
||||
@@ -1325,7 +1325,7 @@ d2r_transpile_expression(Arena *arena, DW_Input *input, U64 image_base, Arch arc
|
||||
}
|
||||
|
||||
internal RDIM_Location
|
||||
d2r_location_from_attrib(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 image_base, Arch arch, DW_Tag tag, DW_AttribKind kind)
|
||||
d2r_location_from_attrib(Arena *arena, DW_Raw *input, DW_CompUnit *cu, U64 image_base, Arch arch, DW_Tag tag, DW_AttribKind kind)
|
||||
{
|
||||
String8 expr = dw_exprloc_from_tag_attrib_kind(input, cu, tag, kind);
|
||||
RDIM_Location location = d2r_transpile_expression(arena, input, image_base, arch, cu->addr_lu, cu, expr);
|
||||
@@ -1336,7 +1336,7 @@ internal RDIM_LocationCaseList
|
||||
d2r_locset_from_attrib(Arena *arena,
|
||||
RDIM_ScopeChunkList *scopes,
|
||||
RDIM_Scope *curr_scope,
|
||||
DW_Input *input,
|
||||
DW_Raw *input,
|
||||
DW_CompUnit *cu,
|
||||
U64 image_base,
|
||||
Arch arch,
|
||||
@@ -1383,7 +1383,7 @@ internal RDIM_LocationCaseList
|
||||
d2r_var_locset_from_tag(Arena *arena,
|
||||
RDIM_ScopeChunkList *scopes,
|
||||
RDIM_Scope *curr_scope,
|
||||
DW_Input *input,
|
||||
DW_Raw *input,
|
||||
DW_CompUnit *cu,
|
||||
U64 image_base,
|
||||
Arch arch,
|
||||
@@ -1450,7 +1450,7 @@ d2r_type_from_offset(D2R_TypeTable *type_table, U64 info_off)
|
||||
}
|
||||
|
||||
internal RDIM_Type *
|
||||
d2r_type_from_attrib(D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind)
|
||||
d2r_type_from_attrib(D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind)
|
||||
{
|
||||
RDIM_Type *type = type_table->builtin_types[RDI_TypeKind_Void];
|
||||
|
||||
@@ -1559,7 +1559,7 @@ d2r_is_type_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, Arch arch, DW_Tag tag, DW_AttribKind kind)
|
||||
d2r_find_or_convert_type(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, DW_Language cu_lang, Arch arch, DW_Tag tag, DW_AttribKind kind)
|
||||
{
|
||||
RDIM_Type *type = type_table->builtin_types[RDI_TypeKind_Void];
|
||||
|
||||
@@ -1604,7 +1604,7 @@ d2r_find_or_convert_type(Arena *arena, D2R_TypeTable *type_table, DW_Input *inpu
|
||||
internal void
|
||||
d2r_convert_types(Arena *arena,
|
||||
D2R_TypeTable *type_table,
|
||||
DW_Input *input,
|
||||
DW_Raw *input,
|
||||
DW_CompUnit *cu,
|
||||
DW_Language cu_lang,
|
||||
Arch arch,
|
||||
@@ -2088,7 +2088,7 @@ d2r_inline_anonymous_udt_member(Arena *arena, RDIM_UDT *top_udt, U64 base_off, R
|
||||
internal void
|
||||
d2r_convert_udts(Arena *arena,
|
||||
D2R_TypeTable *type_table,
|
||||
DW_Input *input,
|
||||
DW_Raw *input,
|
||||
DW_CompUnit *cu,
|
||||
DW_Language cu_lang,
|
||||
DW_TagNode *root)
|
||||
@@ -2205,7 +2205,7 @@ d2r_push_scope(Arena *arena, RDIM_ScopeChunkList *scopes, U64 scope_chunk_cap, D
|
||||
}
|
||||
|
||||
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)
|
||||
d2r_collect_proc_params(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, DW_TagNode *cur_node, U64 *param_count_out)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
|
||||
@@ -2238,7 +2238,7 @@ d2r_collect_proc_params(Arena *arena, D2R_TypeTable *type_table, DW_Input *input
|
||||
}
|
||||
|
||||
internal Rng1U64List
|
||||
d2r_range_list_from_tag(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 image_base, DW_Tag tag)
|
||||
d2r_range_list_from_tag(Arena *arena, DW_Raw *input, DW_CompUnit *cu, U64 image_base, DW_Tag tag)
|
||||
{
|
||||
// collect non-contiguous range
|
||||
Rng1U64List raw_ranges = dw_rnglist_from_tag_attrib_kind(arena, input, cu, tag, DW_AttribKind_Ranges);
|
||||
@@ -2296,7 +2296,7 @@ d2r_range_list_from_tag(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 imag
|
||||
internal void
|
||||
d2r_convert_symbols(Arena *arena,
|
||||
D2R_TypeTable *type_table,
|
||||
DW_Input *input,
|
||||
DW_Raw *input,
|
||||
DW_CompUnit *cu,
|
||||
DW_Language cu_lang,
|
||||
U64 image_base,
|
||||
@@ -2620,7 +2620,7 @@ d2r_sort_ptrs(void **ptrs, U64 count, int (* is_before)(void *a, void *b))
|
||||
}
|
||||
|
||||
internal D2R_CompUnitContribMap
|
||||
d2r_cu_contrib_map_from_aranges(Arena *arena, DW_Input *input, U64 image_base)
|
||||
d2r_cu_contrib_map_from_aranges(Arena *arena, DW_Raw *input, U64 image_base)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
Temp temp = temp_begin(arena);
|
||||
@@ -2726,7 +2726,7 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
|
||||
|
||||
Arch arch = Arch_Null;
|
||||
U64 image_base = 0;
|
||||
DW_Input input = {0};
|
||||
DW_Raw input = {0};
|
||||
PathStyle path_style = PathStyle_Null;
|
||||
|
||||
switch (params->exe_kind) {
|
||||
|
||||
@@ -207,11 +207,11 @@ internal void d2r_push_relational_op(Arena *arena, D2R_ValueTypeStack *
|
||||
////////////////////////////////
|
||||
//~ Expression Conversion
|
||||
|
||||
internal RDIM_EvalBytecode d2r_bytecode_from_expression(Arena *arena, DW_Input *input, U64 image_base, Arch arch, DW_ListUnit *addr_lu, String8 expr, DW_CompUnit *cu, D2R_ValueType *result_type_out);
|
||||
internal RDIM_Location d2r_transpile_expression (Arena *arena, DW_Input *input, U64 image_base, Arch arch, DW_ListUnit *addr_lu, DW_CompUnit *cu, String8 expr);
|
||||
internal RDIM_Location d2r_location_from_attrib (Arena *arena, 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, 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, DW_Input *input, DW_CompUnit *cu, U64 image_base, Arch arch, DW_Tag tag);
|
||||
internal RDIM_EvalBytecode d2r_bytecode_from_expression(Arena *arena, DW_Raw *input, U64 image_base, Arch arch, DW_ListUnit *addr_lu, String8 expr, DW_CompUnit *cu, D2R_ValueType *result_type_out);
|
||||
internal RDIM_Location d2r_transpile_expression (Arena *arena, DW_Raw *input, U64 image_base, Arch arch, DW_ListUnit *addr_lu, DW_CompUnit *cu, String8 expr);
|
||||
internal RDIM_Location d2r_location_from_attrib (Arena *arena, DW_Raw *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, DW_Raw *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, DW_Raw *input, DW_CompUnit *cu, U64 image_base, Arch arch, DW_Tag tag);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Type Table
|
||||
@@ -219,7 +219,7 @@ internal RDIM_LocationCaseList d2r_var_locset_from_tag (Arena *arena, RDIM_S
|
||||
internal RDIM_Type * d2r_create_type (Arena *arena, D2R_TypeTable *type_table);
|
||||
internal RDIM_Type * d2r_create_type_from_offset(Arena *arena, D2R_TypeTable *type_table, U64 info_off);
|
||||
internal RDIM_Type * d2r_type_from_offset(D2R_TypeTable *type_table, U64 info_off);
|
||||
internal RDIM_Type * d2r_type_from_attrib(D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
internal RDIM_Type * d2r_type_from_attrib(D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Tag Iterator
|
||||
@@ -235,8 +235,8 @@ internal DW_Tag d2r_tag_iterator_parent_tag (D2R_TagIterator *ite
|
||||
|
||||
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, Arch arch, 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, Arch arch, DW_TagNode *root);
|
||||
internal RDIM_Type * d2r_find_or_convert_type(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, DW_Language cu_lang, Arch arch, DW_Tag tag, DW_AttribKind kind);
|
||||
internal void d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, DW_Language cu_lang, Arch arch, DW_TagNode *root);
|
||||
|
||||
////////////////////////////////
|
||||
//~ UDT Conversion
|
||||
@@ -244,15 +244,15 @@ internal void d2r_convert_types(Arena *arena, D2R_TypeTable *type_table,
|
||||
internal B8 d2r_is_udt_tag_converted (DW_TagNode *tag_node);
|
||||
internal void d2r_flag_converted_udt_tag(DW_TagNode *tag_node);
|
||||
internal void d2r_inline_anonymous_udt_member(Arena *arena, RDIM_UDT *top_udt, U64 base_off, RDIM_UDT *udt);
|
||||
internal void d2r_convert_udts(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Language cu_lang, DW_TagNode *root);
|
||||
internal void d2r_convert_udts(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, DW_Language cu_lang, DW_TagNode *root);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Symbol Conversion
|
||||
|
||||
internal RDIM_Scope * d2r_push_scope (Arena *arena, RDIM_ScopeChunkList *scopes, U64 scope_chunk_cap, D2R_TagFrame *tag_stack, Rng1U64List ranges);
|
||||
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 Rng1U64List d2r_range_list_from_tag(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 image_base, DW_Tag tag);
|
||||
internal void d2r_convert_symbols(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Language cu_lang, U64 image_base, Arch arch, DW_TagNode *root, RDIM_Unit *unit_rdi);
|
||||
internal RDIM_Type ** d2r_collect_proc_params(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, DW_TagNode *cur_node, U64 *param_count_out);
|
||||
internal Rng1U64List d2r_range_list_from_tag(Arena *arena, DW_Raw *input, DW_CompUnit *cu, U64 image_base, DW_Tag tag);
|
||||
internal void d2r_convert_symbols(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, DW_Language cu_lang, U64 image_base, Arch arch, DW_TagNode *root, RDIM_Unit *unit_rdi);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Line Table Conversion
|
||||
@@ -263,7 +263,7 @@ internal void d2r_sort_ptrs(void **ptrs, U64 count, int (* is_before)(void *a, v
|
||||
////////////////////////////////
|
||||
//~ Contrib Map
|
||||
|
||||
internal D2R_CompUnitContribMap d2r_cu_contrib_map_from_aranges(Arena *arena, DW_Input *input, U64 image_base);
|
||||
internal D2R_CompUnitContribMap d2r_cu_contrib_map_from_aranges(Arena *arena, DW_Raw *input, U64 image_base);
|
||||
internal RDIM_Rng1U64ChunkList d2r_voff_ranges_from_cu_info_off(D2R_CompUnitContribMap map, U64 info_off);
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
@@ -299,9 +299,19 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
||||
lane_sync();
|
||||
|
||||
////////////////////////////
|
||||
//- rjf: parse each unit's line table
|
||||
//- rjf: parse each unit's line table header
|
||||
//
|
||||
DW2_LineTableHeader *unit_line_table_headers = 0;
|
||||
U64 *unit_line_table_header_sizes = 0;
|
||||
ProfScope("parse each unit's line table header")
|
||||
{
|
||||
if(lane_idx() == 0)
|
||||
{
|
||||
unit_line_table_headers = push_array(scratch.arena, DW2_LineTableHeader, unit_count);
|
||||
unit_line_table_header_sizes = push_array(scratch.arena, U64, unit_count);
|
||||
}
|
||||
lane_sync_u64(&unit_line_table_headers, 0);
|
||||
lane_sync_u64(&unit_line_table_header_sizes, 0);
|
||||
U64 unit_take_idx = 0;
|
||||
U64 *unit_take_idx_ptr = &unit_take_idx;
|
||||
lane_sync_u64(&unit_take_idx_ptr, 0);
|
||||
@@ -316,13 +326,173 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
|
||||
DW2_Tag *unit_root_tag = &unit_root_tags[unit_idx];
|
||||
DW2_Attrib *stmt_list = dw2_attrib_from_kind(unit_root_tag, DW_AttribKind_StmtList);
|
||||
U64 line_info_off = stmt_list->val.u128.u64[0];
|
||||
DW2_LineTableHeader line_table_header = {0};
|
||||
String8 line_info_data = raw->sec[DW_Section_Line].data;
|
||||
dw2_read_line_table_header(scratch.arena, ctx, line_info_data, line_info_off, &line_table_header);
|
||||
unit_line_table_header_sizes[unit_idx] = dw2_read_line_table_header(scratch.arena, ctx, line_info_data, line_info_off, &unit_line_table_headers[unit_idx]);
|
||||
}
|
||||
}
|
||||
lane_sync();
|
||||
|
||||
////////////////////////////
|
||||
//- rjf: deduplicate all source files
|
||||
//
|
||||
typedef struct UnitSrcFileMap UnitSrcFileMap;
|
||||
struct UnitSrcFileMap
|
||||
{
|
||||
RDIM_SrcFile **v;
|
||||
};
|
||||
RDIM_SrcFileChunkList *all_src_files = 0;
|
||||
UnitSrcFileMap *unit_src_file_maps = 0;
|
||||
ProfScope("deduplicate all source files") if(lane_idx() == 0)
|
||||
{
|
||||
Temp scratch2 = scratch_begin(&scratch.arena, 1);
|
||||
|
||||
//- rjf: count all files in all units
|
||||
U64 total_file_count = 0;
|
||||
for EachIndex(unit_idx, unit_count)
|
||||
{
|
||||
total_file_count += unit_line_table_headers[unit_idx].files.count;
|
||||
}
|
||||
|
||||
//- rjf: set up path -> src file map
|
||||
typedef struct SrcFileNode SrcFileNode;
|
||||
struct SrcFileNode
|
||||
{
|
||||
SrcFileNode *next;
|
||||
String8 full_path;
|
||||
RDIM_SrcFile *src_file;
|
||||
};
|
||||
all_src_files = push_array(scratch.arena, RDIM_SrcFileChunkList, 1);
|
||||
U64 slots_count = 1 + (total_file_count * 3) / 4;
|
||||
SrcFileNode **slots = push_array(scratch2.arena, SrcFileNode *, slots_count);
|
||||
|
||||
//- rjf: set up unit -> src file maps
|
||||
unit_src_file_maps = push_array(scratch.arena, UnitSrcFileMap, unit_count);
|
||||
for EachIndex(unit_idx, unit_count)
|
||||
{
|
||||
unit_src_file_maps[unit_idx].v = push_array(scratch.arena, RDIM_SrcFile *, unit_line_table_headers[unit_idx].files.count);
|
||||
}
|
||||
|
||||
//- rjf: build path -> src file map
|
||||
for EachIndex(unit_idx, unit_count)
|
||||
{
|
||||
DW2_LineTableHeader *hdr = &unit_line_table_headers[unit_idx];
|
||||
for EachIndex(file_idx, hdr->files.count)
|
||||
{
|
||||
DW2_LineTableFile *f = &hdr->files.v[file_idx];
|
||||
DW2_LineTableFile *dir = &hdr->dirs.v[f->dir_idx];
|
||||
String8 full_file_path = str8f(scratch2.arena, "%S/%S", dir->file_name, f->file_name);
|
||||
U64 hash = u64_hash_from_str8(full_file_path);
|
||||
U64 slot_idx = hash%slots_count;
|
||||
SrcFileNode *node = 0;
|
||||
for(SrcFileNode *n = slots[slot_idx]; n != 0; n = n->next)
|
||||
{
|
||||
if(str8_match(n->full_path, full_file_path, 0))
|
||||
{
|
||||
node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!node)
|
||||
{
|
||||
node = push_array(scratch2.arena, SrcFileNode, 1);
|
||||
node->full_path = full_file_path;
|
||||
node->src_file = rdim_src_file_chunk_list_push(arena, all_src_files, slots_count);
|
||||
node->src_file->path = str8_copy(arena, full_file_path);
|
||||
if(f->flags & DW2_LineTableFileFlag_HasMD5)
|
||||
{
|
||||
node->src_file->checksum_kind = RDI_ChecksumKind_MD5;
|
||||
node->src_file->checksum = str8_copy(arena, str8_struct(&f->md5));
|
||||
}
|
||||
else if(f->flags & DW2_LineTableFileFlag_HasModifyTime)
|
||||
{
|
||||
node->src_file->checksum_kind = RDI_ChecksumKind_Timestamp;
|
||||
node->src_file->checksum = str8_copy(arena, str8_struct(&f->modify_time));
|
||||
}
|
||||
}
|
||||
unit_src_file_maps[unit_idx].v[file_idx] = node->src_file;
|
||||
}
|
||||
}
|
||||
scratch_end(scratch2);
|
||||
}
|
||||
lane_sync_u64(&all_src_files, 0);
|
||||
|
||||
////////////////////////////
|
||||
//- rjf: parse each unit's line info; produce line tables
|
||||
//
|
||||
RDIM_LineTableChunkList *all_line_tables = 0;
|
||||
RDIM_LineTable **unit_line_tables = 0;
|
||||
ProfScope("parse each unit's line info; produce line tables")
|
||||
{
|
||||
//- rjf: prep all per-unit line tables
|
||||
if(lane_idx() == 0)
|
||||
{
|
||||
all_line_tables = push_array(scratch.arena, RDIM_LineTableChunkList, 1);
|
||||
unit_line_tables = push_array(scratch.arena, RDIM_LineTable *, unit_count);
|
||||
for EachIndex(unit_idx, unit_count)
|
||||
{
|
||||
unit_line_tables[unit_idx] = rdim_line_table_chunk_list_push(arena, all_line_tables, unit_count);
|
||||
}
|
||||
}
|
||||
lane_sync_u64(&all_line_tables, 0);
|
||||
lane_sync_u64(&unit_line_tables, 0);
|
||||
|
||||
U64 unit_take_idx = 0;
|
||||
U64 *unit_take_idx_ptr = &unit_take_idx;
|
||||
lane_sync_u64(&unit_take_idx_ptr, 0);
|
||||
for(;;)
|
||||
{
|
||||
//- rjf: take unit
|
||||
U64 unit_idx = ins_atomic_u64_inc_eval(unit_take_idx_ptr) - 1;
|
||||
if(unit_idx >= unit_count)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//- rjf: unpack unit info
|
||||
DW2_LineTableHeader *line_table_header = &unit_line_table_headers[unit_idx];
|
||||
RDIM_LineTable *dst_line_table = unit_line_tables[unit_idx];
|
||||
DW2_Tag *unit_root_tag = &unit_root_tags[unit_idx];
|
||||
DW2_Attrib *stmt_list = dw2_attrib_from_kind(unit_root_tag, DW_AttribKind_StmtList);
|
||||
U64 line_info_off = stmt_list->val.u128.u64[0];
|
||||
String8 all_line_info_data = raw->sec[DW_Section_Line].data;
|
||||
String8 unit_line_table_data = str8_substr(all_line_info_data, r1u64(line_info_off + unit_line_table_header_sizes[unit_idx], line_info_off + line_table_header->unit_length));
|
||||
|
||||
//- rjf: set up vm registers
|
||||
DW2_LineVMRegs vm_regs = {0};
|
||||
{
|
||||
vm_regs.file_index = 1;
|
||||
vm_regs.line = 1;
|
||||
vm_regs.is_stmt = line_table_header->default_is_stmt;
|
||||
}
|
||||
|
||||
//- rjf: run the line opcode program
|
||||
for(U64 off = 0, next_off = 0; off < unit_line_table_data.size; off = next_off)
|
||||
{
|
||||
next_off = unit_line_table_data.size;
|
||||
|
||||
//- rjf: read next opcode
|
||||
U8 opcode = 0;
|
||||
str8_deserial_read_struct(unit_line_table_data, off, &opcode);
|
||||
|
||||
//- rjf: apply "special opcodes" (DWARF v5 6.2.5.1)
|
||||
if(opcode >= line_table_header->opcode_base)
|
||||
{
|
||||
U32 adjusted_opcode = (U32)(opcode - line_table_header->opcode_base);
|
||||
U32 op_advance = adjusted_opcode / line_table_header->line_range;
|
||||
S64 line_advance = (S64)line_table_header->line_base + (S64)adjusted_opcode%(S64)line_table_header->line_range;
|
||||
U64 addr_advance = line_table_header->min_inst_length + (vm_regs.vliw_op_index + op_advance) / line_table_header->max_ops_per_inst;
|
||||
vm_regs.address += addr_advance;
|
||||
vm_regs.vliw_op_index = (vm_regs.vliw_op_index + op_advance) % line_table_header->max_ops_per_inst;
|
||||
vm_regs.line += line_advance;
|
||||
vm_regs.basic_block = 0;
|
||||
vm_regs.prologue_end = 0;
|
||||
vm_regs.epilogue_begin = 0;
|
||||
vm_regs.discriminator = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
//- rjf: fill result
|
||||
//
|
||||
|
||||
@@ -16,6 +16,7 @@ struct D2R2_ConvertParams
|
||||
U64 base_vaddr;
|
||||
RDIM_BinarySectionList binary_sections;
|
||||
DW_Raw raw;
|
||||
PathStyle path_style;
|
||||
RDIM_SubsetFlags subset_flags;
|
||||
B32 deterministic;
|
||||
};
|
||||
|
||||
@@ -103,7 +103,7 @@ dwt_tags_must_match(DW_WriterTag *writer_tag, DW_TagNode *reader_tag)
|
||||
return is_match;
|
||||
}
|
||||
|
||||
internal DW_Input
|
||||
internal DW_Raw
|
||||
dw_input_from_writer(Arena *arena, DW_Writer *writer)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
@@ -127,7 +127,7 @@ dw_input_from_writer(Arena *arena, DW_Writer *writer)
|
||||
PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, exe);
|
||||
COFF_SectionHeader *section_table = (COFF_SectionHeader *)(exe.str + pe.section_table_range.min);
|
||||
String8 string_table = str8_substr(exe, pe.string_table_range);
|
||||
DW_Input input = dw_input_from_coff_section_table(arena, exe, string_table, pe.section_count, section_table);
|
||||
DW_Raw input = dw_input_from_coff_section_table(arena, exe, string_table, pe.section_count, section_table);
|
||||
|
||||
obj_release(&obj);
|
||||
scratch_end(scratch);
|
||||
@@ -141,7 +141,7 @@ TEST(dwarf_32bit)
|
||||
dw_writer_push_attrib_string(writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER"));
|
||||
dw_writer_tag_end(writer);
|
||||
|
||||
DW_Input input = dw_input_from_writer(arena, writer);
|
||||
DW_Raw input = dw_input_from_writer(arena, writer);
|
||||
|
||||
for EachElement(sec_idx, input.sec) {
|
||||
if (sec_idx == DW_Section_Abbrev) continue;
|
||||
@@ -169,7 +169,7 @@ TEST(dwarf_64bit)
|
||||
dw_writer_push_attrib_string(writer, DW_AttribKind_Producer, str8_lit("RAD DWARF WRITER"));
|
||||
dw_writer_tag_end(writer);
|
||||
|
||||
DW_Input input = dw_input_from_writer(arena, writer);
|
||||
DW_Raw input = dw_input_from_writer(arena, writer);
|
||||
|
||||
for EachElement(sec_idx, input.sec) {
|
||||
if (sec_idx == DW_Section_Abbrev) continue;
|
||||
@@ -235,7 +235,7 @@ TEST(dwarf_line_opcodes)
|
||||
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNE_set_discriminator(2));
|
||||
dw_line_inst_list_push(writer->arena, &writer->line.line_insts, DW_LNE_end_sequence());
|
||||
|
||||
DW_Input input = dw_input_from_writer(arena, writer);
|
||||
DW_Raw input = dw_input_from_writer(arena, writer);
|
||||
Rng1U64Array cu_ranges = dw_unit_ranges_from_data_arr(arena, input.sec[DW_Section_Info].data);
|
||||
DW_CompUnit cu = dw_cu_from_info_off(arena, &input, (DW_ListUnitInput){0}, cu_ranges.v[0].min, 0);
|
||||
DW_LineVM *line_vm = dw_line_vm_init(&input, &cu);
|
||||
@@ -411,7 +411,7 @@ TEST(dwarf_line_emit)
|
||||
}
|
||||
}
|
||||
|
||||
DW_Input input = dw_input_from_writer(arena, writer);
|
||||
DW_Raw input = dw_input_from_writer(arena, writer);
|
||||
Rng1U64Array cu_ranges = dw_unit_ranges_from_data_arr(arena, input.sec[DW_Section_Info].data);
|
||||
DW_CompUnit cu = dw_cu_from_info_off(arena, &input, (DW_ListUnitInput){0}, cu_ranges.v[0].min, 0);
|
||||
DW_LineVM *line_vm = dw_line_vm_init(&input, &cu);
|
||||
@@ -621,7 +621,7 @@ TEST(dwarf_writer)
|
||||
dw_writer_tag_end(writer);
|
||||
}
|
||||
|
||||
DW_Input input = dw_input_from_writer(arena, writer);
|
||||
DW_Raw input = dw_input_from_writer(arena, writer);
|
||||
DW_ListUnitInput lu_input = dw_list_unit_input_from_input(arena, &input);
|
||||
DW_CompUnit cu = dw_cu_from_info_off(arena, &input, lu_input, 0, 1);
|
||||
DW_TagTree tag_tree = dw_tag_tree_from_cu(arena, &input, &cu);
|
||||
|
||||
Reference in New Issue
Block a user