ctrl: first pass at new thread registers cache; also checkpoint for progress on moving to new demon layer

This commit is contained in:
Ryan Fleury
2024-03-14 21:09:43 -07:00
parent 936c6149e3
commit aa7c30d85b
4 changed files with 120 additions and 22 deletions
+102 -12
View File
@@ -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;
+3 -1
View File
@@ -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;
+14 -8
View File
@@ -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:
{
+1 -1
View File
@@ -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