From 7cafde33768b5e1790c01573a15e3f6c2306486d Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Thu, 13 Nov 2025 10:53:29 -0800 Subject: [PATCH] revert DWARF changes to commit bda3a7137924acfcb9a564b7819a33fd8765f3fb --- src/base/base_strings.c | 70 +- src/base/base_strings.h | 2 - src/ctrl/ctrl_core.c | 2 +- src/dwarf/dwarf.c | 146 ++- src/dwarf/dwarf.h | 14 +- src/dwarf/dwarf_coff.c | 15 +- src/dwarf/dwarf_coff.h | 3 +- src/dwarf/dwarf_dump.c | 479 ++++----- src/dwarf/dwarf_dump.h | 22 +- src/dwarf/dwarf_elf.c | 7 +- src/dwarf/dwarf_elf.h | 2 +- src/dwarf/dwarf_help.h | 1 + src/dwarf/dwarf_inc.c | 1 - src/dwarf/dwarf_inc.h | 1 - src/dwarf/dwarf_parse.c | 1449 +++++++++++++++------------ src/dwarf/dwarf_parse.h | 273 +++-- src/dwarf/eh_dump.h | 5 +- src/dwarf/eh_frame.c | 272 ++--- src/dwarf/eh_frame.h | 7 +- src/radbin/radbin.c | 163 +-- src/radbin/radbin_main.c | 2 - src/rdi_from_dwarf/rdi_from_dwarf.c | 1321 +++++++++++------------- src/rdi_from_dwarf/rdi_from_dwarf.h | 88 +- src/rdi_from_elf/rdi_from_elf.c | 29 +- src/rdi_from_elf/rdi_from_elf.h | 3 +- src/rdi_make/rdi_make_local.c | 29 + src/rdi_make/rdi_make_local.h | 1 + 27 files changed, 2103 insertions(+), 2304 deletions(-) diff --git a/src/base/base_strings.c b/src/base/base_strings.c index 8c3ab290..0728bedf 100644 --- a/src/base/base_strings.c +++ b/src/base/base_strings.c @@ -2769,14 +2769,14 @@ str8_serial_push_string(Arena *arena, String8List *srl, String8 str){ internal U64 str8_deserial_read(String8 string, U64 off, void *read_dst, U64 read_size, U64 granularity) { - U64 bytes_left = string.size - Min(off, string.size); + U64 bytes_left = string.size-Min(off, string.size); U64 actually_readable_size = Min(bytes_left, read_size); U64 legally_readable_size = actually_readable_size - actually_readable_size%granularity; if(legally_readable_size > 0) { MemoryCopy(read_dst, string.str+off, legally_readable_size); } - return actually_readable_size; + return legally_readable_size; } internal U64 @@ -2838,72 +2838,6 @@ str8_deserial_read_block(String8 string, U64 off, U64 size, String8 *block_out) return block_out->size; } -internal U64 -str8_deserial_read_uleb128(String8 string, U64 off, U64 *value_out) -{ - U64 value = 0; - U64 shift = 0; - U64 cursor = off; - for(;;) - { - U8 byte = 0; - U64 bytes_read = str8_deserial_read_struct(string, cursor, &byte); - if(bytes_read != sizeof(byte)) - { - break; - } - U8 val = byte & 0x7fu; - value |= ((U64)val) << shift; - cursor += bytes_read; - shift += 7u; - if((byte & 0x80u) == 0) - { - break; - } - } - if(value_out != 0) - { - *value_out = value; - } - U64 bytes_read = cursor - off; - return bytes_read; -} - -internal U64 -str8_deserial_read_sleb128(String8 string, U64 off, S64 *value_out) -{ - U64 value = 0; - U64 shift = 0; - U64 cursor = off; - for(;;) - { - U8 byte = 0; - U64 bytes_read = str8_deserial_read_struct(string, cursor, &byte); - if(bytes_read != sizeof(byte)) - { - break; - } - U8 val = byte & 0x7fu; - value |= ((U64)val) << shift; - cursor += bytes_read; - shift += 7u; - if((byte & 0x80u) == 0) - { - if(shift < sizeof(value) * 8 && (byte & 0x40u) != 0) - { - value |= -(S64)(1ull << shift); - } - break; - } - } - if(value_out != 0) - { - *value_out = value; - } - U64 bytes_read = cursor - off; - return bytes_read; -} - //////////////////////////////// internal int diff --git a/src/base/base_strings.h b/src/base/base_strings.h index 65c17f1d..37c7acb2 100644 --- a/src/base/base_strings.h +++ b/src/base/base_strings.h @@ -444,8 +444,6 @@ internal U64 str8_deserial_read_windows_utf16_string16(String8 string, U64 of internal U64 str8_deserial_read_block(String8 string, U64 off, U64 size, String8 *block_out); #define str8_deserial_read_array(string, off, ptr, count) str8_deserial_read((string), (off), (ptr), sizeof(*(ptr))*(count), sizeof(*(ptr))) #define str8_deserial_read_struct(string, off, ptr) str8_deserial_read_array(string, off, ptr, 1) -internal U64 str8_deserial_read_uleb128(String8 string, U64 off, U64 *value_out); -internal U64 str8_deserial_read_sleb128(String8 string, U64 off, S64 *value_out); //////////////////////////////// //~ rjf: Basic String Hashes diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 1faead8d..779f4761 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1978,7 +1978,7 @@ ctrl_unwind_step__dwarf(CTRL_Handle process_handle, CTRL_Handle module_handle, A // compute CIE address U64 cie_delta_off = fde_format == DW_Format_32Bit ? 4 : 12; U64 cie_delta = 0; - U64 cie_delta_size = dw_str8_deserial_read_fmt_uint(fde_data, cie_delta_off, fde_format, &cie_delta); + U64 cie_delta_size = str8_deserial_read_dwarf_uint(fde_data, cie_delta_off, fde_format, &cie_delta); if (cie_delta_size == 0) { goto eh_parse_exit; } cie_addr = (fde_addr + cie_delta_off) - cie_delta; } diff --git a/src/dwarf/dwarf.c b/src/dwarf/dwarf.c index a010a320..2b2f3966 100644 --- a/src/dwarf/dwarf.c +++ b/src/dwarf/dwarf.c @@ -73,10 +73,10 @@ internal U64 dw_reg_count_from_arch(Arch arch) { switch (arch) { - default: { NotImplemented; } // fall-through - case Arch_Null: return 0; - case Arch_x86: return DW_RegX86_Last; - case Arch_x64: return DW_RegX64_Last; + default: { NotImplemented; } // fall-through + case Arch_Null: return 0; + case Arch_x86: return DW_RegX86_Last; + case Arch_x64: return DW_RegX64_Last; } } @@ -98,10 +98,10 @@ internal U64 dw_sp_from_arch(Arch arch) { switch (arch) { - default: NotImplemented; - case Arch_Null: return 0; - case Arch_x86: return DW_RegX86_Esp; - case Arch_x64: return DW_RegX64_Rsp; + default: NotImplemented; + case Arch_Null: return 0; + case Arch_x86: return DW_RegX86_Esp; + case Arch_x64: return DW_RegX64_Rsp; } } @@ -194,7 +194,7 @@ dw_attrib_class_from_attrib_mips(DW_AttribKind k) } internal DW_AttribClass -dw_attrib_class_from_kind(DW_Version ver, DW_Ext ext, DW_AttribKind k) +dw_attrib_class_from_attrib(DW_Version ver, DW_Ext ext, DW_AttribKind k) { DW_AttribClass result = DW_AttribClass_Null; @@ -278,64 +278,58 @@ internal B32 dw_are_attrib_class_and_form_kind_compatible(DW_Version ver, DW_AttribClass attrib_class, DW_FormKind form_kind) { DW_AttribClass compat_flags = dw_attrib_class_from_form_kind(ver, form_kind); - B32 are_compat = (attrib_class & compat_flags) != 0; + B32 are_compat = (attrib_class & compat_flags) != 0; return are_compat; } internal String8 dw_name_string_from_section_kind(DW_SectionKind k) { - String8 result = {0}; - switch(k) - { -#define X(_N,_L,_M,_D) case DW_Section_##_N:{result = str8_lit(_L);}break; + switch (k) { +#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_L); DW_SectionKind_XList(X) #undef X } - return result; + return str8_zero(); } internal String8 dw_mach_name_string_from_section_kind(DW_SectionKind k) { - String8 result = {0}; - switch(k) - { -#define X(_N,_L,_M,_D) case DW_Section_##_N:{result = str8_lit(_M);}break; + switch (k) { +#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_M); DW_SectionKind_XList(X) #undef X } - return result; + return str8_zero(); } internal String8 dw_dwo_name_string_from_section_kind(DW_SectionKind k) { - String8 result = {0}; - switch(k) - { -#define X(_N,_L,_M,_D) case DW_Section_##_N:{result = str8_lit(_D);}break; + switch (k) { +#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_D); DW_SectionKind_XList(X) #undef X } - return result; + return str8_zero(); } internal U64 dw_size_from_format(DW_Format format) { U64 result = 0; - switch(format) - { - default:{}break; + switch (format) { + case DW_Format_Null: break; case DW_Format_32Bit: result = 4; break; case DW_Format_64Bit: result = 8; break; + default: InvalidPath; break; } return result; } internal DW_AttribClass -dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, DW_AttribKind attrib_kind, DW_FormKind form_kind) +dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, B32 relaxed, DW_AttribKind attrib_kind, DW_FormKind form_kind) { // NOTE(rjf): DWARF's spec specifies two mappings: // (DW_AttribKind) => List(DW_AttribClass) @@ -344,12 +338,16 @@ dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, DW_AttribKind attrib_kind // This function's purpose is to find the overlapping class between an // DW_AttribKind and DW_FormKind. - DW_AttribClass attrib_class = dw_attrib_class_from_kind(ver, ext, attrib_kind); + DW_AttribClass attrib_class = dw_attrib_class_from_attrib(ver, ext, attrib_kind); DW_AttribClass form_class = dw_attrib_class_from_form_kind(ver, form_kind); - if(attrib_class == DW_AttribClass_Null || form_class == DW_AttribClass_Null) + + if(relaxed) { - attrib_class = dw_attrib_class_from_kind(DW_Version_Last, ext, attrib_kind); - form_class = dw_attrib_class_from_form_kind(DW_Version_Last, form_kind); + if(attrib_class == DW_AttribClass_Null || form_class == DW_AttribClass_Null) + { + attrib_class = dw_attrib_class_from_attrib(DW_Version_Last, ext, attrib_kind); + form_class = dw_attrib_class_from_form_kind(DW_Version_Last, form_kind); + } } DW_AttribClass result = DW_AttribClass_Null; @@ -430,11 +428,11 @@ dw_operand_count_from_expr_op(DW_ExprOp op) switch (op) { #define X(_N, _ID, _OPER_COUNT, _POP_COUNT, _PUSH_COUNT) case _ID: return _OPER_COUNT; DW_Expr_V3_XList(X) - DW_Expr_V4_XList(X) - DW_Expr_V5_XList(X) - DW_Expr_GNU_XList(X) + DW_Expr_V4_XList(X) + DW_Expr_V5_XList(X) + DW_Expr_GNU_XList(X) #undef X - default: { NotImplemented; } break; + default: { NotImplemented; } break; } return 0; } @@ -445,11 +443,11 @@ dw_pop_count_from_expr_op(DW_ExprOp op) switch (op) { #define X(_N, _ID, _OPER_COUNT, _POP_COUNT, _PUSH_COUNT) case _ID: return _POP_COUNT; DW_Expr_V3_XList(X) - DW_Expr_V4_XList(X) - DW_Expr_V5_XList(X) - DW_Expr_GNU_XList(X) + DW_Expr_V4_XList(X) + DW_Expr_V5_XList(X) + DW_Expr_GNU_XList(X) #undef X - default: { NotImplemented; } break; + default: { NotImplemented; } break; } return 0; } @@ -460,11 +458,11 @@ dw_push_count_from_expr_op(DW_ExprOp op) switch (op) { #define X(_N, _ID, _OPER_COUNT, _POP_COUNT, _PUSH_COUNT) case _ID: return _PUSH_COUNT; DW_Expr_V3_XList(X) - DW_Expr_V4_XList(X) - DW_Expr_V5_XList(X) - DW_Expr_GNU_XList(X) + DW_Expr_V4_XList(X) + DW_Expr_V5_XList(X) + DW_Expr_GNU_XList(X) #undef X - default: { NotImplemented; } break; + default: { NotImplemented; } break; } return 0; } @@ -476,7 +474,7 @@ dw_operand_count_from_cfa_opcode(DW_CFA_Opcode opcode) #define X(_N, _ID, ...) case _ID: { local_persist DW_CFA_OperandType t[] = { DW_CFA_OperandType_Null, __VA_ARGS__ }; return ArrayCount(t)-1; } DW_CFA_Kind_XList(X) #undef X - default: { NotImplemented; } break; + default: { NotImplemented; } break; } return 0; } @@ -486,21 +484,21 @@ dw_is_cfa_expr_opcode_invalid(DW_ExprOp opcode) { B32 is_invalid = 0; switch (opcode) { - case DW_ExprOp_Addrx: - case DW_ExprOp_Call2: - case DW_ExprOp_Call4: - case DW_ExprOp_CallRef: - case DW_ExprOp_ConstType: - case DW_ExprOp_Constx: - case DW_ExprOp_Convert: - case DW_ExprOp_DerefType: - case DW_ExprOp_RegvalType: - case DW_ExprOp_Reinterpret: - case DW_ExprOp_PushObjectAddress: - case DW_ExprOp_CallFrameCfa: { - is_invalid = 1; - } break; - default: break; + case DW_ExprOp_Addrx: + case DW_ExprOp_Call2: + case DW_ExprOp_Call4: + case DW_ExprOp_CallRef: + case DW_ExprOp_ConstType: + case DW_ExprOp_Constx: + case DW_ExprOp_Convert: + case DW_ExprOp_DerefType: + case DW_ExprOp_RegvalType: + case DW_ExprOp_Reinterpret: + case DW_ExprOp_PushObjectAddress: + case DW_ExprOp_CallFrameCfa: { + is_invalid = 1; + } break; + default: break; } return is_invalid; } @@ -510,14 +508,14 @@ dw_is_new_row_cfa_opcode(DW_CFA_Opcode opcode) { B32 is_new_row_op = 0; switch (opcode) { - case DW_CFA_SetLoc: - case DW_CFA_AdvanceLoc: - case DW_CFA_AdvanceLoc1: - case DW_CFA_AdvanceLoc2: - case DW_CFA_AdvanceLoc4: { - is_new_row_op = 1; - } break; - default: break; + case DW_CFA_SetLoc: + case DW_CFA_AdvanceLoc: + case DW_CFA_AdvanceLoc1: + case DW_CFA_AdvanceLoc2: + case DW_CFA_AdvanceLoc4: { + is_new_row_op = 1; + } break; + default: break; } return is_new_row_op; } @@ -529,7 +527,7 @@ dw_operand_types_from_cfa_op(DW_CFA_Opcode opcode) #define X(_N, _ID, ...) case _ID: { local_persist DW_CFA_OperandType t[] = { DW_CFA_OperandType_Null, __VA_ARGS__ }; return &t[0] + 1; } DW_CFA_Kind_XList(X) #undef X - default: { NotImplemented; } break; + default: { NotImplemented; } break; } return 0; } @@ -541,9 +539,9 @@ internal String8 dw_string_from_format(DW_Format format) { switch (format) { - case DW_Format_Null: return str8_zero(); - case DW_Format_32Bit: return str8_lit("DWARF32"); - case DW_Format_64Bit: return str8_lit("DWARF64"); + case DW_Format_Null: return str8_zero(); + case DW_Format_32Bit: return str8_lit("DWARF32"); + case DW_Format_64Bit: return str8_lit("DWARF64"); } return str8_zero(); } @@ -826,7 +824,7 @@ dw_string_from_cfa_opcode(DW_CFA_Opcode opcode) #define X(_NAME, _ID, ...) case _ID: return str8_lit(Stringify(_NAME)); DW_CFA_Kind_XList(X) #undef X - default: InvalidPath; break; + default: InvalidPath; break; } return str8_zero(); } diff --git a/src/dwarf/dwarf.h b/src/dwarf/dwarf.h index 7239aefb..89e9b099 100644 --- a/src/dwarf/dwarf.h +++ b/src/dwarf/dwarf.h @@ -478,7 +478,7 @@ X(GNU_RefAlt, DW_AttribClass_Undefined) \ X(GNU_StrpAlt, DW_AttribClass_String) typedef U64 DW_FormKind; -typedef enum DW_FormKindEnum +typedef enum DW_FormEnum { DW_Form_Null, #define X(_N, _ID) DW_Form_##_N = _ID, @@ -487,7 +487,7 @@ typedef enum DW_FormKindEnum DW_Form_V5_XList(X) DW_Form_GNU_XList(X) #undef X -} DW_FormKindEnum; +} DW_FormEnum; //- Attributes DWARF2 @@ -1582,9 +1582,9 @@ typedef enum DW_ExprOpEnum { #define X(_N, _ID, _OPER_COUNT, _POP_COUNT, _PUSH_COUNT) DW_ExprOp_##_N = _ID, DW_Expr_V3_XList(X) - DW_Expr_V4_XList(X) - DW_Expr_V5_XList(X) - DW_Expr_GNU_XList(X) + DW_Expr_V4_XList(X) + DW_Expr_V5_XList(X) + DW_Expr_GNU_XList(X) #undef X } DW_ExprOpEnum; @@ -1762,7 +1762,7 @@ internal DW_AttribClass dw_attrib_class_from_attrib_llvm (DW_AttribKind k); internal DW_AttribClass dw_attrib_class_from_attrib_apple(DW_AttribKind k); internal DW_AttribClass dw_attrib_class_from_attrib_mips (DW_AttribKind k); -internal DW_AttribClass dw_attrib_class_from_kind(DW_Version ver, DW_Ext ext, DW_AttribKind v); +internal DW_AttribClass dw_attrib_class_from_attrib(DW_Version ver, DW_Ext ext, DW_AttribKind v); //- Form Class Encodings @@ -1782,7 +1782,7 @@ internal U64 dw_size_from_format(DW_Format format); //////////////////////////////// -internal DW_AttribClass dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, DW_AttribKind attrib, DW_FormKind form_kind); +internal DW_AttribClass dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, B32 relaxed, DW_AttribKind attrib, DW_FormKind form_kind); internal U64 dw_pick_default_lower_bound(DW_Language lang); diff --git a/src/dwarf/dwarf_coff.c b/src/dwarf/dwarf_coff.c index 7282f6dc..2c6614f9 100644 --- a/src/dwarf/dwarf_coff.c +++ b/src/dwarf/dwarf_coff.c @@ -23,14 +23,14 @@ dw_is_dwarf_present_coff_section_table(String8 string_table, U64 section_count, return is_dwarf_present; } -internal DW_Raw -dw_raw_from_coff_section_table(Arena *arena, - String8 raw_image, - String8 string_table, - U64 section_count, - COFF_SectionHeader *section_table) +internal DW_Input +dw_input_from_coff_section_table(Arena *arena, + String8 raw_image, + String8 string_table, + U64 section_count, + COFF_SectionHeader *section_table) { - DW_Raw input = {0}; + DW_Input input = {0}; B32 sect_status[ArrayCount(input.sec)] = {0}; for (U64 i = 0; i < section_count; ++i) { @@ -51,6 +51,7 @@ dw_raw_from_coff_section_table(Arena *arena, } else { sect_status[s] = 1; DW_Section *d = &input.sec[s]; + d->name = push_str8_copy(arena, name); d->data = str8_substr(raw_image, raw_data_range); d->is_dwo = is_dwo; } diff --git a/src/dwarf/dwarf_coff.h b/src/dwarf/dwarf_coff.h index 9bcd02a8..79cd37c3 100644 --- a/src/dwarf/dwarf_coff.h +++ b/src/dwarf/dwarf_coff.h @@ -5,6 +5,7 @@ #define DWARF_COFF_H internal B32 dw_is_dwarf_present_coff_section_table(String8 string_table, U64 section_count, COFF_SectionHeader *section_table); -internal DW_Raw dw_raw_from_coff_section_table(Arena *arena, String8 raw_image, String8 string_table, U64 section_count, COFF_SectionHeader *section_table); +internal DW_Input dw_input_from_coff_section_table(Arena *arena, String8 raw_image, String8 string_table, U64 section_count, COFF_SectionHeader *section_table); #endif // DWARF_COFF_H + diff --git a/src/dwarf/dwarf_dump.c b/src/dwarf/dwarf_dump.c index e33ef953..27ad6dd0 100644 --- a/src/dwarf/dwarf_dump.c +++ b/src/dwarf/dwarf_dump.c @@ -211,13 +211,13 @@ dw_string_list_from_expression(Arena *arena, String8 raw_data, U64 cu_base, U64 } break; case DW_ExprOp_CallRef: { U64 x = 0; - cursor += dw_str8_deserial_read_fmt_uint(raw_data, cursor, format, &x); + cursor += str8_deserial_read_dwarf_uint(raw_data, cursor, format, &x); op_value = push_str8f(scratch.arena, "%llu", x); } break; case DW_ExprOp_ImplicitPointer: case DW_ExprOp_GNU_ImplicitPointer: { U64 info_off = 0; - cursor += dw_str8_deserial_read_fmt_uint(raw_data, cursor, format, &info_off); + cursor += str8_deserial_read_dwarf_uint(raw_data, cursor, format, &info_off); S64 ptr = 0; cursor += str8_deserial_read_sleb128(raw_data, cursor, &ptr); @@ -350,7 +350,7 @@ dw_string_list_from_cfi_program(Arena *arena, { Temp scratch = scratch_begin(&arena, 1); String8List list = {0}; - + U64 reg_max = dw_reg_count_from_arch(arch); U64 pc = pc_begin; for (U64 cursor = 0, inst_size; cursor < program.size; cursor += inst_size) { @@ -362,134 +362,134 @@ dw_string_list_from_cfi_program(Arena *arena, str8_list_pushf(arena, &list, "ERROR: failed to unpack CFA instruction @ 0x%I64", cursor); break; } - + // error check operands DW_CFA_OperandType *operand_types = dw_operand_types_from_cfa_op(inst.opcode); U64 operand_count = dw_operand_count_from_cfa_opcode(inst.opcode); for EachIndex(operand_idx, operand_count) { switch (operand_types[operand_idx]) { - case DW_CFA_OperandType_Null: break; - case DW_CFA_OperandType_Value: break; - case DW_CFA_OperandType_Register: { - if (inst.operands[operand_idx].u64 >= reg_max) { - str8_list_pushf(arena, &list, "ERROR: DW_CFA_%S @ 0x%I64x has an invalid register", - dw_string_from_cfa_opcode(inst.opcode), - cursor); + case DW_CFA_OperandType_Null: break; + case DW_CFA_OperandType_Value: break; + case DW_CFA_OperandType_Register: { + if (inst.operands[operand_idx].u64 >= reg_max) { + str8_list_pushf(arena, &list, "ERROR: DW_CFA_%S @ 0x%I64x has an invalid register", + dw_string_from_cfa_opcode(inst.opcode), + cursor); + } + } break; + case DW_CFA_OperandType_Expression: { + DW_Expr expr = dw_expr_from_data(scratch.arena, format, cie->address_size, inst.operands[operand_idx].block); + for EachNode(inst, DW_ExprInst, expr.first) { + if (dw_is_cfa_expr_opcode_invalid(inst->opcode)) { + String8 expr_opcode_str = dw_string_from_expr_op(scratch.arena, ver, ext, inst->opcode); + str8_list_pushf(arena, &list, "ERROR: Exrepssion in DW_CFA_%S @ 0x%I64x has an invalid opcode DW_ExprOp_%S", expr_opcode_str); } - } break; - case DW_CFA_OperandType_Expression: { - DW_Expr expr = dw_expr_from_data(scratch.arena, format, cie->address_size, inst.operands[operand_idx].block); - for EachNode(inst, DW_ExprInst, expr.first) { - if (dw_is_cfa_expr_opcode_invalid(inst->opcode)) { - String8 expr_opcode_str = dw_string_from_expr_op(scratch.arena, ver, ext, inst->opcode); - str8_list_pushf(arena, &list, "ERROR: Exrepssion in DW_CFA_%S @ 0x%I64x has an invalid opcode DW_ExprOp_%S", expr_opcode_str); - } - } - } break; - default: { InvalidPath; } break; + } + } break; + default: { InvalidPath; } break; } } - + // format operands String8 operand_str = str8_lit("???"); switch (inst.opcode) { - case DW_CFA_Nop: { operand_str = str8_zero(); } break; - case DW_CFA_SetLoc: { - operand_str = str8f(arena, "0x%X", inst.operands[0].u64); - pc = inst.operands[0].u64; - } break; - case DW_CFA_AdvanceLoc1: { - U64 delta = inst.operands[0].u64; - pc += delta; - operand_str = str8f(arena, "%+u `PC 0x%I64x`", delta, pc); - } break; - case DW_CFA_AdvanceLoc2: { - U64 delta = inst.operands[0].u64; - pc += delta; - operand_str = str8f(arena, "%+u `PC 0x%I64x`", delta, pc); - } break; - case DW_CFA_AdvanceLoc4: { - U64 delta = inst.operands[0].u64; - pc += delta; - operand_str = str8f(arena, "%+u `PC 0x%I64x`", delta, pc); - } break; - case DW_CFA_OffsetExt: { - U64 reg = inst.operands[0].u64; - S64 offset = (S64)inst.operands[1].u64; - operand_str = dw_string_from_reg_off(arena, arch, reg, offset); - } break; - case DW_CFA_RestoreExt: { operand_str = str8_zero(); } break; - case DW_CFA_Undefined: { - operand_str = str8f(arena, "%I64u", inst.operands[0].u64); - } break; - case DW_CFA_SameValue: { - operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, 0); - } break; - case DW_CFA_Register: { - operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, inst.operands[1].u64); - } break; - case DW_CFA_RememberState: { operand_str = str8_zero(); } break; - case DW_CFA_RestoreState: { operand_str = str8_zero(); } break; - case DW_CFA_DefCfa: { - operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, inst.operands[1].u64); - } break; - case DW_CFA_DefCfaRegister: { - operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, 0); - } break; - case DW_CFA_DefCfaOffset: { - operand_str = str8f(arena, "+%I64u", inst.operands[0].u64); - } break; - case DW_CFA_DefCfaExpr: { - operand_str = dw_string_from_expression(arena, inst.operands[0].block, cu_base, cie->address_size, arch, ver, ext, format); - } break; - case DW_CFA_Expr: { - String8 reg_str = dw_string_from_reg_off(scratch.arena, arch, inst.operands[0].u64, 0); - String8 expr_str = dw_string_from_expression(scratch.arena, inst.operands[1].block, cu_base, cie->address_size, arch, ver, ext, format); - operand_str = str8f(arena, "%S expression %S", reg_str, expr_str); - } break; - case DW_CFA_OffsetExtSf: { - operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, inst.operands[1].s64); - } break; - case DW_CFA_DefCfaSf: { - operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, inst.operands[1].s64); - } break; - case DW_CFA_DefCfaOffsetSf: { operand_str = str8_zero(); } break; - case DW_CFA_ValOffset: { - operand_str = str8f(arena, "value 0x%llx, offset %+I64d", inst.operands[0].u64, inst.operands[1].u64); - } break; - case DW_CFA_ValOffsetSf: { - operand_str = str8f(arena, "value %llu, offset %+I64d", inst.operands[0].u64, inst.operands[1].s64); - } break; - case DW_CFA_ValExpr: { - String8 expr_str = dw_string_from_expression(scratch.arena, inst.operands[1].block, cu_base, cie->address_size, arch, ver, ext, format); - operand_str = str8f(arena, "value +%I64u, expression %S", inst.operands[0].u64, expr_str); - } break; - case DW_CFA_AdvanceLoc: { - U64 delta = inst.operands[0].u64; - pc += delta; - operand_str = str8f(arena, "+%I64u `PC 0x%I64x`", delta, pc); - } break; - case DW_CFA_Offset: { - U64 reg = inst.operands[0].u64; - S64 offset = (S64)inst.operands[1].u64; - operand_str = dw_string_from_reg_off(arena, arch, reg, offset); - } break; - case DW_CFA_Restore: { - operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, 0); - } break; - default: { - str8_list_pushf(arena, &list, "ERROR: unknown CFA opcode 0x%I64u", inst.opcode); - } goto exit; + case DW_CFA_Nop: { operand_str = str8_zero(); } break; + case DW_CFA_SetLoc: { + operand_str = str8f(arena, "0x%X", inst.operands[0].u64); + pc = inst.operands[0].u64; + } break; + case DW_CFA_AdvanceLoc1: { + U64 delta = inst.operands[0].u64; + pc += delta; + operand_str = str8f(arena, "%+u `PC 0x%I64x`", delta, pc); + } break; + case DW_CFA_AdvanceLoc2: { + U64 delta = inst.operands[0].u64; + pc += delta; + operand_str = str8f(arena, "%+u `PC 0x%I64x`", delta, pc); + } break; + case DW_CFA_AdvanceLoc4: { + U64 delta = inst.operands[0].u64; + pc += delta; + operand_str = str8f(arena, "%+u `PC 0x%I64x`", delta, pc); + } break; + case DW_CFA_OffsetExt: { + U64 reg = inst.operands[0].u64; + S64 offset = (S64)inst.operands[1].u64; + operand_str = dw_string_from_reg_off(arena, arch, reg, offset); + } break; + case DW_CFA_RestoreExt: { operand_str = str8_zero(); } break; + case DW_CFA_Undefined: { + operand_str = str8f(arena, "%I64u", inst.operands[0].u64); + } break; + case DW_CFA_SameValue: { + operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, 0); + } break; + case DW_CFA_Register: { + operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, inst.operands[1].u64); + } break; + case DW_CFA_RememberState: { operand_str = str8_zero(); } break; + case DW_CFA_RestoreState: { operand_str = str8_zero(); } break; + case DW_CFA_DefCfa: { + operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, inst.operands[1].u64); + } break; + case DW_CFA_DefCfaRegister: { + operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, 0); + } break; + case DW_CFA_DefCfaOffset: { + operand_str = str8f(arena, "+%I64u", inst.operands[0].u64); + } break; + case DW_CFA_DefCfaExpr: { + operand_str = dw_string_from_expression(arena, inst.operands[0].block, cu_base, cie->address_size, arch, ver, ext, format); + } break; + case DW_CFA_Expr: { + String8 reg_str = dw_string_from_reg_off(scratch.arena, arch, inst.operands[0].u64, 0); + String8 expr_str = dw_string_from_expression(scratch.arena, inst.operands[1].block, cu_base, cie->address_size, arch, ver, ext, format); + operand_str = str8f(arena, "%S expression %S", reg_str, expr_str); + } break; + case DW_CFA_OffsetExtSf: { + operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, inst.operands[1].s64); + } break; + case DW_CFA_DefCfaSf: { + operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, inst.operands[1].s64); + } break; + case DW_CFA_DefCfaOffsetSf: { operand_str = str8_zero(); } break; + case DW_CFA_ValOffset: { + operand_str = str8f(arena, "value 0x%llx, offset %+I64d", inst.operands[0].u64, inst.operands[1].u64); + } break; + case DW_CFA_ValOffsetSf: { + operand_str = str8f(arena, "value %llu, offset %+I64d", inst.operands[0].u64, inst.operands[1].s64); + } break; + case DW_CFA_ValExpr: { + String8 expr_str = dw_string_from_expression(scratch.arena, inst.operands[1].block, cu_base, cie->address_size, arch, ver, ext, format); + operand_str = str8f(arena, "value +%I64u, expression %S", inst.operands[0].u64, expr_str); + } break; + case DW_CFA_AdvanceLoc: { + U64 delta = inst.operands[0].u64; + pc += delta; + operand_str = str8f(arena, "+%I64u `PC 0x%I64x`", delta, pc); + } break; + case DW_CFA_Offset: { + U64 reg = inst.operands[0].u64; + S64 offset = (S64)inst.operands[1].u64; + operand_str = dw_string_from_reg_off(arena, arch, reg, offset); + } break; + case DW_CFA_Restore: { + operand_str = dw_string_from_reg_off(arena, arch, inst.operands[0].u64, 0); + } break; + default: { + str8_list_pushf(arena, &list, "ERROR: unknown CFA opcode 0x%I64u", inst.opcode); + } goto exit; } - + if (operand_str.size) { str8_list_pushf(arena, &list, "DW_CFA_%S: %S", dw_string_from_cfa_opcode(inst.opcode), operand_str); } else { str8_list_pushf(arena, &list, "DW_CFA_%S", dw_string_from_cfa_opcode(inst.opcode)); } } - - exit:; + +exit:; scratch_end(scratch); return list; } @@ -499,10 +499,10 @@ dw_string_from_cfa(Arena *arena, Arch arch, U64 address_size, DW_Version version { String8 cfa_str = str8_lit("???"); switch (cfa.rule) { - case DW_CFA_Rule_Null: {} break; - case DW_CFA_Rule_RegOff: { cfa_str = dw_string_from_reg_off(arena, arch, cfa.reg, cfa.off); } break; - case DW_CFA_Rule_Expression: { cfa_str = dw_string_from_expression(arena, cfa.expr, max_U64, address_size, arch, version, ext, format); } break; - default: { InvalidPath; } break; + case DW_CFA_Rule_Null: {} break; + case DW_CFA_Rule_RegOff: { cfa_str = dw_string_from_reg_off(arena, arch, cfa.reg, cfa.off); } break; + case DW_CFA_Rule_Expression: { cfa_str = dw_string_from_expression(arena, cfa.expr, max_U64, address_size, arch, version, ext, format); } break; + default: { InvalidPath; } break; } return cfa_str; } @@ -517,40 +517,40 @@ dw_string_from_cfi_row(Arena *arena, Arch arch, U64 address_size, DW_Version ver DW_CFI_Register *cfi_reg = &row->regs[reg_idx]; String8 rule_str = str8_lit("???"); switch (cfi_reg->rule) { - case DW_CFI_RegisterRule_Undefined: { - rule_str = str8f(scratch.arena, "Undefined(%S)", dw_string_from_reg(scratch.arena, arch, cfi_reg->n)); - } break; - case DW_CFI_RegisterRule_SameValue: { - rule_str = str8_zero(); - } break; - case DW_CFI_RegisterRule_Offset: { - rule_str = str8f(scratch.arena, "[CFA%+I64d]", cfi_reg->n); - } break; - case DW_CFI_RegisterRule_ValOffset: { - rule_str = str8f(scratch.arena, "Val(CFA%+I64d)", cfi_reg->n); - } break; - case DW_CFI_RegisterRule_Register: { - rule_str = str8f(scratch.arena, "Register(%S)", dw_string_from_reg(scratch.arena, arch, cfi_reg->n)); - } break; - case DW_CFI_RegisterRule_Expression: { - rule_str = str8f(scratch.arena, "Expression(%S)", dw_string_from_expression(scratch.arena, cfi_reg->expr, max_U64, address_size, arch, version, ext, format)); - } break; - case DW_CFI_RegisterRule_ValExpression: { - rule_str = str8f(scratch.arena, "ValExpression(%S)", dw_string_from_expression(scratch.arena, cfi_reg->expr, max_U64, address_size, arch, version, ext, format)); - } break; - case DW_CFI_RegisterRule_Architectural: { - rule_str = str8_lit("???"); - } break; - default: { InvalidPath; } break; + case DW_CFI_RegisterRule_Undefined: { + rule_str = str8f(scratch.arena, "Undefined(%S)", dw_string_from_reg(scratch.arena, arch, cfi_reg->n)); + } break; + case DW_CFI_RegisterRule_SameValue: { + rule_str = str8_zero(); + } break; + case DW_CFI_RegisterRule_Offset: { + rule_str = str8f(scratch.arena, "[CFA%+I64d]", cfi_reg->n); + } break; + case DW_CFI_RegisterRule_ValOffset: { + rule_str = str8f(scratch.arena, "Val(CFA%+I64d)", cfi_reg->n); + } break; + case DW_CFI_RegisterRule_Register: { + rule_str = str8f(scratch.arena, "Register(%S)", dw_string_from_reg(scratch.arena, arch, cfi_reg->n)); + } break; + case DW_CFI_RegisterRule_Expression: { + rule_str = str8f(scratch.arena, "Expression(%S)", dw_string_from_expression(scratch.arena, cfi_reg->expr, max_U64, address_size, arch, version, ext, format)); + } break; + case DW_CFI_RegisterRule_ValExpression: { + rule_str = str8f(scratch.arena, "ValExpression(%S)", dw_string_from_expression(scratch.arena, cfi_reg->expr, max_U64, address_size, arch, version, ext, format)); + } break; + case DW_CFI_RegisterRule_Architectural: { + rule_str = str8_lit("???"); + } break; + default: { InvalidPath; } break; } - + if (rule_str.size) { str8_list_pushf(scratch.arena, &cfi_regs_list, "%S: %S", dw_string_from_reg(scratch.arena, arch, reg_idx), rule_str); } } - + String8 string = str8_list_join(arena, &cfi_regs_list, &(StringJoin){.sep=str8_lit(", ")}); - + scratch_end(scratch); return string; } @@ -680,7 +680,7 @@ dw_print_eh_frame(Arena *arena, String8List *out, String8 indent, String8 raw_eh } internal void -dw_print_debug_loc(Arena *arena, String8List *out, String8 indent, DW_Raw *input, Arch arch, ExecutableImageKind image_type, B32 relaxed) +dw_print_debug_loc(Arena *arena, String8List *out, String8 indent, DW_Input *input, Arch arch, ExecutableImageKind image_type, B32 relaxed) { #if 0 DW_Section info = input->sec[DW_Section_Info]; @@ -827,7 +827,7 @@ dw_print_debug_loc(Arena *arena, String8List *out, String8 indent, DW_Raw *input } internal void -dw_print_debug_ranges(Arena *arena, String8List *out, String8 indent, DW_Raw *input, Arch arch, ExecutableImageKind image_type, B32 relaxed) +dw_print_debug_ranges(Arena *arena, String8List *out, String8 indent, DW_Input *input, Arch arch, ExecutableImageKind image_type, B32 relaxed) { NotImplemented; #if 0 @@ -933,7 +933,7 @@ dw_print_debug_ranges(Arena *arena, String8List *out, String8 indent, DW_Raw *in } internal void -dw_print_debug_aranges(Arena *arena, String8List *out, String8 indent, DW_Raw *input) +dw_print_debug_aranges(Arena *arena, String8List *out, String8 indent, DW_Input *input) { NotImplemented; #if 0 @@ -1022,7 +1022,7 @@ dw_print_debug_aranges(Arena *arena, String8List *out, String8 indent, DW_Raw *i } internal void -dw_print_debug_addr(Arena *arena, String8List *out, String8 indent, DW_Raw *input) +dw_print_debug_addr(Arena *arena, String8List *out, String8 indent, DW_Input *input) { NotImplemented; #if 0 @@ -1131,7 +1131,7 @@ dw_based_range_read_address(void *base, Rng1U64 range, U64 offset, Rng1U64Array } internal void -dw_print_debug_loclists(Arena *arena, String8List *out, String8 indent, DW_Raw *input, Rng1U64Array segment_virtual_ranges, Arch arch) +dw_print_debug_loclists(Arena *arena, String8List *out, String8 indent, DW_Input *input, Rng1U64Array segment_virtual_ranges, Arch arch) { NotImplemented; #if 0 @@ -1284,7 +1284,7 @@ dw_print_debug_loclists(Arena *arena, String8List *out, String8 indent, DW_Raw * } internal void -dw_print_debug_rnglists(Arena *arena, String8List *out, String8 indent, DW_Raw *input, Rng1U64Array segment_ranges) +dw_print_debug_rnglists(Arena *arena, String8List *out, String8 indent, DW_Input *input, Rng1U64Array segment_ranges) { NotImplemented; #if 0 @@ -1423,7 +1423,7 @@ dw_print_debug_rnglists(Arena *arena, String8List *out, String8 indent, DW_Raw * } internal void -dw_format_string_table(Arena *arena, String8List *out, String8 indent, DW_Raw *input, DW_SectionKind sec) +dw_format_string_table(Arena *arena, String8List *out, String8 indent, DW_Input *input, DW_SectionKind sec) { NotImplemented; #if 0 @@ -1485,19 +1485,19 @@ dw_format_string_table(Arena *arena, String8List *out, String8 indent, DW_Raw *i } internal void -dw_print_debug_pubnames(Arena *arena, String8List *out, String8 indent, DW_Raw *input) +dw_print_debug_pubnames(Arena *arena, String8List *out, String8 indent, DW_Input *input) { dw_format_string_table(arena, out, indent, input, DW_Section_PubNames); } internal void -dw_print_debug_pubtypes(Arena *arena, String8List *out, String8 indent, DW_Raw *input) +dw_print_debug_pubtypes(Arena *arena, String8List *out, String8 indent, DW_Input *input) { dw_format_string_table(arena, out, indent, input, DW_Section_PubTypes); } internal void -dw_print_debug_line_str(Arena *arena, String8List *out, String8 indent, DW_Raw *input) +dw_print_debug_line_str(Arena *arena, String8List *out, String8 indent, DW_Input *input) { NotImplemented; #if 0 @@ -1527,7 +1527,7 @@ dw_print_debug_line_str(Arena *arena, String8List *out, String8 indent, DW_Raw * } internal void -dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 indent, DW_Raw *input) +dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 indent, DW_Input *input) { NotImplemented; #if 0 @@ -1598,10 +1598,10 @@ dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 indent, DW_Ra //~ rjf: Dump Entry Point internal String8 -dw_string_from_attrib_value(Arena *arena, DW_Raw *input, Arch arch, DW_CompUnit *unit, DW_LineVMHeader *line_vm, DW_Attrib *attrib) +dw_string_from_attrib_value(Arena *arena, DW_Input *input, Arch arch, DW_CompUnit *unit, DW_LineVMHeader *line_vm, DW_Attrib *attrib) { Temp scratch = scratch_begin(&arena, 1); - + String8List attrib_fmt = {0}; // rjf: log attrib's value based on vlass @@ -1722,7 +1722,7 @@ dw_string_from_attrib_value(Arena *arena, DW_Raw *input, Arch arch, DW_CompUnit enum_info = dw_string_from_attrib_type_encoding(scratch.arena, encoding); }break; } - + if(enum_info.size) { str8_list_pushf(scratch.arena, &attrib_fmt, " `%S`", enum_info); @@ -1730,14 +1730,14 @@ dw_string_from_attrib_value(Arena *arena, DW_Raw *input, Arch arch, DW_CompUnit } String8 result = str8_list_join(arena, &attrib_fmt, 0); - + scratch_end(scratch); return result; } internal String8List dw_dump_list_from_sections(Arena *arena, - DW_Raw *input, + DW_Input *input, Arch arch, DW_DumpSubsetFlags subset_flags) { @@ -1748,17 +1748,18 @@ dw_dump_list_from_sections(Arena *arena, #define DumpSubset(name) if(subset_flags & DW_DumpSubsetFlag_##name) DeferLoop(dumpf("// %S\n\n", dw_name_title_from_dump_subset_table[DW_DumpSubset_##name]), dump(str8_lit("\n"))) Temp scratch = scratch_begin(&arena, 1); Rng1U64Array segment_vranges = {0}; - DW_ListUnitInput lu_input = dw_list_unit_input_from_raw(scratch.arena, input); - + DW_ListUnitInput lu_input = dw_list_unit_input_from_input(scratch.arena, input); + B32 relaxed = 1; + DW_CompUnit *cu_arr; { - DW_ListUnitInput lu_input = dw_list_unit_input_from_raw(scratch.arena, input); + DW_ListUnitInput lu_input = dw_list_unit_input_from_input(scratch.arena, input); Rng1U64List cu_range_list = dw_unit_ranges_from_data(scratch.arena, input->sec[DW_Section_Info].data); Rng1U64Array cu_ranges = rng1u64_array_from_list(scratch.arena, &cu_range_list); cu_arr = push_array(scratch.arena, DW_CompUnit, cu_ranges.count); for EachIndex(cu_idx, cu_ranges.count) { - cu_arr[cu_idx] = dw_cu_from_info_off(scratch.arena, input, lu_input, cu_ranges.v[cu_idx].min); + cu_arr[cu_idx] = dw_cu_from_info_off(scratch.arena, input, lu_input, cu_ranges.v[cu_idx].min, relaxed); } } @@ -1779,7 +1780,7 @@ dw_dump_list_from_sections(Arena *arena, String8 unit_dir = dw_string_from_tag_attrib_kind(input, unit, unit->tag, DW_AttribKind_CompDir ); String8 unit_name = dw_string_from_tag_attrib_kind(input, unit, unit->tag, DW_AttribKind_Name ); String8 stmt_list = dw_line_ptr_from_tag_attrib_kind(input, unit, unit->tag, DW_AttribKind_StmtList); - DW_LineVMHeader line_vm = {0}; + DW_LineVMHeader line_vm = {0}; dw_read_line_vm_header(unit_temp.arena, stmt_list, 0, input, unit_dir, unit_name, unit->address_size, unit->str_offsets_lu, &line_vm); //- rjf: log top-level unit info @@ -1819,25 +1820,25 @@ dw_dump_list_from_sections(Arena *arena, temp_end(attrib_temp); } value_max_size = Min(120, value_max_size); - + // log for EachNode(attrib_n, DW_AttribNode, tag.attribs.first) { DW_Attrib *attrib = &attrib_n->v; - + Temp attrib_temp = temp_begin(tag_temp.arena); - + String8 attrib_kind_str = dw_string_from_attrib_kind(attrib_temp.arena, unit->version, unit->ext, attrib->attrib_kind); String8 form_kind_str = dw_string_from_form_kind(attrib_temp.arena, unit->version, attrib->form_kind); String8 value_str = dw_string_from_attrib_value(attrib_temp.arena, input, arch, unit, &line_vm, attrib); - + dumpf("%S attrib: { kind: %S, %.*sform_kind: %S, %.*svalue: %S, %.*s} // info_off: 0x%I64x\n", - tag_indent, - attrib_kind_str, attrib_name_max_size - attrib_kind_str.size, indent.str, - form_kind_str, form_kind_max_size - form_kind_str.size, indent.str, - value_str, value_str.size < value_max_size ? value_max_size - value_str.size: 0, indent.str, - attrib->info_off, unit_idx, tag_idx); - + tag_indent, + attrib_kind_str, attrib_name_max_size - attrib_kind_str.size, indent.str, + form_kind_str, form_kind_max_size - form_kind_str.size, indent.str, + value_str, value_str.size < value_max_size ? value_max_size - value_str.size: 0, indent.str, + attrib->info_off, unit_idx, tag_idx); + temp_end(attrib_temp); } } @@ -2198,7 +2199,7 @@ dw_dump_list_from_sections(Arena *arena, dumpf(" { 0x%08I64x %llu \"%S\" }\n", cursor, string.size, string); } } - + ////////////////////////////// //~ dump .debug_frame DumpSubset(DebugFrame) @@ -2206,7 +2207,7 @@ dw_dump_list_from_sections(Arena *arena, HashTable *cie_ht = hash_table_init(scratch.arena, 0x2000); String8 debug_frame = input->sec[DW_Section_Frame].data; U64 addr_size = byte_size_from_arch(arch); - + // make offset -> CIE hash table for (U64 cursor = 0, desc_size; cursor < debug_frame.size; cursor += desc_size) { DW_DescriptorEntry desc = {0}; @@ -2228,71 +2229,71 @@ dw_dump_list_from_sections(Arena *arena, desc_size = dw_parse_descriptor_entry_header(debug_frame, cursor, &desc); String8 raw_desc = str8_substr(debug_frame, desc.entry_range); switch (desc.type) { - case DW_DescriptorEntryType_Null: {} break; - case DW_DescriptorEntryType_CIE: { - DW_CIE cie = {0}; - if (dw_parse_cie(raw_desc, desc.format, arch, &cie)) { - String8List init_insts_str_list = dw_string_list_from_cfi_program(scratch.arena, 0, arch, DW_Version_5, DW_Ext_All, cie.format, 0, &cie, dw_decode_ptr_debug_frame, &cie, cie.insts); - - dumpf("CIE: // entry range: %r\n", desc.entry_range); - dumpf("{\n"); - dumpf(" Format: %S\n", dw_string_from_format(desc.format)); - dumpf(" Version: %u\n", cie.version); - dumpf(" Aug string: \"%S\"\n", cie.aug_string); - dumpf(" Code align: %I64u\n", cie.code_align_factor); - dumpf(" Data align: %I64d\n", cie.data_align_factor); - dumpf(" Return addr reg: %u\n", cie.ret_addr_reg); - if (cie.version > DW_Version_3) { - dumpf(" Address size: %u\n", cie.address_size); - dumpf(" Segment selector size: %u\n", cie.segment_selector_size); - } - dumpf(" Initial Insturction:\n"); - dumpf(" {\n"); - for EachNode(n, String8Node, init_insts_str_list.first) { dumpf(" %S\n", n->string); } - dumpf(" }\n"); - dumpf("}\n"); - } else { - dumpf("ERROR: unable to parse CIE @ %I64x\n", desc.entry_range.min); + case DW_DescriptorEntryType_Null: {} break; + case DW_DescriptorEntryType_CIE: { + DW_CIE cie = {0}; + if (dw_parse_cie(raw_desc, desc.format, arch, &cie)) { + String8List init_insts_str_list = dw_string_list_from_cfi_program(scratch.arena, 0, arch, DW_Version_5, DW_Ext_All, cie.format, 0, &cie, dw_decode_ptr_debug_frame, &cie, cie.insts); + + dumpf("CIE: // entry range: %r\n", desc.entry_range); + dumpf("{\n"); + dumpf(" Format: %S\n", dw_string_from_format(desc.format)); + dumpf(" Version: %u\n", cie.version); + dumpf(" Aug string: \"%S\"\n", cie.aug_string); + dumpf(" Code align: %I64u\n", cie.code_align_factor); + dumpf(" Data align: %I64d\n", cie.data_align_factor); + dumpf(" Return addr reg: %u\n", cie.ret_addr_reg); + if (cie.version > DW_Version_3) { + dumpf(" Address size: %u\n", cie.address_size); + dumpf(" Segment selector size: %u\n", cie.segment_selector_size); } - } break; - case DW_DescriptorEntryType_FDE: { - DW_DescriptorEntry cie_desc = {0}; - U64 cie_desc_size = dw_parse_descriptor_entry_header(debug_frame, desc.cie_pointer, &cie_desc); - String8 cie_data = str8_substr(debug_frame, cie_desc.entry_range); - DW_CIE cie = {0}; - dw_parse_cie(cie_data, cie_desc.format, arch, &cie); - - DW_FDE fde = {0}; - if (dw_parse_fde(raw_desc, desc.format, &cie, &fde)) { - DW_Version version = DW_Version_5; - DW_Ext ext = DW_Ext_All; - String8List insts_str_list = dw_string_list_from_cfi_program(scratch.arena, 0, arch, version, ext, fde.format, fde.pc_range.min, &cie, dw_decode_ptr_debug_frame, &cie, fde.insts); - dumpf("FDE: // entry range: %r\n", desc.entry_range); - dumpf("{\n"); - { - dumpf(" Format: %S\n", dw_string_from_format(fde.format)); - dumpf(" CIE pointer: 0x%I64x\n", fde.cie_pointer); - dumpf(" PC range: %r\n", fde.pc_range); - dumpf(" Instructions:\n"); - dumpf(" {\n"); - for EachNode(n, String8Node, insts_str_list.first) { dumpf(" %S\n", n->string); } - dumpf(" }\n"); - } - dumpf(" Unwind:\n"); + dumpf(" Initial Insturction:\n"); + dumpf(" {\n"); + for EachNode(n, String8Node, init_insts_str_list.first) { dumpf(" %S\n", n->string); } + dumpf(" }\n"); + dumpf("}\n"); + } else { + dumpf("ERROR: unable to parse CIE @ %I64x\n", desc.entry_range.min); + } + } break; + case DW_DescriptorEntryType_FDE: { + DW_DescriptorEntry cie_desc = {0}; + U64 cie_desc_size = dw_parse_descriptor_entry_header(debug_frame, desc.cie_pointer, &cie_desc); + String8 cie_data = str8_substr(debug_frame, cie_desc.entry_range); + DW_CIE cie = {0}; + dw_parse_cie(cie_data, cie_desc.format, arch, &cie); + + DW_FDE fde = {0}; + if (dw_parse_fde(raw_desc, desc.format, &cie, &fde)) { + DW_Version version = DW_Version_5; + DW_Ext ext = DW_Ext_All; + String8List insts_str_list = dw_string_list_from_cfi_program(scratch.arena, 0, arch, version, ext, fde.format, fde.pc_range.min, &cie, dw_decode_ptr_debug_frame, &cie, fde.insts); + dumpf("FDE: // entry range: %r\n", desc.entry_range); + dumpf("{\n"); + { + dumpf(" Format: %S\n", dw_string_from_format(fde.format)); + dumpf(" CIE pointer: 0x%I64x\n", fde.cie_pointer); + dumpf(" PC range: %r\n", fde.pc_range); + dumpf(" Instructions:\n"); dumpf(" {\n"); - DW_CFI_Unwind *cfi_unwind = dw_cfi_unwind_init(scratch.arena, arch, &cie, &fde, dw_decode_ptr_debug_frame, &cie); - do { - String8 cfa_str = dw_string_from_cfa(scratch.arena, arch, cie.address_size, version, ext, fde.format, cfi_unwind->row->cfa); - String8 cfi_regs_str = dw_string_from_cfi_row(scratch.arena, arch, cie.address_size, version, ext, fde.format, cfi_unwind->row); - dumpf(" { PC: 0x%I64x, CFA: %-7S, Rules: { %S }\n", cfi_unwind->pc, cfa_str, cfi_regs_str); - } while (dw_cfi_next_row(scratch.arena, cfi_unwind)); + for EachNode(n, String8Node, insts_str_list.first) { dumpf(" %S\n", n->string); } dumpf(" }\n"); - - dumpf("}\n"); - } else { - dumpf("ERROR: unable to parse FDE @ %I64x\n", desc.entry_range.min); } - } break; + dumpf(" Unwind:\n"); + dumpf(" {\n"); + DW_CFI_Unwind *cfi_unwind = dw_cfi_unwind_init(scratch.arena, arch, &cie, &fde, dw_decode_ptr_debug_frame, &cie); + do { + String8 cfa_str = dw_string_from_cfa(scratch.arena, arch, cie.address_size, version, ext, fde.format, cfi_unwind->row->cfa); + String8 cfi_regs_str = dw_string_from_cfi_row(scratch.arena, arch, cie.address_size, version, ext, fde.format, cfi_unwind->row); + dumpf(" { PC: 0x%I64x, CFA: %-7S, Rules: { %S }\n", cfi_unwind->pc, cfa_str, cfi_regs_str); + } while (dw_cfi_next_row(scratch.arena, cfi_unwind)); + dumpf(" }\n"); + + dumpf("}\n"); + } else { + dumpf("ERROR: unable to parse FDE @ %I64x\n", desc.entry_range.min); + } + } break; } } } diff --git a/src/dwarf/dwarf_dump.h b/src/dwarf/dwarf_dump.h index 67aa59d7..472bb7b7 100644 --- a/src/dwarf/dwarf_dump.h +++ b/src/dwarf/dwarf_dump.h @@ -70,21 +70,21 @@ internal String8 dw_string_from_cfi_row(Arena *arena, Arch arch, U64 address_siz #if 0 internal void dw_print_eh_frame (Arena *arena, String8List *out, String8 indent, String8 raw_eh_frame, Arch arch, DW_Version ver, DW_Ext ext, EH_PtrCtx *ptr_ctx); -internal void dw_print_debug_loc (Arena *arena, String8List *out, String8 indent, DW_Raw *input, Arch arch, ExecutableImageKind image_type, B32 relaxed); -internal void dw_print_debug_ranges (Arena *arena, String8List *out, String8 indent, DW_Raw *input, Arch arch, ExecutableImageKind image_type, B32 relaxed); -internal void dw_print_debug_aranges (Arena *arena, String8List *out, String8 indent, DW_Raw *input); -internal void dw_print_debug_addr (Arena *arena, String8List *out, String8 indent, DW_Raw *input); -internal void dw_print_debug_loclists (Arena *arena, String8List *out, String8 indent, DW_Raw *input, Rng1U64Array segment_vranges, Arch arch); -internal void dw_print_debug_rnglists (Arena *arena, String8List *out, String8 indent, DW_Raw *input, Rng1U64Array segment_vranges); -internal void dw_print_debug_pubnames (Arena *arena, String8List *out, String8 indent, DW_Raw *input); -internal void dw_print_debug_pubtypes (Arena *arena, String8List *out, String8 indent, DW_Raw *input); -internal void dw_print_debug_line_str (Arena *arena, String8List *out, String8 indent, DW_Raw *input); -internal void dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 indent, DW_Raw *input); +internal void dw_print_debug_loc (Arena *arena, String8List *out, String8 indent, DW_Input *input, Arch arch, ExecutableImageKind image_type, B32 relaxed); +internal void dw_print_debug_ranges (Arena *arena, String8List *out, String8 indent, DW_Input *input, Arch arch, ExecutableImageKind image_type, B32 relaxed); +internal void dw_print_debug_aranges (Arena *arena, String8List *out, String8 indent, DW_Input *input); +internal void dw_print_debug_addr (Arena *arena, String8List *out, String8 indent, DW_Input *input); +internal void dw_print_debug_loclists (Arena *arena, String8List *out, String8 indent, DW_Input *input, Rng1U64Array segment_vranges, Arch arch); +internal void dw_print_debug_rnglists (Arena *arena, String8List *out, String8 indent, DW_Input *input, Rng1U64Array segment_vranges); +internal void dw_print_debug_pubnames (Arena *arena, String8List *out, String8 indent, DW_Input *input); +internal void dw_print_debug_pubtypes (Arena *arena, String8List *out, String8 indent, DW_Input *input); +internal void dw_print_debug_line_str (Arena *arena, String8List *out, String8 indent, DW_Input *input); +internal void dw_print_debug_str_offsets(Arena *arena, String8List *out, String8 indent, DW_Input *input); #endif //////////////////////////////// //~ rjf: Dump Entry Point -internal String8List dw_dump_list_from_sections(Arena *arena, DW_Raw *input, Arch arch, DW_DumpSubsetFlags subset_flags); +internal String8List dw_dump_list_from_sections(Arena *arena, DW_Input *input, Arch arch, DW_DumpSubsetFlags subset_flags); #endif // DWARF_DUMP_H diff --git a/src/dwarf/dwarf_elf.c b/src/dwarf/dwarf_elf.c index a247434f..39884286 100644 --- a/src/dwarf/dwarf_elf.c +++ b/src/dwarf/dwarf_elf.c @@ -27,10 +27,10 @@ dw_is_dwarf_present_from_elf_bin(String8 data, ELF_Bin *bin) #define SINFL_IMPLEMENTATION #include "third_party/sinfl/sinfl.h" -internal DW_Raw -dw_raw_from_elf_bin(Arena *arena, String8 data, ELF_Bin *bin) +internal DW_Input +dw_input_from_elf_bin(Arena *arena, String8 data, ELF_Bin *bin) { - DW_Raw result = {0}; + DW_Input result = {0}; B32 is_section_present[ArrayCount(result.sec)] = {0}; for(U64 section_idx = 1; section_idx < bin->shdrs.count; section_idx += 1) { @@ -106,6 +106,7 @@ dw_raw_from_elf_bin(Arena *arena, String8 data, ELF_Bin *bin) //- rjf: store is_section_present[section_kind] = 1; DW_Section *d = &result.sec[section_kind]; + d->name = push_str8_copy(arena, section_name); d->data = section_data__uncompressed; d->is_dwo = is_dwo; } diff --git a/src/dwarf/dwarf_elf.h b/src/dwarf/dwarf_elf.h index c2e8ba78..a9a54f38 100644 --- a/src/dwarf/dwarf_elf.h +++ b/src/dwarf/dwarf_elf.h @@ -5,6 +5,6 @@ #define DWARF_ELF_H internal B32 dw_is_dwarf_present_from_elf_bin(String8 raw_image, ELF_Bin *bin); -internal DW_Raw dw_raw_from_elf_bin(Arena *arena, String8 raw_image, ELF_Bin *bin); +internal DW_Input dw_input_from_elf_bin(Arena *arena, String8 raw_image, ELF_Bin *bin); #endif // DWARF_ELF_H diff --git a/src/dwarf/dwarf_help.h b/src/dwarf/dwarf_help.h index ffb7d37e..2882c6b6 100644 --- a/src/dwarf/dwarf_help.h +++ b/src/dwarf/dwarf_help.h @@ -15,3 +15,4 @@ typedef struct DW_CallFrameInfo internal DW_CallFrameInfo dw_call_frame_info_from_data(Arena *arena, Arch arch, U64 rebase, String8 debug_frame); #endif // DWARF_HELP_H + diff --git a/src/dwarf/dwarf_inc.c b/src/dwarf/dwarf_inc.c index cf8f939e..df0cc700 100644 --- a/src/dwarf/dwarf_inc.c +++ b/src/dwarf/dwarf_inc.c @@ -4,7 +4,6 @@ #include "dwarf/dwarf.c" #include "dwarf/dwarf_expr.c" #include "dwarf/dwarf_parse.c" -#include "dwarf/dwarf_parse_2.c" #include "dwarf/dwarf_coff.c" #include "dwarf/dwarf_elf.c" #include "dwarf/dwarf_unwind.c" diff --git a/src/dwarf/dwarf_inc.h b/src/dwarf/dwarf_inc.h index 1f6937af..44783a34 100644 --- a/src/dwarf/dwarf_inc.h +++ b/src/dwarf/dwarf_inc.h @@ -7,7 +7,6 @@ #include "dwarf/dwarf.h" #include "dwarf/dwarf_expr.h" #include "dwarf/dwarf_parse.h" -#include "dwarf/dwarf_parse_2.h" #include "dwarf/dwarf_coff.h" #include "dwarf/dwarf_elf.h" #include "dwarf/dwarf_unwind.h" diff --git a/src/dwarf/dwarf_parse.c b/src/dwarf/dwarf_parse.c index 415e68cc..8559b08d 100644 --- a/src/dwarf/dwarf_parse.c +++ b/src/dwarf/dwarf_parse.c @@ -2,20 +2,22 @@ // Licensed under the MIT license (https://opensource.org/license/mit/) internal U64 -dw_str8_deserial_read_packed_size(String8 string, U64 off, U64 *size_out) +dw_hash_from_string(String8 string) +{ + XXH64_hash_t hash64 = XXH3_64bits(string.str, string.size); + return hash64; +} + +internal U64 +str8_deserial_read_dwarf_packed_size(String8 string, U64 off, U64 *size_out) { U64 bytes_read = 0; - if(str8_deserial_read(string, off, size_out, sizeof(U32), sizeof(U32))) - { - if(*size_out == max_U32) - { - if(str8_deserial_read_struct(string, off+sizeof(U32), size_out)) - { + if (str8_deserial_read(string, off, size_out, sizeof(U32), sizeof(U32))) { + if (*size_out == max_U32) { + if (str8_deserial_read_struct(string, off+sizeof(U32), size_out)) { bytes_read = sizeof(U32) + sizeof(U64); } - } - else - { + } else { *size_out &= (U64)max_U32; bytes_read = sizeof(U32); } @@ -24,25 +26,149 @@ dw_str8_deserial_read_packed_size(String8 string, U64 off, U64 *size_out) } internal U64 -dw_str8_deserial_read_fmt_uint(String8 string, U64 off, DW_Format format, U64 *uint_out) +str8_deserial_read_dwarf_uint(String8 string, U64 off, DW_Format format, U64 *uint_out) { U64 bytes_read = 0; - switch(format) - { + switch (format) { case DW_Format_Null: break; - case DW_Format_32Bit: - { + case DW_Format_32Bit: { *uint_out &= (U64)max_U32; bytes_read = str8_deserial_read(string, off, uint_out, sizeof(U32), sizeof(U32)); - }break; - case DW_Format_64Bit: - { + } break; + case DW_Format_64Bit: { bytes_read = str8_deserial_read_struct(string, off, uint_out); - }break; + } break; } return bytes_read; } +internal U64 +str8_deserial_read_uleb128(String8 string, U64 off, U64 *value_out) +{ + U64 value = 0; + U64 shift = 0; + U64 cursor = off; + for(;;) + { + U8 byte = 0; + U64 bytes_read = str8_deserial_read_struct(string, cursor, &byte); + + if(bytes_read != sizeof(byte)) + { + break; + } + + U8 val = byte & 0x7fu; + value |= ((U64)val) << shift; + + cursor += bytes_read; + shift += 7u; + + if((byte & 0x80u) == 0) + { + break; + } + } + if(value_out != 0) + { + *value_out = value; + } + U64 bytes_read = cursor - off; + return bytes_read; +} + +internal U64 +str8_deserial_read_sleb128(String8 string, U64 off, S64 *value_out) +{ + U64 value = 0; + U64 shift = 0; + U64 cursor = off; + for(;;) + { + U8 byte; + U64 bytes_read = str8_deserial_read_struct(string, cursor, &byte); + if(bytes_read != sizeof(byte)) + { + break; + } + + U8 val = byte & 0x7fu; + value |= ((U64)val) << shift; + + cursor += bytes_read; + shift += 7u; + + if((byte & 0x80u) == 0) + { + if(shift < sizeof(value) * 8 && (byte & 0x40u) != 0) + { + value |= -(S64)(1ull << shift); + } + break; + } + } + if(value_out != 0) + { + *value_out = value; + } + U64 bytes_read = cursor - off; + return bytes_read; +} + +internal U64 +str8_deserial_read_uleb128_array(Arena *arena, String8 string, U64 off, U64 count, U64 **arr_out) +{ + Temp temp = temp_begin(arena); + + U64 *arr = push_array(arena, U64, count); + U64 i, cursor; + for (i = 0, cursor = off; i < count; ++i) { + U64 read_size = str8_deserial_read_uleb128(string, cursor, &arr[i]); + if (read_size == 0) { + break; + } + cursor += read_size; + } + + U64 bytes_read = 0; + if (i == count) { + *arr_out = arr; + bytes_read = cursor - off; + } else { + temp_end(temp); + *arr_out = 0; + } + + return bytes_read; +} + +internal U64 +str8_deserial_read_sleb128_array(Arena *arena, String8 string, U64 off, U64 count, S64 **arr_out) +{ + Temp temp = temp_begin(arena); + + S64 *arr = push_array(arena, S64, count); + U64 i, cursor; + for (i = 0, cursor = off; i < count; ++i) { + U64 read_size = str8_deserial_read_sleb128(string, cursor, &arr[i]); + if (read_size == 0) { + break; + } + cursor += read_size; + } + + U64 bytes_read = 0; + if (i == count) { + *arr_out = arr; + bytes_read = cursor - off; + } else { + temp_end(temp); + *arr_out = 0; + } + + return bytes_read; +} + internal DW_SectionKind dw_section_kind_from_string(String8 string) { @@ -70,26 +196,27 @@ internal Rng1U64List dw_unit_ranges_from_data(Arena *arena, String8 data) { Rng1U64List result = {0}; - for(U64 cursor = 0; cursor < data.size;) - { - // rjf: read CU size; bad read -> terminate - U64 cu_size = 0; - U64 cu_size_size = dw_str8_deserial_read_packed_size(data, cursor, &cu_size); - if(cu_size_size == 0) - { + + for (U64 cursor = 0; cursor < data.size; ) { + // read CU size + U64 cu_size = 0; + U64 cu_size_size = str8_deserial_read_dwarf_packed_size(data, cursor, &cu_size); + + // was read ok? + if (cu_size_size == 0) { break; } - // rjf: push - if(cu_size > 0) - { + if (cu_size > 0) { + // push unit range rng1u64_list_push(arena, &result, rng_1u64(cursor, cursor+cu_size+cu_size_size)); } - // rjf: advance + // advance cursor += cu_size_size; cursor += cu_size; } + return result; } @@ -99,7 +226,7 @@ dw_read_list_unit_header_addr(String8 unit_data, DW_ListUnit *lu_out) U64 header_size = 0; U64 unit_length = 0; - U64 unit_length_size = dw_str8_deserial_read_packed_size(unit_data, 0, &unit_length); + U64 unit_length_size = str8_deserial_read_dwarf_packed_size(unit_data, 0, &unit_length); if (unit_length_size) { DW_Version version = DW_Version_Null; @@ -140,7 +267,7 @@ dw_read_list_unit_header_str_offsets(String8 unit_data, DW_ListUnit *lu_out) U64 header_size = 0; U64 unit_length = 0; - U64 unit_length_size = dw_str8_deserial_read_packed_size(unit_data, 0, &unit_length); + U64 unit_length_size = str8_deserial_read_dwarf_packed_size(unit_data, 0, &unit_length); if (unit_length_size) { DW_Version version = DW_Version_Null; @@ -171,7 +298,7 @@ dw_read_list_unit_header_list(String8 unit_data, DW_ListUnit *lu_out) U64 header_size = 0; U64 unit_length = 0; - U64 unit_length_size = dw_str8_deserial_read_packed_size(unit_data, 0, &unit_length); + U64 unit_length_size = str8_deserial_read_dwarf_packed_size(unit_data, 0, &unit_length); if (unit_length_size) { DW_Version version = DW_Version_Null; @@ -207,7 +334,7 @@ dw_read_list_unit_header_list(String8 unit_data, DW_ListUnit *lu_out) } internal DW_ListUnitInput -dw_list_unit_input_from_raw(Arena *arena, DW_Raw *input) +dw_list_unit_input_from_input(Arena *arena, DW_Input *input) { Temp scratch = scratch_begin(&arena, 1); @@ -589,11 +716,11 @@ dw_read_form(String8 data, if (version < DW_Version_3) { bytes_read = str8_deserial_read(data, off, &form.ref, address_size, address_size); } else { - bytes_read = dw_str8_deserial_read_fmt_uint(data, off, unit_format, &form.ref); + bytes_read = str8_deserial_read_dwarf_uint(data, off, unit_format, &form.ref); } } break; case DW_Form_GNU_RefAlt: { - bytes_read = dw_str8_deserial_read_fmt_uint(data, off, unit_format, &form.ref); + bytes_read = str8_deserial_read_dwarf_uint(data, off, unit_format, &form.ref); } break; case DW_Form_Ref1: { bytes_read = str8_deserial_read(data, off, &form.ref, 1, 1); @@ -614,7 +741,7 @@ dw_read_form(String8 data, case DW_Form_LineStrp: case DW_Form_GNU_StrpAlt: case DW_Form_Strp: { - bytes_read = dw_str8_deserial_read_fmt_uint(data, off, unit_format, &form.sec_offset); + bytes_read = str8_deserial_read_dwarf_uint(data, off, unit_format, &form.sec_offset); } break; case DW_Form_ExprLoc: { U64 expr_size = 0; @@ -644,7 +771,7 @@ dw_read_form(String8 data, NotImplemented; } break; case DW_Form_StrpSup: { - bytes_read = dw_str8_deserial_read_fmt_uint(data, off, unit_format, &form.strp_sup); + bytes_read = str8_deserial_read_dwarf_uint(data, off, unit_format, &form.strp_sup); } break; case DW_Form_Data16: { bytes_read = str8_deserial_read_block(data, off, 16, &form.data); @@ -758,6 +885,8 @@ dw_read_tag(Arena *arena, // fill out node DW_AttribNode *attrib_n = push_array(arena, DW_AttribNode, 1); attrib_n->v.info_off = tag_base + attrib_tag_cursor; + attrib_n->v.abbrev_off = attrib_abbrev_off; + attrib_n->v.abbrev_id = attrib_abbrev.id; attrib_n->v.attrib_kind = attrib_kind; attrib_n->v.form_kind = form_kind; attrib_n->v.form = form; @@ -780,7 +909,7 @@ dw_read_tag(Arena *arena, } internal U64 -dw_read_tag_cu(Arena *arena, DW_Raw *input, DW_CompUnit *cu, U64 info_off, DW_Tag *tag_out) +dw_read_tag_cu(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 info_off, DW_Tag *tag_out) { String8 tag_data = str8_substr(input->sec[DW_Section_Info].data, cu->info_range); U64 tag_off = info_off - cu->info_range.min; @@ -932,14 +1061,14 @@ dw_interp_address(U64 address_size, U64 base_addr, DW_ListUnit *addr_lu, DW_Form } internal String8 -dw_interp_block(DW_Raw *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form) +dw_interp_block(DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form) { NotImplemented; return str8_zero(); } internal String8 -dw_interp_string(DW_Raw *input, +dw_interp_string(DW_Input *input, DW_Format unit_format, DW_ListUnit *str_offsets, DW_FormKind form_kind, @@ -978,7 +1107,7 @@ dw_interp_string(DW_Raw *input, } internal String8 -dw_interp_line_ptr(DW_Raw *input, DW_FormKind form_kind, DW_Form form) +dw_interp_line_ptr(DW_Input *input, DW_FormKind form_kind, DW_Form form) { String8 result = {0}; if (form_kind == DW_Form_SecOffset) { @@ -1003,7 +1132,7 @@ dw_interp_file(DW_LineVMHeader *line_vm, DW_FormKind form_kind, DW_Form form) } internal DW_Reference -dw_interp_ref(DW_Raw *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form) +dw_interp_ref(DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form) { DW_Reference ref = {0}; if (form_kind == DW_Form_Ref1 || form_kind == DW_Form_Ref2 || @@ -1024,7 +1153,7 @@ dw_interp_ref(DW_Raw *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form for } internal DW_LocList -dw_interp_loclist(Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form) +dw_interp_loclist(Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form) { DW_LocList loclist = {0}; @@ -1311,7 +1440,7 @@ dw_interp_flag(DW_FormKind form_kind, DW_Form form) } internal Rng1U64List -dw_interp_rnglist(Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form) +dw_interp_rnglist(Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form) { Rng1U64List rnglist = {0}; @@ -1502,7 +1631,7 @@ dw_interp_rnglist(Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_FormKind form } internal String8 -dw_interp_secptr(DW_Raw *input, DW_SectionKind section, DW_FormKind form_kind, DW_Form form) +dw_interp_secptr(DW_Input *input, DW_SectionKind section, DW_FormKind form_kind, DW_Form form) { String8 secptr = {0}; if (form_kind == DW_Form_SecOffset) { @@ -1516,25 +1645,25 @@ dw_interp_secptr(DW_Raw *input, DW_SectionKind section, DW_FormKind form_kind, D } internal String8 -dw_interp_addrptr(DW_Raw *input, DW_FormKind form_kind, DW_Form form) +dw_interp_addrptr(DW_Input *input, DW_FormKind form_kind, DW_Form form) { return dw_interp_secptr(input, DW_Section_Addr, form_kind, form); } internal String8 -dw_interp_str_offsets_ptr(DW_Raw *input, DW_FormKind form_kind, DW_Form form) +dw_interp_str_offsets_ptr(DW_Input *input, DW_FormKind form_kind, DW_Form form) { return dw_interp_secptr(input, DW_Section_StrOffsets, form_kind, form); } internal String8 -dw_interp_rnglists_ptr(DW_Raw *input, DW_FormKind form_kind, DW_Form form) +dw_interp_rnglists_ptr(DW_Input *input, DW_FormKind form_kind, DW_Form form) { return dw_interp_secptr(input, DW_Section_RngLists, form_kind, form); } internal String8 -dw_interp_loclists_ptr(DW_Raw *input, DW_FormKind form_kind, DW_Form form) +dw_interp_loclists_ptr(DW_Input *input, DW_FormKind form_kind, DW_Form form) { return dw_interp_secptr(input, DW_Section_LocLists, form_kind, form); } @@ -1542,11 +1671,11 @@ dw_interp_loclists_ptr(DW_Raw *input, DW_FormKind form_kind, DW_Form form) internal DW_AttribClass dw_value_class_from_attrib(DW_CompUnit *cu, DW_Attrib *attrib) { - return dw_pick_attrib_value_class(cu->version, cu->ext, attrib->attrib_kind, attrib->form_kind); + return dw_pick_attrib_value_class(cu->version, cu->ext, cu->relaxed, attrib->attrib_kind, attrib->form_kind); } internal String8 -dw_exprloc_from_attrib(DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib) +dw_exprloc_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) { DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_ExprLoc || value_class == DW_AttribClass_Block); @@ -1554,7 +1683,7 @@ 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) +dw_const_u128_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) { DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_Const); @@ -1562,7 +1691,7 @@ 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) +dw_const_u64_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) { DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_Const); @@ -1570,7 +1699,7 @@ 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) +dw_const_u32_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) { DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_Const); @@ -1578,7 +1707,7 @@ 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) +dw_const_s64_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) { DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_Const); @@ -1586,7 +1715,7 @@ 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) +dw_const_s32_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) { DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_Const); @@ -1594,7 +1723,7 @@ 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) +dw_flag_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) { DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_Flag); @@ -1602,7 +1731,7 @@ 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) +dw_address_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) { DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); AssertAlways(value_class == DW_AttribClass_Null || @@ -1627,7 +1756,7 @@ 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) +dw_block_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) { DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_Block); @@ -1635,7 +1764,7 @@ 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) +dw_string_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) { DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_String || value_class == DW_AttribClass_StrOffsetsPtr); @@ -1643,7 +1772,7 @@ 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) +dw_line_ptr_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) { DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_LinePtr); @@ -1659,7 +1788,7 @@ dw_file_from_attrib(DW_CompUnit *cu, DW_LineVMHeader *line_vm, DW_Attrib *attrib } internal DW_Reference -dw_ref_from_attrib(DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib) +dw_ref_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) { DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); AssertAlways(value_class == DW_AttribClass_Null || value_class == DW_AttribClass_Reference); @@ -1667,7 +1796,7 @@ 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) +dw_loclist_from_attrib(Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) { DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); AssertAlways(value_class == DW_AttribClass_Null || @@ -1677,7 +1806,7 @@ dw_loclist_from_attrib(Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_Attrib * } internal Rng1U64List -dw_rnglist_from_attrib(Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib) +dw_rnglist_from_attrib(Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib) { Rng1U64List rnglist = {0}; DW_AttribClass value_class = dw_value_class_from_attrib(cu, attrib); @@ -1704,7 +1833,7 @@ dw_attrib_from_tag_(DW_Tag tag, DW_AttribKind kind) } internal DW_Attrib * -dw_attrib_from_tag(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +dw_attrib_from_tag(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) { DW_Attrib *attrib = dw_attrib_from_tag_(tag, kind); @@ -1723,7 +1852,7 @@ dw_attrib_from_tag(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kin } internal B32 -dw_tag_has_attrib(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +dw_tag_has_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) { DW_Attrib *attrib = dw_attrib_from_tag(input, cu, tag, kind); B32 has_attrib = attrib->attrib_kind != DW_AttribKind_Null; @@ -1731,85 +1860,85 @@ dw_tag_has_attrib(DW_Raw *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) +dw_exprloc_from_tag_attrib_kind(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) { return dw_exprloc_from_attrib(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); } internal String8 -dw_block_from_tag_attrib_kind(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +dw_block_from_tag_attrib_kind(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) { return dw_block_from_attrib(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); } internal U128 -dw_const_u128_from_tag_attrib_kind(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +dw_const_u128_from_tag_attrib_kind(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) { return dw_const_u128_from_attrib(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); } internal U64 -dw_const_u64_from_tag_attrib_kind(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +dw_const_u64_from_tag_attrib_kind(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) { return dw_const_u64_from_attrib(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); } internal U32 -dw_const_u32_from_tag_attrib_kind(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +dw_const_u32_from_tag_attrib_kind(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) { return dw_const_u32_from_attrib(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); } internal U64 -dw_address_from_tag_attrib_kind(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +dw_address_from_tag_attrib_kind(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) { return dw_address_from_attrib(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); } internal String8 -dw_string_from_tag_attrib_kind(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +dw_string_from_tag_attrib_kind(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) { return dw_string_from_attrib(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); } internal String8 -dw_line_ptr_from_tag_attrib_kind(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +dw_line_ptr_from_tag_attrib_kind(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) { return dw_line_ptr_from_attrib(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); } internal DW_Reference -dw_ref_from_tag_attrib_kind(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +dw_ref_from_tag_attrib_kind(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) { return dw_ref_from_attrib(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); } internal DW_LocList -dw_loclist_from_tag_attrib_kind(Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +dw_loclist_from_tag_attrib_kind(Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) { return dw_loclist_from_attrib(arena, input, cu, dw_attrib_from_tag(input, cu, tag, kind)); } internal Rng1U64List -dw_rnglist_from_tag_attrib_kind(Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +dw_rnglist_from_tag_attrib_kind(Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) { return dw_rnglist_from_attrib(arena, input, cu, dw_attrib_from_tag(input, cu, tag, kind)); } internal B32 -dw_flag_from_tag_attrib_kind(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +dw_flag_from_tag_attrib_kind(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) { return dw_flag_from_attrib(input, cu, dw_attrib_from_tag(input, cu, tag, kind)); } internal DW_LineFile * -dw_file_from_tag_attrib_kind(DW_Raw *input, DW_CompUnit *cu, DW_LineVMHeader *line_vm, DW_Tag tag, DW_AttribKind kind) +dw_file_from_tag_attrib_kind(DW_Input *input, DW_CompUnit *cu, DW_LineVMHeader *line_vm, DW_Tag tag, DW_AttribKind kind) { return dw_file_from_attrib(cu, line_vm, dw_attrib_from_tag(input, cu, tag, kind)); } internal B32 -dw_try_byte_size_from_tag(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, U64 *byte_size_out) +dw_try_byte_size_from_tag(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, U64 *byte_size_out) { B32 has_byte_size = dw_tag_has_attrib(input, cu, tag, DW_AttribKind_ByteSize); B32 has_bit_size = dw_tag_has_attrib(input, cu, tag, DW_AttribKind_BitSize ); @@ -1831,7 +1960,7 @@ dw_try_byte_size_from_tag(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, U64 *byte_ } internal U64 -dw_byte_size_from_tag(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag) +dw_byte_size_from_tag(DW_Input *input, DW_CompUnit *cu, DW_Tag tag) { U64 byte_size = max_U64; dw_try_byte_size_from_tag(input, cu, tag, &byte_size); @@ -1839,7 +1968,7 @@ dw_byte_size_from_tag(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag) } internal U32 -dw_byte_size_32_from_tag(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag) +dw_byte_size_32_from_tag(DW_Input *input, DW_CompUnit *cu, DW_Tag tag) { U32 byte_size32 = 0; U64 byte_size64; @@ -1850,7 +1979,7 @@ dw_byte_size_32_from_tag(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag) } internal U64 -dw_u64_from_attrib(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +dw_u64_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) { U64 result = 0; DW_Attrib *attrib = dw_attrib_from_tag(input, cu, tag, kind); @@ -1881,7 +2010,7 @@ dw_u64_from_attrib(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kin } internal DW_CompUnit -dw_cu_from_info_off(Arena *arena, DW_Raw *input, DW_ListUnitInput lu_input, U64 offset) +dw_cu_from_info_off(Arena *arena, DW_Input *input, DW_ListUnitInput lu_input, U64 offset, B32 relaxed) { DW_CompUnit cu = {0}; @@ -1889,7 +2018,7 @@ dw_cu_from_info_off(Arena *arena, DW_Raw *input, DW_ListUnitInput lu_input, U64 // read unit size in bytes U64 length = 0; - U64 length_size = dw_str8_deserial_read_packed_size(info_data, offset, &length); + U64 length_size = str8_deserial_read_dwarf_packed_size(info_data, offset, &length); if (length_size) { // compute unit range @@ -1936,7 +2065,7 @@ dw_cu_from_info_off(Arena *arena, DW_Raw *input, DW_ListUnitInput lu_input, U64 case DW_Version_3: case DW_Version_4: { U64 abbrev_base_off = cursor; - U64 abbrev_base_size = dw_str8_deserial_read_fmt_uint(data, abbrev_base_off, format, &abbrev_base); + U64 abbrev_base_size = str8_deserial_read_dwarf_uint(data, abbrev_base_off, format, &abbrev_base); if (!abbrev_base_size) { break; } @@ -1964,7 +2093,7 @@ dw_cu_from_info_off(Arena *arena, DW_Raw *input, DW_ListUnitInput lu_input, U64 } U64 abbrev_base_off = address_size_off + address_size_size; - U64 abbrev_base_size = dw_str8_deserial_read_fmt_uint(data, abbrev_base_off, format, &abbrev_base); + U64 abbrev_base_size = str8_deserial_read_dwarf_uint(data, abbrev_base_off, format, &abbrev_base); if (!abbrev_base_size) { break; } @@ -2027,6 +2156,7 @@ dw_cu_from_info_off(Arena *arena, DW_Raw *input, DW_ListUnitInput lu_input, U64 U64 low_pc = dw_interp_address(address_size, max_U64, addr_lu, low_pc_attrib->form_kind, low_pc_attrib->form); // fill out compile unit + cu.relaxed = relaxed; cu.ext = DW_Ext_All; cu.kind = unit_kind; cu.version = version; @@ -2087,7 +2217,7 @@ dw_tag_tree_from_data(Arena *arena, String8 info_data, String8 abbrev_data, DW_C } internal DW_TagTree -dw_tag_tree_from_cu(Arena *arena, DW_Raw *input, DW_CompUnit *cu) +dw_tag_tree_from_cu(Arena *arena, DW_Input *input, DW_CompUnit *cu) { String8 abbrev_data = input->sec[DW_Section_Abbrev].data; String8 info_data = str8_substr(input->sec[DW_Section_Info].data, cu->info_range); @@ -2180,7 +2310,7 @@ dw_line_vm_file_array_from_list(Arena *arena, DW_LineVMFileList list) internal U64 dw_read_line_file(String8 data, U64 off, - DW_Raw *input, + DW_Input *input, DW_Version version, DW_Format format, DW_Ext ext, @@ -2242,7 +2372,7 @@ internal U64 dw_read_line_file_array(Arena *arena, String8 data, U64 off, - DW_Raw *input, + DW_Input *input, DW_Version version, DW_Format format, DW_Ext ext, @@ -2290,7 +2420,15 @@ dw_read_line_file_array(Arena *arena, } internal U64 -dw_read_line_vm_header(Arena *arena, String8 line_data, U64 line_off, DW_Raw *input, String8 cu_dir, String8 cu_name, U8 cu_address_size, DW_ListUnit *cu_str_offsets, DW_LineVMHeader *header_out) +dw_read_line_vm_header(Arena *arena, + String8 line_data, + U64 line_off, + DW_Input *input, + String8 cu_dir, + String8 cu_name, + U8 cu_address_size, + DW_ListUnit *cu_str_offsets, + DW_LineVMHeader *header_out) { Temp scratch = scratch_begin(&arena, 1); @@ -2298,7 +2436,7 @@ dw_read_line_vm_header(Arena *arena, String8 line_data, U64 line_off, DW_Raw *in // read unit length U64 unit_length = 0; - U64 unit_length_size = dw_str8_deserial_read_packed_size(line_data, line_off, &unit_length); + U64 unit_length_size = str8_deserial_read_dwarf_packed_size(line_data, line_off, &unit_length); U64 unit_opl = line_off + unit_length_size + unit_length; Rng1U64 unit_range = rng_1u64(line_off, unit_opl); @@ -2335,7 +2473,7 @@ dw_read_line_vm_header(Arena *arena, String8 line_data, U64 line_off, DW_Raw *in // read header length U64 header_length = 0; - U64 header_length_size = dw_str8_deserial_read_fmt_uint(unit_data, unit_cursor, format, &header_length); + U64 header_length_size = str8_deserial_read_dwarf_uint(unit_data, unit_cursor, format, &header_length); if (header_length_size == 0) { goto exit; } @@ -2489,11 +2627,12 @@ dw_read_line_vm_header(Arena *arena, String8 line_data, U64 line_off, DW_Raw *in unit_cursor += enc_count_size; // read table entry encodings - U64 *enc_arr = push_array(scratch.arena, U64, enc_count*2); - for EachIndex(idx, enc_count) - { - unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &enc_arr[idx]); + U64 *enc_arr = 0; + U64 enc_arr_size = str8_deserial_read_uleb128_array(scratch.arena, unit_data, unit_cursor, enc_count*2, &enc_arr); + if (enc_arr_size == 0) { + goto exit; } + unit_cursor += enc_arr_size; // read table count U64 table_count = 0; @@ -2534,11 +2673,12 @@ dw_read_line_vm_header(Arena *arena, String8 line_data, U64 line_off, DW_Raw *in unit_cursor += enc_count_size; // read table entry encodings - U64 *enc_arr = push_array(scratch.arena, U64, enc_count*2); - for EachIndex(idx, enc_count) - { - unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &enc_arr[idx]); + U64 *enc_arr = 0; + U64 enc_arr_size = str8_deserial_read_uleb128_array(scratch.arena, unit_data, unit_cursor, enc_count*2, &enc_arr); + if (enc_arr_size == 0) { + goto exit; } + unit_cursor += enc_arr_size; // read table count U64 table_count = 0; @@ -2684,35 +2824,37 @@ dw_path_from_file_idx(Arena *arena, DW_LineVMHeader *vm, U64 file_idx) } internal DW_LineTableParseResult -dw_parsed_line_table_from_data(Arena *arena, String8 unit_data, DW_Raw *input, String8 cu_dir, String8 cu_name, U8 cu_address_size, DW_ListUnit *cu_str_offsets) +dw_parsed_line_table_from_data(Arena *arena, + String8 unit_data, + DW_Input *input, + String8 cu_dir, + String8 cu_name, + U8 cu_address_size, + DW_ListUnit *cu_str_offsets) { DW_LineVMHeader vm_header = {0}; U64 vm_header_size = dw_read_line_vm_header(arena, unit_data, 0, input, cu_dir, cu_name, cu_address_size, cu_str_offsets, &vm_header); + U64 unit_cursor = vm_header_size; - U64 unit_cursor_opl = Min(unit_data.size, vm_header.unit_range.max); //- rjf: prep state for VM DW_LineVMState vm_state = {0}; dw_line_vm_reset(&vm_state, vm_header.default_is_stmt); //- rjf: VM loop; build output list - DW_LineTableParseResult result = {.vm_header = vm_header}; - B32 end_of_seq = 0; - B32 error = 0; - for(;!error && unit_cursor < unit_cursor_opl;) - { + DW_LineTableParseResult result = { .vm_header = vm_header }; + B32 end_of_seq = 0; + B32 error = 0; + for (; !error && unit_cursor < unit_data.size; ) { //- rjf: parse opcode U8 opcode = 0; unit_cursor += str8_deserial_read_struct(unit_data, unit_cursor, &opcode); //- rjf: do opcode action - switch(opcode) - { - //- rjf: special opcode cases - default: - { - if(opcode >= vm_header.opcode_base) - { + switch (opcode) { + default: { + //- rjf: special opcode case + if (opcode >= vm_header.opcode_base) { U32 adjusted_opcode = (U32)(opcode - vm_header.opcode_base); U32 op_advance = adjusted_opcode / vm_header.line_range; S32 line_inc = (S32)vm_header.line_base + ((S32)adjusted_opcode) % (S32)vm_header.line_range; @@ -2742,31 +2884,25 @@ dw_parsed_line_table_from_data(Arena *arena, String8 unit_data, DW_Raw *input, S } #endif } - // Skipping unknown opcode. This is a valid case and // it works because compiler stores operand lengths. - else - { - if(0 < opcode && opcode <= vm_header.num_opcode_lens) - { + else { + if (0 < opcode && opcode <= vm_header.num_opcode_lens) { U8 num_operands = vm_header.opcode_lens[opcode - 1]; - for(U8 i = 0; i < num_operands; i += 1) - { + for (U8 i = 0; i < num_operands; ++i) { U64 operand = 0; unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &operand); } - } - else - { + } else { error = 1; goto exit; } } - }break; + } break; - //- standard opcodes - case DW_StdOpcode_Copy: - { + //- Standard opcodes + + case DW_StdOpcode_Copy: { if(vm_state.is_stmt) { dw_push_line(arena, &result, &vm_state, end_of_seq); @@ -2776,69 +2912,68 @@ dw_parsed_line_table_from_data(Arena *arena, String8 unit_data, DW_Raw *input, S vm_state.basic_block = 0; vm_state.prologue_end = 0; vm_state.epilogue_begin = 0; - }break; - case DW_StdOpcode_AdvancePc: - { + } break; + + case DW_StdOpcode_AdvancePc: { U64 advance = 0; unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &advance); dw_line_vm_advance(&vm_state, advance, vm_header.min_inst_len, vm_header.max_ops_for_inst); - }break; - case DW_StdOpcode_AdvanceLine: - { + } break; + + case DW_StdOpcode_AdvanceLine: { S64 s = 0; unit_cursor += str8_deserial_read_sleb128(unit_data, unit_cursor, &s); vm_state.line += s; - }break; - case DW_StdOpcode_SetFile: - { + } break; + + case DW_StdOpcode_SetFile: { U64 file_index = 0; unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &file_index); vm_state.file_index = file_index; - }break; - case DW_StdOpcode_SetColumn: - { + } break; + + case DW_StdOpcode_SetColumn: { U64 column = 0; unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &column); vm_state.column = column; - }break; - case DW_StdOpcode_NegateStmt: - { + } break; + + case DW_StdOpcode_NegateStmt: { vm_state.is_stmt = !vm_state.is_stmt; - }break; - case DW_StdOpcode_SetBasicBlock: - { + } break; + + case DW_StdOpcode_SetBasicBlock: { vm_state.basic_block = 1; - }break; - case DW_StdOpcode_ConstAddPc: - { + } break; + + case DW_StdOpcode_ConstAddPc: { U64 advance = (0xffu - vm_header.opcode_base) / vm_header.line_range; dw_line_vm_advance(&vm_state, advance, vm_header.min_inst_len, vm_header.max_ops_for_inst); - }break; - case DW_StdOpcode_FixedAdvancePc: - { + } break; + + case DW_StdOpcode_FixedAdvancePc: { U16 operand = 0; unit_cursor += str8_deserial_read_struct(unit_data, unit_cursor, &operand); vm_state.address += operand; vm_state.op_index = 0; - }break; - case DW_StdOpcode_SetPrologueEnd: - { + } break; + + case DW_StdOpcode_SetPrologueEnd: { vm_state.prologue_end = 1; - }break; - case DW_StdOpcode_SetEpilogueBegin: - { + } break; + + case DW_StdOpcode_SetEpilogueBegin: { vm_state.epilogue_begin = 1; - }break; - case DW_StdOpcode_SetIsa: - { + } break; + + case DW_StdOpcode_SetIsa: { U64 v = 0; unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &v); vm_state.isa = v; - }break; + } break; - //- extended opcodes - case DW_StdOpcode_ExtendedOpcode: - { + //- Extended opcodes + case DW_StdOpcode_ExtendedOpcode: { U64 length = 0; unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &length); @@ -2846,12 +2981,8 @@ dw_parsed_line_table_from_data(Arena *arena, String8 unit_data, DW_Raw *input, S U8 extended_opcode = 0; unit_cursor += str8_deserial_read_struct(unit_data, unit_cursor, &extended_opcode); - switch(extended_opcode) - { - default:{}break; - - case DW_ExtOpcode_EndSequence: - { + switch (extended_opcode) { + case DW_ExtOpcode_EndSequence: { vm_state.end_sequence = 1; if(vm_state.is_stmt) { @@ -2859,18 +2990,16 @@ dw_parsed_line_table_from_data(Arena *arena, String8 unit_data, DW_Raw *input, S } dw_line_vm_reset(&vm_state, vm_header.default_is_stmt); end_of_seq = 1; - }break; + } break; - case DW_ExtOpcode_SetAddress: - { + case DW_ExtOpcode_SetAddress: { U64 address = 0; unit_cursor += str8_deserial_read(unit_data, unit_cursor, &address, vm_header.address_size, vm_header.address_size); vm_state.address = address; vm_state.op_index = 0; - }break; + } break; - case DW_ExtOpcode_DefineFile: - { + case DW_ExtOpcode_DefineFile: { String8 file_name = {0}; U64 dir_index = 0; U64 modify_time = 0; @@ -2888,26 +3017,30 @@ dw_parsed_line_table_from_data(Arena *arena, String8 unit_data, DW_Raw *input, S // // See the DWARF V4 spec (June 10, 2010), page 122. error = 1; - }break; + AssertAlways(!"UNHANDLED DEFINE FILE!!!"); + } break; - case DW_ExtOpcode_SetDiscriminator: - { + case DW_ExtOpcode_SetDiscriminator: { U64 v = 0; unit_cursor += str8_deserial_read_uleb128(unit_data, unit_cursor, &v); vm_state.discriminator = v; - }break; + } break; + + default: break; } unit_cursor = extended_opl; - }break; + } break; } } + exit:; + return result; } internal DW_PubStringsTable -dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Raw *input, DW_SectionKind section_kind) +dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Input *input, DW_SectionKind section_kind) { Temp scratch = scratch_begin(&arena, 1); @@ -2919,7 +3052,7 @@ dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Raw *input, DW_Sectio for(U64 cursor = 0; cursor < section_data.size; ) { U64 unit_length = 0; - U64 unit_length_size = dw_str8_deserial_read_packed_size(section_data, cursor, &unit_length); + U64 unit_length_size = str8_deserial_read_dwarf_packed_size(section_data, cursor, &unit_length); if (unit_length_size == 0) { break; } @@ -2939,13 +3072,13 @@ dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Raw *input, DW_Sectio DW_Format format = DW_FormatFromSize(unit_length); U64 debug_info_off = 0; - cursor += dw_str8_deserial_read_fmt_uint(section_data, cursor, format, &debug_info_off); + cursor += str8_deserial_read_dwarf_uint(section_data, cursor, format, &debug_info_off); if (cursor >= cursor_opl) { break; } U64 debug_info_length = 0; - cursor += dw_str8_deserial_read_packed_size(section_data, cursor, &debug_info_length); + cursor += str8_deserial_read_dwarf_packed_size(section_data, cursor, &debug_info_length); if (cursor >= cursor_opl) { break; } @@ -2953,7 +3086,7 @@ dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Raw *input, DW_Sectio U64 off_size = dw_size_from_format(format); for (; (cursor + off_size) <= cursor_opl;) { U64 info_off = 0; - U64 info_off_size = dw_str8_deserial_read_fmt_uint(section_data, cursor, format, &info_off); + U64 info_off_size = str8_deserial_read_dwarf_uint(section_data, cursor, format, &info_off); cursor += info_off_size; if (info_off_size == 0 || info_off == 0) { @@ -2963,7 +3096,7 @@ dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Raw *input, DW_Sectio String8 string = {0}; cursor += str8_deserial_read_cstr(section_data, cursor, &string); - U64 hash = u64_hash_from_str8(string); + U64 hash = dw_hash_from_string(string); U64 bucket_idx = hash % names_table.size; DW_PubStringsBucket *bucket = push_array(arena, DW_PubStringsBucket, 1); @@ -2985,205 +3118,205 @@ dw_expr_from_data(Arena *arena, DW_Format format, U64 addr_size, String8 data) DW_Expr expr = {0}; for (U64 cursor = 0; cursor < data.size; ) { U64 inst_start = cursor; - + DW_ExprOp opcode = 0; cursor += str8_deserial_read_struct(data, cursor, &opcode); DW_ExprOperand operands[4] = {0}; switch (opcode) { - case DW_ExprOp_Lit0: case DW_ExprOp_Lit1: case DW_ExprOp_Lit2: - case DW_ExprOp_Lit3: case DW_ExprOp_Lit4: case DW_ExprOp_Lit5: - case DW_ExprOp_Lit6: case DW_ExprOp_Lit7: case DW_ExprOp_Lit8: - case DW_ExprOp_Lit9: case DW_ExprOp_Lit10: case DW_ExprOp_Lit11: - case DW_ExprOp_Lit12: case DW_ExprOp_Lit13: case DW_ExprOp_Lit14: - case DW_ExprOp_Lit15: case DW_ExprOp_Lit16: case DW_ExprOp_Lit17: - case DW_ExprOp_Lit18: case DW_ExprOp_Lit19: case DW_ExprOp_Lit20: - case DW_ExprOp_Lit21: case DW_ExprOp_Lit22: case DW_ExprOp_Lit23: - case DW_ExprOp_Lit24: case DW_ExprOp_Lit25: case DW_ExprOp_Lit26: - case DW_ExprOp_Lit27: case DW_ExprOp_Lit28: case DW_ExprOp_Lit29: - case DW_ExprOp_Lit30: case DW_ExprOp_Lit31: { - // implicit operands - } break; - case DW_ExprOp_Const1U: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8); } break; - case DW_ExprOp_Const2U: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].u16); } break; - case DW_ExprOp_Const4U: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].u32); } break; - case DW_ExprOp_Const8U: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].u64); } break; - case DW_ExprOp_Const1S: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].s8); } break; - case DW_ExprOp_Const2S: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].s16); } break; - case DW_ExprOp_Const4S: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].s32); } break; - case DW_ExprOp_Const8S: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].s64); } break; - case DW_ExprOp_ConstU: { cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); } break; - case DW_ExprOp_ConstS: { cursor += str8_deserial_read_sleb128(data, cursor, &operands[0].s64); } break; - case DW_ExprOp_Addr: { cursor += str8_deserial_read(data, cursor, &operands[0].u64, addr_size, addr_size); } break; - case DW_ExprOp_Reg0: case DW_ExprOp_Reg1: case DW_ExprOp_Reg2: - case DW_ExprOp_Reg3: case DW_ExprOp_Reg4: case DW_ExprOp_Reg5: - case DW_ExprOp_Reg6: case DW_ExprOp_Reg7: case DW_ExprOp_Reg8: - case DW_ExprOp_Reg9: case DW_ExprOp_Reg10: case DW_ExprOp_Reg11: - case DW_ExprOp_Reg12: case DW_ExprOp_Reg13: case DW_ExprOp_Reg14: - case DW_ExprOp_Reg15: case DW_ExprOp_Reg16: case DW_ExprOp_Reg17: - case DW_ExprOp_Reg18: case DW_ExprOp_Reg19: case DW_ExprOp_Reg20: - case DW_ExprOp_Reg21: case DW_ExprOp_Reg22: case DW_ExprOp_Reg23: - case DW_ExprOp_Reg24: case DW_ExprOp_Reg25: case DW_ExprOp_Reg26: - case DW_ExprOp_Reg27: case DW_ExprOp_Reg28: case DW_ExprOp_Reg29: - case DW_ExprOp_Reg30: case DW_ExprOp_Reg31: { - // implicit operands - } break; - case DW_ExprOp_RegX: { cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); } break; - case DW_ExprOp_ImplicitValue: { - U64 value_size = 0; String8 value = {0}; - cursor += str8_deserial_read_uleb128(data, cursor, &value_size); - cursor += str8_deserial_read_block(data, cursor, value_size, &operands[0].block); - } break; - case DW_ExprOp_Piece: { - cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); - } break; - case DW_ExprOp_BitPiece: { - cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); - cursor += str8_deserial_read_uleb128(data, cursor, &operands[1].u64); - } break; - case DW_ExprOp_Pick: { - cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8); - } break; - case DW_ExprOp_PlusUConst: { - cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); - } break; - case DW_ExprOp_Skip: { - cursor += str8_deserial_read_struct(data, cursor, &operands[0].s16); - } break; - case DW_ExprOp_Bra: { - cursor += str8_deserial_read_struct(data, cursor, &operands[0].s16); - } break; - case DW_ExprOp_BReg0: case DW_ExprOp_BReg1: case DW_ExprOp_BReg2: - case DW_ExprOp_BReg3: case DW_ExprOp_BReg4: case DW_ExprOp_BReg5: - case DW_ExprOp_BReg6: case DW_ExprOp_BReg7: case DW_ExprOp_BReg8: - case DW_ExprOp_BReg9: case DW_ExprOp_BReg10: case DW_ExprOp_BReg11: - case DW_ExprOp_BReg12: case DW_ExprOp_BReg13: case DW_ExprOp_BReg14: - case DW_ExprOp_BReg15: case DW_ExprOp_BReg16: case DW_ExprOp_BReg17: - case DW_ExprOp_BReg18: case DW_ExprOp_BReg19: case DW_ExprOp_BReg20: - case DW_ExprOp_BReg21: case DW_ExprOp_BReg22: case DW_ExprOp_BReg23: - case DW_ExprOp_BReg24: case DW_ExprOp_BReg25: case DW_ExprOp_BReg26: - case DW_ExprOp_BReg27: case DW_ExprOp_BReg28: case DW_ExprOp_BReg29: - case DW_ExprOp_BReg30: case DW_ExprOp_BReg31: { - cursor += str8_deserial_read_sleb128(data, cursor, &operands[0].s64); - } break; - case DW_ExprOp_BRegX: { - cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); - cursor += str8_deserial_read_sleb128(data, cursor, &operands[1].s64); - } break; - case DW_ExprOp_FBReg: { - cursor += str8_deserial_read_sleb128(data, cursor, &operands[0].s64); - } break; - case DW_ExprOp_Deref: { - // no operands - } break; - case DW_ExprOp_DerefSize: { - cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8); - } break; - case DW_ExprOp_XDerefSize: { - cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8); - } break; - case DW_ExprOp_Call2: { - cursor += str8_deserial_read_struct(data, cursor, &operands[0].u16); - } break; - case DW_ExprOp_Call4: { - cursor += str8_deserial_read_struct(data, cursor, &operands[0].u32); - } break; - case DW_ExprOp_CallRef: { - cursor += dw_str8_deserial_read_fmt_uint(data, cursor, format, &operands[0].u64); - } break; - case DW_ExprOp_ImplicitPointer: - case DW_ExprOp_GNU_ImplicitPointer: { - cursor += dw_str8_deserial_read_fmt_uint(data, cursor, format, &operands[0].u64); - cursor += str8_deserial_read_sleb128(data, cursor, &operands[1].s64); - } break; - case DW_ExprOp_Convert: - case DW_ExprOp_GNU_Convert: { - cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); - } break; - case DW_ExprOp_GNU_ParameterRef: { - cursor += str8_deserial_read_struct(data, cursor, &operands[0].u32); - } break; - case DW_ExprOp_DerefType: - case DW_ExprOp_GNU_DerefType: { - cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8); - cursor += str8_deserial_read_uleb128(data, cursor, &operands[1].u64); - } break; - case DW_ExprOp_XDerefType: { - cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8); - cursor += str8_deserial_read_uleb128(data, cursor, &operands[1].u64); - } break; - case DW_ExprOp_ConstType: - case DW_ExprOp_GNU_ConstType: { - cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); - cursor += str8_deserial_read_struct(data, cursor, &operands[1].u8); - cursor += str8_deserial_read_block(data, cursor, operands[1].u8, &operands[2].block); - } break; - case DW_ExprOp_RegvalType: { - cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); - cursor += str8_deserial_read_uleb128(data, cursor, &operands[1].u64); - } break; - case DW_ExprOp_EntryValue: - case DW_ExprOp_GNU_EntryValue: { - U64 entry_value_expr_size = 0; - cursor += str8_deserial_read_uleb128(data, cursor, &entry_value_expr_size); - cursor += str8_deserial_read_block(data, cursor, entry_value_expr_size, &operands[0].block); - } break; - case DW_ExprOp_Addrx: { - cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); - } break; - case DW_ExprOp_Constx: { - cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); - } break; - case DW_ExprOp_CallFrameCfa: - case DW_ExprOp_FormTlsAddress: - case DW_ExprOp_PushObjectAddress: - case DW_ExprOp_Nop: - case DW_ExprOp_Eq: - case DW_ExprOp_Ge: - case DW_ExprOp_Gt: - case DW_ExprOp_Le: - case DW_ExprOp_Lt: - case DW_ExprOp_Ne: - case DW_ExprOp_Shl: - case DW_ExprOp_Shr: - case DW_ExprOp_Shra: - case DW_ExprOp_Xor: - case DW_ExprOp_XDeref: - case DW_ExprOp_Abs: - case DW_ExprOp_And: - case DW_ExprOp_Div: - case DW_ExprOp_Minus: - case DW_ExprOp_Mod: - case DW_ExprOp_Mul: - case DW_ExprOp_Neg: - case DW_ExprOp_Not: - case DW_ExprOp_Or: - case DW_ExprOp_Plus: - case DW_ExprOp_Rot: - case DW_ExprOp_Swap: - case DW_ExprOp_Dup: - case DW_ExprOp_Drop: - case DW_ExprOp_Over: - case DW_ExprOp_StackValue: - case DW_ExprOp_GNU_PushTlsAddress: { - // no operands - } break; - case DW_ExprOp_GNU_AddrIndex: { - cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); - } break; - case DW_ExprOp_GNU_ConstIndex: { - cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); - } break; - default: { InvalidPath; } break; + case DW_ExprOp_Lit0: case DW_ExprOp_Lit1: case DW_ExprOp_Lit2: + case DW_ExprOp_Lit3: case DW_ExprOp_Lit4: case DW_ExprOp_Lit5: + case DW_ExprOp_Lit6: case DW_ExprOp_Lit7: case DW_ExprOp_Lit8: + case DW_ExprOp_Lit9: case DW_ExprOp_Lit10: case DW_ExprOp_Lit11: + case DW_ExprOp_Lit12: case DW_ExprOp_Lit13: case DW_ExprOp_Lit14: + case DW_ExprOp_Lit15: case DW_ExprOp_Lit16: case DW_ExprOp_Lit17: + case DW_ExprOp_Lit18: case DW_ExprOp_Lit19: case DW_ExprOp_Lit20: + case DW_ExprOp_Lit21: case DW_ExprOp_Lit22: case DW_ExprOp_Lit23: + case DW_ExprOp_Lit24: case DW_ExprOp_Lit25: case DW_ExprOp_Lit26: + case DW_ExprOp_Lit27: case DW_ExprOp_Lit28: case DW_ExprOp_Lit29: + case DW_ExprOp_Lit30: case DW_ExprOp_Lit31: { + // implicit operands + } break; + case DW_ExprOp_Const1U: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8); } break; + case DW_ExprOp_Const2U: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].u16); } break; + case DW_ExprOp_Const4U: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].u32); } break; + case DW_ExprOp_Const8U: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].u64); } break; + case DW_ExprOp_Const1S: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].s8); } break; + case DW_ExprOp_Const2S: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].s16); } break; + case DW_ExprOp_Const4S: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].s32); } break; + case DW_ExprOp_Const8S: { cursor += str8_deserial_read_struct(data, cursor, &operands[0].s64); } break; + case DW_ExprOp_ConstU: { cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); } break; + case DW_ExprOp_ConstS: { cursor += str8_deserial_read_sleb128(data, cursor, &operands[0].s64); } break; + case DW_ExprOp_Addr: { cursor += str8_deserial_read(data, cursor, &operands[0].u64, addr_size, addr_size); } break; + case DW_ExprOp_Reg0: case DW_ExprOp_Reg1: case DW_ExprOp_Reg2: + case DW_ExprOp_Reg3: case DW_ExprOp_Reg4: case DW_ExprOp_Reg5: + case DW_ExprOp_Reg6: case DW_ExprOp_Reg7: case DW_ExprOp_Reg8: + case DW_ExprOp_Reg9: case DW_ExprOp_Reg10: case DW_ExprOp_Reg11: + case DW_ExprOp_Reg12: case DW_ExprOp_Reg13: case DW_ExprOp_Reg14: + case DW_ExprOp_Reg15: case DW_ExprOp_Reg16: case DW_ExprOp_Reg17: + case DW_ExprOp_Reg18: case DW_ExprOp_Reg19: case DW_ExprOp_Reg20: + case DW_ExprOp_Reg21: case DW_ExprOp_Reg22: case DW_ExprOp_Reg23: + case DW_ExprOp_Reg24: case DW_ExprOp_Reg25: case DW_ExprOp_Reg26: + case DW_ExprOp_Reg27: case DW_ExprOp_Reg28: case DW_ExprOp_Reg29: + case DW_ExprOp_Reg30: case DW_ExprOp_Reg31: { + // implicit operands + } break; + case DW_ExprOp_RegX: { cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); } break; + case DW_ExprOp_ImplicitValue: { + U64 value_size = 0; String8 value = {0}; + cursor += str8_deserial_read_uleb128(data, cursor, &value_size); + cursor += str8_deserial_read_block(data, cursor, value_size, &operands[0].block); + } break; + case DW_ExprOp_Piece: { + cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); + } break; + case DW_ExprOp_BitPiece: { + cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); + cursor += str8_deserial_read_uleb128(data, cursor, &operands[1].u64); + } break; + case DW_ExprOp_Pick: { + cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8); + } break; + case DW_ExprOp_PlusUConst: { + cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); + } break; + case DW_ExprOp_Skip: { + cursor += str8_deserial_read_struct(data, cursor, &operands[0].s16); + } break; + case DW_ExprOp_Bra: { + cursor += str8_deserial_read_struct(data, cursor, &operands[0].s16); + } break; + case DW_ExprOp_BReg0: case DW_ExprOp_BReg1: case DW_ExprOp_BReg2: + case DW_ExprOp_BReg3: case DW_ExprOp_BReg4: case DW_ExprOp_BReg5: + case DW_ExprOp_BReg6: case DW_ExprOp_BReg7: case DW_ExprOp_BReg8: + case DW_ExprOp_BReg9: case DW_ExprOp_BReg10: case DW_ExprOp_BReg11: + case DW_ExprOp_BReg12: case DW_ExprOp_BReg13: case DW_ExprOp_BReg14: + case DW_ExprOp_BReg15: case DW_ExprOp_BReg16: case DW_ExprOp_BReg17: + case DW_ExprOp_BReg18: case DW_ExprOp_BReg19: case DW_ExprOp_BReg20: + case DW_ExprOp_BReg21: case DW_ExprOp_BReg22: case DW_ExprOp_BReg23: + case DW_ExprOp_BReg24: case DW_ExprOp_BReg25: case DW_ExprOp_BReg26: + case DW_ExprOp_BReg27: case DW_ExprOp_BReg28: case DW_ExprOp_BReg29: + case DW_ExprOp_BReg30: case DW_ExprOp_BReg31: { + cursor += str8_deserial_read_sleb128(data, cursor, &operands[0].s64); + } break; + case DW_ExprOp_BRegX: { + cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); + cursor += str8_deserial_read_sleb128(data, cursor, &operands[1].s64); + } break; + case DW_ExprOp_FBReg: { + cursor += str8_deserial_read_sleb128(data, cursor, &operands[0].s64); + } break; + case DW_ExprOp_Deref: { + // no operands + } break; + case DW_ExprOp_DerefSize: { + cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8); + } break; + case DW_ExprOp_XDerefSize: { + cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8); + } break; + case DW_ExprOp_Call2: { + cursor += str8_deserial_read_struct(data, cursor, &operands[0].u16); + } break; + case DW_ExprOp_Call4: { + cursor += str8_deserial_read_struct(data, cursor, &operands[0].u32); + } break; + case DW_ExprOp_CallRef: { + cursor += str8_deserial_read_dwarf_uint(data, cursor, format, &operands[0].u64); + } break; + case DW_ExprOp_ImplicitPointer: + case DW_ExprOp_GNU_ImplicitPointer: { + cursor += str8_deserial_read_dwarf_uint(data, cursor, format, &operands[0].u64); + cursor += str8_deserial_read_sleb128(data, cursor, &operands[1].s64); + } break; + case DW_ExprOp_Convert: + case DW_ExprOp_GNU_Convert: { + cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); + } break; + case DW_ExprOp_GNU_ParameterRef: { + cursor += str8_deserial_read_struct(data, cursor, &operands[0].u32); + } break; + case DW_ExprOp_DerefType: + case DW_ExprOp_GNU_DerefType: { + cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8); + cursor += str8_deserial_read_uleb128(data, cursor, &operands[1].u64); + } break; + case DW_ExprOp_XDerefType: { + cursor += str8_deserial_read_struct(data, cursor, &operands[0].u8); + cursor += str8_deserial_read_uleb128(data, cursor, &operands[1].u64); + } break; + case DW_ExprOp_ConstType: + case DW_ExprOp_GNU_ConstType: { + cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); + cursor += str8_deserial_read_struct(data, cursor, &operands[1].u8); + cursor += str8_deserial_read_block(data, cursor, operands[1].u8, &operands[2].block); + } break; + case DW_ExprOp_RegvalType: { + cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); + cursor += str8_deserial_read_uleb128(data, cursor, &operands[1].u64); + } break; + case DW_ExprOp_EntryValue: + case DW_ExprOp_GNU_EntryValue: { + U64 entry_value_expr_size = 0; + cursor += str8_deserial_read_uleb128(data, cursor, &entry_value_expr_size); + cursor += str8_deserial_read_block(data, cursor, entry_value_expr_size, &operands[0].block); + } break; + case DW_ExprOp_Addrx: { + cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); + } break; + case DW_ExprOp_Constx: { + cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); + } break; + case DW_ExprOp_CallFrameCfa: + case DW_ExprOp_FormTlsAddress: + case DW_ExprOp_PushObjectAddress: + case DW_ExprOp_Nop: + case DW_ExprOp_Eq: + case DW_ExprOp_Ge: + case DW_ExprOp_Gt: + case DW_ExprOp_Le: + case DW_ExprOp_Lt: + case DW_ExprOp_Ne: + case DW_ExprOp_Shl: + case DW_ExprOp_Shr: + case DW_ExprOp_Shra: + case DW_ExprOp_Xor: + case DW_ExprOp_XDeref: + case DW_ExprOp_Abs: + case DW_ExprOp_And: + case DW_ExprOp_Div: + case DW_ExprOp_Minus: + case DW_ExprOp_Mod: + case DW_ExprOp_Mul: + case DW_ExprOp_Neg: + case DW_ExprOp_Not: + case DW_ExprOp_Or: + case DW_ExprOp_Plus: + case DW_ExprOp_Rot: + case DW_ExprOp_Swap: + case DW_ExprOp_Dup: + case DW_ExprOp_Drop: + case DW_ExprOp_Over: + case DW_ExprOp_StackValue: + case DW_ExprOp_GNU_PushTlsAddress: { + // no operands + } break; + case DW_ExprOp_GNU_AddrIndex: { + cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); + } break; + case DW_ExprOp_GNU_ConstIndex: { + cursor += str8_deserial_read_uleb128(data, cursor, &operands[0].u64); + } break; + default: { InvalidPath; } break; } - + U64 operand_count = dw_operand_count_from_expr_op(opcode); DW_ExprInst *inst = push_array(arena, DW_ExprInst, 1); inst->opcode = opcode; inst->size = cursor - inst_start; inst->operands = push_array(arena, DW_ExprOperand, operand_count); MemoryCopy(inst->operands, operands, operand_count * sizeof(DW_ExprOperand)); - + DLLPushBack(expr.first, expr.last, inst); expr.count += 1; } @@ -3224,25 +3357,25 @@ dw_parse_descriptor_entry_header(String8 data, U64 off, DW_DescriptorEntry *desc U32 first_four_bytes = 0; str8_deserial_read_struct(data, off, &first_four_bytes); DW_Format format = first_four_bytes == max_U32 ? DW_Format_64Bit : DW_Format_32Bit; - + U64 length = 0; - U64 length_size = dw_str8_deserial_read_packed_size(data, off, &length); + U64 length_size = str8_deserial_read_dwarf_packed_size(data, off, &length); if (length_size == 0) { goto exit; } - + Rng1U64 entry_range = rng_1u64(off, off + length_size + length); String8 entry_data = str8_substr(data, entry_range); U64 id = 0; - U64 id_size = dw_str8_deserial_read_fmt_uint(entry_data, length_size, format, &id); + U64 id_size = str8_deserial_read_dwarf_uint(entry_data, length_size, format, &id); if (id_size == 0) { goto exit; } - + U64 id_type = format == DW_Format_32Bit ? max_U32 : max_U64; desc_out->format = format; desc_out->type = (id == id_type) ? DW_DescriptorEntryType_CIE : DW_DescriptorEntryType_FDE; desc_out->entry_range = entry_range; desc_out->cie_pointer = id; desc_out->cie_pointer_off = length_size; - - exit:; + +exit:; return length + length_size; } @@ -3251,55 +3384,55 @@ dw_parse_cie(String8 data, DW_Format format, Arch arch, DW_CIE *cie_out) { B32 is_parsed = 0; U64 cursor = format == DW_Format_32Bit ? 4 : 12; - + U64 cie_id = 0; - U64 cie_id_size = dw_str8_deserial_read_fmt_uint(data, cursor, format, &cie_id); + U64 cie_id_size = str8_deserial_read_dwarf_uint(data, cursor, format, &cie_id); if (cie_id_size == 0) { goto exit; } cursor += cie_id_size; - + U8 version = 0; U64 version_size = str8_deserial_read_struct(data, cursor, &version); if (version_size == 0) { goto exit; } cursor += version_size; - + String8 aug_string = {0}; U64 aug_string_size = str8_deserial_read_cstr(data, cursor, &aug_string); if (aug_string_size == 0) { goto exit; } cursor += aug_string_size; - + U8 address_size = 0; U8 segment_selector_size = 0; if (version >= DW_Version_4) { U64 address_size_size = str8_deserial_read_struct(data, cursor, &address_size); if (address_size_size == 0) { goto exit; } cursor += address_size_size; - + U64 segment_selector_size_size = str8_deserial_read_struct(data, cursor, &segment_selector_size); if (segment_selector_size_size == 0) { goto exit; } cursor += segment_selector_size; } else { address_size = byte_size_from_arch(arch); } - + U64 code_align_factor = 0; U64 code_align_factor_size = str8_deserial_read_uleb128(data, cursor, &code_align_factor); if (code_align_factor_size == 0) { goto exit; } cursor += code_align_factor_size; - + S64 data_align_factor = 0; U64 data_align_factor_size = str8_deserial_read_sleb128(data, cursor, &data_align_factor); if (data_align_factor_size == 0) { goto exit; } cursor += data_align_factor_size; - + U64 ret_addr_reg = 0; U64 ret_addr_reg_size = 0; if (version == DW_Version_1) { ret_addr_reg_size = str8_deserial_read(data, cursor, &ret_addr_reg, sizeof(U8), sizeof(U8)); } else { ret_addr_reg_size = str8_deserial_read_uleb128(data, cursor, &ret_addr_reg); } if (ret_addr_reg_size == 0) { goto exit; } cursor += ret_addr_reg_size; - + if (aug_string.size > 0) { goto exit; } - + cie_out->insts = str8_skip(data, cursor); cie_out->aug_string = aug_string; cie_out->code_align_factor = code_align_factor; @@ -3309,9 +3442,9 @@ dw_parse_cie(String8 data, DW_Format format, Arch arch, DW_CIE *cie_out) cie_out->version = version; cie_out->address_size = address_size; cie_out->segment_selector_size = segment_selector_size; - + is_parsed = 1; - exit:; +exit:; return is_parsed; } @@ -3320,37 +3453,37 @@ dw_parse_fde(String8 data, DW_Format format, DW_CIE *cie, DW_FDE *fde_out) { B32 is_parsed = 0; U64 cursor = format == DW_Format_32Bit ? 4 : 12; - + // extract CIE pointer U64 cie_pointer = 0; - U64 cie_pointer_size = dw_str8_deserial_read_fmt_uint(data, cursor, format, &cie_pointer); + U64 cie_pointer_size = str8_deserial_read_dwarf_uint(data, cursor, format, &cie_pointer); if (cie_pointer_size == 0) { goto exit; } cursor += cie_pointer_size; - + // extract address of first instruction U64 pc_begin = 0; U64 pc_begin_size = dw_read_debug_frame_ptr(str8_skip(data, cursor), cie, &pc_begin); if (pc_begin_size == 0) { goto exit; } cursor += pc_begin_size; - + // extract instruction range size U64 pc_range = 0; U64 pc_range_size = dw_read_debug_frame_ptr(str8_skip(data, cursor), cie, &pc_range); if (pc_range_size == 0) { goto exit; } cursor += pc_range_size; - + // parse augmentation data String8 aug_data = str8_substr(data, rng_1u64(cursor, cursor + cie->aug_data.size)); cursor += cie->aug_data.size; - + // commit values to out fde_out->format = format; fde_out->cie_pointer = cie_pointer; fde_out->pc_range = rng_1u64(pc_begin, pc_begin + pc_range); fde_out->insts = str8_skip(data, cursor); - + is_parsed = 1; - exit:; +exit:; return is_parsed; } @@ -3363,7 +3496,7 @@ dw_parse_cfi(String8 data, U64 fde_offset, Arch arch, DW_CIE *cie_out, DW_FDE *f if (fde_desc.type == DW_DescriptorEntryType_FDE) { U64 cie_pointer_off = fde_desc.format == DW_Format_32Bit ? 4 : 12; U64 cie_pointer = 0; - U64 cie_pointer_size = dw_str8_deserial_read_fmt_uint(data, fde_offset + cie_pointer_off, fde_desc.format, &cie_pointer); + U64 cie_pointer_size = str8_deserial_read_dwarf_uint(data, fde_offset + cie_pointer_off, fde_desc.format, &cie_pointer); if (cie_pointer_size) { DW_DescriptorEntry cie_desc = {0}; dw_parse_descriptor_entry_header(data, cie_pointer, &cie_desc); @@ -3376,30 +3509,30 @@ dw_parse_cfi(String8 data, U64 fde_offset, Arch arch, DW_CIE *cie_out, DW_FDE *f } } } - + return is_parsed; } internal DW_CFA_ParseErrorCode dw_parse_cfa_inst(String8 data, - U64 code_align_factor, - S64 data_align_factor, - DW_DecodePtr *decode_ptr_func, - void *decode_ptr_ud, - U64 *bytes_read_out, - DW_CFA_Inst *inst_out) + U64 code_align_factor, + S64 data_align_factor, + DW_DecodePtr *decode_ptr_func, + void *decode_ptr_ud, + U64 *bytes_read_out, + DW_CFA_Inst *inst_out) { *bytes_read_out = 0; - + DW_CFA_ParseErrorCode error_code = DW_CFA_ParseErrorCode_End; U64 cursor = 0; - + // read opcode DW_CFA_Opcode raw_opcode = 0; U64 raw_opcode_size = str8_deserial_read_struct(data, cursor, &raw_opcode); if (raw_opcode_size == 0) { goto exit; } cursor += raw_opcode_size; - + // decode opcode implicit operand U64 opcode = raw_opcode & ~DW_CFA_Mask_OpcodeHi; U64 implicit_operand = 0; @@ -3407,262 +3540,262 @@ dw_parse_cfa_inst(String8 data, opcode = raw_opcode & DW_CFA_Mask_OpcodeHi; implicit_operand = raw_opcode & DW_CFA_Mask_Operand; } - + // decode operands DW_CFA_Operand operands[DW_CFA_OperandMax] = {0}; switch (opcode) { - case DW_CFA_SetLoc: { - U64 address_size = decode_ptr_func(str8_skip(data, cursor), decode_ptr_ud, &operands[0].u64); - if (address_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += address_size; - } break; - case DW_CFA_AdvanceLoc: { - operands[0].u64 = implicit_operand * code_align_factor; - } break; - case DW_CFA_AdvanceLoc1: { - U8 delta = 0; - U64 delta_size = str8_deserial_read_struct(data, cursor, &delta); - if (delta_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += delta_size; - operands[0].u64 = delta * code_align_factor; - } break; - case DW_CFA_AdvanceLoc2: { - U16 delta = 0; - U64 delta_size = str8_deserial_read_struct(data, cursor, &delta); - if (delta_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += delta_size; - operands[0].u64 = delta * code_align_factor; - } break; - case DW_CFA_AdvanceLoc4: { - U32 delta = 0; - U64 delta_size = str8_deserial_read_struct(data, cursor, &delta); - if (delta_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - operands[0].u64 = delta * code_align_factor; - } break; - case DW_CFA_DefCfa: { - U64 reg = 0; - U64 reg_size = str8_deserial_read_uleb128(data, cursor, ®); - if (reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += reg_size; - - U64 offset = 0; - U64 offset_size = str8_deserial_read_uleb128(data, cursor, &offset); - if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += offset_size; - - operands[0].u64 = reg; - operands[1].u64 = offset; - } break; - case DW_CFA_DefCfaSf: { - U64 reg = 0; - U64 reg_size = str8_deserial_read_uleb128(data, cursor, ®); - if (reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += reg_size; - - S64 offset = 0; - U64 offset_size = str8_deserial_read_sleb128(data, cursor, &offset); - if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += offset_size; - - operands[0].u64 = reg; - operands[1].s64 = offset * data_align_factor; - } break; - case DW_CFA_DefCfaRegister: { - U64 reg = 0; - U64 reg_size = str8_deserial_read_uleb128(data, cursor, ®); - if (reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += reg_size; - - operands[0].u64 = reg; - } break; - case DW_CFA_DefCfaOffset: { - U64 offset = 0; - U64 offset_size = str8_deserial_read_uleb128(data, cursor, &offset); - if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += offset_size; - - operands[0].u64 = offset; - } break; - case DW_CFA_DefCfaOffsetSf: { - U64 offset = 0; - U64 offset_size = str8_deserial_read_uleb128(data, cursor, &offset); - if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += offset_size; - - operands[0].u64 = offset * data_align_factor; - } break; - case DW_CFA_DefCfaExpr: { - U64 expr_size = 0; - U64 expr_size_size = str8_deserial_read_uleb128(data, cursor, &expr_size); - if (expr_size_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += expr_size_size; - - if (cursor + expr_size > data.size) { goto exit; } - String8 expr = str8_prefix(str8_skip(data, cursor), expr_size); - - operands[0].block = expr; - cursor += expr_size; - } break; - case DW_CFA_Undefined: { - U64 reg = 0; - U64 reg_size = str8_deserial_read_uleb128(data, cursor, ®); - if (reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += reg_size; - - operands[0].u64 = reg; - } break; - case DW_CFA_SameValue: { - U64 reg = 0; - U64 reg_size = str8_deserial_read_uleb128(data, cursor, ®); - if (reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += reg_size; - - operands[0].u64 = reg; - } break; - case DW_CFA_Offset: { - U64 offset = 0; - U64 offset_size = str8_deserial_read_uleb128(data, cursor, &offset); - if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += offset_size; - - operands[0].u64 = implicit_operand; - operands[1].s64 = (S64)offset * data_align_factor; - } break; - case DW_CFA_OffsetExt: { - U64 reg = 0; - U64 reg_size = str8_deserial_read_uleb128(data, cursor, ®); - if (reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += reg_size; - - U64 offset = 0; - U64 offset_size = str8_deserial_read_uleb128(data, cursor, &offset); - if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += offset_size; - - operands[0].u64 = reg; - operands[1].u64 = offset * data_align_factor; - } break; - case DW_CFA_OffsetExtSf: { - U64 reg = 0; - U64 reg_size = str8_deserial_read_uleb128(data, cursor, ®); - if (reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += reg_size; - - S64 offset = 0; - U64 offset_size = str8_deserial_read_sleb128(data, cursor, &offset); - if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += offset_size; - - operands[0].u64 = reg; - operands[1].s64 = offset * data_align_factor; - } break; - case DW_CFA_ValOffset: { - U64 val = 0; - U64 val_size = str8_deserial_read_uleb128(data, cursor, &val); - if (val_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += val_size; - - U64 offset = 0; - U64 offset_size = str8_deserial_read_uleb128(data, cursor, &offset); - if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += offset_size; - - operands[0].u64 = val; - operands[1].u64 = offset * data_align_factor; - } break; - case DW_CFA_ValOffsetSf: { - U64 val = 0; - U64 val_size = str8_deserial_read_uleb128(data, cursor, &val); - if (val_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += val_size; - - S64 offset = 0; - U64 offset_size = str8_deserial_read_sleb128(data, cursor, &offset); - if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += offset_size; - - operands[0].u64 = val; - operands[1].s64 = offset; - } break; - case DW_CFA_Register: { - U64 dst_reg = 0; - U64 dst_reg_size = str8_deserial_read_uleb128(data, cursor, &dst_reg); - if (dst_reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += dst_reg_size; - - U64 src_reg = 0; - U64 src_reg_size = str8_deserial_read_uleb128(data, cursor, &src_reg); - if (src_reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += src_reg_size; - - operands[0].u64 = dst_reg; - operands[1].u64 = src_reg; - } break; - case DW_CFA_Expr: { - U64 reg = 0; - U64 reg_size = str8_deserial_read_uleb128(data, cursor, ®); - if (reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += reg_size; - - U64 expr_size = 0; - U64 expr_size_size = str8_deserial_read_uleb128(data, cursor, &expr_size); - if (expr_size_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += expr_size_size; - - if (cursor + expr_size > data.size) { goto exit; } - String8 expr = str8_prefix(str8_skip(data, cursor), expr_size); - cursor += expr_size; - - operands[0].u64 = reg; - operands[1].block = expr; - } break; - case DW_CFA_ValExpr: { - U64 val = 0; - U64 val_size = str8_deserial_read_uleb128(data, cursor, &val); - if (val_size == 0) { goto exit; } - cursor += val_size; - - U64 expr_size = 0; - U64 expr_size_size = str8_deserial_read_uleb128(data, cursor, &expr_size); - if (expr_size_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } - cursor += expr_size_size; - - if (cursor + expr_size > data.size) { goto exit; } - String8 expr = str8_prefix(str8_skip(data, cursor), expr_size); - cursor += expr_size; - - operands[0].u64 = val; - operands[1].block = expr; - } break; - case DW_CFA_Restore: { - operands[0].u64 = implicit_operand; - } break; - case DW_CFA_RestoreExt: {} break; - case DW_CFA_RememberState: {} break; - case DW_CFA_RestoreState: {} break; - case DW_CFA_Nop: {} break; - default: { NotImplemented; goto exit; } break; + case DW_CFA_SetLoc: { + U64 address_size = decode_ptr_func(str8_skip(data, cursor), decode_ptr_ud, &operands[0].u64); + if (address_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += address_size; + } break; + case DW_CFA_AdvanceLoc: { + operands[0].u64 = implicit_operand * code_align_factor; + } break; + case DW_CFA_AdvanceLoc1: { + U8 delta = 0; + U64 delta_size = str8_deserial_read_struct(data, cursor, &delta); + if (delta_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += delta_size; + operands[0].u64 = delta * code_align_factor; + } break; + case DW_CFA_AdvanceLoc2: { + U16 delta = 0; + U64 delta_size = str8_deserial_read_struct(data, cursor, &delta); + if (delta_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += delta_size; + operands[0].u64 = delta * code_align_factor; + } break; + case DW_CFA_AdvanceLoc4: { + U32 delta = 0; + U64 delta_size = str8_deserial_read_struct(data, cursor, &delta); + if (delta_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + operands[0].u64 = delta * code_align_factor; + } break; + case DW_CFA_DefCfa: { + U64 reg = 0; + U64 reg_size = str8_deserial_read_uleb128(data, cursor, ®); + if (reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += reg_size; + + U64 offset = 0; + U64 offset_size = str8_deserial_read_uleb128(data, cursor, &offset); + if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += offset_size; + + operands[0].u64 = reg; + operands[1].u64 = offset; + } break; + case DW_CFA_DefCfaSf: { + U64 reg = 0; + U64 reg_size = str8_deserial_read_uleb128(data, cursor, ®); + if (reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += reg_size; + + S64 offset = 0; + U64 offset_size = str8_deserial_read_sleb128(data, cursor, &offset); + if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += offset_size; + + operands[0].u64 = reg; + operands[1].s64 = offset * data_align_factor; + } break; + case DW_CFA_DefCfaRegister: { + U64 reg = 0; + U64 reg_size = str8_deserial_read_uleb128(data, cursor, ®); + if (reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += reg_size; + + operands[0].u64 = reg; + } break; + case DW_CFA_DefCfaOffset: { + U64 offset = 0; + U64 offset_size = str8_deserial_read_uleb128(data, cursor, &offset); + if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += offset_size; + + operands[0].u64 = offset; + } break; + case DW_CFA_DefCfaOffsetSf: { + U64 offset = 0; + U64 offset_size = str8_deserial_read_uleb128(data, cursor, &offset); + if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += offset_size; + + operands[0].u64 = offset * data_align_factor; + } break; + case DW_CFA_DefCfaExpr: { + U64 expr_size = 0; + U64 expr_size_size = str8_deserial_read_uleb128(data, cursor, &expr_size); + if (expr_size_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += expr_size_size; + + if (cursor + expr_size > data.size) { goto exit; } + String8 expr = str8_prefix(str8_skip(data, cursor), expr_size); + + operands[0].block = expr; + cursor += expr_size; + } break; + case DW_CFA_Undefined: { + U64 reg = 0; + U64 reg_size = str8_deserial_read_uleb128(data, cursor, ®); + if (reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += reg_size; + + operands[0].u64 = reg; + } break; + case DW_CFA_SameValue: { + U64 reg = 0; + U64 reg_size = str8_deserial_read_uleb128(data, cursor, ®); + if (reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += reg_size; + + operands[0].u64 = reg; + } break; + case DW_CFA_Offset: { + U64 offset = 0; + U64 offset_size = str8_deserial_read_uleb128(data, cursor, &offset); + if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += offset_size; + + operands[0].u64 = implicit_operand; + operands[1].s64 = (S64)offset * data_align_factor; + } break; + case DW_CFA_OffsetExt: { + U64 reg = 0; + U64 reg_size = str8_deserial_read_uleb128(data, cursor, ®); + if (reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += reg_size; + + U64 offset = 0; + U64 offset_size = str8_deserial_read_uleb128(data, cursor, &offset); + if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += offset_size; + + operands[0].u64 = reg; + operands[1].u64 = offset * data_align_factor; + } break; + case DW_CFA_OffsetExtSf: { + U64 reg = 0; + U64 reg_size = str8_deserial_read_uleb128(data, cursor, ®); + if (reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += reg_size; + + S64 offset = 0; + U64 offset_size = str8_deserial_read_sleb128(data, cursor, &offset); + if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += offset_size; + + operands[0].u64 = reg; + operands[1].s64 = offset * data_align_factor; + } break; + case DW_CFA_ValOffset: { + U64 val = 0; + U64 val_size = str8_deserial_read_uleb128(data, cursor, &val); + if (val_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += val_size; + + U64 offset = 0; + U64 offset_size = str8_deserial_read_uleb128(data, cursor, &offset); + if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += offset_size; + + operands[0].u64 = val; + operands[1].u64 = offset * data_align_factor; + } break; + case DW_CFA_ValOffsetSf: { + U64 val = 0; + U64 val_size = str8_deserial_read_uleb128(data, cursor, &val); + if (val_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += val_size; + + S64 offset = 0; + U64 offset_size = str8_deserial_read_sleb128(data, cursor, &offset); + if (offset_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += offset_size; + + operands[0].u64 = val; + operands[1].s64 = offset; + } break; + case DW_CFA_Register: { + U64 dst_reg = 0; + U64 dst_reg_size = str8_deserial_read_uleb128(data, cursor, &dst_reg); + if (dst_reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += dst_reg_size; + + U64 src_reg = 0; + U64 src_reg_size = str8_deserial_read_uleb128(data, cursor, &src_reg); + if (src_reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += src_reg_size; + + operands[0].u64 = dst_reg; + operands[1].u64 = src_reg; + } break; + case DW_CFA_Expr: { + U64 reg = 0; + U64 reg_size = str8_deserial_read_uleb128(data, cursor, ®); + if (reg_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += reg_size; + + U64 expr_size = 0; + U64 expr_size_size = str8_deserial_read_uleb128(data, cursor, &expr_size); + if (expr_size_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += expr_size_size; + + if (cursor + expr_size > data.size) { goto exit; } + String8 expr = str8_prefix(str8_skip(data, cursor), expr_size); + cursor += expr_size; + + operands[0].u64 = reg; + operands[1].block = expr; + } break; + case DW_CFA_ValExpr: { + U64 val = 0; + U64 val_size = str8_deserial_read_uleb128(data, cursor, &val); + if (val_size == 0) { goto exit; } + cursor += val_size; + + U64 expr_size = 0; + U64 expr_size_size = str8_deserial_read_uleb128(data, cursor, &expr_size); + if (expr_size_size == 0) { error_code = DW_CFA_ParseErrorCode_OutOfData; goto exit; } + cursor += expr_size_size; + + if (cursor + expr_size > data.size) { goto exit; } + String8 expr = str8_prefix(str8_skip(data, cursor), expr_size); + cursor += expr_size; + + operands[0].u64 = val; + operands[1].block = expr; + } break; + case DW_CFA_Restore: { + operands[0].u64 = implicit_operand; + } break; + case DW_CFA_RestoreExt: {} break; + case DW_CFA_RememberState: {} break; + case DW_CFA_RestoreState: {} break; + case DW_CFA_Nop: {} break; + default: { NotImplemented; goto exit; } break; } - + // fill out output inst_out->opcode = opcode; MemoryCopyTyped(&inst_out->operands[0], &operands[0], DW_CFA_OperandMax); - + *bytes_read_out = cursor; - + error_code = DW_CFA_ParseErrorCode_NewInst; - - exit:; + +exit:; return error_code; } internal DW_CFA_InstList dw_parse_cfa_inst_list(Arena *arena, - String8 data, - U64 code_align_factor, - S64 data_align_factor, - DW_DecodePtr *decode_ptr_func, - void *decode_ptr_ud) + String8 data, + U64 code_align_factor, + S64 data_align_factor, + DW_DecodePtr *decode_ptr_func, + void *decode_ptr_ud) { U64 pos = arena_pos(arena); DW_CFA_InstList list = {0}; diff --git a/src/dwarf/dwarf_parse.h b/src/dwarf/dwarf_parse.h index c67123a1..e6bd6cc6 100644 --- a/src/dwarf/dwarf_parse.h +++ b/src/dwarf/dwarf_parse.h @@ -4,60 +4,54 @@ #ifndef DWARF_PARSE_H #define DWARF_PARSE_H -//////////////////////////////// -//~ rjf: Raw DWARF Info Bundle - -typedef struct DW_Section DW_Section; -struct DW_Section +typedef struct DW_Section { + String8 name; String8 data; - B32 is_dwo; -}; + B32 is_dwo; +} DW_Section; -typedef struct DW_Raw DW_Raw; -struct DW_Raw +typedef struct DW_Input { DW_Section sec[DW_Section_Count]; -}; + DW_Section sup[DW_Section_Count]; +} DW_Input; -typedef struct DW_ListUnit DW_ListUnit; -struct DW_ListUnit +typedef struct DW_ListUnit { DW_Version version; - U64 address_size; - U64 segment_selector_size; - U64 entry_size; - String8 entries; -}; + U64 address_size; + U64 segment_selector_size; + U64 entry_size; + String8 entries; +} DW_ListUnit; -typedef struct DW_ListUnitInput DW_ListUnitInput; -struct DW_ListUnitInput +typedef struct DW_ListUnitInput { - U64 addr_count; - U64 str_offset_count; - U64 rnglist_count; - U64 loclist_count; - Rng1U64Array addr_ranges; - Rng1U64Array str_offset_ranges; - Rng1U64Array rnglist_ranges; - Rng1U64Array loclist_ranges; - DW_ListUnit *addrs; - DW_ListUnit *str_offsets; - DW_ListUnit *rnglists; - DW_ListUnit *loclists; -}; + U64 addr_count; + U64 str_offset_count; + U64 rnglist_count; + U64 loclist_count; + Rng1U64Array addr_ranges; + Rng1U64Array str_offset_ranges; + Rng1U64Array rnglist_ranges; + Rng1U64Array loclist_ranges; + DW_ListUnit *addrs; + DW_ListUnit *str_offsets; + DW_ListUnit *rnglists; + DW_ListUnit *loclists; +} DW_ListUnitInput; -typedef struct DW_AbbrevTableEntry DW_AbbrevTableEntry; -struct DW_AbbrevTableEntry +typedef struct DW_AbbrevTableEntry { U64 id; U64 off; -}; +} DW_AbbrevTableEntry; typedef struct DW_AbbrevTable DW_AbbrevTable; struct DW_AbbrevTable { - U64 count; + U64 count; DW_AbbrevTableEntry *entries; }; @@ -69,8 +63,7 @@ typedef enum DW_AbbrevKind DW_Abbrev_AttribSequenceEnd, DW_Abbrev_DIEBegin, DW_Abbrev_DIEEnd, -} -DW_AbbrevKind; +} DW_AbbrevKind; typedef U32 DW_AbbrevFlags; enum @@ -79,15 +72,14 @@ enum DW_AbbrevFlag_HasChildren = (1 << 1), }; -typedef struct DW_Abbrev DW_Abbrev; -struct DW_Abbrev +typedef struct DW_Abbrev { - DW_AbbrevKind kind; - U64 sub_kind; - U64 id; - U64 const_value; + DW_AbbrevKind kind; + U64 sub_kind; + U64 id; + U64 const_value; DW_AbbrevFlags flags; -}; +} DW_Abbrev; typedef union DW_Form { @@ -108,78 +100,71 @@ typedef union DW_Form U64 rnglistx; U64 ptr; U64 implicit_const; -} -DW_Form; +} DW_Form; -typedef struct DW_Attrib DW_Attrib; -struct DW_Attrib +typedef struct DW_Attrib { - U64 info_off; - DW_AttribKind attrib_kind; - DW_FormKind form_kind; - DW_Form form; -}; + U64 info_off; + U64 abbrev_off; + U64 abbrev_id; + DW_AttribKind attrib_kind; + DW_FormKind form_kind; + DW_Form form; +} DW_Attrib; -typedef struct DW_AttribNode DW_AttribNode; -struct DW_AttribNode +typedef struct DW_AttribNode { - DW_AttribNode *next; - DW_Attrib v; -}; + struct DW_AttribNode *next; + DW_Attrib v; +} DW_AttribNode; -typedef struct DW_AttribList DW_AttribList; -struct DW_AttribList +typedef struct DW_AttribList { DW_AttribNode *first; DW_AttribNode *last; - U64 count; -}; + U64 count; +} DW_AttribList; -typedef struct DW_Tag DW_Tag; -struct DW_Tag +typedef struct DW_Tag { - B32 has_children; - U64 abbrev_id; - DW_TagKind kind; - DW_AttribList attribs; - U64 info_off; - U8 v[1]; -}; + B32 has_children; + U64 abbrev_id; + DW_TagKind kind; + DW_AttribList attribs; + U64 info_off; + U8 v[1]; +} DW_Tag; -typedef struct DW_TagNode DW_TagNode; -struct DW_TagNode +typedef struct DW_TagNode { - DW_Tag tag; - DW_TagNode *sibling; - DW_TagNode *first_child; - DW_TagNode *last_child; -}; + DW_Tag tag; + struct DW_TagNode *sibling; + struct DW_TagNode *first_child; + struct DW_TagNode *last_child; +} DW_TagNode; -typedef struct DW_Loc DW_Loc; -struct DW_Loc +typedef struct DW_Loc { Rng1U64 range; String8 expr; -}; +} DW_Loc; -typedef struct DW_LocNode DW_LocNode; -struct DW_LocNode +typedef struct DW_LocNode { - DW_LocNode *next; - DW_Loc v; -}; + DW_Loc v; + struct DW_LocNode *next; +} DW_LocNode; -typedef struct DW_LocList DW_LocList; -struct DW_LocList +typedef struct DW_LocList { + U64 count; DW_LocNode *first; DW_LocNode *last; - U64 count; -}; +} DW_LocList; -typedef struct DW_CompUnit DW_CompUnit; -struct DW_CompUnit +typedef struct DW_CompUnit { + B32 relaxed; DW_Ext ext; DW_CompUnitKind kind; DW_Version version; @@ -198,7 +183,7 @@ struct DW_CompUnit U64 dwo_id; DW_Tag tag; HashTable *tag_ht; -}; +} DW_CompUnit; typedef struct DW_TagTree { @@ -343,12 +328,12 @@ typedef union DW_ExprOperand U16 u16; U32 u32; U64 u64; - + S8 s8; S16 s16; S32 s32; S64 s64; - + String8 block; } DW_ExprOperand; @@ -446,10 +431,18 @@ typedef struct DW_CFA_InstList #define DW_DECODE_PTR(name) U64 name(String8 data, void *ud, U64 *ptr_out) typedef DW_DECODE_PTR(DW_DecodePtr); +// hasher + +internal U64 dw_hash_from_string(String8 string); + // deserial helpers -internal U64 dw_str8_deserial_read_packed_size(String8 string, U64 off, U64 *size_out); -internal U64 dw_str8_deserial_read_fmt_uint(String8 string, U64 off, DW_Format format, U64 *uint_out); +internal U64 str8_deserial_read_dwarf_packed_size(String8 string, U64 off, U64 *size_out); +internal U64 str8_deserial_read_dwarf_uint (String8 string, U64 off, DW_Format format, U64 *uint_out); +internal U64 str8_deserial_read_uleb128 (String8 string, U64 off, U64 *value_out); +internal U64 str8_deserial_read_sleb128 (String8 string, U64 off, S64 *value_out); +internal U64 str8_deserial_read_uleb128_array(Arena *arena, String8 string, U64 off, U64 count, U64 **arr_out); +internal U64 str8_deserial_read_sleb128_array(Arena *arena, String8 string, U64 off, U64 count, S64 **arr_out); internal Rng1U64List dw_unit_ranges_from_data(Arena *arena, String8 data); @@ -459,7 +452,7 @@ internal U64 dw_read_list_unit_header_addr (String8 unit_data, DW_ListUnit internal U64 dw_read_list_unit_header_str_offsets(String8 unit_data, DW_ListUnit *lu_out); internal U64 dw_read_list_unit_header_list (String8 unit_data, DW_ListUnit *lu_out); -internal DW_ListUnitInput dw_list_unit_input_from_raw(Arena *arena, DW_Raw *input); +internal DW_ListUnitInput dw_list_unit_input_from_input(Arena *arena, DW_Input *input); internal U64 dw_offset_from_list_unit(DW_ListUnit *lu, U64 index); internal U64 dw_addr_from_list_unit (DW_ListUnit *lu, U64 index); @@ -475,7 +468,7 @@ internal U64 dw_abbrev_offset_from_abbrev_id(DW_AbbrevTable table, U6 internal U64 dw_read_form(String8 data, U64 off, DW_Version version, DW_Format unit_format, U64 address_size, DW_FormKind form_kind, U64 implicit_const, DW_Form *form_out); internal U64 dw_read_tag (Arena *arena, String8 tag_data, U64 tag_off, U64 tag_base, DW_AbbrevTable abbrev_table, String8 abbrev_data, DW_Version version, DW_Format unit_format, U64 address_size, DW_Tag *tag_out); -internal U64 dw_read_tag_cu(Arena *arena, DW_Raw *input, DW_CompUnit *cu, U64 info_off, DW_Tag *tag_out); +internal U64 dw_read_tag_cu(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 info_off, DW_Tag *tag_out); // attrib interp @@ -488,56 +481,56 @@ internal S64 dw_interp_const_s64 (DW_FormKind form_kind, DW_Form form) internal S32 dw_interp_const_s32 (DW_FormKind form_kind, DW_Form form); internal B32 dw_interp_flag (DW_FormKind form_kind, DW_Form form); internal U64 dw_interp_address (U64 address_size, U64 base_addr, DW_ListUnit *addr_xlist, DW_FormKind form_kind, DW_Form form); -internal String8 dw_interp_block (DW_Raw *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form); -internal String8 dw_interp_string (DW_Raw *input, DW_Format unit_format, DW_ListUnit *str_offsets, DW_FormKind form_kind, DW_Form form); -internal String8 dw_interp_line_ptr (DW_Raw *input, DW_FormKind form_kind, DW_Form form); +internal String8 dw_interp_block (DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form); +internal String8 dw_interp_string (DW_Input *input, DW_Format unit_format, DW_ListUnit *str_offsets, DW_FormKind form_kind, DW_Form form); +internal String8 dw_interp_line_ptr (DW_Input *input, DW_FormKind form_kind, DW_Form form); internal DW_LineFile * dw_interp_file (DW_LineVMHeader *line_vm, DW_FormKind form_kind, DW_Form form); -internal DW_Reference dw_interp_ref (DW_Raw *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form); -internal DW_LocList dw_interp_loclist (Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form); -internal Rng1U64List dw_interp_rnglist (Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form); +internal DW_Reference dw_interp_ref (DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form); +internal DW_LocList dw_interp_loclist (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form); +internal Rng1U64List dw_interp_rnglist (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form); -internal String8 dw_exprloc_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib); -internal U128 dw_const_u128_from_attrib(DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib); -internal U64 dw_const_u64_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib); -internal U32 dw_const_u32_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib); -internal S64 dw_const_s64_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib); -internal S32 dw_const_s32_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib); -internal B32 dw_flag_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib); -internal U64 dw_address_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib); -internal String8 dw_block_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib); -internal String8 dw_string_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib); -internal String8 dw_line_ptr_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal String8 dw_exprloc_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal U128 dw_const_u128_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal U64 dw_const_u64_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal U32 dw_const_u32_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal S64 dw_const_s64_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal S32 dw_const_s32_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal B32 dw_flag_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal U64 dw_address_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal String8 dw_block_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal String8 dw_string_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal String8 dw_line_ptr_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); internal DW_LineFile * dw_file_from_attrib (DW_CompUnit *cu, DW_LineVMHeader *line_vm, DW_Attrib *attrib); -internal DW_Reference dw_ref_from_attrib (DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib); -internal DW_LocList dw_loclist_from_attrib (Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib); -internal Rng1U64List dw_rnglist_from_attrib (Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal DW_Reference dw_ref_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal DW_LocList dw_loclist_from_attrib (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); +internal Rng1U64List dw_rnglist_from_attrib (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib); -internal String8 dw_exprloc_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); -internal U128 dw_const_u128_from_tag_attrib_kind(DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); -internal U64 dw_const_u64_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); -internal U32 dw_const_u32_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); -internal B32 dw_flag_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); -internal U64 dw_address_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); -internal String8 dw_block_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); -internal String8 dw_string_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); -internal String8 dw_line_ptr_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); -internal String8 dw_line_ptr_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); -internal DW_LineFile * dw_file_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_LineVMHeader *line_vm, DW_Tag tag, DW_AttribKind kind); -internal DW_Reference dw_ref_from_tag_attrib_kind (DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); -internal DW_LocList dw_loclist_from_tag_attrib_kind (Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); -internal Rng1U64List dw_rnglist_from_tag_attrib_kind (Arena *arena, DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal String8 dw_exprloc_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal U128 dw_const_u128_from_tag_attrib_kind(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal U64 dw_const_u64_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal U32 dw_const_u32_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal B32 dw_flag_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal U64 dw_address_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal String8 dw_block_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal String8 dw_string_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal String8 dw_line_ptr_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal String8 dw_line_ptr_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal DW_LineFile * dw_file_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_LineVMHeader *line_vm, DW_Tag tag, DW_AttribKind kind); +internal DW_Reference dw_ref_from_tag_attrib_kind (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal DW_LocList dw_loclist_from_tag_attrib_kind (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal Rng1U64List dw_rnglist_from_tag_attrib_kind (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); // compile unit -internal DW_CompUnit dw_cu_from_info_off(Arena *arena, DW_Raw *input, DW_ListUnitInput lu_input, U64 offset); -internal DW_TagTree dw_tag_tree_from_cu(Arena *arena, DW_Raw *input, DW_CompUnit *cu); +internal DW_CompUnit dw_cu_from_info_off(Arena *arena, DW_Input *input, DW_ListUnitInput lu_input, U64 offset, B32 relaxed); +internal DW_TagTree dw_tag_tree_from_cu(Arena *arena, DW_Input *input, DW_CompUnit *cu); internal HashTable * dw_make_tag_hash_table(Arena *arena, DW_TagTree tag_tree); internal DW_TagNode * dw_tag_node_from_info_off(DW_CompUnit *cu, U64 info_off); // line info -internal U64 dw_read_line_file(String8 line_data, U64 line_off, DW_Raw *input, DW_Version unit_version, DW_Format unit_format, DW_Ext ext, U64 address_size, DW_ListUnit *str_offsets, U64 enc_count, U64 *enc_arr, DW_LineFile *line_file_out); -internal U64 dw_read_line_vm_header(Arena *arena, String8 line_data, U64 line_off, DW_Raw *input, String8 cu_dir, String8 cu_name, U8 cu_address_size, DW_ListUnit *cu_str_offsets, DW_LineVMHeader *header_out); +internal U64 dw_read_line_file(String8 line_data, U64 line_off, DW_Input *input, DW_Version unit_version, DW_Format unit_format, DW_Ext ext, U64 address_size, DW_ListUnit *str_offsets, U64 enc_count, U64 *enc_arr, DW_LineFile *line_file_out); +internal U64 dw_read_line_vm_header(Arena *arena, String8 line_data, U64 line_off, DW_Input *input, String8 cu_dir, String8 cu_name, U8 cu_address_size, DW_ListUnit *cu_str_offsets, DW_LineVMHeader *header_out); internal void dw_line_vm_reset(DW_LineVMState *state, B32 default_is_stmt); internal void dw_line_vm_advance(DW_LineVMState *state, U64 advance, U64 min_inst_len, U64 max_ops_for_inst); internal DW_LineSeqNode * dw_push_line_seq(Arena* arena, DW_LineTableParseResult *parsed_tbl); @@ -545,11 +538,11 @@ internal DW_LineNode * dw_push_line(Arena *arena, DW_LineTableParseResult *tb internal String8 dw_path_from_file(Arena *arena, DW_LineVMHeader *vm, DW_LineFile *file); internal String8 dw_path_from_file_idx(Arena *arena, DW_LineVMHeader *vm, U64 file_idx); -internal DW_LineTableParseResult dw_parsed_line_table_from_data(Arena *arena, String8 unit_data, DW_Raw *input, String8 cu_dir, String8 cu_name, U8 cu_address_size, DW_ListUnit *cu_str_offsets); +internal DW_LineTableParseResult dw_parsed_line_table_from_data(Arena *arena, String8 unit_data, DW_Input *input, String8 cu_dir, String8 cu_name, U8 cu_address_size, DW_ListUnit *cu_str_offsets); // helper for .debug_pubtypes and .debug_pubnames -internal DW_PubStringsTable dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Raw *input, DW_SectionKind section_kind); +internal DW_PubStringsTable dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Input *input, DW_SectionKind section_kind); // expression diff --git a/src/dwarf/eh_dump.h b/src/dwarf/eh_dump.h index 598a8005..8ba5a6cb 100644 --- a/src/dwarf/eh_dump.h +++ b/src/dwarf/eh_dump.h @@ -8,8 +8,8 @@ //~ Dump Subset Types #define EH_DumpSubset_XList \ -X(EhFrameHdr, eh_frame_hdr, ".eh_frame_hdr") \ -X(EhFrame, eh_frame, ".eh_frame") + X(EhFrameHdr, eh_frame_hdr, ".eh_frame_hdr") \ + X(EhFrame, eh_frame, ".eh_frame") typedef enum EH_DumpSubset { #define X(name, name_lower, title) EH_DumpSubset_##name, @@ -45,3 +45,4 @@ read_only global String8 eh_name_title_from_dump_subset_table[] = internal String8List eh_dump_list_from_data(Arena *arena, Arch arch, U64 eh_frame_hdr_vaddr, U64 eh_frame_vaddr, String8 eh_frame_hdr, String8 eh_frame, EH_DumpSubsetFlags subset_flags); #endif // EH_FRAME_DUMP_H + diff --git a/src/dwarf/eh_frame.c b/src/dwarf/eh_frame.c index 33515e03..cf455905 100644 --- a/src/dwarf/eh_frame.c +++ b/src/dwarf/eh_frame.c @@ -5,69 +5,69 @@ internal U64 eh_parse_ptr(String8 frame_base, U64 off, U64 pc, EH_PtrCtx *ptr_ctx, EH_PtrEnc encoding, U64 *ptr_out) { U64 ptr_off = off; - + if (encoding == EH_PtrEnc_Omit) { return 0; } - + // align read offset as needed if (encoding == EH_PtrEnc_Aligned) { ptr_off = AlignPow2(ptr_off, ptr_ctx->ptr_align); encoding = EH_PtrEnc_Ptr; } - + // decode pointer value U64 decode_size = 0; U64 raw_ptr_size = 0; U64 raw_ptr = 0; switch (encoding & EH_PtrEnc_TypeMask) { - default: { InvalidPath; } break; - - case EH_PtrEnc_Ptr : { raw_ptr_size = 8; } goto ufixed; - case EH_PtrEnc_UData2: { raw_ptr_size = 2; } goto ufixed; - case EH_PtrEnc_UData4: { raw_ptr_size = 4; } goto ufixed; - case EH_PtrEnc_UData8: { raw_ptr_size = 8; } goto ufixed; - ufixed: { - decode_size += str8_deserial_read(frame_base, ptr_off, &raw_ptr, raw_ptr_size, raw_ptr_size); - } break; - - // TODO: Signed is actually just a flag that indicates this int is negavite. - // There shouldn't be a read for Signed. - // For instance, (EH_PtrEnc_UData2 | EH_PtrEnc_Signed) == EH_PtrEnc_SData etc. - case EH_PtrEnc_Signed: { raw_ptr_size = 8; } goto sfixed; - - case EH_PtrEnc_SData2: { raw_ptr_size = 2; } goto sfixed; - case EH_PtrEnc_SData4: { raw_ptr_size = 4; } goto sfixed; - case EH_PtrEnc_SData8: { raw_ptr_size = 8; } goto sfixed; - sfixed: { - decode_size += str8_deserial_read(frame_base, ptr_off, &raw_ptr, raw_ptr_size, raw_ptr_size); - raw_ptr = extend_sign64(raw_ptr, raw_ptr_size); - } break; - - case EH_PtrEnc_ULEB128: { decode_size += str8_deserial_read_uleb128(frame_base, ptr_off, &raw_ptr); } break; - case EH_PtrEnc_SLEB128: { decode_size += str8_deserial_read_sleb128(frame_base, ptr_off, (S64*)&raw_ptr); } break; - } + default: { InvalidPath; } break; + case EH_PtrEnc_Ptr : { raw_ptr_size = 8; } goto ufixed; + case EH_PtrEnc_UData2: { raw_ptr_size = 2; } goto ufixed; + case EH_PtrEnc_UData4: { raw_ptr_size = 4; } goto ufixed; + case EH_PtrEnc_UData8: { raw_ptr_size = 8; } goto ufixed; + ufixed: { + decode_size += str8_deserial_read(frame_base, ptr_off, &raw_ptr, raw_ptr_size, raw_ptr_size); + } break; + + // TODO: Signed is actually just a flag that indicates this int is negavite. + // There shouldn't be a read for Signed. + // For instance, (EH_PtrEnc_UData2 | EH_PtrEnc_Signed) == EH_PtrEnc_SData etc. + case EH_PtrEnc_Signed: { raw_ptr_size = 8; } goto sfixed; + + case EH_PtrEnc_SData2: { raw_ptr_size = 2; } goto sfixed; + case EH_PtrEnc_SData4: { raw_ptr_size = 4; } goto sfixed; + case EH_PtrEnc_SData8: { raw_ptr_size = 8; } goto sfixed; + sfixed: { + decode_size += str8_deserial_read(frame_base, ptr_off, &raw_ptr, raw_ptr_size, raw_ptr_size); + raw_ptr = extend_sign64(raw_ptr, raw_ptr_size); + } break; + + case EH_PtrEnc_ULEB128: { decode_size += str8_deserial_read_uleb128(frame_base, ptr_off, &raw_ptr); } break; + case EH_PtrEnc_SLEB128: { decode_size += str8_deserial_read_sleb128(frame_base, ptr_off, (S64*)&raw_ptr); } break; + } + // apply relative bases if (decode_size > 0) { U64 ptr = raw_ptr; switch (encoding & EH_PtrEnc_ModifierMask) { - case 0: break; - case EH_PtrEnc_PcRel: { ptr = pc + raw_ptr; } break; - case EH_PtrEnc_TextRel: { ptr = ptr_ctx->text_vaddr + raw_ptr; } break; - case EH_PtrEnc_DataRel: { ptr = ptr_ctx->data_vaddr + raw_ptr; } break; - case EH_PtrEnc_FuncRel: { - Assert(!"TODO: need a sample to verify implementation"); - ptr = ptr_ctx->func_vaddr + raw_ptr; - } break; - default: { InvalidPath; } break; + case 0: break; + case EH_PtrEnc_PcRel: { ptr = pc + raw_ptr; } break; + case EH_PtrEnc_TextRel: { ptr = ptr_ctx->text_vaddr + raw_ptr; } break; + case EH_PtrEnc_DataRel: { ptr = ptr_ctx->data_vaddr + raw_ptr; } break; + case EH_PtrEnc_FuncRel: { + Assert(!"TODO: need a sample to verify implementation"); + ptr = ptr_ctx->func_vaddr + raw_ptr; + } break; + default: { InvalidPath; } break; } - + if (ptr_out) { *ptr_out = ptr; } } - + return decode_size; } @@ -76,49 +76,49 @@ eh_parse_frame_hdr(String8 data, U64 address_size, EH_PtrCtx *ptr_ctx) { EH_FrameHdr header = {0}; U64 cursor = 0; - + U64 version_size = str8_deserial_read_struct(data, cursor, &header.version); if (version_size == 0) { goto exit; } cursor += version_size; - + if (header.version == 1) { U64 eh_frame_ptr_enc_size = str8_deserial_read_struct(data, cursor, &header.eh_frame_ptr_enc); if (eh_frame_ptr_enc_size == 0) { goto exit; } cursor += eh_frame_ptr_enc_size; - + U64 fde_count_enc_size = str8_deserial_read_struct(data, cursor, &header.fde_count_enc); if (fde_count_enc_size == 0) { goto exit; } cursor += fde_count_enc_size; - + U64 table_enc_size = str8_deserial_read_struct(data, cursor, &header.table_enc); if (table_enc_size == 0) { goto exit; } cursor += table_enc_size; - + cursor += eh_parse_ptr(data, cursor, cursor, ptr_ctx, header.eh_frame_ptr_enc, &header.eh_frame_ptr); cursor += eh_parse_ptr(data, cursor, cursor, ptr_ctx, header.fde_count_enc, &header.fde_count); - + switch (header.table_enc & EH_PtrEnc_TypeMask) { - case EH_PtrEnc_Ptr: { header.field_byte_size = address_size; } break; - case EH_PtrEnc_ULEB128: { InvalidPath; } break; // TODO: when loading module convert these to UData8 - case EH_PtrEnc_UData2: { header.field_byte_size = 2; } break; - case EH_PtrEnc_UData4: { header.field_byte_size = 4; } break; - case EH_PtrEnc_UData8: { header.field_byte_size = 8; } break; - case EH_PtrEnc_Signed: { header.field_byte_size = address_size; } break; - case EH_PtrEnc_SLEB128: { InvalidPath; } break; // TODO: when loading module convert these to UData8 - case EH_PtrEnc_SData2: { header.field_byte_size = 2; } break; - case EH_PtrEnc_SData4: { header.field_byte_size = 4; } break; - case EH_PtrEnc_SData8: { header.field_byte_size = 8; } break; - default: { InvalidPath; } break; + case EH_PtrEnc_Ptr: { header.field_byte_size = address_size; } break; + case EH_PtrEnc_ULEB128: { InvalidPath; } break; // TODO: when loading module convert these to UData8 + case EH_PtrEnc_UData2: { header.field_byte_size = 2; } break; + case EH_PtrEnc_UData4: { header.field_byte_size = 4; } break; + case EH_PtrEnc_UData8: { header.field_byte_size = 8; } break; + case EH_PtrEnc_Signed: { header.field_byte_size = address_size; } break; + case EH_PtrEnc_SLEB128: { InvalidPath; } break; // TODO: when loading module convert these to UData8 + case EH_PtrEnc_SData2: { header.field_byte_size = 2; } break; + case EH_PtrEnc_SData4: { header.field_byte_size = 4; } break; + case EH_PtrEnc_SData8: { header.field_byte_size = 8; } break; + default: { InvalidPath; } break; } header.entry_byte_size = header.field_byte_size * 2; - + header.table = str8_skip(data, cursor); AssertAlways(header.table.size == header.entry_byte_size * header.fde_count); } else { Assert(0 && "unknown version"); } - - exit:; + +exit:; return header; } @@ -130,9 +130,9 @@ eh_parse_aug_data(String8 aug_string, String8 aug_data, U64 pc, EH_PtrCtx *ptr_c // On 32bit arch it is a 4-byte and on 64-bit 8-byte value. // Reference: https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html // Reference doc doesn't clarify structure for EH Data though - + U64 cursor = 0; - + U64 aug_data_size = 0; EH_AugFlags aug_flags = 0; EH_PtrEnc lsda_encoding = EH_PtrEnc_Omit; @@ -141,30 +141,30 @@ eh_parse_aug_data(String8 aug_string, String8 aug_data, U64 pc, EH_PtrCtx *ptr_c U64 handler_ip = 0; if (str8_match(str8_prefix(aug_string, 1), str8_lit("z"), 0)) { cursor = str8_deserial_read_uleb128(aug_data, cursor, &aug_data_size); - + for (U8 *ptr = aug_string.str+1; ptr < (aug_string.str+aug_string.size); ptr += 1) { switch (*ptr) { - case 'L': { - cursor += str8_deserial_read_struct(aug_data, cursor, &lsda_encoding); - aug_flags |= EH_AugFlag_HasLSDA; - } break; - case 'P': { - cursor += str8_deserial_read_struct(aug_data, cursor, &handler_encoding); - cursor += eh_parse_ptr(aug_data, cursor, pc + cursor, ptr_ctx, handler_encoding, &handler_ip); - aug_flags |= EH_AugFlag_HasHandler; - } break; - case 'R': { - cursor += str8_deserial_read_struct(aug_data, cursor, &addr_encoding); - aug_flags |= EH_AugFlag_HasAddrEnc; - } break; - case 'S': { - aug_flags |= EH_AugFlag_SignalFrame; - } break; - default: { Assert(!"failed to parse augmentation string"); goto exit; } break; + case 'L': { + cursor += str8_deserial_read_struct(aug_data, cursor, &lsda_encoding); + aug_flags |= EH_AugFlag_HasLSDA; + } break; + case 'P': { + cursor += str8_deserial_read_struct(aug_data, cursor, &handler_encoding); + cursor += eh_parse_ptr(aug_data, cursor, pc + cursor, ptr_ctx, handler_encoding, &handler_ip); + aug_flags |= EH_AugFlag_HasHandler; + } break; + case 'R': { + cursor += str8_deserial_read_struct(aug_data, cursor, &addr_encoding); + aug_flags |= EH_AugFlag_HasAddrEnc; + } break; + case 'S': { + aug_flags |= EH_AugFlag_SignalFrame; + } break; + default: { Assert(!"failed to parse augmentation string"); goto exit; } break; } } } - + if (aug_out) { aug_out->handler_ip = handler_ip; aug_out->handler_encoding = handler_encoding; @@ -173,8 +173,8 @@ eh_parse_aug_data(String8 aug_string, String8 aug_data, U64 pc, EH_PtrCtx *ptr_c aug_out->flags = aug_flags; aug_out->size = aug_data_size; } - - exit:; + +exit:; U64 parse_size = cursor; return parse_size; } @@ -185,24 +185,24 @@ eh_parse_descriptor_entry_header(String8 data, U64 off, DW_DescriptorEntry *desc U32 first_four_bytes = 0; str8_deserial_read_struct(data, off, &first_four_bytes); DW_Format format = first_four_bytes == max_U32 ? DW_Format_64Bit : DW_Format_32Bit; - + U64 length = 0; - U64 length_size = dw_str8_deserial_read_packed_size(data, off, &length); + U64 length_size = str8_deserial_read_dwarf_packed_size(data, off, &length); if (length_size == 0) { goto exit; } - + Rng1U64 entry_range = rng_1u64(off, off + length_size + length); String8 entry_data = str8_substr(data, entry_range); U64 id = 0; - U64 id_size = dw_str8_deserial_read_fmt_uint(entry_data, length_size, format, &id); + U64 id_size = str8_deserial_read_dwarf_uint(entry_data, length_size, format, &id); if (id_size == 0) { goto exit; } - + desc_out->format = format; desc_out->type = (id == 0) ? DW_DescriptorEntryType_CIE : DW_DescriptorEntryType_FDE; desc_out->entry_range = entry_range; desc_out->cie_pointer = id; desc_out->cie_pointer_off = off + length_size; - - exit:; + +exit:; return length + length_size; } @@ -211,17 +211,17 @@ eh_parse_cie(String8 data, DW_Format format, Arch arch, U64 pc, EH_PtrCtx *ptr_c { B32 is_parsed = 0; U64 cursor = format == DW_Format_32Bit ? 4 : 12; - + U64 cie_id = 0; - U64 cie_id_size = dw_str8_deserial_read_fmt_uint(data, cursor, format, &cie_id); + U64 cie_id_size = str8_deserial_read_dwarf_uint(data, cursor, format, &cie_id); if (cie_id_size == 0) { goto exit; } cursor += cie_id_size; - + U8 version = 0; U64 version_size = str8_deserial_read_struct(data, cursor, &version); if (version_size == 0) { goto exit; } cursor += version_size; - + String8 aug_string = {0}; String8 aug_data = {0}; EH_Augmentation aug = {0}; @@ -232,33 +232,33 @@ eh_parse_cie(String8 data, DW_Format format, Arch arch, U64 pc, EH_PtrCtx *ptr_c U64 aug_string_size = str8_deserial_read_cstr(data, cursor, &aug_string); if (aug_string_size == 0) { goto exit; } cursor += aug_string_size; - + U64 eh_data = 0; if (str8_match(aug_string, str8_lit("eh"), 0)) { U64 arch_byte_size = byte_size_from_arch(arch); cursor += str8_deserial_read(data, cursor, &eh_data, arch_byte_size, arch_byte_size); } - + U64 code_align_factor_size = str8_deserial_read_uleb128(data, cursor, &code_align_factor); if (code_align_factor_size == 0) { goto exit; } cursor += code_align_factor_size; - + U64 data_align_factor_size = str8_deserial_read_sleb128(data, cursor, &data_align_factor); if (data_align_factor_size == 0) { goto exit; } cursor += data_align_factor_size; - + ret_addr_reg = 0; U64 ret_addr_reg_size = str8_deserial_read(data, cursor, &ret_addr_reg, sizeof(U8), sizeof(U8)); if (ret_addr_reg_size == 0) { goto exit; } cursor += ret_addr_reg_size; - + U64 aug_data_size = eh_parse_aug_data(aug_string, str8_skip(data, cursor), pc + cursor, ptr_ctx, &aug); aug_data = str8_substr(data, r1u64(cursor, cursor + aug.size)); cursor += aug_data_size; } else { Assert(0 && "unexpected version"); } - + cie_out->insts = str8_skip(data, cursor); cie_out->aug_string = aug_string; cie_out->aug_data = aug_data; @@ -269,11 +269,11 @@ eh_parse_cie(String8 data, DW_Format format, Arch arch, U64 pc, EH_PtrCtx *ptr_c cie_out->version = version; cie_out->address_size = byte_size_from_arch(arch); cie_out->segment_selector_size = 0; - + cie_out->ext[EH_CIE_Ext_LSDAEnc] = EH_PtrEnc_Omit; cie_out->ext[EH_CIE_Ext_AddrEnc] = EH_PtrEnc_Omit; cie_out->ext[EH_CIE_Ext_HandlerEnc] = EH_PtrEnc_Omit; - + if (aug.flags & EH_AugFlag_HasLSDA) { cie_out->ext[EH_CIE_Ext_LSDAEnc] = aug.lsda_encoding; } @@ -284,9 +284,9 @@ eh_parse_cie(String8 data, DW_Format format, Arch arch, U64 pc, EH_PtrCtx *ptr_c cie_out->ext[EH_CIE_Ext_HandlerEnc] = aug.handler_encoding; cie_out->ext[EH_CIE_Ext_HandlerIp ] = aug.handler_ip; } - + is_parsed = 1; - exit:; +exit:; return is_parsed; } @@ -295,7 +295,7 @@ eh_parse_fde(String8 data, DW_Format format, U64 pc, DW_CIE *cie, EH_PtrCtx *ptr { B32 is_parsed = 0; U64 cursor = format == DW_Format_32Bit ? 8 : 20; - + U64 pc_begin = 0; U64 pc_delta = 0; EH_PtrEnc addr_enc = cie->ext[EH_CIE_Ext_AddrEnc]; @@ -303,21 +303,21 @@ eh_parse_fde(String8 data, DW_Format format, U64 pc, DW_CIE *cie, EH_PtrCtx *ptr U64 pc_begin_size = eh_parse_ptr(data, cursor, pc + cursor, ptr_ctx, addr_enc, &pc_begin); if (pc_begin_size == 0) { goto exit; } cursor += pc_begin_size; - + U64 pc_delta_size = eh_parse_ptr(data, cursor, pc + cursor, ptr_ctx, addr_enc & EH_PtrEnc_TypeMask, &pc_delta); if (pc_delta_size == 0) { goto exit; } cursor += pc_delta_size; } - + if (cursor + cie->aug_data.size > data.size) { goto exit; } cursor += cie->aug_data.size; - + fde_out->format = format; fde_out->pc_range = rng_1u64(pc_begin, pc_begin + pc_delta); fde_out->insts = str8_skip(data, cursor); - + is_parsed = 1; - exit:; +exit:; return is_parsed; } @@ -326,7 +326,7 @@ eh_find_nearest_fde(EH_FrameHdr header, EH_PtrCtx *ptr_ctx, U64 pc) { U64 fde_addr = max_U64; U64 fde_idx = max_U64; - + if (header.version == 1) { if (header.fde_count > 0) { U64 first = 0; @@ -339,7 +339,7 @@ eh_find_nearest_fde(EH_FrameHdr header, EH_PtrCtx *ptr_ctx, U64 pc) if (first > pc) { goto exit; } - + U64 last_off = header.table.size - header.entry_byte_size; U64 last = 0; U64 last_size = eh_parse_ptr(header.table, last_off, ptr_ctx->pc_vaddr + last_off, ptr_ctx, header.table_enc, &last); @@ -348,7 +348,7 @@ eh_find_nearest_fde(EH_FrameHdr header, EH_PtrCtx *ptr_ctx, U64 pc) fde_idx = header.fde_count - 1; goto exit; } - + U64 l = 0; U64 r = header.fde_count - 1; while (l <= r) { @@ -366,12 +366,12 @@ eh_find_nearest_fde(EH_FrameHdr header, EH_PtrCtx *ptr_ctx, U64 pc) goto exit; } } - + fde_idx = l > 0 ? l-1 : 0; } } - - exit:; + +exit:; if (fde_idx < header.fde_count) { U64 fde_addr_off = (fde_idx * header.entry_byte_size) + header.field_byte_size; U64 fde_addr_size = eh_parse_ptr(header.table, fde_addr_off, ptr_ctx->pc_vaddr + fde_addr_off, ptr_ctx, header.table_enc, &fde_addr); @@ -390,7 +390,7 @@ internal String8 eh_frame_hdr_from_call_frame_info(Arena *arena, U64 fde_count, U64 *fde_offsets, DW_FDE *fde) { Temp scratch = scratch_begin(&arena, 1); - + // make .eh_frame_hdr String8List srl = {0}; str8_serial_begin(scratch.arena, &srl); @@ -400,14 +400,14 @@ eh_frame_hdr_from_call_frame_info(Arena *arena, U64 fde_count, U64 *fde_offsets, str8_serial_push_u8(scratch.arena, &srl, EH_PtrEnc_UData8); // table encoding str8_serial_push_u64(scratch.arena, &srl, fde_count); // fde_count String8 header = str8_serial_end(scratch.arena, &srl); - + // alloc buffer for output U64 buffer_size = header.size + sizeof(EH_FrameHdrEntry) * fde_count; U8 *buffer = push_array(arena, U8, buffer_size); - + // copy header MemoryCopyStr8(buffer, header); - + // write the table EH_FrameHdrEntry *table = (EH_FrameHdrEntry *)(buffer + header.size); for EachIndex(fde_idx, fde_count) { @@ -415,7 +415,7 @@ eh_frame_hdr_from_call_frame_info(Arena *arena, U64 fde_count, U64 *fde_offsets, table[fde_idx].fde_offset = fde_offsets[fde_idx]; } radsort(table, fde_count, eh_frame_hdr_entry_sort); - + String8 eh_frame_hdr = str8(buffer, buffer_size); scratch_end(scratch); return eh_frame_hdr; @@ -432,16 +432,16 @@ internal String8 eh_string_from_ptr_enc_type(EH_PtrEnc type) { switch (type) { - case EH_PtrEnc_Ptr: return str8_lit("Ptr"); - case EH_PtrEnc_ULEB128: return str8_lit("ULEB128"); - case EH_PtrEnc_UData2: return str8_lit("UData2"); - case EH_PtrEnc_UData4: return str8_lit("UData4"); - case EH_PtrEnc_UData8: return str8_lit("UData8"); - case EH_PtrEnc_Signed: return str8_lit("Signed"); - case EH_PtrEnc_SLEB128: return str8_lit("SLEB128"); - case EH_PtrEnc_SData2: return str8_lit("SData2"); - case EH_PtrEnc_SData4: return str8_lit("SData4"); - case EH_PtrEnc_SData8: return str8_lit("SData8"); + case EH_PtrEnc_Ptr: return str8_lit("Ptr"); + case EH_PtrEnc_ULEB128: return str8_lit("ULEB128"); + case EH_PtrEnc_UData2: return str8_lit("UData2"); + case EH_PtrEnc_UData4: return str8_lit("UData4"); + case EH_PtrEnc_UData8: return str8_lit("UData8"); + case EH_PtrEnc_Signed: return str8_lit("Signed"); + case EH_PtrEnc_SLEB128: return str8_lit("SLEB128"); + case EH_PtrEnc_SData2: return str8_lit("SData2"); + case EH_PtrEnc_SData4: return str8_lit("SData4"); + case EH_PtrEnc_SData8: return str8_lit("SData8"); } return str8_zero(); } @@ -450,11 +450,11 @@ internal String8 eh_string_from_ptr_enc_modifier(EH_PtrEnc modifier) { switch (modifier) { - case EH_PtrEnc_PcRel: return str8_lit("PcRel"); - case EH_PtrEnc_TextRel: return str8_lit("TextRel"); - case EH_PtrEnc_DataRel: return str8_lit("DataRel"); - case EH_PtrEnc_FuncRel: return str8_lit("FuncRel"); - case EH_PtrEnc_Aligned: return str8_lit("Aligned"); + case EH_PtrEnc_PcRel: return str8_lit("PcRel"); + case EH_PtrEnc_TextRel: return str8_lit("TextRel"); + case EH_PtrEnc_DataRel: return str8_lit("DataRel"); + case EH_PtrEnc_FuncRel: return str8_lit("FuncRel"); + case EH_PtrEnc_Aligned: return str8_lit("Aligned"); } return str8_zero(); } diff --git a/src/dwarf/eh_frame.h b/src/dwarf/eh_frame.h index 5e8807c7..9ae4a257 100644 --- a/src/dwarf/eh_frame.h +++ b/src/dwarf/eh_frame.h @@ -20,7 +20,7 @@ enum EH_PtrEnc_SData2 = 0x0A, // Signed 16-bit value EH_PtrEnc_SData4 = 0x0B, // Signed 32-bit value EH_PtrEnc_SData8 = 0x0C, // Signed 64-bit value - + EH_PtrEnc_TypeMask = 0x0F, }; @@ -31,7 +31,7 @@ enum EH_PtrEnc_DataRel = 0x30, // Value is relative to the .got or .eh_frame_hdr section. EH_PtrEnc_FuncRel = 0x40, // Value is relative to the function. EH_PtrEnc_Aligned = 0x50, // Value is aligned to an address unit sized boundary. - + EH_PtrEnc_ModifierMask = 0x70, }; @@ -104,7 +104,7 @@ typedef struct EH_DecodePtrCtx EH_PtrEnc addr_enc; EH_PtrCtx *ptr_ctx; } EH_DecodePtrCtx; - + //////////////////////////////// internal U64 eh_parse_ptr(String8 frame_base, U64 off, U64 pc, EH_PtrCtx *ptr_ctx, EH_PtrEnc encoding, U64 *ptr_out); @@ -123,3 +123,4 @@ internal String8 eh_string_from_ptr_enc_modifier(EH_PtrEnc modifier); internal String8 eh_string_from_ptr_enc(Arena *arena, EH_PtrEnc enc); #endif // EH_FRAME_H + diff --git a/src/radbin/radbin.c b/src/radbin/radbin.c index 04a74ea5..3811d462 100644 --- a/src/radbin/radbin.c +++ b/src/radbin/radbin.c @@ -613,10 +613,12 @@ rb_thread_entry_point(void *p) }break; } - //- rjf: convert DWARF in inputs to RDI info + //- rjf: convert inputs to RDI info B32 convert_done = 0; + RDIM_BakeParams pdb_bake_params = {0}; RDIM_BakeParams dwarf_bake_params = {0}; { + //- rjf: PE inputs w/ DWARF, or ELF inputs => DWARF -> RDI conversion B32 pe_w_dwarf = (input_files_from_format_table[RB_FileFormat_PE].count != 0 && input_files_from_format_table[RB_FileFormat_PE].first->v->format_flags & RB_FileFormatFlag_HasDWARF); B32 elf_w_dwarf = (input_files_from_format_table[RB_FileFormat_ELF32].count != 0 || @@ -628,103 +630,7 @@ rb_thread_entry_point(void *p) else if(pe_w_dwarf) { log_infof("PEs w/ DWARF specified; converting DWARF data to RDI\n"); } else if(elf_w_dwarf) { log_infof("ELFs specified; converting DWARF data to RDI\n"); } - // rjf: input files -> exe, exe metadata, & raw dwarf - RB_File *exe_file = &rb_file_nil; - Arch arch = Arch_Null; - U64 base_vaddr = 0; - RDIM_BinarySectionList binary_sections = {0}; - DW_Raw raw = {0}; - B32 got_dwarf = 0; - { - for(RB_FileNode *n = input_files.first; n != 0; n = n->next) - { - // rjf: the first PE w/ DWARF, *or* the first ELF => pick as our exectable - if(exe_file == &rb_file_nil && - ((n->v->format == RB_FileFormat_PE && n->v->format_flags & RB_FileFormatFlag_HasDWARF) || - n->v->format == RB_FileFormat_ELF64 || - n->v->format == RB_FileFormat_ELF32)) - { - exe_file = n->v; - } - - // rjf: PE => get PE info - PE_BinInfo pe = {0}; - if(n->v->format == RB_FileFormat_PE) - { - pe = pe_bin_info_from_data(arena, n->v->data); - if(arch == Arch_Null) - { - arch = pe.arch; - } - if(base_vaddr == 0) - { - base_vaddr = pe.image_base; - } - if(binary_sections.count == 0) - { - String8 raw_sections = str8_substr(n->v->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(n->v->data, pe.string_table_range); - binary_sections = c2r_rdi_binary_sections_from_coff_sections(arena, n->v->data, string_table, pe.section_count, section_table); - } - } - - // rjf: ELF => get ELF info - ELF_Bin elf = {0}; - if(n->v->format == RB_FileFormat_ELF32 || - n->v->format == RB_FileFormat_ELF64) - { - elf = elf_bin_from_data(arena, n->v->data); - if(arch == Arch_Null) - { - arch = arch_from_elf_machine(elf.hdr.e_machine); - } - if(base_vaddr == 0) - { - base_vaddr = elf_base_addr_from_bin(&elf); - } - if(binary_sections.count == 0) - { - binary_sections = e2r_rdi_binary_sections_from_elf_section_table(arena, n->v->data, &elf, elf.shdrs); - } - } - - // rjf: PE w/ DWARF => gather DWARF sections - if(!got_dwarf && n->v->format == RB_FileFormat_PE && n->v->format_flags & RB_FileFormatFlag_HasDWARF) - { - String8 raw_sections = str8_substr(n->v->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(n->v->data, pe.string_table_range); - raw = dw_raw_from_coff_section_table(arena, n->v->data, string_table, pe.section_count, section_table); - got_dwarf = 1; - } - - // rjf: ELF w/ DWARF => gather DWARF sections - if(!got_dwarf && (n->v->format == RB_FileFormat_ELF32 || n->v->format == RB_FileFormat_ELF64) && n->v->format_flags & RB_FileFormatFlag_HasDWARF) - { - raw = dw_raw_from_elf_bin(arena, n->v->data, &elf); - got_dwarf = 1; - } - } - } - - // rjf: convert (NEW) -#if 0 - D2R2_ConvertParams convert_params = {0}; - { - convert_params.exe_name = exe_file->path; - convert_params.exe_data = exe_file->data; - convert_params.arch = arch; - convert_params.base_vaddr = base_vaddr; - convert_params.binary_sections = binary_sections; - convert_params.raw = raw; - convert_params.subset_flags = subset_flags; - convert_params.deterministic = cmd_line_has_flag(cmdline, str8_lit("deterministic")); - } - ProfScope("convert") dwarf_bake_params = d2r2_convert(arena, &convert_params); - // rjf: convert -#else D2R_ConvertParams convert_params = {0}; { B32 got_exe = 0; @@ -804,37 +710,34 @@ rb_thread_entry_point(void *p) convert_params.deterministic = cmd_line_has_flag(cmdline, str8_lit("deterministic")); } ProfScope("convert") dwarf_bake_params = d2r_convert(arena, &convert_params); -#endif } - } - lane_sync(); - - //- rjf: convert PDB in inputs to RDI info - RDIM_BakeParams pdb_bake_params = {0}; - if(input_files_from_format_table[RB_FileFormat_PDB].count != 0) - { - convert_done = 1; - log_infof("PDBs specified; converting PDB data to RDI\n"); - // rjf: get EXE/PDB file data - RB_File *exe_file = rb_file_list_first(&input_files_from_format_table[RB_FileFormat_PE]); - RB_File *pdb_file = rb_file_list_first(&input_files_from_format_table[RB_FileFormat_PDB]); - String8 exe_path = exe_file->path; - String8 pdb_path = pdb_file->path; - String8 exe_data = exe_file->data; - String8 pdb_data = pdb_file->data; - - // rjf: convert - P2R_ConvertParams convert_params = {0}; + //- rjf: PDB inputs => PDB -> RDI conversion + if(input_files_from_format_table[RB_FileFormat_PDB].count != 0) { - convert_params.input_pdb_name = pdb_path; - convert_params.input_exe_name = exe_path; - convert_params.input_pdb_data = pdb_data; - convert_params.input_exe_data = exe_data; - convert_params.subset_flags = subset_flags; - convert_params.deterministic = cmd_line_has_flag(cmdline, str8_lit("deterministic")); + convert_done = 1; + log_infof("PDBs specified; converting PDB data to RDI\n"); + + // rjf: get EXE/PDB file data + RB_File *exe_file = rb_file_list_first(&input_files_from_format_table[RB_FileFormat_PE]); + RB_File *pdb_file = rb_file_list_first(&input_files_from_format_table[RB_FileFormat_PDB]); + String8 exe_path = exe_file->path; + String8 pdb_path = pdb_file->path; + String8 exe_data = exe_file->data; + String8 pdb_data = pdb_file->data; + + // rjf: convert + P2R_ConvertParams convert_params = {0}; + { + convert_params.input_pdb_name = pdb_path; + convert_params.input_exe_name = exe_path; + convert_params.input_pdb_data = pdb_data; + convert_params.input_exe_data = exe_data; + convert_params.subset_flags = subset_flags; + convert_params.deterministic = cmd_line_has_flag(cmdline, str8_lit("deterministic")); + } + ProfScope("convert") pdb_bake_params = p2r_convert(arena, &convert_params); } - ProfScope("convert") pdb_bake_params = p2r_convert(arena, &convert_params); } lane_sync(); @@ -1196,7 +1099,7 @@ rb_thread_entry_point(void *p) Arch arch = Arch_Null; PE_BinInfo pe = {0}; ELF_Bin elf = {0}; - DW_Raw dw = {0}; + DW_Input dw = {0}; U64 eh_frame_hdr_vaddr = 0; U64 eh_frame_vaddr = 0; String8 eh_frame_hdr = {0}; @@ -1212,7 +1115,7 @@ rb_thread_entry_point(void *p) { elf = elf_bin_from_data(arena, f->data); arch = arch_from_elf_machine(elf.hdr.e_machine); - + for EachIndex(sect_idx, elf.hdr.e_shnum) { ELF_Shdr64 *shdr = &elf.shdrs.v[sect_idx]; @@ -1221,7 +1124,7 @@ rb_thread_entry_point(void *p) { eh_frame_hdr = str8_substr(f->data, r1u64(shdr->sh_offset, shdr->sh_offset + shdr->sh_size)); eh_frame_hdr_vaddr = shdr->sh_addr; - + } else if(str8_match(name, str8_lit(".eh_frame"), 0)) { @@ -1238,12 +1141,12 @@ rb_thread_entry_point(void *p) U64 section_count = raw_sections.size / sizeof(COFF_SectionHeader); COFF_SectionHeader *section_table = (COFF_SectionHeader *)raw_sections.str; String8 string_table = str8_substr(f->data, pe.string_table_range); - dw = dw_raw_from_coff_section_table(arena, f->data, string_table, section_count, section_table); + dw = dw_input_from_coff_section_table(arena, f->data, string_table, section_count, section_table); } else if(f->format == RB_FileFormat_ELF32 || f->format == RB_FileFormat_ELF64) { - dw = dw_raw_from_elf_bin(arena, f->data, &elf); + dw = dw_input_from_elf_bin(arena, f->data, &elf); } } } @@ -1338,7 +1241,7 @@ rb_thread_entry_point(void *p) } } } - + if(eh_dump_subset_flags) { if(lane_idx() == 0) diff --git a/src/radbin/radbin_main.c b/src/radbin/radbin_main.c index 2769ef3e..5b742c04 100644 --- a/src/radbin/radbin_main.c +++ b/src/radbin/radbin_main.c @@ -34,7 +34,6 @@ #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] @@ -61,7 +60,6 @@ #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" //////////////////////////////// diff --git a/src/rdi_from_dwarf/rdi_from_dwarf.c b/src/rdi_from_dwarf/rdi_from_dwarf.c index caa0fe21..45f13d62 100644 --- a/src/rdi_from_dwarf/rdi_from_dwarf.c +++ b/src/rdi_from_dwarf/rdi_from_dwarf.c @@ -45,6 +45,7 @@ d2r_rdi_language_from_dw_language(DW_Language v) switch(v) { default:{}break; + case DW_Language_C89: case DW_Language_C99: case DW_Language_C11: @@ -52,6 +53,7 @@ d2r_rdi_language_from_dw_language(DW_Language v) { result = RDI_Language_C; }break; + case DW_Language_CPlusPlus03: case DW_Language_CPlusPlus11: case DW_Language_CPlusPlus14: @@ -70,7 +72,7 @@ d2r_rdi_reg_code_from_dw_reg_x86(DW_RegX86 v) switch(v) { default:{}break; -#define X(reg_dw, val_dw, reg_rdi, ...) case DW_RegX86_##reg_dw:{result = RDI_RegCodeX86_##reg_rdi;}break; +#define X(reg_dw, val_dw, reg_rdi, ...) case DW_RegX86_##reg_dw: result = RDI_RegCodeX86_##reg_rdi; break; DW_Regs_X86_XList(X) #undef X } @@ -99,7 +101,6 @@ d2r_rdi_reg_code_from_dw_reg(Arch arch, DW_Reg v) { default: case Arch_Null: - {}break; case Arch_x86:{result = d2r_rdi_reg_code_from_dw_reg_x86(v);}break; case Arch_x64:{result = d2r_rdi_reg_code_from_dw_reg_x64(v);}break; } @@ -136,7 +137,7 @@ d2r_type_from_offset(D2R_TypeTable *type_table, U64 info_off) } internal RDIM_Type * -d2r_type_from_attrib(D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) +d2r_type_from_attrib(D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind) { RDIM_Type *type = type_table->builtin_types[RDI_TypeKind_Void]; @@ -165,7 +166,7 @@ d2r_type_from_attrib(D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, } internal Rng1U64List -d2r_range_list_from_tag(Arena *arena, DW_Raw *input, DW_CompUnit *cu, U64 image_base, DW_Tag tag) +d2r_range_list_from_tag(Arena *arena, DW_Input *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); @@ -223,7 +224,7 @@ d2r_range_list_from_tag(Arena *arena, DW_Raw *input, DW_CompUnit *cu, U64 image_ } 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) +d2r_collect_proc_params(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_TagNode *cur_node, U64 *param_count_out) { Temp scratch = scratch_begin(&arena, 1); @@ -256,7 +257,6 @@ d2r_collect_proc_params(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, } //////////////////////////////// -//~ RDIM Bytecode Helpers internal B32 rdim_is_eval_bytecode_static(RDIM_EvalBytecode bc) @@ -892,7 +892,7 @@ d2r_push_relational_op(Arena *arena, D2R_ValueTypeStack *stack, RDIM_EvalBytecod internal RDIM_EvalBytecode d2r_bytecode_from_expression(Arena *arena, - DW_Raw *input, + DW_Input *input, U64 image_base, U64 address_size, Arch arch, @@ -1438,7 +1438,7 @@ d2r_bytecode_from_expression(Arena *arena, } internal RDIM_Location * -d2r_transpile_expression(Arena *arena, RDIM_LocationChunkList *locations, DW_Raw *input, U64 image_base, U64 address_size, Arch arch, DW_ListUnit *addr_lu, DW_CompUnit *cu, String8 expr) +d2r_transpile_expression(Arena *arena, RDIM_LocationChunkList *locations, DW_Input *input, U64 image_base, U64 address_size, Arch arch, DW_ListUnit *addr_lu, DW_CompUnit *cu, String8 expr) { RDIM_Location *loc = 0; if (expr.size) { @@ -1454,12 +1454,20 @@ d2r_transpile_expression(Arena *arena, RDIM_LocationChunkList *locations, DW_Raw return loc; } +internal RDIM_Location * +d2r_location_from_attrib(Arena *arena, RDIM_LocationChunkList *locations, DW_Input *input, DW_CompUnit *cu, U64 image_base, Arch arch, DW_Tag tag, DW_AttribKind kind) +{ + String8 expr = dw_exprloc_from_tag_attrib_kind(input, cu, tag, kind); + RDIM_Location *location = d2r_transpile_expression(arena, locations, input, image_base, cu->address_size, arch, cu->addr_lu, cu, expr); + return location; +} + internal RDIM_LocationCaseList d2r_locset_from_attrib(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Scope *curr_scope, RDIM_LocationChunkList *locations, - DW_Raw *input, + DW_Input *input, DW_CompUnit *cu, U64 image_base, Arch arch, @@ -1507,7 +1515,7 @@ d2r_var_locset_from_tag(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Scope *curr_scope, RDIM_LocationChunkList *locations, - DW_Raw *input, + DW_Input *input, DW_CompUnit *cu, U64 image_base, Arch arch, @@ -1548,6 +1556,92 @@ d2r_var_locset_from_tag(Arena *arena, return locset; } +internal D2R_CompUnitContribMap +d2r_cu_contrib_map_from_aranges(Arena *arena, DW_Input *input, U64 image_base) +{ + Temp scratch = scratch_begin(&arena, 1); + + String8 aranges_data = input->sec[DW_Section_ARanges].data; + Rng1U64List unit_range_list = dw_unit_ranges_from_data(scratch.arena, aranges_data); + + D2R_CompUnitContribMap cm = {0}; + cm.count = 0; + cm.info_off_arr = push_array(arena, U64, unit_range_list.count); + cm.voff_range_arr = push_array(arena, RDIM_Rng1U64ChunkList, unit_range_list.count); + + for EachNode(range_n, Rng1U64Node, unit_range_list.first) { + String8 unit_data = str8_substr(aranges_data, range_n->v); + U64 unit_cursor = 0; + + U64 unit_length = 0; + U64 unit_length_size = str8_deserial_read_dwarf_packed_size(unit_data, unit_cursor, &unit_length); + if (unit_length_size == 0) { continue; } + unit_cursor += unit_length_size; + + DW_Version version = 0; + U64 version_size = str8_deserial_read_struct(unit_data, unit_cursor, &version); + if (version_size == 0) { continue; } + unit_cursor += version; + + if (version != DW_Version_2) { + AssertAlways(!"unknown .debug_aranges version"); + continue; + } + + DW_Format unit_format = DW_FormatFromSize(unit_length); + U64 cu_info_off = 0; + U64 cu_info_off_size = str8_deserial_read_dwarf_uint(unit_data, unit_cursor, unit_format, &cu_info_off); + if (cu_info_off_size == 0) { continue; } + unit_cursor += cu_info_off_size; + + U8 address_size = 0; + U64 address_size_size = str8_deserial_read_struct(unit_data, unit_cursor, &address_size); + if (address_size_size == 0) { continue; } + unit_cursor += address_size_size; + + U8 segment_selector_size = 0; + U64 segment_selector_size_size = str8_deserial_read_struct(unit_data, unit_cursor, &segment_selector_size); + if (segment_selector_size_size == 0) { continue; } + unit_cursor += segment_selector_size_size; + + U64 tuple_size = address_size * 2 + segment_selector_size; + U64 bytes_too_far_past_boundary = unit_cursor % tuple_size; + if (bytes_too_far_past_boundary > 0) { + unit_cursor += tuple_size - bytes_too_far_past_boundary; + } + + RDIM_Rng1U64ChunkList voff_ranges = {0}; + if (segment_selector_size == 0) { + while (unit_cursor + address_size * 2 <= unit_data.size) { + U64 address = 0; + U64 length = 0; + unit_cursor += str8_deserial_read(unit_data, unit_cursor, &address, address_size, address_size); + unit_cursor += str8_deserial_read(unit_data, unit_cursor, &length, address_size, address_size); + + if (address == 0 && length == 0) { break; } + if (address == 0) { continue; } + + // TODO: error handling + AssertAlways(address >= image_base); + + U64 min = address - image_base; + U64 max = min + length; + rdim_rng1u64_chunk_list_push(arena, &voff_ranges, 256, (RDIM_Rng1U64){.min = min, .max = max}); + } + } else { + // TODO: segment relative addressing + NotImplemented; + } + + U64 map_idx = cm.count++; + cm.info_off_arr[map_idx] = cu_info_off; + cm.voff_range_arr[map_idx] = voff_ranges; + } + + scratch_end(scratch); + return cm; +} + //////////////////////////////// //~ rjf: Compilation Unit / Scope Conversion Helpers @@ -1594,28 +1688,27 @@ d2r_push_scope(Arena *arena, RDIM_ScopeChunkList *scopes, U64 scope_chunk_cap, D } //////////////////////////////// -//~ Tag Iterator +//~ rjf: Main Conversion Entry Point -internal D2R_TagIter * -d2r_tag_iter_init(Arena *arena, DW_TagNode *root) +internal D2R_TagIterator * +d2r_tag_iterator_init(Arena *arena, DW_TagNode *root) { - D2R_TagIter *iter = push_array(arena, D2R_TagIter, 1); - iter->free_list = 0; - iter->stack = push_array(arena, D2R_TagFrame, 1); - iter->stack->node = push_array(arena, DW_TagNode, 1); + D2R_TagIterator *iter = push_array(arena, D2R_TagIterator, 1); + iter->free_list = 0; + iter->stack = push_array(arena, D2R_TagFrame, 1); + iter->stack->node = push_array(arena, DW_TagNode, 1); if(root != 0) { - *iter->stack->node = *root; + *iter->stack->node = *root; } iter->stack->node->sibling = 0; - iter->visit_children = 1; - iter->tag_node = root; - iter->root = root; + iter->visit_children = 1; + iter->tag_node = root; return iter; } internal void -d2r_tag_iter_next(Arena *arena, D2R_TagIter *iter) +d2r_tag_iterator_next(Arena *arena, D2R_TagIterator *iter) { // descend to first child if (iter->visit_children) { @@ -1644,36 +1737,27 @@ d2r_tag_iter_next(Arena *arena, D2R_TagIter *iter) // update iterator iter->visit_children = 1; iter->tag_node = iter->stack ? iter->stack->node : 0; - - // rjf: exit on root - if(iter->tag_node == iter->root) - { - iter->tag_node = 0; - } } internal void -d2r_tag_iter_skip_children(D2R_TagIter *iter) +d2r_tag_iterator_skip_children(D2R_TagIterator *iter) { iter->visit_children = 0; } internal DW_TagNode * -d2r_tag_iter_parent_tag_node(D2R_TagIter *iter) +d2r_tag_iterator_parent_tag_node(D2R_TagIterator *iter) { return iter->stack->next->node; } internal DW_Tag -d2r_tag_iter_parent_tag(D2R_TagIter *iter) +d2r_tag_iterator_parent_tag(D2R_TagIterator *iter) { - DW_TagNode *tag_node = d2r_tag_iter_parent_tag_node(iter); + DW_TagNode *tag_node = d2r_tag_iterator_parent_tag_node(iter); return tag_node->tag; } -//////////////////////////////// -//~ Type/UDT/Symbol Conversion - internal void d2r_flag_converted_tag(DW_TagNode *tag_node) { @@ -1687,7 +1771,7 @@ d2r_is_tag_converted(DW_TagNode *tag_node) } internal RDIM_Type * -d2r_find_or_convert_type(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, DW_Language cu_lang, U64 arch_addr_size, DW_Tag tag, DW_AttribKind kind) +d2r_find_or_convert_type(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Language cu_lang, U64 arch_addr_size, DW_Tag tag, DW_AttribKind kind) { RDIM_Type *type = type_table->builtin_types[RDI_TypeKind_Void]; @@ -1730,40 +1814,37 @@ d2r_find_or_convert_type(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, } internal void -d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, DW_Language cu_lang, U64 arch_addr_size, DW_TagNode *root) +d2r_convert_types(Arena *arena, + D2R_TypeTable *type_table, + DW_Input *input, + DW_CompUnit *cu, + DW_Language cu_lang, + U64 arch_addr_size, + DW_TagNode *root) { Temp scratch = scratch_begin(&arena, 1); - for(D2R_TagIter *it = d2r_tag_iter_init(scratch.arena, root); - it->tag_node != 0; - d2r_tag_iter_next(scratch.arena, it)) - { + for (D2R_TagIterator *it = d2r_tag_iterator_init(scratch.arena, root); it->tag_node != 0; d2r_tag_iterator_next(scratch.arena, it)) { DW_TagNode *tag_node = it->tag_node; DW_Tag tag = tag_node->tag; // skip converted tags - if(d2r_is_tag_converted(tag_node)) - { - d2r_tag_iter_skip_children(it); + if (d2r_is_tag_converted(tag_node)) { + d2r_tag_iterator_skip_children(it); continue; } - // mark the tag as converted here, because during conversion we may recurse on the same tag d2r_flag_converted_tag(tag_node); - switch(tag.kind) - { - case DW_TagKind_ClassType: - { + switch (tag.kind) { + case DW_TagKind_ClassType: { B32 is_decl = dw_flag_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Declaration); - if(is_decl) - { + if (is_decl) { RDIM_Type *type = d2r_create_type_from_offset(arena, type_table, tag.info_off); type->kind = RDI_TypeKind_IncompleteClass; type->name = dw_string_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Name); - d2r_tag_iter_skip_children(it); - } - else - { + Assert(!tag_node->first_child); + d2r_tag_iterator_skip_children(it); + } else { RDIM_Type *direct_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch_addr_size, tag, DW_AttribKind_Type); RDIM_Type *type = d2r_create_type_from_offset(arena, type_table, tag.info_off); type->name = dw_string_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Name); @@ -1771,58 +1852,51 @@ d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_Com type->byte_size = dw_byte_size_32_from_tag(input, cu, tag); type->direct_type = d2r_type_from_attrib(type_table, input, cu, tag, DW_AttribKind_Type); } - }break; - - case DW_TagKind_StructureType: - { + } break; + case DW_TagKind_StructureType: { B32 is_decl = dw_flag_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Declaration); - if(is_decl) - { + if (is_decl) { RDIM_Type *type = d2r_create_type_from_offset(arena, type_table, tag.info_off); type->name = dw_string_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Name); type->kind = RDI_TypeKind_IncompleteStruct; - d2r_tag_iter_skip_children(it); - } - else - { + + // TODO: error handling + Assert(!tag_node->first_child); + d2r_tag_iterator_skip_children(it); + } else { RDIM_Type *type = d2r_create_type_from_offset(arena, type_table, tag.info_off); type->name = dw_string_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Name); type->kind = RDI_TypeKind_Struct; type->byte_size = dw_byte_size_32_from_tag(input, cu, tag); } - }break; - - case DW_TagKind_UnionType: - { + } break; + case DW_TagKind_UnionType: { B32 is_decl = dw_flag_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Declaration); - if(is_decl) - { + if (is_decl) { RDIM_Type *type = d2r_create_type_from_offset(arena, type_table, tag.info_off); type->name = dw_string_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Name); type->kind = RDI_TypeKind_IncompleteUnion; - d2r_tag_iter_skip_children(it); - } - else - { + + // TODO: error handling + Assert(!tag_node->first_child); + d2r_tag_iterator_skip_children(it); + } else { RDIM_Type *type = d2r_create_type_from_offset(arena, type_table, tag.info_off); type->name = dw_string_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Name); type->kind = RDI_TypeKind_Union; type->byte_size = dw_byte_size_32_from_tag(input, cu, tag); } - }break; - - case DW_TagKind_EnumerationType: - { + } break; + case DW_TagKind_EnumerationType: { B32 is_decl = dw_flag_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Declaration); - if(is_decl) - { + if (is_decl) { RDIM_Type *type = d2r_create_type_from_offset(arena, type_table, tag.info_off); type->name = dw_string_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Name); type->kind = RDI_TypeKind_IncompleteEnum; - d2r_tag_iter_skip_children(it); - } - else - { + // TODO: error handling + Assert(!tag_node->first_child); + d2r_tag_iterator_skip_children(it); + } else { RDIM_Type *enum_base_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch_addr_size, tag, DW_AttribKind_Type); RDIM_Type *type = d2r_create_type_from_offset(arena, type_table, tag.info_off); type->name = dw_string_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Name); @@ -1830,10 +1904,8 @@ d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_Com type->byte_size = dw_byte_size_32_from_tag(input, cu, tag); type->direct_type = enum_base_type; } - }break; - - case DW_TagKind_SubroutineType: - { + } break; + case DW_TagKind_SubroutineType: { RDIM_Type *ret_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch_addr_size, tag, DW_AttribKind_Type); // collect parameters @@ -1858,11 +1930,9 @@ d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_Com type->count = param_list.count; type->param_types = rdim_array_from_type_list(arena, param_list); - d2r_tag_iter_skip_children(it); - }break; - - case DW_TagKind_Typedef: - { + d2r_tag_iterator_skip_children(it); + } break; + case DW_TagKind_Typedef: { RDIM_Type *direct_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch_addr_size, tag, DW_AttribKind_Type); RDIM_Type *type = d2r_create_type_from_offset(arena, type_table, tag.info_off); type->kind = RDI_TypeKind_Alias; @@ -1874,105 +1944,116 @@ d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_Com break; } } - }break; - - case DW_TagKind_BaseType: - { - DW_ATE encoding = dw_const_u64_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Encoding); - U64 byte_size = dw_byte_size_from_tag(input, cu, tag); + } break; + case DW_TagKind_BaseType: { + DW_ATE encoding = dw_const_u64_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Encoding); + U64 byte_size = dw_byte_size_from_tag(input, cu, tag); - // rjf: attribute type encoding -> RDI type kind + // convert base type encoding to RDI version RDI_TypeKind kind = RDI_TypeKind_NULL; - switch(encoding) - { - default:{}break; - case DW_ATE_Null: {kind = RDI_TypeKind_NULL;}break; - case DW_ATE_Boolean: {kind = RDI_TypeKind_Bool;}break; - case DW_ATE_ComplexFloat: - switch(byte_size) - { - case 4: {kind = RDI_TypeKind_ComplexF32;}break; - case 8: {kind = RDI_TypeKind_ComplexF64;}break; - case 10: {kind = RDI_TypeKind_ComplexF80;}break; - case 16: {kind = RDI_TypeKind_ComplexF128;}break; - default: {log_infof("Unsupported complex float size (%I64u) at 0x%I64x.\n", byte_size, tag.info_off);}break; - }break; - case DW_ATE_Float: - switch(byte_size) - { - case 2: {kind = RDI_TypeKind_F16; }break; - case 4: {kind = RDI_TypeKind_F32; }break; - case 6: {kind = RDI_TypeKind_F48; }break; - case 8: {kind = RDI_TypeKind_F64; }break; - case 16: {kind = RDI_TypeKind_F128;}break; - default: {log_infof("Unsupported float size (%I64u) at 0x%I64x.\n", byte_size, tag.info_off);}break; - }break; - case DW_ATE_Signed: - switch(byte_size) - { - case 1: {kind = RDI_TypeKind_S8; }break; - case 2: {kind = RDI_TypeKind_S16; }break; - case 4: {kind = RDI_TypeKind_S32; }break; - case 8: {kind = RDI_TypeKind_S64; }break; - case 16: {kind = RDI_TypeKind_S128;}break; - case 32: {kind = RDI_TypeKind_S256;}break; - case 64: {kind = RDI_TypeKind_S512;}break; - default: {log_infof("Unsupported signed integer size (%I64u) at 0x%I64x.\n", byte_size, tag.info_off);}break; - }break; - case DW_ATE_SignedChar: - switch(byte_size) - { - case 1: {kind = RDI_TypeKind_Char8; }break; - case 2: {kind = RDI_TypeKind_Char16;}break; - case 4: {kind = RDI_TypeKind_Char32;}break; - default:{log_infof("Unsupported signed character size (%I64u) at 0x%I64x.\n", byte_size, tag.info_off);}break; - }break; - case DW_ATE_Address: - case DW_ATE_Unsigned: - switch(byte_size) - { - case 1: {kind = RDI_TypeKind_U8; }break; - case 2: {kind = RDI_TypeKind_U16; }break; - case 4: {kind = RDI_TypeKind_U32; }break; - case 8: {kind = RDI_TypeKind_U64; }break; - case 16: {kind = RDI_TypeKind_U128;}break; - case 32: {kind = RDI_TypeKind_U256;}break; - case 64: {kind = RDI_TypeKind_U512;}break; - default:{log_infof("Unsupported unsigned integer size (%I64u) at 0x%I64x.\n", byte_size, tag.info_off);}break; - }break; - case DW_ATE_UnsignedChar: - switch(byte_size) - { - case 1: {kind = RDI_TypeKind_UChar8; }break; - case 2: {kind = RDI_TypeKind_UChar16;}break; - case 4: {kind = RDI_TypeKind_UChar32;}break; - default:{log_infof("Unsupported unsigned character size (%I64u) at 0x%I64x.\n", byte_size, tag.info_off);}break; - }break; - case DW_ATE_ImaginaryFloat: - case DW_ATE_PackedDecimal: - case DW_ATE_NumericString: - case DW_ATE_Edited: - case DW_ATE_SignedFixed: - case DW_ATE_UnsignedFixed: - case DW_ATE_DecimalFloat: - case DW_ATE_Utf: - case DW_ATE_Ucs: - case DW_ATE_Ascii: - { - // TODO(rjf): not implemented - }break; + switch (encoding) { + case DW_ATE_Null: kind = RDI_TypeKind_NULL; break; + case DW_ATE_Address: kind = RDI_TypeKind_Void; break; + case DW_ATE_Boolean: kind = RDI_TypeKind_Bool; break; + case DW_ATE_ComplexFloat: { + switch (byte_size) { + case 4: kind = RDI_TypeKind_ComplexF32; break; + case 8: kind = RDI_TypeKind_ComplexF64; break; + case 10: kind = RDI_TypeKind_ComplexF80; break; + case 16: kind = RDI_TypeKind_ComplexF128; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_Float: { + switch (byte_size) { + case 2: kind = RDI_TypeKind_F16; break; + case 4: kind = RDI_TypeKind_F32; break; + case 6: kind = RDI_TypeKind_F48; break; + case 8: kind = RDI_TypeKind_F64; break; + case 16: kind = RDI_TypeKind_F128; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_Signed: { + switch (byte_size) { + case 1: kind = RDI_TypeKind_S8; break; + case 2: kind = RDI_TypeKind_S16; break; + case 4: kind = RDI_TypeKind_S32; break; + case 8: kind = RDI_TypeKind_S64; break; + case 16: kind = RDI_TypeKind_S128; break; + case 32: kind = RDI_TypeKind_S256; break; + case 64: kind = RDI_TypeKind_S512; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_SignedChar: { + switch (byte_size) { + case 1: kind = RDI_TypeKind_Char8; break; + case 2: kind = RDI_TypeKind_Char16; break; + case 4: kind = RDI_TypeKind_Char32; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_Unsigned: { + switch (byte_size) { + case 1: kind = RDI_TypeKind_U8; break; + case 2: kind = RDI_TypeKind_U16; break; + case 4: kind = RDI_TypeKind_U32; break; + case 8: kind = RDI_TypeKind_U64; break; + case 16: kind = RDI_TypeKind_U128; break; + case 32: kind = RDI_TypeKind_U256; break; + case 64: kind = RDI_TypeKind_U512; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_UnsignedChar: { + switch (byte_size) { + case 1: kind = RDI_TypeKind_UChar8; break; + case 2: kind = RDI_TypeKind_UChar16; break; + case 4: kind = RDI_TypeKind_UChar32; break; + default: AssertAlways(!"unexpected size"); break; // TODO: error handling + } + } break; + case DW_ATE_ImaginaryFloat: { + NotImplemented; + } break; + case DW_ATE_PackedDecimal: { + NotImplemented; + } break; + case DW_ATE_NumericString: { + NotImplemented; + } break; + case DW_ATE_Edited: { + NotImplemented; + } break; + case DW_ATE_SignedFixed: { + NotImplemented; + } break; + case DW_ATE_UnsignedFixed: { + NotImplemented; + } break; + case DW_ATE_DecimalFloat: { + NotImplemented; + } break; + case DW_ATE_Utf: { + NotImplemented; + } break; + case DW_ATE_Ucs: { + NotImplemented; + } break; + case DW_ATE_Ascii: { + NotImplemented; + } break; + default: AssertAlways(!"unexpected base type encoding"); break; // TODO: error handling } - // rjf: build RDIM_Type *type = d2r_create_type_from_offset(arena, type_table, tag.info_off); type->kind = RDI_TypeKind_Alias; type->name = dw_string_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Name); type->direct_type = type_table->builtin_types[kind]; type->byte_size = byte_size; - }break; - - case DW_TagKind_PointerType: - { + } break; + case DW_TagKind_PointerType: { RDIM_Type *direct_type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch_addr_size, tag, DW_AttribKind_Type); // TODO: @@ -1984,16 +2065,16 @@ d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_Com Assert(!dw_tag_has_attrib(input, cu, tag, DW_AttribKind_AddressClass)); U64 byte_size = arch_addr_size; - dw_try_byte_size_from_tag(input, cu, tag, &byte_size); + if (cu->version == DW_Version_5 || cu->relaxed) { + dw_try_byte_size_from_tag(input, cu, tag, &byte_size); + } RDIM_Type *type = d2r_create_type_from_offset(arena, type_table, tag.info_off); type->kind = RDI_TypeKind_Ptr; type->byte_size = byte_size; type->direct_type = direct_type; - }break; - - case DW_TagKind_RestrictType: - { + } break; + case DW_TagKind_RestrictType: { // TODO: Assert(!dw_tag_has_attrib(input, cu, tag, DW_AttribKind_Alignment)); Assert(!dw_tag_has_attrib(input, cu, tag, DW_AttribKind_Name)); @@ -2004,10 +2085,8 @@ d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_Com type->byte_size = arch_addr_size; type->flags = RDI_TypeModifierFlag_Restrict; type->direct_type = direct_type; - }break; - - case DW_TagKind_VolatileType: - { + } break; + case DW_TagKind_VolatileType: { // TODO: Assert(!dw_tag_has_attrib(input, cu, tag, DW_AttribKind_Name)); @@ -2017,10 +2096,8 @@ d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_Com type->byte_size = arch_addr_size; type->flags = RDI_TypeModifierFlag_Volatile; type->direct_type = direct_type; - }break; - - case DW_TagKind_ConstType: - { + } break; + case DW_TagKind_ConstType: { // TODO: Assert(!dw_tag_has_attrib(input, cu, tag, DW_AttribKind_Name)); Assert(!dw_tag_has_attrib(input, cu, tag, DW_AttribKind_Alignment)); @@ -2031,10 +2108,8 @@ d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_Com type->byte_size = arch_addr_size; type->flags = RDI_TypeModifierFlag_Const; type->direct_type = direct_type; - }break; - - case DW_TagKind_ArrayType: - { + } break; + case DW_TagKind_ArrayType: { // * DWARF vs RDI Array Type Graph * // // For example lets take following decl: @@ -2110,18 +2185,14 @@ d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_Com direct_type = t; } - d2r_tag_iter_skip_children(it); - }break; - - case DW_TagKind_SubrangeType: - { + d2r_tag_iterator_skip_children(it); + } break; + case DW_TagKind_SubrangeType: { // TODO: error handling AssertAlways(!"unexpected tag"); - }break; - - case DW_TagKind_Inheritance: - { - DW_Tag parent_tag = d2r_tag_iter_parent_tag(it); + } break; + case DW_TagKind_Inheritance: { + DW_Tag parent_tag = d2r_tag_iterator_parent_tag(it); if (parent_tag.kind != DW_TagKind_StructureType && parent_tag.kind != DW_TagKind_ClassType) { // TODO: error handling AssertAlways(!"unexpected parent tag"); @@ -2136,8 +2207,7 @@ d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_Com member->type = type; member->off = safe_cast_u32(dw_const_u32_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_DataMemberLocation)); } - }break; - + } break; } } scratch_end(scratch); @@ -2146,24 +2216,21 @@ d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_Com internal void d2r_convert_udts(Arena *arena, D2R_TypeTable *type_table, - DW_Raw *input, + DW_Input *input, DW_CompUnit *cu, DW_Language cu_lang, U64 arch_addr_size, DW_TagNode *root) { Temp scratch = scratch_begin(&arena, 1); - for(D2R_TagIter *it = d2r_tag_iter_init(scratch.arena, root); - it->tag_node != 0; - d2r_tag_iter_next(scratch.arena, it)) - { + for (D2R_TagIterator *it = d2r_tag_iterator_init(scratch.arena, root); it->tag_node != 0; d2r_tag_iterator_next(scratch.arena, it)) { DW_TagNode *tag_node = it->tag_node; DW_Tag tag = tag_node->tag; switch (tag.kind) { case DW_TagKind_ClassType: { B32 is_decl = dw_flag_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Declaration); if (is_decl) { - d2r_tag_iter_skip_children(it); + d2r_tag_iterator_skip_children(it); } else { RDIM_Type *type = d2r_type_from_offset(type_table, tag.info_off); RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP); @@ -2174,7 +2241,7 @@ d2r_convert_udts(Arena *arena, case DW_TagKind_StructureType: { B32 is_decl = dw_flag_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Declaration); if (is_decl) { - d2r_tag_iter_skip_children(it); + d2r_tag_iterator_skip_children(it); } else { RDIM_Type *type = d2r_type_from_offset(type_table, tag.info_off); RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP); @@ -2185,7 +2252,7 @@ d2r_convert_udts(Arena *arena, case DW_TagKind_UnionType: { B32 is_decl = dw_flag_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Declaration); if (is_decl) { - d2r_tag_iter_skip_children(it); + d2r_tag_iterator_skip_children(it); } else { RDIM_Type *type = d2r_type_from_offset(type_table, tag.info_off); RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP); @@ -2196,7 +2263,7 @@ d2r_convert_udts(Arena *arena, case DW_TagKind_EnumerationType: { B32 is_decl = dw_flag_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Declaration); if (is_decl) { - d2r_tag_iter_skip_children(it); + d2r_tag_iterator_skip_children(it); } else { RDIM_Type *type = d2r_type_from_offset(type_table, tag.info_off); RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP); @@ -2205,7 +2272,7 @@ d2r_convert_udts(Arena *arena, } } break; case DW_TagKind_Member: { - DW_Tag parent_tag = d2r_tag_iter_parent_tag(it); + DW_Tag parent_tag = d2r_tag_iterator_parent_tag(it); B32 is_parent_udt = parent_tag.kind == DW_TagKind_StructureType || parent_tag.kind == DW_TagKind_ClassType || parent_tag.kind == DW_TagKind_UnionType; @@ -2228,7 +2295,7 @@ d2r_convert_udts(Arena *arena, } } break; case DW_TagKind_Enumerator: { - DW_Tag parent_tag = d2r_tag_iter_parent_tag(it); + DW_Tag parent_tag = d2r_tag_iterator_parent_tag(it); if (parent_tag.kind == DW_TagKind_EnumerationType) { RDIM_Type *parent_type = d2r_type_from_offset(type_table, parent_tag.info_off); RDIM_UDTEnumVal *udt_member = rdim_udt_push_enum_val(arena, &udts, parent_type->udt); @@ -2245,26 +2312,28 @@ d2r_convert_udts(Arena *arena, } internal void -d2r_convert_symbols(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, DW_Language cu_lang, U64 arch_addr_size, U64 image_base, Arch arch, DW_TagNode *root) +d2r_convert_symbols(Arena *arena, + D2R_TypeTable *type_table, + RDIM_Scope *global_scope, + DW_Input *input, + DW_CompUnit *cu, + DW_Language cu_lang, + U64 arch_addr_size, + U64 image_base, + Arch arch, + DW_TagNode *root) { Temp scratch = scratch_begin(&arena, 1); - for(D2R_TagIter *it = d2r_tag_iter_init(scratch.arena, root); - it->tag_node != 0; - d2r_tag_iter_next(scratch.arena, it)) - { + for (D2R_TagIterator *it = d2r_tag_iterator_init(scratch.arena, root); it->tag_node != 0; d2r_tag_iterator_next(scratch.arena, it)) { DW_TagNode *tag_node = it->tag_node; DW_Tag tag = tag_node->tag; - switch(tag.kind) - { - case DW_TagKind_Null:{}break; - + switch (tag.kind) { + case DW_TagKind_Null: { InvalidPath; } break; case DW_TagKind_ClassType: case DW_TagKind_StructureType: - case DW_TagKind_UnionType: - { - // TODO(rjf): visit children to collect methods and variables - }break; - + case DW_TagKind_UnionType: { + // visit children to collect methods and variables + } break; case DW_TagKind_EnumerationType: case DW_TagKind_SubroutineType: case DW_TagKind_Typedef: @@ -2277,19 +2346,15 @@ d2r_convert_symbols(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_C case DW_TagKind_SubrangeType: case DW_TagKind_Inheritance: case DW_TagKind_Enumerator: - case DW_TagKind_Member: - { - d2r_tag_iter_skip_children(it); - }break; - - case DW_TagKind_SubProgram: - { + case DW_TagKind_Member: { + d2r_tag_iterator_skip_children(it); + } break; + case DW_TagKind_SubProgram: { DW_InlKind inl = DW_Inl_NotInlined; if (dw_tag_has_attrib(input, cu, tag, DW_AttribKind_Inline)) { inl = dw_const_u64_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Inline); } - switch(inl) - { - case DW_Inl_NotInlined: - { + + switch (inl) { + case DW_Inl_NotInlined: { U64 param_count = 0; RDIM_Type **params = d2r_collect_proc_params(arena, type_table, input, cu, tag_node, ¶m_count); @@ -2332,7 +2397,7 @@ d2r_convert_symbols(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_C proc->location_cases = d2r_locset_from_attrib(arena, &scopes, root_scope, &locations, input, cu, image_base, arch, tag, DW_AttribKind_FrameBase); // sub program with user-defined parent tag is a method - DW_Tag parent_tag = d2r_tag_iter_parent_tag(it); + DW_Tag parent_tag = d2r_tag_iterator_parent_tag(it); if (parent_tag.kind == DW_TagKind_ClassType || parent_tag.kind == DW_TagKind_StructureType) { RDI_MemberKind member_kind = RDI_MemberKind_NULL; DW_VirtualityKind virtuality = dw_const_u64_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Virtuality); @@ -2353,19 +2418,16 @@ d2r_convert_symbols(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_C } it->stack->scope = root_scope; - }break; + } break; case DW_Inl_DeclaredNotInlined: case DW_Inl_DeclaredInlined: - case DW_Inl_Inlined: - { - d2r_tag_iter_skip_children(it); - }break; - default:{}break; + case DW_Inl_Inlined: { + d2r_tag_iterator_skip_children(it); + } break; + default: InvalidPath; break; } - }break; - - case DW_TagKind_InlinedSubroutine: - { + } break; + case DW_TagKind_InlinedSubroutine: { U64 param_count = 0; RDIM_Type **params = d2r_collect_proc_params(arena, type_table, input, cu, tag_node, ¶m_count); @@ -2397,14 +2459,12 @@ d2r_convert_symbols(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_C Rng1U64List ranges = d2r_range_list_from_tag(scratch.arena, input, cu, image_base, tag); RDIM_Scope *root_scope = d2r_push_scope(arena, &scopes, SCOPE_CHUNK_CAP, it->stack, ranges); root_scope->inline_site = inline_site; - }break; - - case DW_TagKind_Variable: - { + } break; + case DW_TagKind_Variable: { String8 name = dw_string_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Name); RDIM_Type *type = d2r_type_from_attrib(type_table, input, cu, tag, DW_AttribKind_Type); - DW_Tag parent_tag = d2r_tag_iter_parent_tag(it); + DW_Tag parent_tag = d2r_tag_iterator_parent_tag(it); if (parent_tag.kind == DW_TagKind_SubProgram || parent_tag.kind == DW_TagKind_InlinedSubroutine || parent_tag.kind == DW_TagKind_LexicalBlock) { @@ -2460,11 +2520,9 @@ d2r_convert_symbols(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_C var->container_symbol = 0; var->container_type = 0; // TODO: NotImplemented; } - }break; - - case DW_TagKind_FormalParameter: - { - DW_Tag parent_tag = d2r_tag_iter_parent_tag(it); + } break; + case DW_TagKind_FormalParameter: { + DW_Tag parent_tag = d2r_tag_iterator_parent_tag(it); if (parent_tag.kind == DW_TagKind_SubProgram || parent_tag.kind == DW_TagKind_InlinedSubroutine) { RDIM_Scope *scope = it->stack->next->scope; RDIM_Local *param = rdim_scope_push_local(arena, &scopes, scope); @@ -2472,35 +2530,26 @@ d2r_convert_symbols(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_C param->name = dw_string_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Name); param->type = d2r_type_from_attrib(type_table, input, cu, tag, DW_AttribKind_Type); param->location_cases = d2r_var_locset_from_tag(arena, &scopes, scope, &locations, input, cu, image_base, arch, tag); + } else { + // TODO: error handling + AssertAlways(!"this is a local variable"); } - else - { - // TODO: error handling; this is a local variable - } - }break; - - case DW_TagKind_LexicalBlock: - { - DW_Tag parent_tag = d2r_tag_iter_parent_tag(it); - if(parent_tag.kind == DW_TagKind_SubProgram || - parent_tag.kind == DW_TagKind_InlinedSubroutine || - parent_tag.kind == DW_TagKind_LexicalBlock) - { + } break; + case DW_TagKind_LexicalBlock: { + DW_Tag parent_tag = d2r_tag_iterator_parent_tag(it); + if (parent_tag.kind == DW_TagKind_SubProgram || + parent_tag.kind == DW_TagKind_InlinedSubroutine || + parent_tag.kind == DW_TagKind_LexicalBlock) { Rng1U64List ranges = d2r_range_list_from_tag(scratch.arena, input, cu, image_base, tag); d2r_push_scope(arena, &scopes, SCOPE_CHUNK_CAP, it->stack, ranges); } - }break; - - case DW_TagKind_CallSite: - { + } break; + case DW_TagKind_CallSite: { // TODO - }break; - - case DW_TagKind_CallSiteParameter: - { + } break; + case DW_TagKind_CallSiteParameter: { // TODO - }break; - + } break; case DW_TagKind_Label: case DW_TagKind_CompileUnit: case DW_TagKind_UnspecifiedParameters: @@ -2508,11 +2557,9 @@ d2r_convert_symbols(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_C case DW_TagKind_ImportedDeclaration: case DW_TagKind_PtrToMemberType: case DW_TagKind_TemplateTypeParameter: - case DW_TagKind_ReferenceType: - { - // TODO - }break; - + case DW_TagKind_ReferenceType: { + // TODO: + } break; default: { // NotImplemented; @@ -2522,489 +2569,288 @@ d2r_convert_symbols(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_C scratch_end(scratch); } -//////////////////////////////// -//~ rjf: Main Conversion Entry Point - internal RDIM_BakeParams d2r_convert(Arena *arena, D2R_ConvertParams *params) { Temp scratch = scratch_begin(&arena, 1); - if(lane_idx() == 0) - { - //////////////////////////// - //- rjf: unpack input image info - // - Arch arch = Arch_Null; - U64 image_base = 0; - DW_Raw input = {0}; - PathStyle path_style = PathStyle_Null; - switch(params->exe_kind) - { - default:{}break; - case ExecutableImageKind_CoffPe: - { - PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, params->exe_data); - String8 raw_sections = str8_substr(params->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(params->exe_data, pe.string_table_range); - arch = pe.arch; - image_base = pe.image_base; - binary_sections = c2r_rdi_binary_sections_from_coff_sections(arena, params->exe_data, string_table, pe.section_count, section_table); - input = dw_raw_from_coff_section_table(scratch.arena, params->exe_data, string_table, pe.section_count, section_table); - path_style = PathStyle_WindowsAbsolute; - }break; - case ExecutableImageKind_Elf32: - case ExecutableImageKind_Elf64: - { - ELF_Bin bin = elf_bin_from_data(scratch.arena, params->dbg_data); - arch = arch_from_elf_machine(bin.hdr.e_machine); - image_base = (bin.hdr.e_type == ELF_Type_Dyn ? 0 : elf_base_addr_from_bin(&bin)); - binary_sections = e2r_rdi_binary_sections_from_elf_section_table(arena, params->dbg_data, &bin, bin.shdrs); - input = dw_raw_from_elf_bin(scratch.arena, params->dbg_data, &bin); - path_style = PathStyle_UnixAbsolute; - }break; - } - U64 arch_addr_size = rdi_addr_size_from_arch(arch); + if (lane_idx() == 0) { + //////////////////////////////// - //////////////////////////// - //- rjf: determine acceptable address range - // - // in many cases, linkers seem to trample over addresses in various DWARF sections, - // potentially due to optimizations. we'd like to filter out those busted addresses - // from our final debug info - a good enough heuristic is to disqualify them by - // whether or not they actually fall into the ranges covered by the binary sections. - // - Rng1U64 acceptable_vaddr_range = {0}; - { - acceptable_vaddr_range.min = max_U64; - acceptable_vaddr_range.max = 0; - for EachNode(n, RDIM_BinarySectionNode, binary_sections.first) - { - acceptable_vaddr_range.min = Min(n->v.voff_first, acceptable_vaddr_range.min); - acceptable_vaddr_range.max = Max(n->v.voff_opl, acceptable_vaddr_range.max); - } - } - - //////////////////////////// - //- rjf: compute exe hash - // ProfBegin("compute exe hash"); U64 exe_hash = rdi_hash(params->exe_data.str, params->exe_data.size); ProfEnd(); - //////////////////////////// - //- rjf: convert top-level-info - // - { - // rjf: base arch -> rdi - RDI_Arch arch_rdi = RDI_Arch_NULL; - switch(arch) - { - case Arch_Null: - case Arch_arm64: - case Arch_arm32: - case Arch_COUNT: - {}break; - case Arch_x64:{arch_rdi = RDI_Arch_X64;}break; - case Arch_x86:{arch_rdi = RDI_Arch_X86;}break; - } - - // rjf: binary sections -> voff max - U64 exe_voff_max = 0; - for EachNode(sect_n, RDIM_BinarySectionNode, binary_sections.first) - { - exe_voff_max = Max(exe_voff_max, sect_n->v.voff_opl); - } - - // rjf: fill - top_level_info.arch = arch_rdi; - top_level_info.exe_name = params->exe_name; - top_level_info.exe_hash = exe_hash; - top_level_info.voff_max = exe_voff_max; - if(!params->deterministic) - { - // TODO(rjf): top_level_info.guid = ...; - top_level_info.producer_name = str8_lit(BUILD_TITLE_STRING_LITERAL); - } + //////////////////////////////// + + Arch arch = Arch_Null; + U64 image_base = 0; + DW_Input input = {0}; + PathStyle path_style = PathStyle_Null; + + switch(params->exe_kind) { + default:{}break; + case ExecutableImageKind_CoffPe: { + PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, params->exe_data); + String8 raw_sections = str8_substr(params->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(params->exe_data, pe.string_table_range); + arch = pe.arch; + image_base = pe.image_base; + binary_sections = c2r_rdi_binary_sections_from_coff_sections(arena, params->exe_data, string_table, pe.section_count, section_table); + input = dw_input_from_coff_section_table(scratch.arena, params->exe_data, string_table, pe.section_count, section_table); + path_style = PathStyle_WindowsAbsolute; + } break; + case ExecutableImageKind_Elf32: + case ExecutableImageKind_Elf64: { + ELF_Bin bin = elf_bin_from_data(scratch.arena, params->dbg_data); + arch = arch_from_elf_machine(bin.hdr.e_machine); + image_base = elf_base_addr_from_bin(&bin); + binary_sections = e2r_rdi_binary_sections_from_elf_section_table(arena, bin.shdrs); + input = dw_input_from_elf_bin(scratch.arena, params->dbg_data, &bin); + path_style = PathStyle_UnixAbsolute; + } break; } - //////////////////////////// - //- rjf: parse unit contribution map - // + //////////////////////////////// + + top_level_info = rdim_make_top_level_info(params->exe_name, arch, exe_hash, binary_sections); + + //////////////////////////////// + + U64 arch_addr_size = rdi_addr_size_from_arch(top_level_info.arch); + + //////////////////////////////// + + RDIM_Scope *global_scope = rdim_scope_chunk_list_push(arena, &scopes, SCOPE_CHUNK_CAP); + + //////////////////////////////// + + ProfBegin("Parse Unit Contrib Map"); D2R_CompUnitContribMap cu_contrib_map = {0}; - ProfScope("parse unit contribution map") - { - String8 aranges_data = input.sec[DW_Section_ARanges].data; - if(aranges_data.size != 0) - { - Temp scratch = scratch_begin(&arena, 1); - - //- rjf: unpack input - Rng1U64List unit_range_list = dw_unit_ranges_from_data(scratch.arena, aranges_data); - - //- rjf: set up map - cu_contrib_map.info_off_arr = push_array(arena, U64, unit_range_list.count); - cu_contrib_map.voff_range_arr = push_array(arena, RDIM_Rng1U64ChunkList, unit_range_list.count); - - //- rjf: convert all units - for EachNode(range_n, Rng1U64Node, unit_range_list.first) - { - //- rjf: unpack unit - String8 unit_data = str8_substr(aranges_data, range_n->v); - U64 unit_cursor = 0; - - //- rjf: read unit data length - U64 unit_length = 0; - U64 unit_length_size = dw_str8_deserial_read_packed_size(unit_data, unit_cursor, &unit_length); - B32 unit_length_good = (unit_length_size != 0); - unit_cursor += unit_length_size; - DW_Format unit_format = DW_FormatFromSize(unit_length); - - //- rjf: read unit version - DW_Version version = 0; - U64 version_size = str8_deserial_read_struct(unit_data, unit_cursor, &version); - B32 version_good = (version_size != 0); - unit_cursor += version_size; - - //- rjf: parse section by version - switch(version) - { - //- rjf: unsupported versions - default: - { - log_infof("Unknown .debug_aranges version (%i).\n", version); - }break; - - //- rjf: version 2 - case DW_Version_2: - { - // rjf: unpack & read unit header info - U64 unit_info_off = 0; - U8 unit_address_size = 0; - U8 unit_segment_selector_size = 0; - B32 unit_good = 0; - { - U64 unit_info_off_size = dw_str8_deserial_read_fmt_uint(unit_data, unit_cursor, unit_format, &unit_info_off); - unit_cursor += unit_info_off_size; - U64 unit_address_size_size = str8_deserial_read_struct(unit_data, unit_cursor, &unit_address_size); - unit_cursor += unit_address_size_size; - U64 unit_segment_selector_size_size = str8_deserial_read_struct(unit_data, unit_cursor, &unit_segment_selector_size); - unit_cursor += unit_segment_selector_size_size; - unit_good = (unit_info_off_size != 0 && unit_address_size_size != 0 && unit_segment_selector_size_size != 0); - } - U64 tuple_size = unit_address_size * 2 + unit_segment_selector_size; - - // rjf: align cursor to be divisible by the tuple size (see the February 13, 2017 spec) - { - U64 bytes_too_far_past_boundary = unit_cursor % tuple_size; - if(bytes_too_far_past_boundary > 0) - { - unit_cursor += tuple_size - bytes_too_far_past_boundary; - } - } - - // rjf: read all ranges - RDIM_Rng1U64ChunkList voff_ranges = {0}; - if(unit_segment_selector_size == 0) - { - for(;unit_cursor + unit_address_size*2 <= unit_data.size;) - { - U64 segment = 0; - U64 address = 0; - U64 length = 0; - unit_cursor += str8_deserial_read(unit_data, unit_cursor, &segment, unit_segment_selector_size, Max(unit_segment_selector_size, 1)); - unit_cursor += str8_deserial_read(unit_data, unit_cursor, &address, unit_address_size, unit_address_size); - unit_cursor += str8_deserial_read(unit_data, unit_cursor, &length, unit_address_size, unit_address_size); - if((segment != 0 || address != 0 || length != 0) && - (contains_1u64(acceptable_vaddr_range, address) || - contains_1u64(acceptable_vaddr_range, address + length))) - { - RDIM_Rng1U64 range = - { - address - image_base, - address - image_base + length, - }; - rdim_rng1u64_chunk_list_push(arena, &voff_ranges, 256, range); - } - else - { - break; - } - } - } - else - { - log_infof("Segment-relative addressing detected in .debug_aranges; this is not currently supported.\n"); - } - - // rjf: store record - U64 map_idx = cu_contrib_map.count; - cu_contrib_map.info_off_arr[map_idx] = unit_info_off; - cu_contrib_map.voff_range_arr[map_idx] = voff_ranges; - cu_contrib_map.count += 1; - }break; - } - } - - scratch_end(scratch); - } + if (input.sec[DW_Section_ARanges].data.size) { + cu_contrib_map = d2r_cu_contrib_map_from_aranges(arena, &input, image_base); } + ProfEnd(); - //////////////////////////// - //- rjf: parse list of comp units - // - DW_ListUnitInput lu_input = {0}; - ProfScope("parse list of comp units") - { - lu_input = dw_list_unit_input_from_raw(scratch.arena, &input); + ProfBegin("Parse Comop Unit Ranges"); + DW_ListUnitInput lu_input = dw_list_unit_input_from_input(scratch.arena, &input); + Rng1U64List cu_range_list = dw_unit_ranges_from_data(scratch.arena, input.sec[DW_Section_Info].data); + Rng1U64Array cu_ranges = rng1u64_array_from_list(scratch.arena, &cu_range_list); + ProfEnd(); + + //////////////////////////////// + + ProfBegin("Parse Compile Unit Headers"); + // TODO(rjf): parse should always be relaxed. any verification checks we do + // should just be logged via log_info(...), and then the caller of this + // converter can collect those & display as necessary. + B32 is_parse_relaxed = 1; + DW_CompUnit *cu_arr = push_array(scratch.arena, DW_CompUnit, cu_ranges.count); + for EachIndex(cu_idx, cu_ranges.count) { + cu_arr[cu_idx] = dw_cu_from_info_off(scratch.arena, &input, lu_input, cu_ranges.v[cu_idx].min, is_parse_relaxed); } + ProfEnd(); - //////////////////////////// - //- rjf: parse comp unit ranges - // - Rng1U64Array cu_ranges = {0}; - ProfScope("parse comp unit ranges") - { - Rng1U64List cu_range_list = dw_unit_ranges_from_data(scratch.arena, input.sec[DW_Section_Info].data); - cu_ranges = rng1u64_array_from_list(scratch.arena, &cu_range_list); - } + //////////////////////////////// - //////////////////////////// - //- rjf: parse comp unit headers - // - DW_CompUnit *cu_arr = 0; - ProfScope("parse comp unit headers") - { - cu_arr = push_array(scratch.arena, DW_CompUnit, cu_ranges.count); - for EachIndex(cu_idx, cu_ranges.count) - { - cu_arr[cu_idx] = dw_cu_from_info_off(scratch.arena, &input, lu_input, cu_ranges.v[cu_idx].min); - } - } - - //////////////////////////// - //- rjf: parse line tables - // + ProfBegin("Parse Line Tables"); DW_LineTableParseResult *cu_line_tables = push_array(scratch.arena, DW_LineTableParseResult, cu_ranges.count); - ProfScope("parse line tables") - { - for EachIndex(cu_idx, cu_ranges.count) - { - DW_CompUnit *cu = &cu_arr[cu_idx]; - String8 cu_stmt_list = dw_line_ptr_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_StmtList); - String8 cu_dir = dw_string_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_CompDir); - String8 cu_name = dw_string_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_Name); - cu_line_tables[cu_idx] = dw_parsed_line_table_from_data(scratch.arena, cu_stmt_list, &input, cu_dir, cu_name, cu->address_size, cu->str_offsets_lu); - } + for EachIndex(cu_idx, cu_ranges.count) { + DW_CompUnit *cu = &cu_arr[cu_idx]; + String8 cu_stmt_list = dw_line_ptr_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_StmtList); + String8 cu_dir = dw_string_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_CompDir); + String8 cu_name = dw_string_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_Name); + cu_line_tables[cu_idx] = dw_parsed_line_table_from_data(scratch.arena, cu_stmt_list, &input, cu_dir, cu_name, cu->address_size, cu->str_offsets_lu); } + ProfEnd(); - //////////////////////////// - //- rjf: convert line tables - // - RDIM_LineTable **cu_line_tables_rdi = 0; - ProfScope("convert line tables") - { - HashTable *source_file_ht = hash_table_init(scratch.arena, 0x4000); - cu_line_tables_rdi = push_array(scratch.arena, RDIM_LineTable *, cu_ranges.count); - for EachIndex(cu_idx, cu_ranges.count) - { - cu_line_tables_rdi[cu_idx] = rdim_line_table_chunk_list_push(arena, &line_tables, LINE_TABLE_CAP); - - DW_LineTableParseResult *line_table = &cu_line_tables[cu_idx]; - DW_LineVMFileArray *dir_table = &line_table->vm_header.dir_table; - DW_LineVMFileArray *file_table = &line_table->vm_header.file_table; - RDIM_SrcFile **src_file_map = push_array(scratch.arena, RDIM_SrcFile *, file_table->count); - for EachIndex(file_idx, file_table->count) - { - DW_LineFile *file = &file_table->v[file_idx]; - String8 file_path = dw_path_from_file_idx(scratch.arena, &line_table->vm_header, file_idx); - String8List file_path_split = str8_split_path(scratch.arena, file_path); - str8_path_list_resolve_dots_in_place(&file_path_split, path_style); - String8 file_path_resolved = str8_path_list_join_by_style(scratch.arena, &file_path_split, path_style); - RDIM_SrcFile *src_file = hash_table_search_path_raw(source_file_ht, file_path_resolved); - if(src_file == 0) - { - src_file = rdim_src_file_chunk_list_push(arena, &src_files, SRC_FILE_CAP); - src_file->path = push_str8_copy(arena, file_path_resolved); - hash_table_push_path_raw(scratch.arena, source_file_ht, src_file->path, src_file); - } - src_file_map[file_idx] = src_file; + //////////////////////////////// + + ProfBegin("Convert Line Tables"); + HashTable *source_file_ht = hash_table_init(scratch.arena, 0x4000); + RDIM_LineTable **cu_line_tables_rdi = push_array(scratch.arena, RDIM_LineTable *, cu_ranges.count); + for EachIndex(cu_idx, cu_ranges.count) { + cu_line_tables_rdi[cu_idx] = rdim_line_table_chunk_list_push(arena, &line_tables, LINE_TABLE_CAP); + + DW_LineTableParseResult *line_table = &cu_line_tables[cu_idx]; + DW_LineVMFileArray *dir_table = &line_table->vm_header.dir_table; + DW_LineVMFileArray *file_table = &line_table->vm_header.file_table; + RDIM_SrcFile **src_file_map = push_array(scratch.arena, RDIM_SrcFile *, file_table->count); + for EachIndex(file_idx, file_table->count) { + DW_LineFile *file = &file_table->v[file_idx]; + String8 file_path = dw_path_from_file_idx(scratch.arena, &line_table->vm_header, file_idx); + String8List file_path_split = str8_split_path(scratch.arena, file_path); + str8_path_list_resolve_dots_in_place(&file_path_split, path_style); + String8 file_path_resolved = str8_path_list_join_by_style(scratch.arena, &file_path_split, path_style); + RDIM_SrcFile *src_file = hash_table_search_path_raw(source_file_ht, file_path_resolved); + if (src_file == 0) { + src_file = rdim_src_file_chunk_list_push(arena, &src_files, SRC_FILE_CAP); + src_file->path = push_str8_copy(arena, file_path_resolved); + hash_table_push_path_raw(scratch.arena, source_file_ht, src_file->path, src_file); } + src_file_map[file_idx] = src_file; + } + + for EachNode(line_seq, DW_LineSeqNode, line_table->first_seq) { + if (line_seq->count == 0) { continue; } - for EachNode(line_seq, DW_LineSeqNode, line_table->first_seq) - { - if(line_seq->count == 0) {continue;} - - U64 *voffs = push_array(arena, U64, line_seq->count); - U32 *line_nums = push_array(arena, U32, line_seq->count); - U16 *col_nums = 0; - U64 line_idx = 0; - - DW_LineNode *file_line_n = line_seq->first; - U64 file_line_count = 0; - - for EachNode(line_n, DW_LineNode, file_line_n) - { - if(file_line_n->v.file_index != line_n->v.file_index || line_n->next == 0) - { - U64 file_index = file_line_n->v.file_index; - U64 *file_voffs = &voffs[line_idx]; - U32 *file_line_nums = &line_nums[line_idx]; - U16 *file_col_nums = 0; - - U64 lines_written = 0; - U64 prev_ln = max_U64; - DW_LineNode *sentinel = line_n->v.file_index != file_line_n->v.file_index ? line_n : 0; - for(; file_line_n != sentinel; file_line_n = file_line_n->next) - { - if(file_line_n->v.line != prev_ln) - { - if(file_line_n->v.address == 0) {continue;} - - voffs[line_idx] = file_line_n->v.address; - line_nums[line_idx] = file_line_n->v.line; - - lines_written += 1; - line_idx += 1; - - prev_ln = file_line_n->v.line; - } - } - - RDIM_SrcFile *src_file = src_file_map[file_index]; - RDIM_LineSequence *line_seq = rdim_line_table_push_sequence(arena, &line_tables, cu_line_tables_rdi[cu_idx], src_file, file_voffs, file_line_nums, file_col_nums, lines_written); - rdim_src_file_push_line_sequence(arena, &src_files, src_file, line_seq); - - file_line_count = 1; - } - else - { - file_line_count += 1; - } - } - - // handle last line - if(file_line_n) - { + U64 *voffs = push_array(arena, U64, line_seq->count); + U32 *line_nums = push_array(arena, U32, line_seq->count); + U16 *col_nums = 0; + U64 line_idx = 0; + + DW_LineNode *file_line_n = line_seq->first; + U64 file_line_count = 0; + + for EachNode(line_n, DW_LineNode, file_line_n) { + if (file_line_n->v.file_index != line_n->v.file_index || line_n->next == 0) { U64 file_index = file_line_n->v.file_index; U64 *file_voffs = &voffs[line_idx]; U32 *file_line_nums = &line_nums[line_idx]; U16 *file_col_nums = 0; - for(;file_line_n != 0; file_line_n = file_line_n->next, line_idx += 1) - { - // NOTE(rjf): DWARF encodes line info as "relocatable addresses"; we do *not* - // need to translate from 'addresses' to 'voffs' with the image base here. - voffs[line_idx] = file_line_n->v.address; - line_nums[line_idx] = file_line_n->v.line; + + U64 lines_written = 0; + U64 prev_ln = max_U64; + DW_LineNode *sentinel = line_n->v.file_index != file_line_n->v.file_index ? line_n : 0; + for (; file_line_n != sentinel; file_line_n = file_line_n->next) { + if (file_line_n->v.line != prev_ln) { + if (file_line_n->v.address == 0) { continue; } + + voffs[line_idx] = file_line_n->v.address - image_base; + line_nums[line_idx] = file_line_n->v.line; + + ++lines_written; + ++line_idx; + + prev_ln = file_line_n->v.line; + } } + RDIM_SrcFile *src_file = src_file_map[file_index]; - RDIM_LineSequence *line_seq = rdim_line_table_push_sequence(arena, &line_tables, cu_line_tables_rdi[cu_idx], src_file, file_voffs, file_line_nums, file_col_nums, file_line_count); + RDIM_LineSequence *line_seq = rdim_line_table_push_sequence(arena, &line_tables, cu_line_tables_rdi[cu_idx], src_file, file_voffs, file_line_nums, file_col_nums, lines_written); rdim_src_file_push_line_sequence(arena, &src_files, src_file, line_seq); + + file_line_count = 1; + } else { + file_line_count += 1; } } + + // handle last line + if (file_line_n) { + U64 file_index = file_line_n->v.file_index; + U64 *file_voffs = &voffs[line_idx]; + U32 *file_line_nums = &line_nums[line_idx]; + U16 *file_col_nums = 0; + + for (; file_line_n != 0; file_line_n = file_line_n->next, line_idx += 1) { + // TODO: error handling + AssertAlways(file_line_n->v.address >= image_base); + voffs[line_idx] = file_line_n->v.address - image_base; + line_nums[line_idx] = file_line_n->v.line; + } + + RDIM_SrcFile *src_file = src_file_map[file_index]; + RDIM_LineSequence *line_seq = rdim_line_table_push_sequence(arena, &line_tables, cu_line_tables_rdi[cu_idx], src_file, file_voffs, file_line_nums, file_col_nums, file_line_count); + rdim_src_file_push_line_sequence(arena, &src_files, src_file, line_seq); + } + + //Assert(line_idx == line_seq->count); } } + ProfEnd(); + + //////////////////////////////// - //////////////////////////// - //- rjf: build built-in basic types - // RDIM_Type *builtin_types[RDI_TypeKind_Count] = {0}; - ProfScope("build built-in basic types") - { - for(RDI_TypeKind type_kind = RDI_TypeKind_FirstBuiltIn; type_kind <= RDI_TypeKind_LastBuiltIn; type_kind += 1) - { - RDIM_Type *type = rdim_type_chunk_list_push(arena, &types, TYPE_CHUNK_CAP); - type->kind = type_kind; - type->name.str = rdi_string_from_type_kind(type_kind, &type->name.size); - type->byte_size = rdi_size_from_basic_type_kind(type_kind); - builtin_types[type_kind] = type; - } - builtin_types[RDI_TypeKind_Handle]->byte_size = arch_addr_size; - builtin_types[RDI_TypeKind_Variadic] = rdim_type_chunk_list_push(arena, &types, TYPE_CHUNK_CAP); - builtin_types[RDI_TypeKind_Variadic]->kind = RDI_TypeKind_Variadic; + for (RDI_TypeKind type_kind = RDI_TypeKind_FirstBuiltIn; type_kind <= RDI_TypeKind_LastBuiltIn; type_kind += 1) { + RDIM_Type *type = rdim_type_chunk_list_push(arena, &types, TYPE_CHUNK_CAP); + type->kind = type_kind; + type->name.str = rdi_string_from_type_kind(type_kind, &type->name.size); + type->byte_size = rdi_size_from_basic_type_kind(type_kind); + builtin_types[type_kind] = type; } + builtin_types[RDI_TypeKind_Void]->byte_size = arch_addr_size; + builtin_types[RDI_TypeKind_Handle]->byte_size = arch_addr_size; - //////////////////////////// - //- rjf: convert units - // - ProfScope("convert units") - { - for EachIndex(cu_idx, cu_ranges.count) + builtin_types[RDI_TypeKind_Variadic] = rdim_type_chunk_list_push(arena, &types, TYPE_CHUNK_CAP); + builtin_types[RDI_TypeKind_Variadic]->kind = RDI_TypeKind_Variadic; + + //////////////////////////////// + + ProfBegin("Convert Units"); + for EachIndex(cu_idx, cu_ranges.count) { + Temp comp_temp = temp_begin(scratch.arena); + + DW_CompUnit *cu = &cu_arr[cu_idx]; + + // parse and build tag tree + DW_TagTree tag_tree = dw_tag_tree_from_cu(comp_temp.arena, &input, cu); + + // skip DWO { - Temp comp_temp = temp_begin(scratch.arena); + if (cu->dwo_id) { goto next_cu; } - DW_CompUnit *cu = &cu_arr[cu_idx]; + String8 dwo_name = dw_string_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_DwoName); + if (dwo_name.size) { goto next_cu; } - // parse and build tag tree - DW_TagTree tag_tree = dw_tag_tree_from_cu(comp_temp.arena, &input, cu); - - // skip DWO - { - if (cu->dwo_id) { goto next_cu; } - - String8 dwo_name = dw_string_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_DwoName); - if (dwo_name.size) { goto next_cu; } - - String8 gnu_dwo_name = dw_string_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_GNU_DwoName); - if (gnu_dwo_name.size) { goto next_cu; } - } - - // build (info offset -> tag) hash table to resolve tags with abstract origin - cu->tag_ht = dw_make_tag_hash_table(comp_temp.arena, tag_tree); - - // extract compile unit info - String8 cu_name = dw_string_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_Name); - String8 cu_dir = dw_string_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_CompDir); - String8 cu_prod = dw_string_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_Producer); - DW_Language cu_lang = dw_const_u64_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_Language); - - // init type table - D2R_TypeTable *type_table = push_array(comp_temp.arena, D2R_TypeTable, 1); - type_table->ht = hash_table_init(comp_temp.arena, 0x4000); - type_table->types = &types; - type_table->type_chunk_cap = TYPE_CHUNK_CAP; - type_table->builtin_types = builtin_types; - - // convert debug info - d2r_convert_types(arena, type_table, &input, cu, cu_lang, arch_addr_size, tag_tree.root); - d2r_convert_udts(arena, type_table, &input, cu, cu_lang, arch_addr_size, tag_tree.root); - d2r_convert_symbols(arena, type_table, &input, cu, cu_lang, arch_addr_size, image_base, arch, tag_tree.root); - - RDIM_Rng1U64ChunkList cu_voff_ranges = {0}; - if(cu_idx < cu_contrib_map.count) - { - cu_voff_ranges = d2r_voff_ranges_from_cu_info_off(cu_contrib_map, cu_ranges.v[cu_idx].min); - } - else - { - Rng1U64List range_list = d2r_range_list_from_tag(scratch.arena, &input, cu, image_base, cu->tag); - for EachNode(n, Rng1U64Node, range_list.first) - { - rdim_rng1u64_chunk_list_push(arena, &cu_voff_ranges, 512, (RDIM_Rng1U64){ .min = n->v.min, .max = n->v.max }); - } - } - - // convert compile unit - { - RDIM_Unit *unit = rdim_unit_chunk_list_push(arena, &units, UNIT_CHUNK_CAP); - unit->unit_name = cu_name; - unit->compiler_name = cu_prod; - unit->source_file = str8_zero(); // TODO - unit->object_file = str8_zero(); // TODO - unit->archive_file = str8_zero(); // TODO - unit->build_path = cu_dir; - unit->language = d2r_rdi_language_from_dw_language(cu_lang); - unit->line_table = cu_line_tables_rdi[cu_idx]; - unit->voff_ranges = cu_voff_ranges; - } - - next_cu:; - temp_end(comp_temp); + String8 gnu_dwo_name = dw_string_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_GNU_DwoName); + if (gnu_dwo_name.size) { goto next_cu; } } + + // build (info offset -> tag) hash table to resolve tags with abstract origin + cu->tag_ht = dw_make_tag_hash_table(comp_temp.arena, tag_tree); + + // extract compile unit info + String8 cu_name = dw_string_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_Name); + String8 cu_dir = dw_string_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_CompDir); + String8 cu_prod = dw_string_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_Producer); + DW_Language cu_lang = dw_const_u64_from_tag_attrib_kind(&input, cu, cu->tag, DW_AttribKind_Language); + + // init type table + D2R_TypeTable *type_table = push_array(comp_temp.arena, D2R_TypeTable, 1); + type_table->ht = hash_table_init(comp_temp.arena, 0x4000); + type_table->types = &types; + type_table->type_chunk_cap = TYPE_CHUNK_CAP; + type_table->builtin_types = builtin_types; + + // convert debug info + d2r_convert_types(arena, type_table, &input, cu, cu_lang, arch_addr_size, tag_tree.root); + d2r_convert_udts(arena, type_table, &input, cu, cu_lang, arch_addr_size, tag_tree.root); + d2r_convert_symbols(arena, type_table, global_scope, &input, cu, cu_lang, arch_addr_size, image_base, arch, tag_tree.root); + + RDIM_Rng1U64ChunkList cu_voff_ranges = {0}; + if (cu_idx < cu_contrib_map.count) { + cu_voff_ranges = d2r_voff_ranges_from_cu_info_off(cu_contrib_map, cu_ranges.v[cu_idx].min); + } else { + Rng1U64List range_list = d2r_range_list_from_tag(scratch.arena, &input, cu, image_base, cu->tag); + for EachNode(n, Rng1U64Node, range_list.first) { + rdim_rng1u64_chunk_list_push(arena, &cu_voff_ranges, 512, (RDIM_Rng1U64){ .min = n->v.min, .max = n->v.max }); + } + } + + // convert compile unit + { + RDIM_Unit *unit = rdim_unit_chunk_list_push(arena, &units, UNIT_CHUNK_CAP); + unit->unit_name = cu_name; + unit->compiler_name = cu_prod; + unit->source_file = str8_zero(); // TODO + unit->object_file = str8_zero(); // TODO + unit->archive_file = str8_zero(); // TODO + unit->build_path = cu_dir; + unit->language = d2r_rdi_language_from_dw_language(cu_lang); + unit->line_table = cu_line_tables_rdi[cu_idx]; + unit->voff_ranges = cu_voff_ranges; + } + + next_cu:; + temp_end(comp_temp); } - + ProfEnd(); } + lane_sync(); + RDIM_BakeParams bake_params = {0}; bake_params.subset_flags = params->subset_flags; bake_params.top_level_info = top_level_info; @@ -3020,6 +2866,7 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params) bake_params.procedures = procs; bake_params.scopes = scopes; bake_params.inline_sites = inline_sites; + scratch_end(scratch); return bake_params; } diff --git a/src/rdi_from_dwarf/rdi_from_dwarf.h b/src/rdi_from_dwarf/rdi_from_dwarf.h index 25cd3770..5b297184 100644 --- a/src/rdi_from_dwarf/rdi_from_dwarf.h +++ b/src/rdi_from_dwarf/rdi_from_dwarf.h @@ -1,11 +1,7 @@ // Copyright (c) Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -#ifndef RDI_FROM_DWARF_H -#define RDI_FROM_DWARF_H - -//////////////////////////////// -//~ rjf: Conversion Stage Inputs +#pragma once typedef struct D2R_ConvertParams D2R_ConvertParams; struct D2R_ConvertParams @@ -19,43 +15,35 @@ struct D2R_ConvertParams B32 deterministic; }; -//////////////////////////////// -//~ rjf: Conversion Helper Types - -typedef struct D2R_TypeTable D2R_TypeTable; -struct D2R_TypeTable +typedef struct D2R_TypeTable { - HashTable *ht; + HashTable *ht; RDIM_TypeChunkList *types; - U64 type_chunk_cap; - RDIM_Type **builtin_types; -}; + U64 type_chunk_cap; + RDIM_Type **builtin_types; +} D2R_TypeTable; -typedef struct D2R_TagFrame D2R_TagFrame; -struct D2R_TagFrame +typedef struct D2R_TagFrame { DW_TagNode *node; RDIM_Scope *scope; struct D2R_TagFrame *next; -}; +} D2R_TagFrame; -typedef struct D2R_TagIter D2R_TagIter; -struct D2R_TagIter +typedef struct D2R_TagIterator { D2R_TagFrame *free_list; D2R_TagFrame *stack; - DW_TagNode *tag_node; - DW_TagNode *root; - B32 visit_children; -}; + DW_TagNode *tag_node; + B32 visit_children; +} D2R_TagIterator; -typedef struct D2R_CompUnitContribMap D2R_CompUnitContribMap; -struct D2R_CompUnitContribMap +typedef struct D2R_CompUnitContribMap { - U64 count; - U64 *info_off_arr; + U64 count; + U64 *info_off_arr; RDIM_Rng1U64ChunkList *voff_range_arr; -}; +} D2R_CompUnitContribMap; #define D2R_ValueType_IsSigned(x) ((x) == D2R_ValueType_S8 || (x) == D2R_ValueType_S16 || (x) == D2R_ValueType_S32 || (x) == D2R_ValueType_S64 || (x) == D2R_ValueType_S128 || (x) == D2R_ValueType_S256 || (x) == D2R_ValueType_S512) #define D2R_ValueType_IsUnsigned(x) ((x) == D2R_ValueType_U8 || (x) == D2R_ValueType_U16 || (x) == D2R_ValueType_U32 || (x) == D2R_ValueType_U64 || (x) == D2R_ValueType_U128 || (x) == D2R_ValueType_U256 || (x) == D2R_ValueType_U512) @@ -88,7 +76,7 @@ typedef enum D2R_ValueType typedef struct D2R_ValueTypeNode { D2R_ValueType type; - + struct D2R_ValueTypeNode *next; } D2R_ValueTypeNode; @@ -113,9 +101,12 @@ internal RDI_RegCode d2r_rdi_reg_code_from_dw_reg(Arch arch, DW_Reg v); 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_Raw *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); -internal Rng1U64List d2r_range_list_from_tag(Arena *arena, DW_Raw *input, DW_CompUnit *cu, U64 image_base, DW_Tag tag); -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 RDIM_Type * d2r_type_from_attrib(D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind); +internal Rng1U64List d2r_range_list_from_tag(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 image_base, DW_Tag tag); +internal RDIM_Type ** d2r_collect_proc_params(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_TagNode *cur_node, U64 *param_count_out); +internal RDI_TypeKind d2r_unsigned_type_kind_from_size(U64 byte_size); +internal RDI_TypeKind d2r_signed_type_kind_from_size(U64 byte_size); +internal RDI_EvalTypeGroup d2r_type_group_from_type_kind(RDI_TypeKind x); //////////////////////////////// //~ RDIM Bytecode Helpers @@ -141,25 +132,26 @@ internal D2R_ValueType d2r_apply_usual_arithmetic_conversions(Arena *arena, D2R_ internal void d2r_push_arithmetic_op(Arena *arena, D2R_ValueTypeStack *stack, RDIM_EvalBytecode *bc, RDI_EvalOp op); internal void d2r_push_relational_op(Arena *arena, D2R_ValueTypeStack *stack, RDIM_EvalBytecode *bc, RDI_EvalOp op); -internal RDIM_EvalBytecode d2r_bytecode_from_expression(Arena *arena, DW_Raw *input, U64 image_base, U64 address_size, Arch arch, DW_ListUnit *addr_lu, String8 expr, DW_CompUnit *cu, D2R_ValueType *result_type_out); -internal RDIM_Location * d2r_transpile_expression(Arena *arena, RDIM_LocationChunkList *locations, DW_Raw *input, U64 image_base, U64 address_size, Arch arch, DW_ListUnit *addr_lu, DW_CompUnit *cu, String8 expr); -internal RDIM_LocationCaseList d2r_locset_from_attrib(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Scope *curr_scope, RDIM_LocationChunkList *locations, 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, RDIM_LocationChunkList *locations, DW_Raw *input, DW_CompUnit *cu, U64 image_base, Arch arch, DW_Tag tag); +internal RDIM_EvalBytecode d2r_bytecode_from_expression(Arena *arena, DW_Input *input, U64 image_base, U64 address_size, Arch arch, DW_ListUnit *addr_lu, String8 expr, DW_CompUnit *cu, D2R_ValueType *result_type_out); +internal RDIM_Location * d2r_transpile_expression(Arena *arena, RDIM_LocationChunkList *locations, DW_Input *input, U64 image_base, U64 address_size, Arch arch, DW_ListUnit *addr_lu, DW_CompUnit *cu, String8 expr); +internal RDIM_Location * d2r_location_from_attrib(Arena *arena, RDIM_LocationChunkList *locations, DW_Input *input, DW_CompUnit *cu, U64 image_base, Arch arch, DW_Tag tag, DW_AttribKind kind); +internal RDIM_LocationCaseList d2r_locset_from_attrib(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Scope *curr_scope, RDIM_LocationChunkList *locations, DW_Input *input, DW_CompUnit *cu, U64 image_base, Arch arch, DW_Tag tag, DW_AttribKind kind); +internal RDIM_LocationCaseList d2r_var_locset_from_tag(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Scope *curr_scope, RDIM_LocationChunkList *locations, DW_Input *input, DW_CompUnit *cu, U64 image_base, Arch arch, DW_Tag tag); //////////////////////////////// //~ rjf: Compilation Unit / Scope Conversion Helpers -internal RDIM_Rng1U64ChunkList d2r_voff_ranges_from_cu_info_off(D2R_CompUnitContribMap map, U64 info_off); -internal RDIM_Scope *d2r_push_scope(Arena *arena, RDIM_ScopeChunkList *scopes, U64 scope_chunk_cap, D2R_TagFrame *tag_stack, Rng1U64List ranges); +internal D2R_CompUnitContribMap d2r_cu_contrib_map_from_aranges(Arena *arena, DW_Input *input, U64 image_base); +internal RDIM_Rng1U64ChunkList d2r_voff_ranges_from_cu_info_off(D2R_CompUnitContribMap map, U64 info_off); //////////////////////////////// //~ Tag Iterator -internal D2R_TagIter *d2r_tag_iter_init(Arena *arena, DW_TagNode *root); -internal void d2r_tag_iter_next(Arena *arena, D2R_TagIter *iter); -internal void d2r_tag_iter_skip_children(D2R_TagIter *iter); -internal DW_TagNode * d2r_tag_iter_parent_tag_node(D2R_TagIter *iter); -internal DW_Tag d2r_tag_iter_parent_tag(D2R_TagIter *iter); +internal D2R_TagIterator * d2r_tag_iterator_init(Arena *arena, DW_TagNode *root); +internal void d2r_tag_iterator_next(Arena *arena, D2R_TagIterator *iter); +internal void d2r_tag_iterator_skip_children(D2R_TagIterator *iter); +internal DW_TagNode * d2r_tag_iterator_parent_tag_node(D2R_TagIterator *iter); +internal DW_Tag d2r_tag_iterator_parent_tag(D2R_TagIterator *iter); //////////////////////////////// //~ Type/UDT/Symbol Conversion @@ -167,15 +159,11 @@ internal DW_Tag d2r_tag_iter_parent_tag(D2R_TagIter *iter); internal void d2r_flag_converted_tag(DW_TagNode *tag_node); internal B8 d2r_is_tag_converted(DW_TagNode *tag_node); -internal RDIM_Type *d2r_find_or_convert_type(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, DW_Language cu_lang, U64 arch_addr_size, DW_Tag tag, DW_AttribKind kind); - -internal void d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, DW_Language cu_lang, U64 arch_addr_size, DW_TagNode *root); -internal void d2r_convert_udts(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, DW_Language cu_lang, U64 arch_addr_size, DW_TagNode *root); -internal void d2r_convert_symbols(Arena *arena, D2R_TypeTable *type_table, DW_Raw *input, DW_CompUnit *cu, DW_Language cu_lang, U64 arch_addr_size, U64 image_base, Arch arch, DW_TagNode *root); +internal void d2r_convert_types(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Language cu_lang, U64 arch_addr_size, DW_TagNode *root); +internal void d2r_convert_udts(Arena *arena, D2R_TypeTable *type_table, DW_Input *input, DW_CompUnit *cu, DW_Language cu_lang, U64 arch_addr_size, DW_TagNode *root); +internal void d2r_convert_symbols(Arena *arena, D2R_TypeTable *type_table, RDIM_Scope *global_scope, DW_Input *input, DW_CompUnit *cu, DW_Language cu_lang, U64 arch_addr_size, U64 image_base, Arch arch, DW_TagNode *root); //////////////////////////////// //~ rjf: Main Conversion Entry Point internal RDIM_BakeParams d2r_convert(Arena *arena, D2R_ConvertParams *params); - -#endif // RDI_FROM_DWARF_H diff --git a/src/rdi_from_elf/rdi_from_elf.c b/src/rdi_from_elf/rdi_from_elf.c index eb85fa89..ccbb1351 100644 --- a/src/rdi_from_elf/rdi_from_elf.c +++ b/src/rdi_from_elf/rdi_from_elf.c @@ -1,36 +1,9 @@ // Copyright (c) Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -internal RDI_BinarySectionFlags -e2r_rdi_binary_section_flags_from_elf(ELF_SectionFlags f) -{ - RDI_BinarySectionFlags result = RDI_BinarySectionFlag_Read; - if(f & ELF_Shf_Write) - { - result |= RDI_BinarySectionFlag_Write; - } - if(f & ELF_Shf_ExecInstr) - { - result |= RDI_BinarySectionFlag_Execute; - } - return result; -} - internal RDIM_BinarySectionList -e2r_rdi_binary_sections_from_elf_section_table(Arena *arena, String8 data, ELF_Bin *bin, ELF_Shdr64Array shdrs) +e2r_rdi_binary_sections_from_elf_section_table(Arena *arena, ELF_Shdr64Array shdrs) { RDIM_BinarySectionList result = {0}; - U64 base_vaddr = elf_base_addr_from_bin(bin); - for EachIndex(idx, shdrs.count) - { - ELF_Shdr64 *src = &shdrs.v[idx]; - RDIM_BinarySection *dst = rdim_binary_section_list_push(arena, &result); - dst->name = elf_name_from_shdr64(data, bin, src); - dst->flags = e2r_rdi_binary_section_flags_from_elf(src->sh_flags); - dst->voff_first = src->sh_addr - base_vaddr; - dst->voff_opl = dst->voff_first + src->sh_size; - dst->foff_first = src->sh_offset; - dst->foff_opl = dst->foff_first + src->sh_size; - } return result; } diff --git a/src/rdi_from_elf/rdi_from_elf.h b/src/rdi_from_elf/rdi_from_elf.h index 2915e3eb..3d979c8f 100644 --- a/src/rdi_from_elf/rdi_from_elf.h +++ b/src/rdi_from_elf/rdi_from_elf.h @@ -4,7 +4,6 @@ #ifndef RDI_FROM_ELF_H #define RDI_FROM_ELF_H -internal RDI_BinarySectionFlags e2r_rdi_binary_section_flags_from_elf(ELF_SectionFlags f); -internal RDIM_BinarySectionList e2r_rdi_binary_sections_from_elf_section_table(Arena *arena, String8 data, ELF_Bin *bin, ELF_Shdr64Array shdrs); +internal RDIM_BinarySectionList e2r_rdi_binary_sections_from_elf_section_table(Arena *arena, ELF_Shdr64Array shdrs); #endif // RDI_FROM_ELF_H diff --git a/src/rdi_make/rdi_make_local.c b/src/rdi_make/rdi_make_local.c index 554b1c5f..7d5ad140 100644 --- a/src/rdi_make/rdi_make_local.c +++ b/src/rdi_make/rdi_make_local.c @@ -17,6 +17,35 @@ rdim_data_model_from_os_arch(OperatingSystem os, RDI_Arch arch) return data_model; } +internal RDIM_TopLevelInfo +rdim_make_top_level_info(String8 image_name, Arch arch, U64 exe_hash, RDIM_BinarySectionList sections) +{ + // convert arch + RDI_Arch arch_rdi = RDI_Arch_NULL; + switch(arch) + { + default:{}break; + case Arch_x64:{arch_rdi = RDI_Arch_X64;}break; + case Arch_x86:{arch_rdi = RDI_Arch_X86;}break; + } + + // find max VOFF + U64 exe_voff_max = 0; + for EachNode(sect_n, RDIM_BinarySectionNode, sections.first) + { + exe_voff_max = Max(exe_voff_max, sect_n->v.voff_opl); + } + + // fill out top level info + RDIM_TopLevelInfo top_level_info = {0}; + top_level_info.arch = arch_rdi; + top_level_info.exe_hash = exe_hash; + top_level_info.voff_max = exe_voff_max; + top_level_info.producer_name = str8_lit(BUILD_TITLE_STRING_LITERAL); + + return top_level_info; +} + internal RDIM_BakeResults rdim_bake(Arena *arena, RDIM_BakeParams *params) { diff --git a/src/rdi_make/rdi_make_local.h b/src/rdi_make/rdi_make_local.h index b3d5da2e..b7ed9ed9 100644 --- a/src/rdi_make/rdi_make_local.h +++ b/src/rdi_make/rdi_make_local.h @@ -161,6 +161,7 @@ struct RDIM_Shared global RDIM_Shared *rdim_shared = 0; internal RDIM_DataModel rdim_data_model_from_os_arch(OperatingSystem os, RDI_Arch arch); +internal RDIM_TopLevelInfo rdim_make_top_level_info(String8 image_name, Arch arch, U64 exe_hash, RDIM_BinarySectionList sections); internal RDIM_BakeResults rdim_bake(Arena *arena, RDIM_BakeParams *params); internal RDIM_SerializedSectionBundle rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in);