mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 09:18:09 +00:00
generalize machine ops
This commit is contained in:
@@ -678,6 +678,29 @@ union Guid
|
||||
};
|
||||
StaticAssert(sizeof(Guid) == 16, g_guid_size_check);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Machine Ops
|
||||
|
||||
typedef enum MachineOpResult
|
||||
{
|
||||
MachineOpResult_Null,
|
||||
MachineOpResult_Ok,
|
||||
MachineOpResult_Fail,
|
||||
MachineOpResult_Maybe,
|
||||
} MachineOpResult;
|
||||
|
||||
#define MACHINE_OP_REG_READ(name) MachineOpResult name(U64 reg_id, void *buffer, U64 buffer_max, void *ud)
|
||||
typedef MACHINE_OP_REG_READ(MachineOp_RegRead);
|
||||
|
||||
#define MACHINE_OP_REG_WRITE(name) MachineOpResult name(U64 reg_id, void *value, U64 value_size, void *ud)
|
||||
typedef MACHINE_OP_REG_WRITE(MachineOp_RegWrite);
|
||||
|
||||
#define MACHINE_OP_MEM_READ(name) MachineOpResult name(U64 addr, void *buffer, U64 buffer_size, void *ud)
|
||||
typedef MACHINE_OP_MEM_READ(MachineOp_MemRead);
|
||||
|
||||
#define MACHINE_OP_MEM_WRITE(name) MachineOpResult name(U64 addr, void *value, U64 value_size, void *ud)
|
||||
typedef MACHINE_OP_MEM_WRITE(MachineOp_MemWrite);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Constants
|
||||
|
||||
|
||||
+30
-81
@@ -1833,93 +1833,42 @@ typedef struct
|
||||
} CTRL_MemoryReadContextDwarfX64;
|
||||
|
||||
internal
|
||||
DW_MEM_READ(ctrl_unwind_mem_read_dwarf_x64)
|
||||
MACHINE_OP_MEM_READ(ctrl_machine_mem_read)
|
||||
{
|
||||
CTRL_MemoryReadContextDwarfX64 *ctx = ud;
|
||||
|
||||
B32 is_stale = 0;
|
||||
B32 is_read = ctrl_process_memory_read(ctx->process_handle, r1u64(addr, addr + size), &is_stale, buffer, ctx->endt_us);
|
||||
B32 is_read = ctrl_process_memory_read(ctx->process_handle, r1u64(addr, addr + buffer_size), &is_stale, buffer, ctx->endt_us);
|
||||
|
||||
DW_UnwindStatus status = DW_UnwindStatus_Fail;
|
||||
MachineOpResult status = MachineOpResult_Fail;
|
||||
if(is_stale)
|
||||
{
|
||||
status = DW_UnwindStatus_Maybe;
|
||||
status = MachineOpResult_Maybe;
|
||||
}
|
||||
else if(is_read)
|
||||
{
|
||||
status = DW_UnwindStatus_Ok;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
internal
|
||||
DW_REG_READ(ctrl_unwind_reg_read_dwarf_x64)
|
||||
{
|
||||
// map DWARF register to -> the internal register
|
||||
REGS_RegBlockX64 *regs = ud;
|
||||
U64 reg_size = 0; void *reg_bytes = 0;
|
||||
switch(reg_id)
|
||||
{
|
||||
#define X(_N, _ID, _MAP_N, ...) case _ID: { reg_size = sizeof(regs->_MAP_N); reg_bytes = ®s->_MAP_N; } break;
|
||||
DW_Regs_X64_XList(X)
|
||||
#undef X
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
|
||||
// copy out register value
|
||||
DW_UnwindStatus status = DW_UnwindStatus_Fail;
|
||||
if(reg_size > 0)
|
||||
{
|
||||
AssertAlways(reg_size == buffer_max);
|
||||
MemoryCopy(buffer, reg_bytes, reg_size);
|
||||
status = DW_UnwindStatus_Ok;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
internal
|
||||
DW_REG_WRITE(ctrl_unwind_reg_write_dwarf_x64)
|
||||
{
|
||||
// map DWARF register to -> the internal register
|
||||
REGS_RegBlockX64 *regs = ud;
|
||||
U64 reg_size = 0; void *reg_bytes = 0;
|
||||
switch(reg_id)
|
||||
{
|
||||
#define X(_N, _ID, _MAP_N, ...) case _ID: { reg_size = sizeof(regs->_MAP_N); reg_bytes = ®s->_MAP_N; } break;
|
||||
DW_Regs_X64_XList(X)
|
||||
#undef X
|
||||
default: { InvalidPath; } break;
|
||||
}
|
||||
|
||||
// write value to the register
|
||||
DW_UnwindStatus status = DW_UnwindStatus_Fail;
|
||||
if(reg_size > 0)
|
||||
{
|
||||
AssertAlways(value_size <= reg_size);
|
||||
MemoryCopy(reg_bytes, value, value_size);
|
||||
status = DW_UnwindStatus_Ok;
|
||||
status = MachineOpResult_Ok;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
internal CTRL_UnwindStepResult
|
||||
ctrl_unwind_step_result_from_dwarf_status(DW_UnwindStatus s)
|
||||
ctrl_unwind_step_result_from_machine_op_result(MachineOpResult s)
|
||||
{
|
||||
CTRL_UnwindStepResult result = {0};
|
||||
switch(s)
|
||||
{
|
||||
case DW_UnwindStatus_Ok:
|
||||
case MachineOpResult_Null: {} break;
|
||||
case MachineOpResult_Ok:
|
||||
{
|
||||
result.flags &= ~(CTRL_UnwindFlag_Error|CTRL_UnwindFlag_Stale);
|
||||
}break;
|
||||
case DW_UnwindStatus_Fail:
|
||||
case MachineOpResult_Fail:
|
||||
{
|
||||
result.flags |= CTRL_UnwindFlag_Error;
|
||||
}break;
|
||||
case DW_UnwindStatus_Maybe:
|
||||
case MachineOpResult_Maybe:
|
||||
{
|
||||
result.flags &= ~CTRL_UnwindFlag_Error;
|
||||
result.flags |= CTRL_UnwindFlag_Stale;
|
||||
@@ -2083,8 +2032,8 @@ ctrl_establish_frame_unwind_context__dwarf(Arena *arena, CTRL_Handle process_han
|
||||
// setup machine ops
|
||||
void *mem_read_ctx = 0;
|
||||
void *reg_read_ctx = 0;
|
||||
DW_MemRead *mem_read_func = 0;
|
||||
DW_RegRead *reg_read_func = 0;
|
||||
MachineOp_MemRead *mem_read_func = 0;
|
||||
MachineOp_RegRead *reg_read_func = 0;
|
||||
switch(arch)
|
||||
{
|
||||
case Arch_Null: break;
|
||||
@@ -2094,11 +2043,11 @@ ctrl_establish_frame_unwind_context__dwarf(Arena *arena, CTRL_Handle process_han
|
||||
mem_read_ctx_x64->process_handle = process_handle;
|
||||
mem_read_ctx_x64->endt_us = endt_us;
|
||||
|
||||
mem_read_ctx = mem_read_ctx_x64;
|
||||
reg_read_ctx = regs;
|
||||
mem_read_ctx = mem_read_ctx_x64;
|
||||
reg_read_ctx = regs;
|
||||
|
||||
mem_read_func = ctrl_unwind_mem_read_dwarf_x64;
|
||||
reg_read_func = ctrl_unwind_reg_read_dwarf_x64;
|
||||
mem_read_func = ctrl_machine_mem_read;
|
||||
reg_read_func = regs_read_dwarf_x64;
|
||||
}break;
|
||||
case Arch_x86:
|
||||
case Arch_arm64:
|
||||
@@ -2111,10 +2060,10 @@ ctrl_establish_frame_unwind_context__dwarf(Arena *arena, CTRL_Handle process_han
|
||||
|
||||
// compute CFA for the row
|
||||
U64 cfa = 0;
|
||||
DW_UnwindStatus unwind_status = dw_compute_cfa(arch, cfi_row, mem_read_func, mem_read_ctx, reg_read_func, reg_read_ctx, &cfa);
|
||||
MachineOpResult unwind_status = dw_compute_cfa(arch, cfi_row, mem_read_func, mem_read_ctx, reg_read_func, reg_read_ctx, &cfa);
|
||||
|
||||
// on success fill out output
|
||||
if(unwind_status == DW_UnwindStatus_Ok)
|
||||
if(unwind_status == MachineOpResult_Ok)
|
||||
{
|
||||
ctx_out->cfa = cfa;
|
||||
ctx_out->cfi_row = cfi_row;
|
||||
@@ -2122,7 +2071,7 @@ ctrl_establish_frame_unwind_context__dwarf(Arena *arena, CTRL_Handle process_han
|
||||
}
|
||||
|
||||
// translate unwind status code
|
||||
result = ctrl_unwind_step_result_from_dwarf_status(unwind_status);
|
||||
result = ctrl_unwind_step_result_from_machine_op_result(unwind_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2142,9 +2091,9 @@ ctrl_unwind_step__dwarf(CTRL_Handle process_handle, Arch arch, void *regs, CTRL_
|
||||
void *mem_read_ctx = 0;
|
||||
void *reg_read_ctx = 0;
|
||||
void *reg_write_ctx = 0;
|
||||
DW_MemRead *mem_read_func = 0;
|
||||
DW_RegRead *reg_read_func = 0;
|
||||
DW_RegWrite *reg_write_func = 0;
|
||||
MachineOp_MemRead *mem_read_func = 0;
|
||||
MachineOp_RegRead *reg_read_func = 0;
|
||||
MachineOp_RegWrite *reg_write_func = 0;
|
||||
switch(arch)
|
||||
{
|
||||
case Arch_Null: break;
|
||||
@@ -2158,9 +2107,9 @@ ctrl_unwind_step__dwarf(CTRL_Handle process_handle, Arch arch, void *regs, CTRL_
|
||||
reg_read_ctx = regs;
|
||||
reg_write_ctx = regs;
|
||||
|
||||
mem_read_func = ctrl_unwind_mem_read_dwarf_x64;
|
||||
reg_read_func = ctrl_unwind_reg_read_dwarf_x64;
|
||||
reg_write_func = ctrl_unwind_reg_write_dwarf_x64;
|
||||
mem_read_func = ctrl_machine_mem_read;
|
||||
reg_read_func = regs_read_dwarf_x64;
|
||||
reg_write_func = regs_write_dwarf_x64;
|
||||
}break;
|
||||
case Arch_x86:
|
||||
case Arch_arm64:
|
||||
@@ -2172,7 +2121,7 @@ ctrl_unwind_step__dwarf(CTRL_Handle process_handle, Arch arch, void *regs, CTRL_
|
||||
}
|
||||
|
||||
// apply register rules to the context
|
||||
DW_UnwindStatus unwind_status = dw_cfi_apply_register_rules(arch,
|
||||
MachineOpResult unwind_status = dw_cfi_apply_register_rules(arch,
|
||||
frame_ctx->cfa,
|
||||
frame_ctx->cfi_row,
|
||||
mem_read_func,
|
||||
@@ -2189,7 +2138,7 @@ ctrl_unwind_step__dwarf(CTRL_Handle process_handle, Arch arch, void *regs, CTRL_
|
||||
}
|
||||
|
||||
// translate unwind status code
|
||||
result = ctrl_unwind_step_result_from_dwarf_status(unwind_status);
|
||||
result = ctrl_unwind_step_result_from_machine_op_result(unwind_status);
|
||||
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
@@ -3812,10 +3761,10 @@ ctrl_thread__append_program_defined_bp_traps(Arena *arena, CTRL_Entity *bp, DMN_
|
||||
//- rjf: module lifetime open/close work
|
||||
|
||||
internal
|
||||
DW_MEM_READ(ctrl_dmn_mem_read)
|
||||
MACHINE_OP_MEM_READ(ctrl_dmn_mem_read)
|
||||
{
|
||||
U64 read = dmn_process_read(((CTRL_Handle *)ud)->dmn_handle, r1u64(addr, addr + size), buffer);
|
||||
return read == size ? DW_UnwindStatus_Ok : DW_UnwindStatus_Fail;
|
||||
U64 read = dmn_process_read(((CTRL_Handle *)ud)->dmn_handle, r1u64(addr, addr + buffer_size), buffer);
|
||||
return read == buffer_size ? MachineOpResult_Ok : MachineOpResult_Fail;
|
||||
}
|
||||
|
||||
internal void
|
||||
|
||||
@@ -117,6 +117,12 @@ dmn_lnx_read_string(Arena *arena, int memory_fd, U64 vaddr)
|
||||
return dmn_lnx_read_string_capped(arena, memory_fd, vaddr, 4096);
|
||||
}
|
||||
|
||||
internal
|
||||
MACHINE_OP_MEM_READ(dmn_lnx_machine_op_mem_read)
|
||||
{
|
||||
return dmn_lnx_read(((DMN_LNX_Entity *)ud)->fd, r1u64(addr, addr + buffer_size), buffer);
|
||||
}
|
||||
|
||||
internal int
|
||||
dmn_lnx_ptrace_seize(pid_t pid)
|
||||
{
|
||||
@@ -673,12 +679,6 @@ dmn_lnx_dl_path_from_pid(Arena *arena, pid_t pid, U64 auxv_base)
|
||||
return dl_path;
|
||||
}
|
||||
|
||||
internal
|
||||
GNU_MEM_READ(dmn_lnx_gnu_mem_read)
|
||||
{
|
||||
return dmn_lnx_read(((DMN_LNX_Entity *)ud)->fd, r1u64(addr, addr + size), buffer);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ SDT Probes
|
||||
|
||||
@@ -1799,9 +1799,9 @@ dmn_lnx_hanlde_unload_module(Arena *arena, DMN_EventList *events, DMN_LNX_Entity
|
||||
|
||||
// mark live modules
|
||||
B32 is_64bit = process->dl_class == ELF_Class_64;
|
||||
GNU_RDebugInfoList rdebug_list = gnu_parse_rdebug(scratch.arena, is_64bit, rdebug_vaddr, dmn_lnx_gnu_mem_read, process);
|
||||
GNU_RDebugInfoList rdebug_list = gnu_parse_rdebug(scratch.arena, is_64bit, rdebug_vaddr, dmn_lnx_machine_op_mem_read, process);
|
||||
for EachNode(rdebug_n, GNU_RDebugInfoNode, rdebug_list.first) {
|
||||
GNU_LinkMapList link_map_list = gnu_parse_link_map_list(scratch.arena, is_64bit, rdebug_n->v.r_map, dmn_lnx_gnu_mem_read, process);
|
||||
GNU_LinkMapList link_map_list = gnu_parse_link_map_list(scratch.arena, is_64bit, rdebug_n->v.r_map, dmn_lnx_machine_op_mem_read, process);
|
||||
for EachNode(link_map_n, GNU_LinkMapNode, link_map_list.first) {
|
||||
DMN_LNX_Entity *module = hash_table_search_u64_raw(process->loaded_modules_ht, link_map_n->v.addr_vaddr);
|
||||
module->is_live = 1;
|
||||
@@ -2078,7 +2078,7 @@ dmn_lnx_handle_attach(Arena *arena, DMN_EventList *events, pid_t pid)
|
||||
|
||||
// extract modules from r_debug
|
||||
B32 is_64bit = process->dl_class == ELF_Class_64;
|
||||
GNU_RDebugInfoList rdebug_list = gnu_parse_rdebug(scratch.arena, is_64bit, process->rdebug_vaddr, dmn_lnx_gnu_mem_read, process);
|
||||
GNU_RDebugInfoList rdebug_list = gnu_parse_rdebug(scratch.arena, is_64bit, process->rdebug_vaddr, dmn_lnx_machine_op_mem_read, process);
|
||||
U64 name_space_id = 0;
|
||||
for EachNode(rdebug_n, GNU_RDebugInfoNode, rdebug_list.first)
|
||||
{
|
||||
|
||||
+16
-16
@@ -236,14 +236,14 @@ dw_cfi_row_from_pc(Arena *arena, Arch arch, DW_CIE *cie, DW_FDE *fde, DW_DecodeP
|
||||
return result;
|
||||
}
|
||||
|
||||
internal DW_UnwindStatus
|
||||
internal MachineOpResult
|
||||
dw_compute_cfa(Arch arch,
|
||||
DW_CFI_Row *row,
|
||||
DW_MemRead *mem_read_func, void *mem_read_ud,
|
||||
DW_RegRead *reg_read_func, void *reg_read_ud,
|
||||
MachineOp_MemRead *mem_read_func, void *mem_read_ud,
|
||||
MachineOp_RegRead *reg_read_func, void *reg_read_ud,
|
||||
U64 *cfa_out)
|
||||
{
|
||||
DW_UnwindStatus unwind_status = DW_UnwindStatus_Fail;
|
||||
MachineOpResult unwind_status = MachineOpResult_Fail;
|
||||
|
||||
switch (row->cfa.rule) {
|
||||
case DW_CFA_Rule_Null: break;
|
||||
@@ -253,7 +253,7 @@ dw_compute_cfa(Arch arch,
|
||||
U64 reg_size = dw_reg_size_from_code(arch, row->cfa.reg);
|
||||
AssertAlways(reg_size <= sizeof(cfa_reg_value));
|
||||
unwind_status = reg_read_func(row->cfa.reg, &cfa_reg_value, reg_size, reg_read_ud);
|
||||
if (unwind_status != DW_UnwindStatus_Ok) { break; }
|
||||
if (unwind_status != MachineOpResult_Ok) { break; }
|
||||
*cfa_out = cfa_reg_value + row->cfa.off;
|
||||
} break;
|
||||
case DW_CFA_Rule_Expression: {
|
||||
@@ -265,16 +265,16 @@ dw_compute_cfa(Arch arch,
|
||||
return unwind_status;
|
||||
}
|
||||
|
||||
internal DW_UnwindStatus
|
||||
internal MachineOpResult
|
||||
dw_cfi_apply_register_rules(Arch arch,
|
||||
U64 cfa,
|
||||
DW_CFI_Row *row,
|
||||
DW_MemRead *mem_read_func, void *mem_read_ud,
|
||||
DW_RegRead *reg_read_func, void *reg_read_ud,
|
||||
DW_RegWrite *reg_write_func, void *reg_write_ud)
|
||||
MachineOp_MemRead *mem_read_func, void *mem_read_ud,
|
||||
MachineOp_RegRead *reg_read_func, void *reg_read_ud,
|
||||
MachineOp_RegWrite *reg_write_func, void *reg_write_ud)
|
||||
{
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
DW_UnwindStatus unwind_status = DW_UnwindStatus_Ok;
|
||||
MachineOpResult unwind_status = MachineOpResult_Ok;
|
||||
|
||||
U64 max_reg_size = dw_reg_max_size_from_arch(arch);
|
||||
void *reg_buffer = push_array(scratch.arena, U8, max_reg_size);
|
||||
@@ -289,12 +289,12 @@ dw_cfi_apply_register_rules(Arch arch,
|
||||
// read register value from memory
|
||||
U64 addr = cfa + reg->n;
|
||||
U64 reg_size = dw_reg_size_from_code(arch, reg_idx);
|
||||
unwind_status = mem_read_func(addr, reg_size, reg_buffer, mem_read_ud);
|
||||
if (unwind_status != DW_UnwindStatus_Ok) { goto exit; }
|
||||
unwind_status = mem_read_func(addr, reg_buffer, reg_size, mem_read_ud);
|
||||
if (unwind_status != MachineOpResult_Ok) { goto exit; }
|
||||
|
||||
// write register value to the thread context
|
||||
unwind_status = reg_write_func(reg_idx, reg_buffer, reg_size, reg_write_ud);
|
||||
if (unwind_status != DW_UnwindStatus_Ok) { goto exit; }
|
||||
if (unwind_status != MachineOpResult_Ok) { goto exit; }
|
||||
} break;
|
||||
case DW_CFI_RegisterRule_ValOffset: {
|
||||
// compute register value
|
||||
@@ -303,17 +303,17 @@ dw_cfi_apply_register_rules(Arch arch,
|
||||
// write register value to the thread context
|
||||
U64 reg_size = dw_reg_size_from_code(arch, reg_idx);
|
||||
unwind_status = reg_write_func(reg_idx, ®_value, reg_size, reg_write_ud);
|
||||
if (unwind_status != DW_UnwindStatus_Ok) { goto exit; }
|
||||
if (unwind_status != MachineOpResult_Ok) { goto exit; }
|
||||
} break;
|
||||
case DW_CFI_RegisterRule_Register: {
|
||||
// read register value from another register
|
||||
U64 reg_size = dw_reg_size_from_code(arch, reg_idx);
|
||||
unwind_status = reg_read_func(reg->n, reg_buffer, reg_size, reg_read_ud);
|
||||
if (unwind_status != DW_UnwindStatus_Ok) { goto exit; }
|
||||
if (unwind_status != MachineOpResult_Ok) { goto exit; }
|
||||
|
||||
// write register value to the thread context
|
||||
unwind_status = reg_write_func(reg_idx, reg_buffer, reg_size, reg_write_ud);
|
||||
if (unwind_status != DW_UnwindStatus_Ok) { goto exit; }
|
||||
if (unwind_status != MachineOpResult_Ok) { goto exit; }
|
||||
} break;
|
||||
case DW_CFI_RegisterRule_Expression: {
|
||||
// TODO: evaluate expression
|
||||
|
||||
@@ -74,7 +74,7 @@ internal DW_CFI_Unwind * dw_cfi_unwind_init(Arena *arena, Arch arch, DW_CIE *cie
|
||||
internal B32 dw_cfi_next_row(Arena *arena, DW_CFI_Unwind *uw);
|
||||
|
||||
internal DW_CFI_Row * dw_cfi_row_from_pc(Arena *arena, Arch arch, struct DW_CIE *cie, struct DW_FDE *fde, DW_DecodePtr *decode_ptr_func, void *decode_ptr_ctx, U64 pc);
|
||||
internal DW_UnwindStatus dw_cfi_apply_register_rules(Arch arch, U64 cfa, DW_CFI_Row *row, DW_MemRead *mem_read_func, void *mem_read_ud, DW_RegRead *reg_read_func, void *reg_read_ud, DW_RegWrite *reg_write_func, void *reg_write_ud);
|
||||
internal MachineOpResult dw_cfi_apply_register_rules(Arch arch, U64 cfa, DW_CFI_Row *row, MachineOp_MemRead *mem_read_func, void *mem_read_ud, MachineOp_RegRead *reg_read_func, void *reg_read_ud, MachineOp_RegWrite *reg_write_func, void *reg_write_ud);
|
||||
|
||||
#endif // DWARF_UNWIND_H
|
||||
|
||||
|
||||
+7
-7
@@ -2,24 +2,24 @@
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
internal GNU_RDebugInfoList
|
||||
gnu_parse_rdebug(Arena *arena, B32 is_64bit, U64 first_rdebug_vaddr, GNU_MemRead *mem_read_func, void *mem_read_ud)
|
||||
gnu_parse_rdebug(Arena *arena, B32 is_64bit, U64 first_rdebug_vaddr, MachineOp_MemRead *mem_read_func, void *mem_read_ud)
|
||||
{
|
||||
GNU_RDebugInfoList result = {0};
|
||||
|
||||
for (U64 rdebug_vaddr = first_rdebug_vaddr, rdebug_next = 0; rdebug_vaddr != 0; rdebug_vaddr = rdebug_next) {
|
||||
GNU_RDebugInfo64 rdebug;
|
||||
if (is_64bit) {
|
||||
U64 rdebug_read_size = mem_read_func(rdebug_vaddr, sizeof(rdebug), &rdebug, mem_read_ud);
|
||||
U64 rdebug_read_size = mem_read_func(rdebug_vaddr, &rdebug, sizeof(rdebug),mem_read_ud);
|
||||
if (rdebug_read_size != sizeof(rdebug)) { goto exit; }
|
||||
} else {
|
||||
GNU_RDebugInfo32 rdebug32;
|
||||
U64 rdebug_read_size = mem_read_func(rdebug_vaddr, sizeof(rdebug32), &rdebug32, mem_read_ud);
|
||||
U64 rdebug_read_size = mem_read_func(rdebug_vaddr, &rdebug32, sizeof(rdebug32), mem_read_ud);
|
||||
if (rdebug_read_size != sizeof(rdebug32)) { goto exit; }
|
||||
}
|
||||
if (rdebug.r_version < 1) { goto exit; }
|
||||
|
||||
if (rdebug.r_version > 1) {
|
||||
U64 r_next_size = mem_read_func(rdebug_vaddr + sizeof(rdebug), sizeof(rdebug_next), &rdebug_next, mem_read_ud);
|
||||
U64 r_next_size = mem_read_func(rdebug_vaddr + sizeof(rdebug), &rdebug_next, sizeof(rdebug_next), mem_read_ud);
|
||||
if (r_next_size != sizeof(rdebug_next)) { goto exit; }
|
||||
}
|
||||
|
||||
@@ -34,18 +34,18 @@ gnu_parse_rdebug(Arena *arena, B32 is_64bit, U64 first_rdebug_vaddr, GNU_MemRead
|
||||
}
|
||||
|
||||
internal GNU_LinkMapList
|
||||
gnu_parse_link_map_list(Arena *arena, B32 is_64bit, U64 first_link_map_vaddr, GNU_MemRead *mem_read_func, void *mem_read_ud)
|
||||
gnu_parse_link_map_list(Arena *arena, B32 is_64bit, U64 first_link_map_vaddr, MachineOp_MemRead *mem_read_func, void *mem_read_ud)
|
||||
{
|
||||
GNU_LinkMapList result = {0};
|
||||
|
||||
GNU_LinkMap64 link_map = {0};
|
||||
for (U64 link_map_vaddr = first_link_map_vaddr; link_map_vaddr != 0; link_map_vaddr = link_map.next_vaddr) {
|
||||
if (is_64bit) {
|
||||
U64 link_map_size = mem_read_func(link_map_vaddr, sizeof(link_map), &link_map, mem_read_ud);
|
||||
U64 link_map_size = mem_read_func(link_map_vaddr, &link_map, sizeof(link_map), mem_read_ud);
|
||||
if (link_map_size != sizeof(link_map)) { goto exit; }
|
||||
} else {
|
||||
GNU_LinkMap32 link_map32 = {0};
|
||||
U64 link_map_size = mem_read_func(link_map_vaddr, sizeof(link_map32), &link_map32, mem_read_ud);
|
||||
U64 link_map_size = mem_read_func(link_map_vaddr, &link_map32, sizeof(link_map32), mem_read_ud);
|
||||
if (link_map_size != sizeof(link_map32)) { goto exit; }
|
||||
gnu_linkmap64_from_linkmap32(link_map32);
|
||||
}
|
||||
|
||||
+3
-5
@@ -30,12 +30,10 @@ typedef struct GNU_RDebugInfoList
|
||||
GNU_RDebugInfoNode *last;
|
||||
} GNU_RDebugInfoList;
|
||||
|
||||
#define GNU_MEM_READ(name) U64 name(U64 addr, U64 size, void *buffer, void *ud)
|
||||
typedef GNU_MEM_READ(GNU_MemRead);
|
||||
|
||||
////////////////////////////////
|
||||
internal GNU_RDebugInfoList gnu_parse_rdebug(Arena *arena, B32 is_64bit, U64 first_rdebug_vaddr, GNU_MemRead *mem_read_func, void *mem_read_ud);
|
||||
internal GNU_LinkMapList gnu_parse_link_map_list(Arena *arena, B32 is_64bit, U64 first_link_map_vaddr, GNU_MemRead *mem_read_func, void *mem_read_ud);
|
||||
|
||||
internal GNU_RDebugInfoList gnu_parse_rdebug(Arena *arena, B32 is_64bit, U64 first_rdebug_vaddr, MachineOp_MemRead *mem_read_func, void *mem_read_ud);
|
||||
internal GNU_LinkMapList gnu_parse_link_map_list(Arena *arena, B32 is_64bit, U64 first_link_map_vaddr, MachineOp_MemRead *mem_read_func, void *mem_read_ud);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user