mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-17 01:22:24 -07:00
ctrl: first pass at new thread registers cache; also checkpoint for progress on moving to new demon layer
This commit is contained in:
+102
-12
@@ -666,7 +666,7 @@ ctrl_entity_release(CTRL_EntityStore *store, CTRL_Entity *entity)
|
||||
Task *last_task = &start_task;
|
||||
for(Task *t = first_task; t != 0; t = t->next)
|
||||
{
|
||||
for(CTRL_Entity *child = entity->first; child != &ctrl_entity_nil; child = child->next)
|
||||
for(CTRL_Entity *child = t->e->first; child != &ctrl_entity_nil; child = child->next)
|
||||
{
|
||||
Task *t = push_array(scratch.arena, Task, 1);
|
||||
t->e = child;
|
||||
@@ -786,6 +786,7 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list)
|
||||
CTRL_Entity *process = ctrl_entity_from_machine_id_handle(store, event->machine_id, event->parent);
|
||||
CTRL_Entity *module = ctrl_entity_alloc(store, process, CTRL_EntityKind_Module, event->arch, event->machine_id, event->entity);
|
||||
ctrl_entity_equip_string(store, module, event->string);
|
||||
module->vaddr_range = event->vaddr_rng;
|
||||
}break;
|
||||
case CTRL_EventKind_EndModule:
|
||||
{
|
||||
@@ -1276,8 +1277,73 @@ ctrl_process_write(CTRL_MachineID machine_id, DMN_Handle process, Rng1U64 range,
|
||||
internal void *
|
||||
ctrl_query_cached_reg_block_from_thread(Arena *arena, CTRL_MachineID machine_id, DMN_Handle thread)
|
||||
{
|
||||
// TODO(rjf)
|
||||
return 0;
|
||||
CTRL_ThreadRegCache *cache = &ctrl_state->thread_reg_cache;
|
||||
Architecture arch = dmn_arch_from_thread(thread);
|
||||
U64 reg_block_size = regs_block_size_from_architecture(arch);
|
||||
U64 hash = ctrl_hash_from_machine_id_handle(machine_id, thread);
|
||||
U64 slot_idx = hash%cache->slots_count;
|
||||
U64 stripe_idx = slot_idx%cache->stripes_count;
|
||||
CTRL_ThreadRegCacheSlot *slot = &cache->slots[slot_idx];
|
||||
CTRL_ThreadRegCacheStripe *stripe = &cache->stripes[stripe_idx];
|
||||
void *result = push_array(arena, U8, reg_block_size);
|
||||
OS_MutexScopeR(stripe->rw_mutex)
|
||||
{
|
||||
// rjf: find existing node
|
||||
CTRL_ThreadRegCacheNode *node = 0;
|
||||
for(CTRL_ThreadRegCacheNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(n->machine_id == machine_id && dmn_handle_match(n->thread, thread))
|
||||
{
|
||||
node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: allocate existing node
|
||||
if(!node)
|
||||
{
|
||||
OS_MutexScopeRWPromote(stripe->rw_mutex)
|
||||
{
|
||||
for(CTRL_ThreadRegCacheNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(n->machine_id == machine_id && dmn_handle_match(n->thread, thread))
|
||||
{
|
||||
node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!node)
|
||||
{
|
||||
node = push_array(stripe->arena, CTRL_ThreadRegCacheNode, 1);
|
||||
DLLPushBack(slot->first, slot->last, node);
|
||||
node->machine_id = machine_id;
|
||||
node->thread = thread;
|
||||
node->block_size = reg_block_size;
|
||||
node->block = push_array(stripe->arena, U8, reg_block_size);
|
||||
}
|
||||
}
|
||||
for(CTRL_ThreadRegCacheNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(n->machine_id == machine_id && dmn_handle_match(n->thread, thread))
|
||||
{
|
||||
node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: copy from node
|
||||
if(node)
|
||||
{
|
||||
U64 current_reggen_idx = ctrl_reggen_idx();
|
||||
if(node->reggen_idx != current_reggen_idx && dmn_thread_read_reg_block(thread, node->block))
|
||||
{
|
||||
node->reggen_idx = current_reggen_idx;
|
||||
}
|
||||
MemoryCopy(result, node->block, reg_block_size);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal U64
|
||||
@@ -1290,15 +1356,23 @@ ctrl_query_cached_tls_root_vaddr_from_thread(CTRL_MachineID machine_id, DMN_Hand
|
||||
internal U64
|
||||
ctrl_query_cached_rip_from_thread(CTRL_MachineID machine_id, DMN_Handle thread)
|
||||
{
|
||||
// TODO(rjf)
|
||||
return 0;
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
Architecture arch = dmn_arch_from_thread(thread);
|
||||
void *block = ctrl_query_cached_reg_block_from_thread(scratch.arena, machine_id, thread);
|
||||
U64 result = regs_rip_from_arch_block(arch, block);
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal U64
|
||||
ctrl_query_cached_rsp_from_thread(CTRL_MachineID machine_id, DMN_Handle thread)
|
||||
{
|
||||
// TODO(rjf)
|
||||
return 0;
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
Architecture arch = dmn_arch_from_thread(thread);
|
||||
void *block = ctrl_query_cached_reg_block_from_thread(scratch.arena, machine_id, thread);
|
||||
U64 result = regs_rsp_from_arch_block(arch, block);
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
//- rjf: thread register writing
|
||||
@@ -1370,7 +1444,7 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_MachineID ma
|
||||
Rng1U64 module_vaddr_range = {0};
|
||||
for(CTRL_Entity *m = process_entity->first; m != &ctrl_entity_nil; m = m->next)
|
||||
{
|
||||
if(contains_1u64(m->vaddr_range, rip))
|
||||
if(m->kind == CTRL_EntityKind_Module && contains_1u64(m->vaddr_range, rip))
|
||||
{
|
||||
module = m->handle;
|
||||
module_name = m->string;
|
||||
@@ -1851,7 +1925,15 @@ ctrl_thread__next_dmn_event(Arena *arena, CTRL_Msg *msg, DMN_RunCtrls *run_ctrls
|
||||
{
|
||||
DBGI_Scope *scope = dbgi_scope_open();
|
||||
CTRL_Entity *process = ctrl_entity_from_machine_id_handle(ctrl_state->ctrl_thread_entity_store, CTRL_MachineID_Local, ev->process);
|
||||
CTRL_Entity *module = process->first;
|
||||
CTRL_Entity *module = &ctrl_entity_nil;
|
||||
for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next)
|
||||
{
|
||||
if(child->kind == CTRL_EntityKind_Module)
|
||||
{
|
||||
module = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(module != &ctrl_entity_nil)
|
||||
{
|
||||
// rjf: determine base address of asan shadow space
|
||||
@@ -2365,7 +2447,15 @@ ctrl_thread__launch_and_init(CTRL_Msg *msg)
|
||||
{
|
||||
//- rjf: unpack process & first module info
|
||||
CTRL_Entity *process = ctrl_entity_from_machine_id_handle(ctrl_state->ctrl_thread_entity_store, CTRL_MachineID_Local, run_ctrls.run_entities[process_idx]);
|
||||
CTRL_Entity *module = process->first;
|
||||
CTRL_Entity *module = &ctrl_entity_nil;
|
||||
for(CTRL_Entity *child = process->first; child != &ctrl_entity_nil; child = child->next)
|
||||
{
|
||||
if(child->kind == CTRL_EntityKind_Module)
|
||||
{
|
||||
module = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
U64 module_base_vaddr = module->vaddr_range.min;
|
||||
String8 exe_path = module->string;
|
||||
DBGI_Parse *dbgi = dbgi_parse_from_exe_path(scope, exe_path, max_U64);
|
||||
@@ -2999,7 +3089,7 @@ ctrl_thread__run(CTRL_Msg *msg)
|
||||
CTRL_Entity *process = ctrl_entity_from_machine_id_handle(ctrl_state->ctrl_thread_entity_store, CTRL_MachineID_Local, event->process);
|
||||
for(CTRL_Entity *module = process->first; module != &ctrl_entity_nil; module = module->next)
|
||||
{
|
||||
if(contains_1u64(module->vaddr_range, thread_rip_vaddr))
|
||||
if(module->kind == CTRL_EntityKind_Module && contains_1u64(module->vaddr_range, thread_rip_vaddr))
|
||||
{
|
||||
module_name = module->string;
|
||||
module_base_vaddr = module->vaddr_range.min;
|
||||
@@ -3129,7 +3219,7 @@ ctrl_thread__run(CTRL_Msg *msg)
|
||||
if(bytecode.size != 0)
|
||||
{
|
||||
U64 module_base = module_base_vaddr;
|
||||
U64 tls_base = 0; // TODO(rjf)
|
||||
U64 tls_base = ctrl_query_cached_tls_root_vaddr_from_thread(CTRL_MachineID_Local, event->thread);
|
||||
EVAL_Machine machine = {0};
|
||||
machine.u = &event->process;
|
||||
machine.arch = arch;
|
||||
|
||||
@@ -441,7 +441,9 @@ struct CTRL_ThreadRegCacheNode
|
||||
CTRL_ThreadRegCacheNode *prev;
|
||||
CTRL_MachineID machine_id;
|
||||
DMN_Handle thread;
|
||||
U128 regs_hash;
|
||||
U64 block_size;
|
||||
void *block;
|
||||
U64 reggen_idx;
|
||||
};
|
||||
|
||||
typedef struct CTRL_ThreadRegCacheSlot CTRL_ThreadRegCacheSlot;
|
||||
|
||||
@@ -40,7 +40,7 @@ dmn_w32_entity_from_handle(DMN_Handle handle)
|
||||
{
|
||||
U32 idx = handle.u32[0];
|
||||
U32 gen = handle.u32[1];
|
||||
DMN_W32_Entity *entity = dmn_w32_shared->entities_base;
|
||||
DMN_W32_Entity *entity = dmn_w32_shared->entities_base + idx;
|
||||
if(entity->gen != gen)
|
||||
{
|
||||
entity = &dmn_w32_entity_nil;
|
||||
@@ -141,7 +141,7 @@ dmn_w32_entity_release(DMN_W32_Entity *entity)
|
||||
Task *last_task = &start_task;
|
||||
for(Task *t = first_task; t != 0; t = t->next)
|
||||
{
|
||||
for(DMN_W32_Entity *child = entity->first; child != &dmn_w32_entity_nil; child = child->next)
|
||||
for(DMN_W32_Entity *child = t->e->first; child != &dmn_w32_entity_nil; child = child->next)
|
||||
{
|
||||
Task *t = push_array(scratch.arena, Task, 1);
|
||||
t->e = child;
|
||||
@@ -581,9 +581,10 @@ dmn_w32_thread_read_reg_block(Architecture arch, HANDLE thread, void *reg_block)
|
||||
//- rjf: unimplemented win32/arch combos
|
||||
//
|
||||
case Architecture_Null:
|
||||
case Architecture_COUNT:
|
||||
{}break;
|
||||
case Architecture_arm64:
|
||||
case Architecture_arm32:
|
||||
case Architecture_COUNT:
|
||||
{NotImplemented;}break;
|
||||
|
||||
////////////////////////////
|
||||
@@ -824,9 +825,10 @@ dmn_w32_thread_write_reg_block(Architecture arch, HANDLE thread, void *reg_block
|
||||
//- rjf: unimplemented win32/arch combos
|
||||
//
|
||||
case Architecture_Null:
|
||||
case Architecture_COUNT:
|
||||
{}break;
|
||||
case Architecture_arm64:
|
||||
case Architecture_arm32:
|
||||
case Architecture_COUNT:
|
||||
{NotImplemented;}break;
|
||||
|
||||
////////////////////////////
|
||||
@@ -1148,9 +1150,10 @@ dmn_run(Arena *arena, DMN_RunCtrls *ctrls)
|
||||
{
|
||||
//- rjf: unimplemented win32/arch combos
|
||||
case Architecture_Null:
|
||||
case Architecture_COUNT:
|
||||
{}break;
|
||||
case Architecture_arm64:
|
||||
case Architecture_arm32:
|
||||
case Architecture_COUNT:
|
||||
{NotImplemented;}break;
|
||||
|
||||
//- rjf: x86/64
|
||||
@@ -1219,7 +1222,7 @@ dmn_run(Arena *arena, DMN_RunCtrls *ctrls)
|
||||
|
||||
//- rjf: scan all threads in this process
|
||||
for(DMN_W32_Entity *thread = process->first;
|
||||
thread != 0;
|
||||
thread != &dmn_w32_entity_nil;
|
||||
thread = thread->next)
|
||||
{
|
||||
if(thread->kind != DMN_W32_EntityKind_Thread) {continue;}
|
||||
@@ -1432,6 +1435,7 @@ dmn_run(Arena *arena, DMN_RunCtrls *ctrls)
|
||||
process->handle = process_handle;
|
||||
process->arch = image_info.arch;
|
||||
thread->handle = thread_handle;
|
||||
thread->arch = image_info.arch;
|
||||
thread->thread.thread_local_base = tls_base;
|
||||
module->handle = module_handle;
|
||||
module->module.vaddr_range = r1u64(module_base, image_info.size);
|
||||
@@ -2050,9 +2054,10 @@ dmn_run(Arena *arena, DMN_RunCtrls *ctrls)
|
||||
{
|
||||
//- rjf: unimplemented win32/arch combos
|
||||
case Architecture_Null:
|
||||
case Architecture_COUNT:
|
||||
{}break;
|
||||
case Architecture_arm64:
|
||||
case Architecture_arm32:
|
||||
case Architecture_COUNT:
|
||||
{NotImplemented;}break;
|
||||
|
||||
//- rjf: x86/64
|
||||
@@ -2353,9 +2358,10 @@ dmn_stack_base_vaddr_from_thread(DMN_Handle handle)
|
||||
switch(thread->arch)
|
||||
{
|
||||
case Architecture_Null:
|
||||
case Architecture_COUNT:
|
||||
{}break;
|
||||
case Architecture_arm64:
|
||||
case Architecture_arm32:
|
||||
case Architecture_COUNT:
|
||||
{NotImplemented;}break;
|
||||
case Architecture_x64:
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#define BUILD_VERSION_MAJOR 0
|
||||
#define BUILD_VERSION_MINOR 9
|
||||
#define BUILD_VERSION_PATCH 8
|
||||
#define BUILD_VERSION_PATCH 9
|
||||
#define BUILD_RELEASE_PHASE_STRING_LITERAL "ALPHA"
|
||||
#define BUILD_TITLE "The RAD Debugger"
|
||||
#define OS_FEATURE_GRAPHICAL 1
|
||||
|
||||
Reference in New Issue
Block a user