mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-02 20:18:12 +00:00
double buffer locals cache & tls base cache; introduce synchronizing mechanism for run vs. non-run ctrl thread states, to only attempt demon reads/queries during non-running times
This commit is contained in:
+32
-15
@@ -800,6 +800,7 @@ ctrl_init(void)
|
||||
Arena *arena = arena_alloc();
|
||||
ctrl_state = push_array(arena, CTRL_State, 1);
|
||||
ctrl_state->arena = arena;
|
||||
ctrl_state->ctrl_run_mutex = os_mutex_alloc();
|
||||
for(Architecture arch = (Architecture)0; arch < Architecture_COUNT; arch = (Architecture)(arch+1))
|
||||
{
|
||||
String8 *reg_names = regs_reg_code_string_table_from_architecture(arch);
|
||||
@@ -1344,12 +1345,17 @@ ctrl_query_cached_reg_block_from_thread(Arena *arena, CTRL_MachineID machine_id,
|
||||
if(node)
|
||||
{
|
||||
U64 current_reg_gen = dmn_reg_gen();
|
||||
if(node->reg_gen != current_reg_gen && dmn_thread_read_reg_block(thread, result))
|
||||
B32 need_stale = 1;
|
||||
if(node->reg_gen != current_reg_gen)
|
||||
{
|
||||
node->reg_gen = current_reg_gen;
|
||||
MemoryCopy(node->block, result, reg_block_size);
|
||||
OS_MutexScope(ctrl_state->ctrl_run_mutex) if(ctrl_state->ctrl_run_state == 0 && dmn_thread_read_reg_block(thread, result))
|
||||
{
|
||||
need_stale = 0;
|
||||
node->reg_gen = current_reg_gen;
|
||||
MemoryCopy(node->block, result, reg_block_size);
|
||||
}
|
||||
}
|
||||
else
|
||||
if(need_stale)
|
||||
{
|
||||
MemoryCopy(result, node->block, reg_block_size);
|
||||
}
|
||||
@@ -1719,6 +1725,12 @@ ctrl_thread__entry_point(void *p)
|
||||
//- rjf: get next messages
|
||||
CTRL_MsgList msgs = ctrl_u2c_pop_msgs(scratch.arena);
|
||||
|
||||
//- rjf: begin run state
|
||||
OS_MutexScope(ctrl_state->ctrl_run_mutex)
|
||||
{
|
||||
ctrl_state->ctrl_run_state = 1;
|
||||
}
|
||||
|
||||
//- rjf: process messages
|
||||
{
|
||||
B32 done = 0;
|
||||
@@ -1753,6 +1765,12 @@ ctrl_thread__entry_point(void *p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: end run state
|
||||
OS_MutexScope(ctrl_state->ctrl_run_mutex)
|
||||
{
|
||||
ctrl_state->ctrl_run_state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
@@ -2879,7 +2897,7 @@ ctrl_thread__run(CTRL_Msg *msg)
|
||||
if(process->kind != CTRL_EntityKind_Process) { continue; }
|
||||
for(CTRL_Entity *thread = process->first; thread != &ctrl_entity_nil; thread = thread->next)
|
||||
{
|
||||
U64 rip = ctrl_query_cached_rip_from_thread(thread->machine_id, thread->handle);
|
||||
U64 rip = dmn_rip_from_thread(thread->handle);
|
||||
|
||||
// rjf: determine if thread is frozen
|
||||
B32 thread_is_frozen = !msg->freeze_state_is_frozen;
|
||||
@@ -2998,7 +3016,7 @@ ctrl_thread__run(CTRL_Msg *msg)
|
||||
//
|
||||
if(stop_event == 0)
|
||||
{
|
||||
U64 sp_check_value = ctrl_query_cached_rsp_from_thread(CTRL_MachineID_Local, target_thread);
|
||||
U64 sp_check_value = dmn_rsp_from_thread(target_thread);
|
||||
B32 spoof_mode = 0;
|
||||
CTRL_Spoof spoof = {0};
|
||||
for(;;)
|
||||
@@ -3085,9 +3103,7 @@ ctrl_thread__run(CTRL_Msg *msg)
|
||||
//
|
||||
CTRL_Entity *thread = ctrl_entity_from_machine_id_handle(ctrl_state->ctrl_thread_entity_store, CTRL_MachineID_Local, event->thread);
|
||||
Architecture arch = thread->arch;
|
||||
U64 reg_size = regs_block_size_from_architecture(arch);
|
||||
void *thread_regs_block = ctrl_query_cached_reg_block_from_thread(scratch.arena, CTRL_MachineID_Local, event->thread);
|
||||
U64 thread_rip_vaddr = regs_rip_from_arch_block(arch, thread_regs_block);
|
||||
U64 thread_rip_vaddr = dmn_rsp_from_thread(event->thread);
|
||||
DMN_Handle module = {0};
|
||||
String8 module_name = {0};
|
||||
U64 module_base_vaddr = 0;
|
||||
@@ -3226,15 +3242,16 @@ ctrl_thread__run(CTRL_Msg *msg)
|
||||
if(bytecode.size != 0)
|
||||
{
|
||||
U64 module_base = module_base_vaddr;
|
||||
U64 tls_base = ctrl_query_cached_tls_root_vaddr_from_thread(CTRL_MachineID_Local, event->thread);
|
||||
U64 tls_base = dmn_tls_root_vaddr_from_thread(event->thread);
|
||||
EVAL_Machine machine = {0};
|
||||
machine.u = &event->process;
|
||||
machine.arch = arch;
|
||||
machine.memory_read = ctrl_eval_memory_read;
|
||||
machine.reg_data = thread_regs_block;
|
||||
machine.reg_size = reg_size;
|
||||
machine.reg_size = regs_block_size_from_architecture(arch);
|
||||
machine.reg_data = push_array(scratch.arena, U8, machine.reg_size);
|
||||
machine.module_base = &module_base;
|
||||
machine.tls_base = &tls_base;
|
||||
dmn_thread_read_reg_block(event->thread, machine.reg_data);
|
||||
eval = eval_interpret(&machine, bytecode);
|
||||
}
|
||||
if(eval.code == EVAL_ResultCode_Good && eval.value.u64 == 0)
|
||||
@@ -3335,7 +3352,7 @@ ctrl_thread__run(CTRL_Msg *msg)
|
||||
B32 stack_pointer_matches = 0;
|
||||
if(use_trap_net_logic)
|
||||
{
|
||||
U64 sp = ctrl_query_cached_rsp_from_thread(CTRL_MachineID_Local, target_thread);
|
||||
U64 sp = dmn_rsp_from_thread(target_thread);
|
||||
stack_pointer_matches = (sp == sp_check_value);
|
||||
}
|
||||
|
||||
@@ -3383,7 +3400,7 @@ ctrl_thread__run(CTRL_Msg *msg)
|
||||
{
|
||||
// rjf: setup spoof mode
|
||||
begin_spoof_mode = 1;
|
||||
U64 spoof_sp = ctrl_query_cached_rsp_from_thread(CTRL_MachineID_Local, target_thread);
|
||||
U64 spoof_sp = dmn_rsp_from_thread(target_thread);
|
||||
spoof_mode = 1;
|
||||
spoof.process = target_process;
|
||||
spoof.thread = target_thread;
|
||||
@@ -3401,7 +3418,7 @@ ctrl_thread__run(CTRL_Msg *msg)
|
||||
if(stack_pointer_matches)
|
||||
{
|
||||
save_stack_pointer = 1;
|
||||
sp_check_value = ctrl_query_cached_rsp_from_thread(CTRL_MachineID_Local, target_thread);
|
||||
sp_check_value = dmn_rsp_from_thread(target_thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -491,6 +491,10 @@ struct CTRL_State
|
||||
EVAL_String2NumMap arch_string2reg_tables[Architecture_COUNT];
|
||||
EVAL_String2NumMap arch_string2alias_tables[Architecture_COUNT];
|
||||
|
||||
// rjf: access locking mechanism
|
||||
OS_Handle ctrl_run_mutex;
|
||||
B32 ctrl_run_state;
|
||||
|
||||
// rjf: caches
|
||||
CTRL_ProcessMemoryCache process_memory_cache;
|
||||
CTRL_ThreadRegCache thread_reg_cache;
|
||||
|
||||
@@ -116,3 +116,38 @@ dmn_event_list_push(Arena *arena, DMN_EventList *list)
|
||||
DMN_Event *result = &n->v;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Thread Reading Helper Functions (Helpers, Implemented Once)
|
||||
|
||||
internal U64
|
||||
dmn_rip_from_thread(DMN_Handle thread)
|
||||
{
|
||||
U64 result = 0;
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
{
|
||||
Architecture arch = dmn_arch_from_thread(thread);
|
||||
U64 reg_block_size = regs_block_size_from_architecture(arch);
|
||||
void *reg_block = push_array(scratch.arena, U8, reg_block_size);
|
||||
dmn_thread_read_reg_block(thread, reg_block);
|
||||
result = regs_rip_from_arch_block(arch, reg_block);
|
||||
}
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal U64
|
||||
dmn_rsp_from_thread(DMN_Handle thread)
|
||||
{
|
||||
U64 result = 0;
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
{
|
||||
Architecture arch = dmn_arch_from_thread(thread);
|
||||
U64 reg_block_size = regs_block_size_from_architecture(arch);
|
||||
void *reg_block = push_array(scratch.arena, U8, reg_block_size);
|
||||
dmn_thread_read_reg_block(thread, reg_block);
|
||||
result = regs_rsp_from_arch_block(arch, reg_block);
|
||||
}
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -160,6 +160,12 @@ internal DMN_HandleArray dmn_handle_array_copy(Arena *arena, DMN_HandleArray *sr
|
||||
//- rjf: event list building
|
||||
internal DMN_Event *dmn_event_list_push(Arena *arena, DMN_EventList *list);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Thread Reading Helper Functions (Helpers, Implemented Once)
|
||||
|
||||
internal U64 dmn_rip_from_thread(DMN_Handle thread);
|
||||
internal U64 dmn_rsp_from_thread(DMN_Handle thread);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @dmn_os_hooks Main Layer Initialization (Implemented Per-OS)
|
||||
|
||||
|
||||
+45
-17
@@ -6217,13 +6217,18 @@ internal U64
|
||||
df_query_cached_tls_base_vaddr_from_process_root_rip(DF_Entity *process, U64 root_vaddr, U64 rip_vaddr)
|
||||
{
|
||||
U64 result = 0;
|
||||
for(U64 cache_idx = 0; cache_idx < ArrayCount(df_state->tls_base_caches); cache_idx += 1)
|
||||
{
|
||||
DF_RunTLSBaseCache *cache = &df_state->tls_base_cache;
|
||||
if(cache->slots_count == 0)
|
||||
DF_RunTLSBaseCache *cache = &df_state->tls_base_caches[(df_state->tls_base_cache_gen+cache_idx)%ArrayCount(df_state->tls_base_caches)];
|
||||
if(cache_idx == 0 && cache->slots_count == 0)
|
||||
{
|
||||
cache->slots_count = 256;
|
||||
cache->slots = push_array(cache->arena, DF_RunTLSBaseCacheSlot, cache->slots_count);
|
||||
}
|
||||
else if(cache->slots_count == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
DF_Handle handle = df_handle_from_entity(process);
|
||||
U64 hash = df_hash_from_seed_string(df_hash_from_string(str8_struct(&handle)), str8_struct(&rip_vaddr));
|
||||
U64 slot_idx = hash%cache->slots_count;
|
||||
@@ -6239,14 +6244,22 @@ df_query_cached_tls_base_vaddr_from_process_root_rip(DF_Entity *process, U64 roo
|
||||
}
|
||||
if(node == 0)
|
||||
{
|
||||
node = push_array(cache->arena, DF_RunTLSBaseCacheNode, 1);
|
||||
SLLQueuePush_N(slot->first, slot->last, node, hash_next);
|
||||
node->process = handle;
|
||||
node->root_vaddr = root_vaddr;
|
||||
node->rip_vaddr = rip_vaddr;
|
||||
node->tls_base_vaddr = df_tls_base_vaddr_from_process_root_rip(process, root_vaddr, rip_vaddr);
|
||||
U64 tls_base_vaddr = df_tls_base_vaddr_from_process_root_rip(process, root_vaddr, rip_vaddr);
|
||||
if(tls_base_vaddr != 0)
|
||||
{
|
||||
node = push_array(cache->arena, DF_RunTLSBaseCacheNode, 1);
|
||||
SLLQueuePush_N(slot->first, slot->last, node, hash_next);
|
||||
node->process = handle;
|
||||
node->root_vaddr = root_vaddr;
|
||||
node->rip_vaddr = rip_vaddr;
|
||||
node->tls_base_vaddr = tls_base_vaddr;
|
||||
}
|
||||
}
|
||||
if(node != 0 && node->tls_base_vaddr != 0)
|
||||
{
|
||||
result = node->tls_base_vaddr;
|
||||
break;
|
||||
}
|
||||
result = node->tls_base_vaddr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -6256,13 +6269,18 @@ df_query_cached_locals_map_from_binary_voff(DF_Entity *binary, U64 voff)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
EVAL_String2NumMap *map = &eval_string2num_map_nil;
|
||||
for(U64 cache_idx = 0; cache_idx < ArrayCount(df_state->locals_caches); cache_idx += 1)
|
||||
{
|
||||
DF_RunLocalsCache *cache = &df_state->locals_cache;
|
||||
if(cache->table_size == 0)
|
||||
DF_RunLocalsCache *cache = &df_state->locals_caches[(df_state->locals_cache_gen+cache_idx)%ArrayCount(df_state->locals_caches)];
|
||||
if(cache_idx == 0 && cache->table_size == 0)
|
||||
{
|
||||
cache->table_size = 256;
|
||||
cache->table = push_array(cache->arena, DF_RunLocalsCacheSlot, cache->table_size);
|
||||
}
|
||||
else if(cache->table_size == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
DF_Handle handle = df_handle_from_entity(binary);
|
||||
U64 hash = df_hash_from_string(str8_struct(&handle));
|
||||
U64 slot_idx = hash % cache->table_size;
|
||||
@@ -6290,9 +6308,10 @@ df_query_cached_locals_map_from_binary_voff(DF_Entity *binary, U64 voff)
|
||||
}
|
||||
dbgi_scope_close(scope);
|
||||
}
|
||||
if(node != 0)
|
||||
if(node != 0 && node->locals_map->slots_count != 0)
|
||||
{
|
||||
map = node->locals_map;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ProfEnd();
|
||||
@@ -6413,8 +6432,14 @@ df_core_init(CmdLine *cmdln, DF_StateDeltaHistory *hist)
|
||||
{
|
||||
df_state->unwind_caches[idx].arena = arena_alloc();
|
||||
}
|
||||
df_state->tls_base_cache.arena = arena_alloc();
|
||||
df_state->locals_cache.arena = arena_alloc();
|
||||
for(U64 idx = 0; idx < ArrayCount(df_state->tls_base_caches); idx += 1)
|
||||
{
|
||||
df_state->tls_base_caches[idx].arena = arena_alloc();
|
||||
}
|
||||
for(U64 idx = 0; idx < ArrayCount(df_state->locals_caches); idx += 1)
|
||||
{
|
||||
df_state->locals_caches[idx].arena = arena_alloc();
|
||||
}
|
||||
df_state->member_cache.arena = arena_alloc();
|
||||
|
||||
// rjf: set up eval view cache
|
||||
@@ -6901,7 +6926,8 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
|
||||
df_state->tls_base_cache_memgen_idx != new_mem_gen) &&
|
||||
!df_ctrl_targets_running())
|
||||
{
|
||||
DF_RunTLSBaseCache *cache = &df_state->tls_base_cache;
|
||||
df_state->tls_base_cache_gen += 1;
|
||||
DF_RunTLSBaseCache *cache = &df_state->tls_base_caches[df_state->tls_base_cache_gen%ArrayCount(df_state->tls_base_caches)];
|
||||
arena_clear(cache->arena);
|
||||
cache->slots_count = 0;
|
||||
cache->slots = 0;
|
||||
@@ -6910,9 +6936,11 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
|
||||
}
|
||||
|
||||
//- rjf: clear locals cache
|
||||
if(df_state->locals_cache_reggen_idx != new_reg_gen && !df_ctrl_targets_running())
|
||||
if(df_state->locals_cache_reggen_idx != new_reg_gen &&
|
||||
!df_ctrl_targets_running())
|
||||
{
|
||||
DF_RunLocalsCache *cache = &df_state->locals_cache;
|
||||
df_state->locals_cache_gen += 1;
|
||||
DF_RunLocalsCache *cache = &df_state->locals_caches[df_state->locals_cache_gen%ArrayCount(df_state->locals_caches)];
|
||||
arena_clear(cache->arena);
|
||||
cache->table_size = 0;
|
||||
cache->table = 0;
|
||||
|
||||
@@ -1139,9 +1139,11 @@ struct DF_State
|
||||
U64 unwind_cache_gen;
|
||||
U64 tls_base_cache_reggen_idx;
|
||||
U64 tls_base_cache_memgen_idx;
|
||||
DF_RunTLSBaseCache tls_base_cache;
|
||||
DF_RunTLSBaseCache tls_base_caches[2];
|
||||
U64 tls_base_cache_gen;
|
||||
U64 locals_cache_reggen_idx;
|
||||
DF_RunLocalsCache locals_cache;
|
||||
DF_RunLocalsCache locals_caches[2];
|
||||
U64 locals_cache_gen;
|
||||
U64 member_cache_reggen_idx;
|
||||
DF_RunLocalsCache member_cache;
|
||||
|
||||
|
||||
@@ -6244,7 +6244,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
DF_Entity *thread = thread_n->entity;
|
||||
U64 unwind_count = (thread == selected_thread) ? ctrl_ctx.unwind_count : 0;
|
||||
U64 rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, unwind_count);
|
||||
if(contains_1u64(disasm_vaddr_rng, rip_vaddr)) ProfScope("in-range rip scan")
|
||||
if(contains_1u64(disasm_vaddr_rng, rip_vaddr))
|
||||
{
|
||||
U64 rip_off = rip_vaddr - disasm_vaddr_rng.min;
|
||||
S64 line_num = dasm_inst_array_idx_from_off__linear_scan(&insts, rip_off)+1;
|
||||
|
||||
Reference in New Issue
Block a user