mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-11 16:18:07 +00:00
dead code elimination
This commit is contained in:
+1
-1
@@ -49,7 +49,7 @@ commands =
|
||||
// .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
// .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg debug telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
// .f1 = { .win = "raddbg_stable --ipc kill_all && build radbin", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
.f1 = { .win = "build torture", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
.f1 = { .win = "build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
|
||||
//- rjf: [raddbg wsl]
|
||||
// .f1 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -49,17 +49,6 @@ struct D_Unwind
|
||||
D_UnwindFlags flags;
|
||||
};
|
||||
|
||||
#if 0 // TODO(rjf): @unwind
|
||||
typedef struct D_FrameUnwindContext D_FrameUnwindContext;
|
||||
struct D_FrameUnwindContext
|
||||
{
|
||||
// DWARF
|
||||
U64 cfa;
|
||||
DW_CFI_Row *cfi_row;
|
||||
U64 ret_addr_reg;
|
||||
};
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Call Stack Types
|
||||
|
||||
@@ -558,9 +547,6 @@ internal U64 d_cached_sp_from_thread(D_Handle handle);
|
||||
//~ rjf: Module Image Info Functions
|
||||
|
||||
//- rjf: cache lookups
|
||||
#if 0 // TODO(rjf): @unwind
|
||||
internal PE_IntelPdata *d_intel_pdata_from_module_voff(Arena *arena, D_Handle module_handle, U64 voff);
|
||||
#endif
|
||||
internal D_ModuleInfo *d_info_from_module(Access *access, D_Handle module);
|
||||
internal U64 d_entry_point_voff_from_module(D_Handle module_handle);
|
||||
internal String8 d_initial_debug_info_path_from_module(Arena *arena, D_Handle module_handle);
|
||||
@@ -568,18 +554,6 @@ internal String8 d_initial_debug_info_path_from_module(Arena *arena, D_Handle mo
|
||||
////////////////////////////////
|
||||
//~ rjf: Unwinding Functions
|
||||
|
||||
#if 0 // TODO(rjf): @unwind
|
||||
//- rjf: [dwarf]
|
||||
internal D_UnwindStepResult d_unwind_step_result_from_machine_op_result(MachineOpResult s);
|
||||
internal D_UnwindStepResult d_establish_frame_unwind_context__dwarf(Arena *arena, D_Handle process_handle, D_Handle module_handle, Arch arch, void *regs, U64 endt_us, D_FrameUnwindContext *ctx_out);
|
||||
internal D_UnwindStepResult d_unwind_step__dwarf(D_Handle process_handle, Arch arch, void *regs, D_FrameUnwindContext *frame_ctx, U64 endt_us);
|
||||
|
||||
//- rjf: [x64]
|
||||
internal U64 *d_unwind_reg_from_pe_gpr_reg__pe_x64(X64_RegBlock *regs, PE_UnwindGprRegX64 gpr_reg);
|
||||
internal D_UnwindStepResult d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 module_base_vaddr, X64_RegBlock *regs, U64 endt_us);
|
||||
#endif
|
||||
|
||||
//- rjf: abstracted full unwind
|
||||
internal D_Unwind d_unwind_from_thread(Arena *arena, D_Handle thread, U64 endt_us);
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
@@ -448,327 +448,3 @@ dw_reg_count_from_arch(Arch arch)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ TODO(rjf): OLD vvvvvvvvvvv
|
||||
|
||||
#if 0
|
||||
internal DW_AttribClass
|
||||
dw_attrib_class_from_form_kind(DW_Version ver, DW_FormKind k)
|
||||
{
|
||||
DW_AttribClass result = 0;
|
||||
switch(k)
|
||||
{
|
||||
default:{}break;
|
||||
#define X(name, code, version, ext, class) case DW_FormKind_##name:{result = (class);}break;
|
||||
DW_FormKind_XList
|
||||
#undef X
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
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_operand_count_from_cfa_opcode(DW_CFA_Opcode opcode)
|
||||
{
|
||||
switch (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
|
||||
#undef X
|
||||
default: { NotImplemented; } break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal B32
|
||||
dw_is_cfa_expr_opcode_invalid(DW_ExprOp opcode)
|
||||
{
|
||||
B32 is_invalid = 0;
|
||||
switch(opcode)
|
||||
{
|
||||
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;
|
||||
}
|
||||
return is_invalid;
|
||||
}
|
||||
|
||||
internal B32
|
||||
dw_is_new_row_cfa_opcode(DW_CFA_Opcode opcode)
|
||||
{
|
||||
B32 is_new_row_op = 0;
|
||||
switch(opcode)
|
||||
{
|
||||
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;
|
||||
}
|
||||
return is_new_row_op;
|
||||
}
|
||||
|
||||
internal DW_CFA_OperandType *
|
||||
dw_operand_types_from_cfa_op(DW_CFA_Opcode opcode)
|
||||
{
|
||||
switch (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
|
||||
#undef X
|
||||
default: { NotImplemented; } break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_language(Arena *arena, DW_Language kind)
|
||||
{
|
||||
switch (kind) {
|
||||
#define X(_N,_ID) case DW_Language_##_N: return str8_lit(Stringify(_N));
|
||||
DW_Language_XList
|
||||
#undef X
|
||||
}
|
||||
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)
|
||||
{
|
||||
switch (kind) {
|
||||
#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N));
|
||||
DW_Inl_XList
|
||||
#undef X
|
||||
}
|
||||
return push_str8f(arena, "%x", kind);
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_access_kind(Arena *arena, DW_AccessKind kind)
|
||||
{
|
||||
switch (kind) {
|
||||
#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N));
|
||||
DW_AccessKind_XList
|
||||
#undef X
|
||||
}
|
||||
return push_str8f(arena, "%llx", kind);
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_calling_convetion(Arena *arena, DW_CallingConventionKind kind)
|
||||
{
|
||||
switch (kind) {
|
||||
#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N));
|
||||
DW_CallingConventionKind_XList
|
||||
#undef X
|
||||
}
|
||||
return push_str8f(arena, "%llx", kind);
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_attrib_type_encoding(Arena *arena, DW_ATE kind)
|
||||
{
|
||||
switch (kind) {
|
||||
#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N));
|
||||
DW_ATE_XList
|
||||
#undef X
|
||||
}
|
||||
return push_str8f(arena, "%llx", kind);
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_attrib_visibility(Arena *arena, DW_Vis vis)
|
||||
{
|
||||
switch (vis) {
|
||||
#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N));
|
||||
DW_Vis_XList
|
||||
#undef X
|
||||
}
|
||||
return push_str8f(arena, "%llx", vis);
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_std_opcode(Arena *arena, DW_StdOpcode kind)
|
||||
{
|
||||
switch (kind) {
|
||||
#define X(_N,_ID) case DW_StdOpcode_##_N: return str8_lit(Stringify(_N));
|
||||
DW_StdOpcode_XList
|
||||
#undef X
|
||||
}
|
||||
return push_str8f(arena, "%x", kind);
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_ext_opcode(Arena *arena, DW_ExtOpcode kind)
|
||||
{
|
||||
switch (kind) {
|
||||
#define X(_N,_ID) case DW_ExtOpcode_##_N: return str8_lit(Stringify(_N));
|
||||
DW_ExtOpcode_XList
|
||||
#undef X
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
return push_str8f(arena, "%x", kind);
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_loc_list_entry_kind(Arena *arena, DW_LLE kind)
|
||||
{
|
||||
NotImplemented;
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_section_kind(Arena *arena, DW_SectionKind kind)
|
||||
{
|
||||
NotImplemented;
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_rng_list_entry_kind(Arena *arena, DW_RLE kind)
|
||||
{
|
||||
NotImplemented;
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_register(Arena *arena, Arch arch, U64 reg_id)
|
||||
{
|
||||
String8 reg_str = str8_zero();
|
||||
switch (arch) {
|
||||
case Arch_Null: break;
|
||||
case Arch_x64: {
|
||||
switch (reg_id) {
|
||||
#define X(_N, _ID, ...) case DW_RegX64_##_N: reg_str = str8_lit(Stringify(_N)); break;
|
||||
DW_Regs_X64_XList
|
||||
#undef X
|
||||
}
|
||||
} break;
|
||||
case Arch_arm32: NotImplemented; break;
|
||||
case Arch_arm64: NotImplemented; break;
|
||||
case Arch_x86: NotImplemented; break;
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
if (reg_str.size == 0) {
|
||||
reg_str = push_str8f(arena, "%#llx", reg_id);
|
||||
}
|
||||
return reg_str;
|
||||
}
|
||||
|
||||
internal String8
|
||||
dw_string_from_cfa_opcode(DW_CFA_Opcode opcode)
|
||||
{
|
||||
switch (opcode) {
|
||||
#define X(_NAME, _ID, ...) case _ID: return str8_lit(Stringify(_NAME));
|
||||
DW_CFA_Kind_XList
|
||||
#undef X
|
||||
default: InvalidPath; break;
|
||||
}
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal String8
|
||||
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();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -65,46 +65,4 @@ internal String8 dw_dwo_name_from_section_kind(DW_SectionKind k);
|
||||
//- rjf: architecture info
|
||||
internal U64 dw_reg_count_from_arch(Arch arch);
|
||||
|
||||
////////////////////////////////
|
||||
//~ TODO(rjf): OLD vvvvvvvvvvvvvvvvvvv
|
||||
|
||||
#if 0
|
||||
////////////////////////////////
|
||||
// xlist helpers
|
||||
|
||||
// regs
|
||||
internal U64 dw_reg_size_from_code(Arch arch, DW_Reg reg_code);
|
||||
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_size_from_format(DW_Format format);
|
||||
|
||||
// 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);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: String <=> Enum
|
||||
|
||||
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);
|
||||
internal String8 dw_string_from_attrib_type_encoding(Arena *arena, DW_ATE kind);
|
||||
internal String8 dw_string_from_attrib_visibility(Arena *arena, DW_Vis vis);
|
||||
internal String8 dw_string_from_std_opcode(Arena *arena, DW_StdOpcode kind);
|
||||
internal String8 dw_string_from_ext_opcode(Arena *arena, DW_ExtOpcode kind);
|
||||
internal String8 dw_string_from_loc_list_entry_kind(Arena *arena, DW_LLE kind);
|
||||
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);
|
||||
#endif
|
||||
|
||||
#endif // DWARF_H
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#include "dwarf/dwarf.c"
|
||||
// #include "dwarf/dwarf_parse.c"
|
||||
// #include "dwarf/dwarf_expr.c"
|
||||
#include "dwarf/dwarf_expr_2.c"
|
||||
// #include "dwarf/dwarf_unwind.c"
|
||||
// #include "dwarf/dwarf_dump.c"
|
||||
#include "dwarf/dwarf_parse_2.c"
|
||||
#include "dwarf/dwarf_unwind_2.c"
|
||||
#include "dwarf/dwarf_dump_2.c"
|
||||
@@ -16,7 +12,3 @@
|
||||
#if defined(ELF_H)
|
||||
# include "dwarf/dwarf_parse_elf.c"
|
||||
#endif
|
||||
|
||||
#if 0 // TODO(rjf): this uses concepts from the old parser
|
||||
# include "dwarf/dwarf_writer.c"
|
||||
#endif
|
||||
|
||||
@@ -5,11 +5,7 @@
|
||||
#define DWARF_INC_H
|
||||
|
||||
#include "dwarf/dwarf.h"
|
||||
// #include "dwarf/dwarf_parse.h"
|
||||
// #include "dwarf/dwarf_expr.h"
|
||||
#include "dwarf/dwarf_expr_2.h"
|
||||
// #include "dwarf/dwarf_unwind.h"
|
||||
// #include "dwarf/dwarf_dump.h"
|
||||
#include "dwarf/dwarf_parse_2.h"
|
||||
#include "dwarf/dwarf_unwind_2.h"
|
||||
#include "dwarf/dwarf_dump_2.h"
|
||||
@@ -20,8 +16,4 @@
|
||||
# include "dwarf/dwarf_parse_elf.h"
|
||||
#endif
|
||||
|
||||
#if 0 // TODO(rjf): this uses concepts from the old parser
|
||||
# include "dwarf/dwarf_writer.h"
|
||||
#endif
|
||||
|
||||
#endif // DWARF_INC_H
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
// TODO(rjf): this uses concepts from the old parser
|
||||
|
||||
internal DW_IntEnc
|
||||
dw_int_enc_from_sint(S64 v)
|
||||
{
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#ifndef DWARF_WRITER_H
|
||||
#define DWARF_WRITER_H
|
||||
|
||||
// TODO(rjf): this uses concepts from the old parser
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
typedef enum
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#if 0
|
||||
#if 0 // TODO(rjf): this uses concepts from the old parser
|
||||
|
||||
internal U64
|
||||
t_dw_test_uleb128(U64 v, U64 expected_length)
|
||||
|
||||
+27
-251
@@ -1,77 +1,8 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#if 0
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
if (ptr_out) {
|
||||
*ptr_out = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
return decode_size;
|
||||
}
|
||||
#endif
|
||||
////////////////////////////////
|
||||
//~ rjf: .eh_frame Parsing Functions
|
||||
|
||||
internal EH_FrameHdr
|
||||
eh_parse_frame_hdr(String8 data, U64 address_size, EH_PtrCtx *ptr_ctx)
|
||||
@@ -124,65 +55,6 @@ eh_parse_frame_hdr(String8 data, U64 address_size, EH_PtrCtx *ptr_ctx)
|
||||
return header;
|
||||
}
|
||||
|
||||
#if 0
|
||||
internal U64
|
||||
eh_parse_aug_data(String8 aug_string, String8 aug_data, U64 pc, EH_PtrCtx *ptr_ctx, EH_Augmentation *aug_out)
|
||||
{
|
||||
// TODO:
|
||||
// Handle "eh" param, it indicates presence of EH Data field.
|
||||
// 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;
|
||||
EH_PtrEnc addr_encoding = EH_PtrEnc_UData8;
|
||||
EH_PtrEnc handler_encoding = EH_PtrEnc_Omit;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aug_out) {
|
||||
aug_out->handler_ip = handler_ip;
|
||||
aug_out->handler_encoding = handler_encoding;
|
||||
aug_out->lsda_encoding = handler_encoding;
|
||||
aug_out->addr_encoding = addr_encoding;
|
||||
aug_out->flags = aug_flags;
|
||||
aug_out->size = aug_data_size;
|
||||
}
|
||||
|
||||
exit:;
|
||||
U64 parse_size = cursor;
|
||||
return parse_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
internal U64
|
||||
eh_read_ptr(String8 data, U64 off, U64 pc, EH_PtrCtx *ptr_ctx, EH_PtrEnc encoding, U64 *ptr_out)
|
||||
{
|
||||
@@ -464,100 +336,6 @@ eh_read_fde(String8 data, U64 off, DW_Format fmt, Arch arch, U64 pc, EH_PtrCtx *
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
#if 0
|
||||
internal B32
|
||||
eh_parse_fde(String8 data, DW_Format format, U64 pc, DW_CIE *cie, EH_PtrCtx *ptr_ctx, DW_FDE *fde_out)
|
||||
{
|
||||
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];
|
||||
if (addr_enc != EH_PtrEnc_Omit) {
|
||||
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:;
|
||||
return is_parsed;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
internal U64
|
||||
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;
|
||||
U64 first_size = eh_parse_ptr(header.table, 0, ptr_ctx->pc_vaddr, ptr_ctx, header.table_enc, &first);
|
||||
AssertAlways(first_size);
|
||||
if (first == pc) {
|
||||
fde_idx = 0;
|
||||
goto exit;
|
||||
}
|
||||
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);
|
||||
AssertAlways(last_size);
|
||||
if (last <= pc) {
|
||||
fde_idx = header.fde_count - 1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
U64 l = 0;
|
||||
U64 r = header.fde_count - 1;
|
||||
while (l <= r) {
|
||||
U64 m = l + (r - l) / 2;
|
||||
U64 m_pc_off = m * header.entry_byte_size;
|
||||
U64 m_pc = 0;
|
||||
U64 m_pc_size = eh_parse_ptr(header.table, m_pc_off, ptr_ctx->pc_vaddr + m_pc_off, ptr_ctx, header.table_enc, &m_pc);
|
||||
Assert(m_pc_size);
|
||||
if (m_pc > pc) {
|
||||
r = m - 1;
|
||||
} else if (m_pc < pc) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
fde_idx = m;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
fde_idx = l > 0 ? l-1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
Assert(fde_addr_size);
|
||||
}
|
||||
return fde_addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
internal int
|
||||
eh_frame_hdr_entry_sort(void *raw_a, void *raw_b)
|
||||
{
|
||||
@@ -599,44 +377,42 @@ eh_frame_hdr_from_call_frame_info(Arena *arena, U64 fde_count, U64 *fde_offsets,
|
||||
return eh_frame_hdr;
|
||||
}
|
||||
|
||||
#if 0
|
||||
internal
|
||||
DW_DECODE_PTR(eh_decode_ptr)
|
||||
{
|
||||
EH_DecodePtrCtx *ctx = ud;
|
||||
return eh_parse_ptr(data, 0, ctx->ptr_ctx->pc_vaddr, ctx->ptr_ctx, ctx->addr_enc, ptr_out);
|
||||
}
|
||||
#endif
|
||||
////////////////////////////////
|
||||
//~ rjf: Enum -> String
|
||||
|
||||
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");
|
||||
String8 result = {0};
|
||||
switch(type)
|
||||
{
|
||||
case EH_PtrEnc_Ptr: {result = s("Ptr");}break;
|
||||
case EH_PtrEnc_ULEB128: {result = s("ULEB128");}break;
|
||||
case EH_PtrEnc_UData2: {result = s("UData2");}break;
|
||||
case EH_PtrEnc_UData4: {result = s("UData4");}break;
|
||||
case EH_PtrEnc_UData8: {result = s("UData8");}break;
|
||||
case EH_PtrEnc_Signed: {result = s("Signed");}break;
|
||||
case EH_PtrEnc_SLEB128: {result = s("SLEB128");}break;
|
||||
case EH_PtrEnc_SData2: {result = s("SData2");}break;
|
||||
case EH_PtrEnc_SData4: {result = s("SData4");}break;
|
||||
case EH_PtrEnc_SData8: {result = s("SData8");}break;
|
||||
}
|
||||
return str8_zero();
|
||||
return result;
|
||||
}
|
||||
|
||||
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");
|
||||
String8 result = {0};
|
||||
switch(modifier)
|
||||
{
|
||||
case EH_PtrEnc_PcRel: {result = s("PcRel");}break;
|
||||
case EH_PtrEnc_TextRel: {result = s("TextRel");}break;
|
||||
case EH_PtrEnc_DataRel: {result = s("DataRel");}break;
|
||||
case EH_PtrEnc_FuncRel: {result = s("FuncRel");}break;
|
||||
case EH_PtrEnc_Aligned: {result = s("Aligned");}break;
|
||||
}
|
||||
return str8_zero();
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
|
||||
@@ -106,14 +106,9 @@ typedef struct EH_DecodePtrCtx
|
||||
} EH_DecodePtrCtx;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: .eh_frame Parsing Functions
|
||||
|
||||
#if 0
|
||||
internal U64 eh_parse_ptr(String8 frame_base, U64 off, U64 pc, EH_PtrCtx *ptr_ctx, EH_PtrEnc encoding, U64 *ptr_out);
|
||||
#endif
|
||||
internal EH_FrameHdr eh_parse_frame_hdr(String8 data, U64 address_size, EH_PtrCtx *ptr_ctx);
|
||||
#if 0
|
||||
internal U64 eh_parse_aug_data(String8 aug_string, String8 aug_data, U64 pc, EH_PtrCtx *ptr_ctx, EH_Augmentation *aug_out);
|
||||
#endif
|
||||
|
||||
internal U64 eh_read_ptr(String8 data, U64 off, U64 pc, EH_PtrCtx *ptr_ctx, EH_PtrEnc encoding, U64 *ptr_out);
|
||||
internal U64 eh_read_aug_data(String8 data, U64 off, String8 string, U64 pc, EH_PtrCtx *ptr_ctx, EH_Augmentation *aug_out);
|
||||
@@ -121,12 +116,11 @@ internal U64 eh_read_cfi_header(String8 data, U64 off, DW_CFIHeader *cfi
|
||||
internal U64 eh_read_cie(String8 data, U64 off, DW_Format fmt, Arch arch, U64 pc, EH_PtrCtx *ptr_ctx, DW_CIE *cie_out);
|
||||
internal U64 eh_read_fde(String8 data, U64 off, DW_Format fmt, Arch arch, U64 pc, EH_PtrCtx *ptr_ctx, DW_CIE *cie, DW_FDE *fde_out);
|
||||
|
||||
internal B32 eh_parse_fde(String8 data, DW_Format format, U64 pc, DW_CIE *cie, EH_PtrCtx *ptr_ctx, DW_FDE *fde_out);
|
||||
internal U64 eh_find_nearest_fde(EH_FrameHdr header, EH_PtrCtx *ptr_ctx, U64 pc);
|
||||
internal int eh_frame_hdr_entry_sort(void *raw_a, void *raw_b);
|
||||
internal String8 eh_frame_hdr_from_call_frame_info(Arena *arena, U64 fde_count, U64 *fde_offsets, struct DW_FDE *fde);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Enum -> String
|
||||
//~ rjf: Enum -> String
|
||||
|
||||
internal String8 eh_string_from_ptr_enc_type(EH_PtrEnc type);
|
||||
internal String8 eh_string_from_ptr_enc_modifier(EH_PtrEnc modifier);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
//
|
||||
// [ ] d2r_types alias size and byte size on __float80 typedef mismatch
|
||||
|
||||
#if 0
|
||||
#if 0 // TODO(rjf): this uses concepts from the old parser - replace with p2r-style exemplar testing to catch regressions
|
||||
|
||||
internal RDI_Parsed *
|
||||
d2r_rdi_from_dwarf_writer(Arena *arena, DW_Writer *writer)
|
||||
|
||||
Reference in New Issue
Block a user