generalize machine ops

This commit is contained in:
Nikita Smith
2025-12-16 10:40:48 -08:00
parent 782f87e512
commit 952afd49a7
7 changed files with 89 additions and 119 deletions
+23
View File
@@ -678,6 +678,29 @@ union Guid
}; };
StaticAssert(sizeof(Guid) == 16, g_guid_size_check); 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 //~ rjf: Basic Constants
+30 -81
View File
@@ -1833,93 +1833,42 @@ typedef struct
} CTRL_MemoryReadContextDwarfX64; } CTRL_MemoryReadContextDwarfX64;
internal internal
DW_MEM_READ(ctrl_unwind_mem_read_dwarf_x64) MACHINE_OP_MEM_READ(ctrl_machine_mem_read)
{ {
CTRL_MemoryReadContextDwarfX64 *ctx = ud; CTRL_MemoryReadContextDwarfX64 *ctx = ud;
B32 is_stale = 0; 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) if(is_stale)
{ {
status = DW_UnwindStatus_Maybe; status = MachineOpResult_Maybe;
} }
else if(is_read) else if(is_read)
{ {
status = DW_UnwindStatus_Ok; status = MachineOpResult_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 = &regs->_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 = &regs->_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;
} }
return status; return status;
} }
internal CTRL_UnwindStepResult 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}; CTRL_UnwindStepResult result = {0};
switch(s) switch(s)
{ {
case DW_UnwindStatus_Ok: case MachineOpResult_Null: {} break;
case MachineOpResult_Ok:
{ {
result.flags &= ~(CTRL_UnwindFlag_Error|CTRL_UnwindFlag_Stale); result.flags &= ~(CTRL_UnwindFlag_Error|CTRL_UnwindFlag_Stale);
}break; }break;
case DW_UnwindStatus_Fail: case MachineOpResult_Fail:
{ {
result.flags |= CTRL_UnwindFlag_Error; result.flags |= CTRL_UnwindFlag_Error;
}break; }break;
case DW_UnwindStatus_Maybe: case MachineOpResult_Maybe:
{ {
result.flags &= ~CTRL_UnwindFlag_Error; result.flags &= ~CTRL_UnwindFlag_Error;
result.flags |= CTRL_UnwindFlag_Stale; result.flags |= CTRL_UnwindFlag_Stale;
@@ -2083,8 +2032,8 @@ ctrl_establish_frame_unwind_context__dwarf(Arena *arena, CTRL_Handle process_han
// setup machine ops // setup machine ops
void *mem_read_ctx = 0; void *mem_read_ctx = 0;
void *reg_read_ctx = 0; void *reg_read_ctx = 0;
DW_MemRead *mem_read_func = 0; MachineOp_MemRead *mem_read_func = 0;
DW_RegRead *reg_read_func = 0; MachineOp_RegRead *reg_read_func = 0;
switch(arch) switch(arch)
{ {
case Arch_Null: break; 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->process_handle = process_handle;
mem_read_ctx_x64->endt_us = endt_us; mem_read_ctx_x64->endt_us = endt_us;
mem_read_ctx = mem_read_ctx_x64; mem_read_ctx = mem_read_ctx_x64;
reg_read_ctx = regs; reg_read_ctx = regs;
mem_read_func = ctrl_unwind_mem_read_dwarf_x64; mem_read_func = ctrl_machine_mem_read;
reg_read_func = ctrl_unwind_reg_read_dwarf_x64; reg_read_func = regs_read_dwarf_x64;
}break; }break;
case Arch_x86: case Arch_x86:
case Arch_arm64: case Arch_arm64:
@@ -2111,10 +2060,10 @@ ctrl_establish_frame_unwind_context__dwarf(Arena *arena, CTRL_Handle process_han
// compute CFA for the row // compute CFA for the row
U64 cfa = 0; 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 // on success fill out output
if(unwind_status == DW_UnwindStatus_Ok) if(unwind_status == MachineOpResult_Ok)
{ {
ctx_out->cfa = cfa; ctx_out->cfa = cfa;
ctx_out->cfi_row = cfi_row; 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 // 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 *mem_read_ctx = 0;
void *reg_read_ctx = 0; void *reg_read_ctx = 0;
void *reg_write_ctx = 0; void *reg_write_ctx = 0;
DW_MemRead *mem_read_func = 0; MachineOp_MemRead *mem_read_func = 0;
DW_RegRead *reg_read_func = 0; MachineOp_RegRead *reg_read_func = 0;
DW_RegWrite *reg_write_func = 0; MachineOp_RegWrite *reg_write_func = 0;
switch(arch) switch(arch)
{ {
case Arch_Null: break; 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_read_ctx = regs;
reg_write_ctx = regs; reg_write_ctx = regs;
mem_read_func = ctrl_unwind_mem_read_dwarf_x64; mem_read_func = ctrl_machine_mem_read;
reg_read_func = ctrl_unwind_reg_read_dwarf_x64; reg_read_func = regs_read_dwarf_x64;
reg_write_func = ctrl_unwind_reg_write_dwarf_x64; reg_write_func = regs_write_dwarf_x64;
}break; }break;
case Arch_x86: case Arch_x86:
case Arch_arm64: 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 // 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->cfa,
frame_ctx->cfi_row, frame_ctx->cfi_row,
mem_read_func, mem_read_func,
@@ -2189,7 +2138,7 @@ ctrl_unwind_step__dwarf(CTRL_Handle process_handle, Arch arch, void *regs, CTRL_
} }
// translate unwind status code // 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); scratch_end(scratch);
return result; 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 //- rjf: module lifetime open/close work
internal 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); U64 read = dmn_process_read(((CTRL_Handle *)ud)->dmn_handle, r1u64(addr, addr + buffer_size), buffer);
return read == size ? DW_UnwindStatus_Ok : DW_UnwindStatus_Fail; return read == buffer_size ? MachineOpResult_Ok : MachineOpResult_Fail;
} }
internal void internal void
+9 -9
View File
@@ -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); 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 internal int
dmn_lnx_ptrace_seize(pid_t pid) 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; 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 //~ SDT Probes
@@ -1799,9 +1799,9 @@ dmn_lnx_hanlde_unload_module(Arena *arena, DMN_EventList *events, DMN_LNX_Entity
// mark live modules // mark live modules
B32 is_64bit = process->dl_class == ELF_Class_64; 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) { 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) { 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); DMN_LNX_Entity *module = hash_table_search_u64_raw(process->loaded_modules_ht, link_map_n->v.addr_vaddr);
module->is_live = 1; 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 // extract modules from r_debug
B32 is_64bit = process->dl_class == ELF_Class_64; 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; U64 name_space_id = 0;
for EachNode(rdebug_n, GNU_RDebugInfoNode, rdebug_list.first) for EachNode(rdebug_n, GNU_RDebugInfoNode, rdebug_list.first)
{ {
+16 -16
View File
@@ -236,14 +236,14 @@ dw_cfi_row_from_pc(Arena *arena, Arch arch, DW_CIE *cie, DW_FDE *fde, DW_DecodeP
return result; return result;
} }
internal DW_UnwindStatus internal MachineOpResult
dw_compute_cfa(Arch arch, dw_compute_cfa(Arch arch,
DW_CFI_Row *row, DW_CFI_Row *row,
DW_MemRead *mem_read_func, void *mem_read_ud, MachineOp_MemRead *mem_read_func, void *mem_read_ud,
DW_RegRead *reg_read_func, void *reg_read_ud, MachineOp_RegRead *reg_read_func, void *reg_read_ud,
U64 *cfa_out) U64 *cfa_out)
{ {
DW_UnwindStatus unwind_status = DW_UnwindStatus_Fail; MachineOpResult unwind_status = MachineOpResult_Fail;
switch (row->cfa.rule) { switch (row->cfa.rule) {
case DW_CFA_Rule_Null: break; 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); U64 reg_size = dw_reg_size_from_code(arch, row->cfa.reg);
AssertAlways(reg_size <= sizeof(cfa_reg_value)); AssertAlways(reg_size <= sizeof(cfa_reg_value));
unwind_status = reg_read_func(row->cfa.reg, &cfa_reg_value, reg_size, reg_read_ud); 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; *cfa_out = cfa_reg_value + row->cfa.off;
} break; } break;
case DW_CFA_Rule_Expression: { case DW_CFA_Rule_Expression: {
@@ -265,16 +265,16 @@ dw_compute_cfa(Arch arch,
return unwind_status; return unwind_status;
} }
internal DW_UnwindStatus internal MachineOpResult
dw_cfi_apply_register_rules(Arch arch, dw_cfi_apply_register_rules(Arch arch,
U64 cfa, U64 cfa,
DW_CFI_Row *row, DW_CFI_Row *row,
DW_MemRead *mem_read_func, void *mem_read_ud, MachineOp_MemRead *mem_read_func, void *mem_read_ud,
DW_RegRead *reg_read_func, void *reg_read_ud, MachineOp_RegRead *reg_read_func, void *reg_read_ud,
DW_RegWrite *reg_write_func, void *reg_write_ud) MachineOp_RegWrite *reg_write_func, void *reg_write_ud)
{ {
Temp scratch = scratch_begin(0,0); 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); U64 max_reg_size = dw_reg_max_size_from_arch(arch);
void *reg_buffer = push_array(scratch.arena, U8, max_reg_size); 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 // read register value from memory
U64 addr = cfa + reg->n; U64 addr = cfa + reg->n;
U64 reg_size = dw_reg_size_from_code(arch, reg_idx); U64 reg_size = dw_reg_size_from_code(arch, reg_idx);
unwind_status = mem_read_func(addr, reg_size, reg_buffer, mem_read_ud); unwind_status = mem_read_func(addr, reg_buffer, reg_size, mem_read_ud);
if (unwind_status != DW_UnwindStatus_Ok) { goto exit; } if (unwind_status != MachineOpResult_Ok) { goto exit; }
// write register value to the thread context // write register value to the thread context
unwind_status = reg_write_func(reg_idx, reg_buffer, reg_size, reg_write_ud); 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; } break;
case DW_CFI_RegisterRule_ValOffset: { case DW_CFI_RegisterRule_ValOffset: {
// compute register value // compute register value
@@ -303,17 +303,17 @@ dw_cfi_apply_register_rules(Arch arch,
// write register value to the thread context // write register value to the thread context
U64 reg_size = dw_reg_size_from_code(arch, reg_idx); U64 reg_size = dw_reg_size_from_code(arch, reg_idx);
unwind_status = reg_write_func(reg_idx, &reg_value, reg_size, reg_write_ud); unwind_status = reg_write_func(reg_idx, &reg_value, reg_size, reg_write_ud);
if (unwind_status != DW_UnwindStatus_Ok) { goto exit; } if (unwind_status != MachineOpResult_Ok) { goto exit; }
} break; } break;
case DW_CFI_RegisterRule_Register: { case DW_CFI_RegisterRule_Register: {
// read register value from another register // read register value from another register
U64 reg_size = dw_reg_size_from_code(arch, reg_idx); 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); 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 // write register value to the thread context
unwind_status = reg_write_func(reg_idx, reg_buffer, reg_size, reg_write_ud); 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; } break;
case DW_CFI_RegisterRule_Expression: { case DW_CFI_RegisterRule_Expression: {
// TODO: evaluate expression // TODO: evaluate expression
+1 -1
View File
@@ -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 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_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 #endif // DWARF_UNWIND_H
+7 -7
View File
@@ -2,24 +2,24 @@
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
internal GNU_RDebugInfoList 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}; GNU_RDebugInfoList result = {0};
for (U64 rdebug_vaddr = first_rdebug_vaddr, rdebug_next = 0; rdebug_vaddr != 0; rdebug_vaddr = rdebug_next) { for (U64 rdebug_vaddr = first_rdebug_vaddr, rdebug_next = 0; rdebug_vaddr != 0; rdebug_vaddr = rdebug_next) {
GNU_RDebugInfo64 rdebug; GNU_RDebugInfo64 rdebug;
if (is_64bit) { 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; } if (rdebug_read_size != sizeof(rdebug)) { goto exit; }
} else { } else {
GNU_RDebugInfo32 rdebug32; 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_read_size != sizeof(rdebug32)) { goto exit; }
} }
if (rdebug.r_version < 1) { goto exit; } if (rdebug.r_version < 1) { goto exit; }
if (rdebug.r_version > 1) { 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; } 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 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_LinkMapList result = {0};
GNU_LinkMap64 link_map = {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) { for (U64 link_map_vaddr = first_link_map_vaddr; link_map_vaddr != 0; link_map_vaddr = link_map.next_vaddr) {
if (is_64bit) { 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; } if (link_map_size != sizeof(link_map)) { goto exit; }
} else { } else {
GNU_LinkMap32 link_map32 = {0}; 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; } if (link_map_size != sizeof(link_map32)) { goto exit; }
gnu_linkmap64_from_linkmap32(link_map32); gnu_linkmap64_from_linkmap32(link_map32);
} }
+3 -5
View File
@@ -30,12 +30,10 @@ typedef struct GNU_RDebugInfoList
GNU_RDebugInfoNode *last; GNU_RDebugInfoNode *last;
} GNU_RDebugInfoList; } 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 #endif