diff --git a/src/dwarf/dwarf.c b/src/dwarf/dwarf.c index 9e768ba1..2aad1d7a 100644 --- a/src/dwarf/dwarf.c +++ b/src/dwarf/dwarf.c @@ -1,84 +1,6 @@ // Copyright (c) Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -internal U64 -dw_reg_size_from_code_x64(DW_Reg reg_code) -{ - switch (reg_code) { -#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX64_##reg_name_dw: return reg_size; - DW_Regs_X64_XList -#undef X - } - return 0; -} - -internal U64 -dw_reg_pos_from_code_x64(DW_Reg reg_code) -{ - switch (reg_code) { -#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX64_##reg_name_dw: return reg_pos; - DW_Regs_X64_XList -#undef X - } - return max_U64; -} - -internal U64 -dw_reg_size_from_code(Arch arch, DW_Reg reg_code) -{ - switch (arch) { - case Arch_Null: break; - case Arch_x64: return dw_reg_size_from_code_x64(reg_code); - default: NotImplemented; break; - } - return 0; -} - -internal U64 -dw_reg_pos_from_code(Arch arch, DW_Reg reg_code) -{ - switch (arch) { - case Arch_Null: break; - case Arch_x64: return dw_reg_pos_from_code_x64(reg_code); - default: NotImplemented; break; - } - return max_U64; -} - -internal U64 -dw_reg_count_from_arch(Arch arch) -{ - switch (arch) { - default: { NotImplemented; } // fall-through - case Arch_Null: return 0; - case Arch_x64: return DW_RegX64_Last; - } -} - -internal U64 -dw_reg_max_size_from_arch(Arch arch) -{ - local_persist U64 max_size = 0; - if (max_size == 0) { - U64 max_idx = dw_reg_count_from_arch(arch); - for EachIndex(reg_idx, max_idx) { - U64 reg_size = dw_reg_size_from_code(arch, reg_idx); - max_size = Max(max_size, reg_size); - } - } - return max_size; -} - -internal U64 -dw_sp_from_arch(Arch arch) -{ - switch (arch) { - default: NotImplemented; - case Arch_Null: return 0; - case Arch_x64: return DW_RegX64_Rsp; - } -} - internal DW_AttribClass dw_attrib_class_from_attrib_v2(DW_AttribKind k) { @@ -275,39 +197,85 @@ dw_is_form_kind_ref(DW_Version ver, DW_Ext ext, DW_FormKind form_kind) return is_ref; } -internal String8 -dw_name_string_from_section_kind(DW_SectionKind k) +internal U64 +dw_reg_size_from_code_x64(DW_Reg reg_code) { - switch (k) { -#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_L); - DW_SectionKind_XList + switch (reg_code) { +#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX64_##reg_name_dw: return reg_size; + DW_Regs_X64_XList #undef X } - return str8_zero(); + return 0; } -internal String8 -dw_mach_name_string_from_section_kind(DW_SectionKind k) +internal U64 +dw_reg_pos_from_code_x64(DW_Reg reg_code) { - switch (k) { -#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_M); - DW_SectionKind_XList + switch (reg_code) { +#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX64_##reg_name_dw: return reg_pos; + DW_Regs_X64_XList #undef X } - return str8_zero(); + return max_U64; } -internal String8 -dw_dwo_name_string_from_section_kind(DW_SectionKind k) +internal U64 +dw_reg_size_from_code(Arch arch, DW_Reg reg_code) { - switch (k) { -#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_D); - DW_SectionKind_XList -#undef X + switch (arch) { + case Arch_Null: break; + case Arch_x64: return dw_reg_size_from_code_x64(reg_code); + default: NotImplemented; break; } - return str8_zero(); + return 0; } +internal U64 +dw_reg_pos_from_code(Arch arch, DW_Reg reg_code) +{ + switch (arch) { + case Arch_Null: break; + case Arch_x64: return dw_reg_pos_from_code_x64(reg_code); + default: NotImplemented; break; + } + return max_U64; +} + +internal U64 +dw_reg_count_from_arch(Arch arch) +{ + switch (arch) { + default: { NotImplemented; } // fall-through + case Arch_Null: return 0; + case Arch_x64: return DW_RegX64_Last; + } +} + +internal U64 +dw_reg_max_size_from_arch(Arch arch) +{ + local_persist U64 max_size = 0; + if (max_size == 0) { + U64 max_idx = dw_reg_count_from_arch(arch); + for EachIndex(reg_idx, max_idx) { + U64 reg_size = dw_reg_size_from_code(arch, reg_idx); + max_size = Max(max_size, reg_size); + } + } + return max_size; +} + +internal U64 +dw_sp_from_arch(Arch arch) +{ + switch (arch) { + default: NotImplemented; + case Arch_Null: return 0; + case Arch_x64: return DW_RegX64_Rsp; + } +} + + internal U64 dw_size_from_format(DW_Format format) { @@ -540,14 +508,11 @@ dw_operand_types_from_cfa_op(DW_CFA_Opcode opcode) return 0; } -//////////////////////////////// -//~ rjf: String <=> Enum - internal String8 dw_string_from_format(DW_Format format) { switch (format) { - case DW_Format_Null: return str8_zero(); + case DW_Format_Null: return str8_lit("NULL"); case DW_Format_32Bit: return str8_lit("DWARF32"); case DW_Format_64Bit: return str8_lit("DWARF64"); } @@ -704,6 +669,17 @@ dw_string_from_language(Arena *arena, DW_Language kind) return push_str8f(arena, "%x", kind); } +internal String8 +dw_string_from_comp_unit_kind(Arena *arena, DW_CompUnitKind kind) +{ + switch (kind) { +#define X(_N,_ID) case DW_CompUnitKind_##_N: return str8_lit(Stringify(_N)); + DW_CompUnitKind_XList +#undef X + } + return push_str8f(arena, "%x", kind); +} + internal String8 dw_string_from_inl(Arena *arena, DW_InlKind kind) { @@ -829,10 +805,42 @@ dw_string_from_cfa_opcode(DW_CFA_Opcode opcode) } internal String8 -dw_write_uleb128(Arena *arena, U64 v) +dw_name_string_from_section_kind(DW_SectionKind k) +{ + switch (k) { +#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_L); + DW_SectionKind_XList +#undef X + } + return str8_zero(); +} + +internal String8 +dw_mach_name_string_from_section_kind(DW_SectionKind k) +{ + switch (k) { +#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_M); + DW_SectionKind_XList +#undef X + } + return str8_zero(); +} + +internal String8 +dw_dwo_name_string_from_section_kind(DW_SectionKind k) +{ + switch (k) { +#define X(_N,_L,_M,_D) case DW_Section_##_N: return str8_lit(_D); + DW_SectionKind_XList +#undef X + } + return str8_zero(); +} + +internal U64 +dw_write_to_buffer_uleb128(U8 buffer[10], U64 v) { U64 buffer_size = 0; - U8 buffer[10]; U64 value = v; do { U8 byte = value & 0x7f; @@ -840,17 +848,16 @@ dw_write_uleb128(Arena *arena, U64 v) if (value != 0) { byte |= 0x80; } - Assert(buffer_size < sizeof(buffer)); + Assert(buffer_size < 10); buffer[buffer_size++] = byte; } while (value > 0); - return str8_copy(arena, str8(buffer, buffer_size)); + return buffer_size; } -internal String8 -dw_write_sleb128(Arena *arena, S64 v) +internal U64 +dw_write_to_buffer_sleb128(U8 buffer[10], U64 v) { U64 buffer_size = 0; - U8 buffer[10]; for (S64 value = v, more = 1; more != 0; ) { U8 byte = value & 0x7f; value >>= 7; @@ -860,9 +867,87 @@ dw_write_sleb128(Arena *arena, S64 v) } else { byte |= 0x80; } - Assert(buffer_size < sizeof(buffer)); + Assert(buffer_size < 10); buffer[buffer_size++] = byte; } + return buffer_size; +} + +internal String8 +dw_write_uleb128(Arena *arena, U64 v) +{ + U8 buffer[10]; + U64 buffer_size = dw_write_to_buffer_uleb128(buffer, v); return str8_copy(arena, str8(buffer, buffer_size)); } +internal String8 +dw_write_sleb128(Arena *arena, S64 v) +{ + U8 buffer[10]; + U64 buffer_size = dw_write_to_buffer_sleb128(buffer, v); + return str8_copy(arena, str8(buffer, buffer_size)); +} + +internal U64 +dw_size_from_uleb128(U64 v) +{ + U8 buffer[10]; + return dw_write_to_buffer_uleb128(buffer, v); +} + +internal U64 +dw_size_from_sleb128(S64 v) +{ + U8 buffer[10]; + return dw_write_to_buffer_sleb128(buffer, v); +} + +internal void * +dw_serial_push_length(Arena *arena, String8List *srl, DW_Format format, U64 length) +{ + void *result; + if (format == DW_Format_64Bit) { + U8 buffer[sizeof(U32) + sizeof(U64)]; + MemorySet(&buffer[0], 0xff, sizeof(U32)); + MemoryCopy(buffer + sizeof(U32), &length, sizeof(length)); + result = str8_serial_push_string(arena, srl, str8_array_fixed(buffer)); + } else { + result = str8_serial_push_string(arena, srl, str8((U8 *)&length, sizeof(U32))); + } + return result; +} + +internal void * +dw_serial_push_uint(Arena *arena, String8List *srl, DW_Format format, U64 v) +{ + String8 uint; + if (format == DW_Format_64Bit) { + U64 *ptr = push_array(arena, U64, 1); + *ptr = v; + uint = str8((U8 *)ptr, sizeof(*ptr)); + } else { + U32 *ptr = push_array(arena, U32, 1); + *ptr = safe_cast_u32(v); + uint = str8((U8 *)ptr, sizeof(*ptr)); + } + return str8_serial_push_string(arena, srl, uint); +} + +internal void * +dw_serial_push_uleb128(Arena *arena, String8List *srl, U64 v) +{ + U8 buffer[10]; + U64 buffer_size = dw_write_to_buffer_uleb128(buffer, v); + return str8_serial_push_string(arena, srl, str8(buffer, buffer_size)); +} + +internal void * +dw_serial_push_sleb128(Arena *arena, String8List *srl, S64 v) +{ + U8 buffer[10]; + U64 buffer_size = dw_write_to_buffer_sleb128(buffer, v); + return str8_serial_push_string(arena, srl, str8(buffer, buffer_size)); +} + + diff --git a/src/dwarf/dwarf.h b/src/dwarf/dwarf.h index 2b540976..96689070 100644 --- a/src/dwarf/dwarf.h +++ b/src/dwarf/dwarf.h @@ -68,6 +68,15 @@ typedef enum DW_SectionKindEnum DW_Section_Count } DW_SectionKindEnum; +typedef U32 DW_SectionFlags; +enum +{ +#define X(_N, ...) DW_SectionFlag_##_N = (1 << DW_Section_##_N), + DW_SectionKind_XList +#undef X + DW_SectionFlag_All = 0xffffffffu, +}; + #define DW_Language_XList \ X(Null, 0x00) \ X(C89, 0x01) \ @@ -485,6 +494,30 @@ typedef enum DW_FormEnum #undef X } DW_FormEnum; +typedef union DW_Form +{ + DW_FormKind kind; + union { + String8 addr; + String8 block; + String8 data; + String8 string; + String8 exprloc; + B8 flag; + S64 sdata; + U64 udata; + U64 sec_offset; + U64 ref; + U64 strp_sup; + U64 xval; + U64 addrx; + U64 strx; + U64 rnglistx; + U64 ptr; + U64 implicit_const; + }; +} DW_Form; + //- Attributes DWARF2 #define DW_AttribKind_V2_XList \ @@ -1695,7 +1728,33 @@ typedef enum DW_RegX64Enum } DW_RegX64Enum; //////////////////////////////// +// Speced Encodings +internal DW_AttribClass dw_attrib_class_from_attrib_v2(DW_AttribKind k); +internal DW_AttribClass dw_attrib_class_from_attrib_v3(DW_AttribKind k); +internal DW_AttribClass dw_attrib_class_from_attrib_v4(DW_AttribKind k); +internal DW_AttribClass dw_attrib_class_from_attrib_v5(DW_AttribKind k); + +//////////////////////////////// +// Extensions + +internal DW_AttribClass dw_attrib_class_from_attrib_gnu (DW_AttribKind k); +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_attrib(DW_Version ver, DW_Ext ext, DW_AttribKind v); + +//////////////////////////////// +// Form Class Encodings + +internal DW_AttribClass dw_attrib_class_from_form_kind(DW_Version ver, DW_FormKind k); +internal B32 dw_are_attrib_class_and_form_kind_compatible(DW_Version ver, DW_AttribClass attrib_class, DW_FormKind form_kind); +internal B32 dw_is_form_kind_ref(DW_Version ver, DW_Ext ext, DW_FormKind form_kind); + +//////////////////////////////// +// xlist helpers + +// regs internal U64 dw_reg_size_from_code_x64(DW_Reg reg_code); internal U64 dw_reg_pos_from_code_x64(DW_Reg reg_code); internal U64 dw_reg_size_from_code(Arch arch, DW_Reg reg_code); @@ -1703,58 +1762,24 @@ internal U64 dw_reg_pos_from_code(Arch arch, DW_Reg reg_code); internal U64 dw_reg_count_from_arch(Arch arch); internal U64 dw_reg_max_size_from_arch(Arch arch); internal U64 dw_sp_from_arch(Arch arch); - -//- Attrib Class Encodings - -// Speced Encodings -internal DW_AttribClass dw_attrib_class_from_attrib_v2(DW_AttribKind k); -internal DW_AttribClass dw_attrib_class_from_attrib_v3(DW_AttribKind k); -internal DW_AttribClass dw_attrib_class_from_attrib_v4(DW_AttribKind k); -internal DW_AttribClass dw_attrib_class_from_attrib_v5(DW_AttribKind k); - -// Extensions -internal DW_AttribClass dw_attrib_class_from_attrib_gnu (DW_AttribKind k); -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_attrib(DW_Version ver, DW_Ext ext, DW_AttribKind v); - -//- Form Class Encodings - -internal DW_AttribClass dw_attrib_class_from_form_kind(DW_Version ver, DW_FormKind k); - -internal B32 dw_are_attrib_class_and_form_kind_compatible(DW_Version ver, DW_AttribClass attrib_class, DW_FormKind form_kind); - -internal B32 dw_is_form_kind_ref(DW_Version ver, DW_Ext ext, DW_FormKind form_kind); - -//- Section Names - -internal String8 dw_name_string_from_section_kind (DW_SectionKind k); -internal String8 dw_mach_name_string_from_section_kind(DW_SectionKind k); -internal String8 dw_dwo_name_string_from_section_kind (DW_SectionKind k); - -//////////////////////////////// - internal U64 dw_size_from_format(DW_Format format); -//////////////////////////////// - +// attrib form -> value class internal DW_AttribClass dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, B32 relaxed, DW_AttribKind attrib, DW_FormKind form_kind); +// lang internal U64 dw_pick_default_lower_bound(DW_Language lang); +// expr internal U64 dw_operand_count_from_expr_op(DW_ExprOp op); internal U64 dw_pop_count_from_expr_op(DW_ExprOp op); internal U64 dw_push_count_from_expr_op(DW_ExprOp op); internal DW_ExprOperandType * dw_operand_types_from_expr_opcode(DW_ExprOp op); -//////////////////////////////// -//~ CFA - -internal U64 dw_operand_count_from_cfa_opcode(DW_CFA_Opcode opcode); -internal B32 dw_is_cfa_expr_opcode_invalid(DW_ExprOp opcode); -internal B32 dw_is_new_row_cfa_opcode(DW_CFA_Opcode opcode); +// CFA +internal U64 dw_operand_count_from_cfa_opcode(DW_CFA_Opcode opcode); +internal B32 dw_is_cfa_expr_opcode_invalid(DW_ExprOp opcode); +internal B32 dw_is_new_row_cfa_opcode(DW_CFA_Opcode opcode); internal DW_CFA_OperandType * dw_operand_types_from_cfa_op(DW_CFA_Opcode opcode); //////////////////////////////// @@ -1766,6 +1791,7 @@ internal String8 dw_string_from_tag_kind(Arena *arena, DW_TagKind kind); internal String8 dw_string_from_attrib_kind(Arena *arena, DW_Version ver, DW_Ext ext, DW_AttribKind kind); internal String8 dw_string_from_form_kind(Arena *arena, DW_Version ver, DW_FormKind kind); internal String8 dw_string_from_language(Arena *arena, DW_Language kind); +internal String8 dw_string_from_comp_unit_kind(Arena *arena, DW_CompUnitKind kind); internal String8 dw_string_from_inl(Arena *arena, DW_InlKind kind); internal String8 dw_string_from_access_kind(Arena *arena, DW_AccessKind kind); internal String8 dw_string_from_calling_convetion(Arena *arena, DW_CallingConventionKind kind); @@ -1777,10 +1803,24 @@ internal String8 dw_string_from_section_kind(Arena *arena, DW_SectionKind kind); internal String8 dw_string_from_rng_list_entry_kind(Arena *arena, DW_RLE kind); internal String8 dw_string_from_register(Arena *arena, Arch arch, U64 reg_id); internal String8 dw_string_from_cfa_opcode(DW_CFA_Opcode opcode); +internal String8 dw_name_string_from_section_kind(DW_SectionKind k); +internal String8 dw_mach_name_string_from_section_kind(DW_SectionKind k); +internal String8 dw_dwo_name_string_from_section_kind (DW_SectionKind k); //////////////////////////////// +// Serializers + +internal U64 dw_write_to_buffer_uleb128(U8 buffer[10], U64 v); +internal U64 dw_write_to_buffer_sleb128(U8 buffer[10], U64 v); internal String8 dw_write_uleb128(Arena *arena, U64 v); internal String8 dw_write_sleb128(Arena *arena, S64 v); +internal U64 dw_size_from_uleb128(U64 v); +internal U64 dw_size_from_sleb128(S64 v); + +internal void * dw_serial_push_length(Arena *arena, String8List *srl, DW_Format format, U64 length); +internal void * dw_serial_push_uint(Arena *arena, String8List *srl, DW_Format format, U64 v); +internal void * dw_serial_push_uleb128(Arena *arena, String8List *srl, U64 v); +internal void * dw_serial_push_sleb128(Arena *arena, String8List *srl, S64 v); #endif // DWARF_H diff --git a/src/dwarf/dwarf_parse.h b/src/dwarf/dwarf_parse.h index d34d7e00..3ef4c79e 100644 --- a/src/dwarf/dwarf_parse.h +++ b/src/dwarf/dwarf_parse.h @@ -81,34 +81,12 @@ typedef struct DW_Abbrev DW_AbbrevFlags flags; } DW_Abbrev; -typedef union DW_Form -{ - String8 addr; - String8 block; - String8 data; - String8 string; - String8 exprloc; - B8 flag; - S64 sdata; - U64 udata; - U64 sec_offset; - U64 ref; - U64 strp_sup; - U64 xval; - U64 addrx; - U64 strx; - U64 rnglistx; - U64 ptr; - U64 implicit_const; -} DW_Form; - typedef struct DW_Attrib { U64 info_off; U64 abbrev_off; U64 abbrev_id; DW_AttribKind attrib_kind; - DW_FormKind form_kind; DW_Form form; } DW_Attrib;