mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-05 13:28:40 +00: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;
|
Task *last_task = &start_task;
|
||||||
for(Task *t = first_task; t != 0; t = t->next)
|
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);
|
Task *t = push_array(scratch.arena, Task, 1);
|
||||||
t->e = child;
|
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 *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 *module = ctrl_entity_alloc(store, process, CTRL_EntityKind_Module, event->arch, event->machine_id, event->entity);
|
||||||
ctrl_entity_equip_string(store, module, event->string);
|
ctrl_entity_equip_string(store, module, event->string);
|
||||||
|
module->vaddr_range = event->vaddr_rng;
|
||||||
}break;
|
}break;
|
||||||
case CTRL_EventKind_EndModule:
|
case CTRL_EventKind_EndModule:
|
||||||
{
|
{
|
||||||
@@ -1276,8 +1277,73 @@ ctrl_process_write(CTRL_MachineID machine_id, DMN_Handle process, Rng1U64 range,
|
|||||||
internal void *
|
internal void *
|
||||||
ctrl_query_cached_reg_block_from_thread(Arena *arena, CTRL_MachineID machine_id, DMN_Handle thread)
|
ctrl_query_cached_reg_block_from_thread(Arena *arena, CTRL_MachineID machine_id, DMN_Handle thread)
|
||||||
{
|
{
|
||||||
// TODO(rjf)
|
CTRL_ThreadRegCache *cache = &ctrl_state->thread_reg_cache;
|
||||||
return 0;
|
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
|
internal U64
|
||||||
@@ -1290,15 +1356,23 @@ ctrl_query_cached_tls_root_vaddr_from_thread(CTRL_MachineID machine_id, DMN_Hand
|
|||||||
internal U64
|
internal U64
|
||||||
ctrl_query_cached_rip_from_thread(CTRL_MachineID machine_id, DMN_Handle thread)
|
ctrl_query_cached_rip_from_thread(CTRL_MachineID machine_id, DMN_Handle thread)
|
||||||
{
|
{
|
||||||
// TODO(rjf)
|
Temp scratch = scratch_begin(0, 0);
|
||||||
return 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
|
internal U64
|
||||||
ctrl_query_cached_rsp_from_thread(CTRL_MachineID machine_id, DMN_Handle thread)
|
ctrl_query_cached_rsp_from_thread(CTRL_MachineID machine_id, DMN_Handle thread)
|
||||||
{
|
{
|
||||||
// TODO(rjf)
|
Temp scratch = scratch_begin(0, 0);
|
||||||
return 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
|
//- 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};
|
Rng1U64 module_vaddr_range = {0};
|
||||||
for(CTRL_Entity *m = process_entity->first; m != &ctrl_entity_nil; m = m->next)
|
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 = m->handle;
|
||||||
module_name = m->string;
|
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();
|
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 *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)
|
if(module != &ctrl_entity_nil)
|
||||||
{
|
{
|
||||||
// rjf: determine base address of asan shadow space
|
// 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
|
//- 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 *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;
|
U64 module_base_vaddr = module->vaddr_range.min;
|
||||||
String8 exe_path = module->string;
|
String8 exe_path = module->string;
|
||||||
DBGI_Parse *dbgi = dbgi_parse_from_exe_path(scope, exe_path, max_U64);
|
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);
|
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)
|
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_name = module->string;
|
||||||
module_base_vaddr = module->vaddr_range.min;
|
module_base_vaddr = module->vaddr_range.min;
|
||||||
@@ -3129,7 +3219,7 @@ ctrl_thread__run(CTRL_Msg *msg)
|
|||||||
if(bytecode.size != 0)
|
if(bytecode.size != 0)
|
||||||
{
|
{
|
||||||
U64 module_base = module_base_vaddr;
|
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};
|
EVAL_Machine machine = {0};
|
||||||
machine.u = &event->process;
|
machine.u = &event->process;
|
||||||
machine.arch = arch;
|
machine.arch = arch;
|
||||||
|
|||||||
@@ -441,7 +441,9 @@ struct CTRL_ThreadRegCacheNode
|
|||||||
CTRL_ThreadRegCacheNode *prev;
|
CTRL_ThreadRegCacheNode *prev;
|
||||||
CTRL_MachineID machine_id;
|
CTRL_MachineID machine_id;
|
||||||
DMN_Handle thread;
|
DMN_Handle thread;
|
||||||
U128 regs_hash;
|
U64 block_size;
|
||||||
|
void *block;
|
||||||
|
U64 reggen_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct CTRL_ThreadRegCacheSlot CTRL_ThreadRegCacheSlot;
|
typedef struct CTRL_ThreadRegCacheSlot CTRL_ThreadRegCacheSlot;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ dmn_w32_entity_from_handle(DMN_Handle handle)
|
|||||||
{
|
{
|
||||||
U32 idx = handle.u32[0];
|
U32 idx = handle.u32[0];
|
||||||
U32 gen = handle.u32[1];
|
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)
|
if(entity->gen != gen)
|
||||||
{
|
{
|
||||||
entity = &dmn_w32_entity_nil;
|
entity = &dmn_w32_entity_nil;
|
||||||
@@ -141,7 +141,7 @@ dmn_w32_entity_release(DMN_W32_Entity *entity)
|
|||||||
Task *last_task = &start_task;
|
Task *last_task = &start_task;
|
||||||
for(Task *t = first_task; t != 0; t = t->next)
|
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);
|
Task *t = push_array(scratch.arena, Task, 1);
|
||||||
t->e = child;
|
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
|
//- rjf: unimplemented win32/arch combos
|
||||||
//
|
//
|
||||||
case Architecture_Null:
|
case Architecture_Null:
|
||||||
|
case Architecture_COUNT:
|
||||||
|
{}break;
|
||||||
case Architecture_arm64:
|
case Architecture_arm64:
|
||||||
case Architecture_arm32:
|
case Architecture_arm32:
|
||||||
case Architecture_COUNT:
|
|
||||||
{NotImplemented;}break;
|
{NotImplemented;}break;
|
||||||
|
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
@@ -824,9 +825,10 @@ dmn_w32_thread_write_reg_block(Architecture arch, HANDLE thread, void *reg_block
|
|||||||
//- rjf: unimplemented win32/arch combos
|
//- rjf: unimplemented win32/arch combos
|
||||||
//
|
//
|
||||||
case Architecture_Null:
|
case Architecture_Null:
|
||||||
|
case Architecture_COUNT:
|
||||||
|
{}break;
|
||||||
case Architecture_arm64:
|
case Architecture_arm64:
|
||||||
case Architecture_arm32:
|
case Architecture_arm32:
|
||||||
case Architecture_COUNT:
|
|
||||||
{NotImplemented;}break;
|
{NotImplemented;}break;
|
||||||
|
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
@@ -1148,9 +1150,10 @@ dmn_run(Arena *arena, DMN_RunCtrls *ctrls)
|
|||||||
{
|
{
|
||||||
//- rjf: unimplemented win32/arch combos
|
//- rjf: unimplemented win32/arch combos
|
||||||
case Architecture_Null:
|
case Architecture_Null:
|
||||||
|
case Architecture_COUNT:
|
||||||
|
{}break;
|
||||||
case Architecture_arm64:
|
case Architecture_arm64:
|
||||||
case Architecture_arm32:
|
case Architecture_arm32:
|
||||||
case Architecture_COUNT:
|
|
||||||
{NotImplemented;}break;
|
{NotImplemented;}break;
|
||||||
|
|
||||||
//- rjf: x86/64
|
//- rjf: x86/64
|
||||||
@@ -1219,7 +1222,7 @@ dmn_run(Arena *arena, DMN_RunCtrls *ctrls)
|
|||||||
|
|
||||||
//- rjf: scan all threads in this process
|
//- rjf: scan all threads in this process
|
||||||
for(DMN_W32_Entity *thread = process->first;
|
for(DMN_W32_Entity *thread = process->first;
|
||||||
thread != 0;
|
thread != &dmn_w32_entity_nil;
|
||||||
thread = thread->next)
|
thread = thread->next)
|
||||||
{
|
{
|
||||||
if(thread->kind != DMN_W32_EntityKind_Thread) {continue;}
|
if(thread->kind != DMN_W32_EntityKind_Thread) {continue;}
|
||||||
@@ -1432,6 +1435,7 @@ dmn_run(Arena *arena, DMN_RunCtrls *ctrls)
|
|||||||
process->handle = process_handle;
|
process->handle = process_handle;
|
||||||
process->arch = image_info.arch;
|
process->arch = image_info.arch;
|
||||||
thread->handle = thread_handle;
|
thread->handle = thread_handle;
|
||||||
|
thread->arch = image_info.arch;
|
||||||
thread->thread.thread_local_base = tls_base;
|
thread->thread.thread_local_base = tls_base;
|
||||||
module->handle = module_handle;
|
module->handle = module_handle;
|
||||||
module->module.vaddr_range = r1u64(module_base, image_info.size);
|
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
|
//- rjf: unimplemented win32/arch combos
|
||||||
case Architecture_Null:
|
case Architecture_Null:
|
||||||
|
case Architecture_COUNT:
|
||||||
|
{}break;
|
||||||
case Architecture_arm64:
|
case Architecture_arm64:
|
||||||
case Architecture_arm32:
|
case Architecture_arm32:
|
||||||
case Architecture_COUNT:
|
|
||||||
{NotImplemented;}break;
|
{NotImplemented;}break;
|
||||||
|
|
||||||
//- rjf: x86/64
|
//- rjf: x86/64
|
||||||
@@ -2353,9 +2358,10 @@ dmn_stack_base_vaddr_from_thread(DMN_Handle handle)
|
|||||||
switch(thread->arch)
|
switch(thread->arch)
|
||||||
{
|
{
|
||||||
case Architecture_Null:
|
case Architecture_Null:
|
||||||
|
case Architecture_COUNT:
|
||||||
|
{}break;
|
||||||
case Architecture_arm64:
|
case Architecture_arm64:
|
||||||
case Architecture_arm32:
|
case Architecture_arm32:
|
||||||
case Architecture_COUNT:
|
|
||||||
{NotImplemented;}break;
|
{NotImplemented;}break;
|
||||||
case Architecture_x64:
|
case Architecture_x64:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#define BUILD_VERSION_MAJOR 0
|
#define BUILD_VERSION_MAJOR 0
|
||||||
#define BUILD_VERSION_MINOR 9
|
#define BUILD_VERSION_MINOR 9
|
||||||
#define BUILD_VERSION_PATCH 8
|
#define BUILD_VERSION_PATCH 9
|
||||||
#define BUILD_RELEASE_PHASE_STRING_LITERAL "ALPHA"
|
#define BUILD_RELEASE_PHASE_STRING_LITERAL "ALPHA"
|
||||||
#define BUILD_TITLE "The RAD Debugger"
|
#define BUILD_TITLE "The RAD Debugger"
|
||||||
#define OS_FEATURE_GRAPHICAL 1
|
#define OS_FEATURE_GRAPHICAL 1
|
||||||
|
|||||||
Reference in New Issue
Block a user