mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-13 07:32:23 -07:00
move module image info parse / cache management to ctrl thread, directly tie to module lifetime as ctrl thread sees it; reduce load from each unwind
This commit is contained in:
+274
-164
@@ -845,6 +845,15 @@ ctrl_init(void)
|
||||
ctrl_state->thread_reg_cache.stripes[idx].arena = arena_alloc();
|
||||
ctrl_state->thread_reg_cache.stripes[idx].rw_mutex = os_rw_mutex_alloc();
|
||||
}
|
||||
ctrl_state->module_image_info_cache.slots_count = 1024;
|
||||
ctrl_state->module_image_info_cache.slots = push_array(arena, CTRL_ModuleImageInfoCacheSlot, ctrl_state->module_image_info_cache.slots_count);
|
||||
ctrl_state->module_image_info_cache.stripes_count = os_logical_core_count();
|
||||
ctrl_state->module_image_info_cache.stripes = push_array(arena, CTRL_ModuleImageInfoCacheStripe, ctrl_state->module_image_info_cache.stripes_count);
|
||||
for(U64 idx = 0; idx < ctrl_state->module_image_info_cache.stripes_count; idx += 1)
|
||||
{
|
||||
ctrl_state->module_image_info_cache.stripes[idx].arena = arena_alloc();
|
||||
ctrl_state->module_image_info_cache.stripes[idx].rw_mutex = os_rw_mutex_alloc();
|
||||
}
|
||||
ctrl_state->u2c_ring_size = KB(64);
|
||||
ctrl_state->u2c_ring_base = push_array_no_zero(arena, U8, ctrl_state->u2c_ring_size);
|
||||
ctrl_state->u2c_ring_mutex = os_mutex_alloc();
|
||||
@@ -1453,6 +1462,78 @@ ctrl_thread_write_reg_block(CTRL_MachineID machine_id, DMN_Handle thread, void *
|
||||
return good;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Module Image Info Functions
|
||||
|
||||
//- rjf: cache lookups
|
||||
|
||||
internal PE_IntelPdata *
|
||||
ctrl_intel_pdata_from_module_voff(Arena *arena, CTRL_MachineID machine_id, DMN_Handle module_handle, U64 voff)
|
||||
{
|
||||
PE_IntelPdata *first_pdata = 0;
|
||||
{
|
||||
U64 hash = ctrl_hash_from_machine_id_handle(machine_id, module_handle);
|
||||
U64 slot_idx = hash%ctrl_state->module_image_info_cache.slots_count;
|
||||
U64 stripe_idx = slot_idx%ctrl_state->module_image_info_cache.stripes_count;
|
||||
CTRL_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx];
|
||||
CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_idx];
|
||||
OS_MutexScopeR(stripe->rw_mutex) for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(n->machine_id == machine_id && dmn_handle_match(n->module, module_handle))
|
||||
{
|
||||
PE_IntelPdata *pdatas = n->pdatas;
|
||||
U64 pdatas_count = n->pdatas_count;
|
||||
if(n->pdatas_count != 0 && voff >= n->pdatas[0].voff_first)
|
||||
{
|
||||
// NOTE(rjf):
|
||||
//
|
||||
// binary search:
|
||||
// find max index s.t. pdata_array[index].voff_first <= voff
|
||||
// we assume (i < j) -> (pdata_array[i].voff_first < pdata_array[j].voff_first)
|
||||
U64 index = pdatas_count;
|
||||
U64 min = 0;
|
||||
U64 opl = pdatas_count;
|
||||
for(;;)
|
||||
{
|
||||
U64 mid = (min + opl)/2;
|
||||
PE_IntelPdata *pdata = pdatas + mid;
|
||||
if(voff < pdata->voff_first)
|
||||
{
|
||||
opl = mid;
|
||||
}
|
||||
else if(pdata->voff_first < voff)
|
||||
{
|
||||
min = mid;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = mid;
|
||||
break;
|
||||
}
|
||||
if(min + 1 >= opl)
|
||||
{
|
||||
index = min;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: if we are in range fill result
|
||||
{
|
||||
PE_IntelPdata *pdata = pdatas + index;
|
||||
if(pdata->voff_first <= voff && voff < pdata->voff_one_past_last)
|
||||
{
|
||||
first_pdata = push_array(arena, PE_IntelPdata, 1);
|
||||
MemoryCopyStruct(first_pdata, pdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return first_pdata;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Unwinding Functions
|
||||
|
||||
@@ -1521,169 +1602,9 @@ ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN
|
||||
U64 rip_voff = regs->rip.u64 - module->vaddr_range.min;
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: unpack relevant PE info
|
||||
//- rjf: rip_voff -> first pdata
|
||||
//
|
||||
PE_IntelPdata *pdatas = 0;
|
||||
U64 pdatas_count = 0;
|
||||
ProfScope("unpack relevant PE info") if(module != &ctrl_entity_nil)
|
||||
{
|
||||
B32 is_valid = 1;
|
||||
|
||||
//- rjf: read DOS header
|
||||
PE_DosHeader dos_header = {0};
|
||||
if(is_valid)
|
||||
{
|
||||
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, module->vaddr_range.min, &is_stale, &dos_header, endt_us) ||
|
||||
is_stale ||
|
||||
dos_header.magic != PE_DOS_MAGIC)
|
||||
{
|
||||
is_valid = 0;
|
||||
is_good = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: read PE magic
|
||||
U32 pe_magic = 0;
|
||||
if(is_valid)
|
||||
{
|
||||
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, module->vaddr_range.min + dos_header.coff_file_offset, &is_stale, &pe_magic, endt_us) ||
|
||||
is_stale ||
|
||||
pe_magic != PE_MAGIC)
|
||||
{
|
||||
is_valid = 0;
|
||||
is_good = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: read COFF header
|
||||
U64 coff_header_off = dos_header.coff_file_offset + sizeof(pe_magic);
|
||||
COFF_Header coff_header = {0};
|
||||
if(is_valid)
|
||||
{
|
||||
if(!ctrl_read_cached_process_memory_struct(machine_id, process->handle, module->vaddr_range.min + coff_header_off, &is_stale, &coff_header, endt_us) ||
|
||||
is_stale)
|
||||
{
|
||||
is_valid = 0;
|
||||
is_good = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: unpack range of optional extension header
|
||||
U32 opt_ext_size = coff_header.optional_header_size;
|
||||
Rng1U64 opt_ext_off_range = r1u64(coff_header_off + sizeof(coff_header),
|
||||
coff_header_off + sizeof(coff_header) + opt_ext_size);
|
||||
|
||||
//- rjf: read optional header
|
||||
U16 optional_magic = 0;
|
||||
U64 image_base = 0;
|
||||
U64 entry_point = 0;
|
||||
U32 data_dir_count = 0;
|
||||
U64 virt_section_align = 0;
|
||||
U64 file_section_align = 0;
|
||||
Rng1U64 *data_dir_franges = 0;
|
||||
if(opt_ext_size > 0)
|
||||
{
|
||||
// rjf: read magic number
|
||||
U16 opt_ext_magic = 0;
|
||||
ctrl_read_cached_process_memory_struct(machine_id, process->handle, module->vaddr_range.min + opt_ext_off_range.min, &is_stale, &opt_ext_magic, endt_us);
|
||||
|
||||
// rjf: read info
|
||||
U32 reported_data_dir_offset = 0;
|
||||
U32 reported_data_dir_count = 0;
|
||||
switch(opt_ext_magic)
|
||||
{
|
||||
case PE_PE32_MAGIC:
|
||||
{
|
||||
PE_OptionalHeader32 pe_optional = {0};
|
||||
ctrl_read_cached_process_memory_struct(machine_id, process->handle, module->vaddr_range.min + opt_ext_off_range.min, &is_stale, &pe_optional, endt_us);
|
||||
image_base = pe_optional.image_base;
|
||||
entry_point = pe_optional.entry_point_va;
|
||||
virt_section_align = pe_optional.section_alignment;
|
||||
file_section_align = pe_optional.file_alignment;
|
||||
reported_data_dir_offset = sizeof(pe_optional);
|
||||
reported_data_dir_count = pe_optional.data_dir_count;
|
||||
}break;
|
||||
case PE_PE32PLUS_MAGIC:
|
||||
{
|
||||
PE_OptionalHeader32Plus pe_optional = {0};
|
||||
ctrl_read_cached_process_memory_struct(machine_id, process->handle, module->vaddr_range.min + opt_ext_off_range.min, &is_stale, &pe_optional, endt_us);
|
||||
image_base = pe_optional.image_base;
|
||||
entry_point = pe_optional.entry_point_va;
|
||||
virt_section_align = pe_optional.section_alignment;
|
||||
file_section_align = pe_optional.file_alignment;
|
||||
reported_data_dir_offset = sizeof(pe_optional);
|
||||
reported_data_dir_count = pe_optional.data_dir_count;
|
||||
}break;
|
||||
}
|
||||
|
||||
// rjf: find number of data directories
|
||||
U32 data_dir_max = (opt_ext_size - reported_data_dir_offset) / sizeof(PE_DataDirectory);
|
||||
data_dir_count = ClampTop(reported_data_dir_count, data_dir_max);
|
||||
|
||||
// rjf: grab pdatas from exceptions section
|
||||
if(data_dir_count > PE_DataDirectoryIndex_EXCEPTIONS)
|
||||
{
|
||||
PE_DataDirectory dir = {0};
|
||||
ctrl_read_cached_process_memory_struct(machine_id, process->handle, module->vaddr_range.min + opt_ext_off_range.min + reported_data_dir_offset + sizeof(PE_DataDirectory)*PE_DataDirectoryIndex_EXCEPTIONS, &is_stale, &dir, endt_us);
|
||||
Rng1U64 pdatas_voff_range = r1u64((U64)dir.virt_off, (U64)dir.virt_off + (U64)dir.virt_size);
|
||||
pdatas_count = dim_1u64(pdatas_voff_range)/sizeof(PE_IntelPdata);
|
||||
pdatas = push_array(scratch.arena, PE_IntelPdata, pdatas_count);
|
||||
ctrl_read_cached_process_memory(machine_id, process->handle, r1u64(module->vaddr_range.min + pdatas_voff_range.min, module->vaddr_range.min + pdatas_voff_range.max), &is_stale, pdatas, endt_us);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: find current rip's pdata entry
|
||||
//
|
||||
PE_IntelPdata *first_pdata = 0;
|
||||
if(pdatas_count != 0) ProfScope("find current RIP's pdata entry")
|
||||
{
|
||||
U64 first_pdata_voff = 0;
|
||||
if(rip_voff >= pdatas[0].voff_first)
|
||||
{
|
||||
// NOTE(rjf):
|
||||
//
|
||||
// binary search:
|
||||
// find max index s.t. pdata_array[index].voff_first <= voff
|
||||
// we assume (i < j) -> (pdata_array[i].voff_first < pdata_array[j].voff_first)
|
||||
U64 index = pdatas_count;
|
||||
U64 min = 0;
|
||||
U64 opl = pdatas_count;
|
||||
for(;;)
|
||||
{
|
||||
U64 mid = (min + opl)/2;
|
||||
PE_IntelPdata *pdata = pdatas + mid;
|
||||
if(rip_voff < pdata->voff_first)
|
||||
{
|
||||
opl = mid;
|
||||
}
|
||||
else if(pdata->voff_first < rip_voff)
|
||||
{
|
||||
min = mid;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = mid;
|
||||
break;
|
||||
}
|
||||
if(min + 1 >= opl)
|
||||
{
|
||||
index = min;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: if we are in range fill result
|
||||
{
|
||||
PE_IntelPdata *pdata = pdatas + index;
|
||||
if(pdata->voff_first <= rip_voff && rip_voff < pdata->voff_one_past_last)
|
||||
{
|
||||
first_pdata = pdata;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PE_IntelPdata *first_pdata = ctrl_intel_pdata_from_module_voff(scratch.arena, machine_id, module_handle, rip_voff);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: pdata -> detect if in epilog
|
||||
@@ -2955,6 +2876,195 @@ ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_MachineID
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: module lifetime open/close work
|
||||
|
||||
internal void
|
||||
ctrl_thread__module_open(CTRL_MachineID machine_id, DMN_Handle process, DMN_Handle module, Rng1U64 vaddr_range, String8 path)
|
||||
{
|
||||
//////////////////////////////
|
||||
//- rjf: open debug info
|
||||
//
|
||||
dbgi_binary_open(path);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: parse module image info
|
||||
//
|
||||
Arena *arena = arena_alloc();
|
||||
PE_IntelPdata *pdatas = 0;
|
||||
U64 pdatas_count = 0;
|
||||
ProfScope("unpack relevant PE info")
|
||||
{
|
||||
B32 is_valid = 1;
|
||||
|
||||
//- rjf: read DOS header
|
||||
PE_DosHeader dos_header = {0};
|
||||
if(is_valid)
|
||||
{
|
||||
if(!dmn_process_read_struct(process, vaddr_range.min, &dos_header) ||
|
||||
dos_header.magic != PE_DOS_MAGIC)
|
||||
{
|
||||
is_valid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: read PE magic
|
||||
U32 pe_magic = 0;
|
||||
if(is_valid)
|
||||
{
|
||||
if(!dmn_process_read_struct(process, vaddr_range.min + dos_header.coff_file_offset, &pe_magic) ||
|
||||
pe_magic != PE_MAGIC)
|
||||
{
|
||||
is_valid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: read COFF header
|
||||
U64 coff_header_off = dos_header.coff_file_offset + sizeof(pe_magic);
|
||||
COFF_Header coff_header = {0};
|
||||
if(is_valid)
|
||||
{
|
||||
if(!dmn_process_read_struct(process, vaddr_range.min + coff_header_off, &coff_header))
|
||||
{
|
||||
is_valid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: unpack range of optional extension header
|
||||
U32 opt_ext_size = coff_header.optional_header_size;
|
||||
Rng1U64 opt_ext_off_range = r1u64(coff_header_off + sizeof(coff_header),
|
||||
coff_header_off + sizeof(coff_header) + opt_ext_size);
|
||||
|
||||
//- rjf: read optional header
|
||||
U16 optional_magic = 0;
|
||||
U64 image_base = 0;
|
||||
U64 entry_point = 0;
|
||||
U32 data_dir_count = 0;
|
||||
U64 virt_section_align = 0;
|
||||
U64 file_section_align = 0;
|
||||
Rng1U64 *data_dir_franges = 0;
|
||||
if(opt_ext_size > 0)
|
||||
{
|
||||
// rjf: read magic number
|
||||
U16 opt_ext_magic = 0;
|
||||
dmn_process_read_struct(process, vaddr_range.min + opt_ext_off_range.min, &opt_ext_magic);
|
||||
|
||||
// rjf: read info
|
||||
U32 reported_data_dir_offset = 0;
|
||||
U32 reported_data_dir_count = 0;
|
||||
switch(opt_ext_magic)
|
||||
{
|
||||
case PE_PE32_MAGIC:
|
||||
{
|
||||
PE_OptionalHeader32 pe_optional = {0};
|
||||
dmn_process_read_struct(process, vaddr_range.min + opt_ext_off_range.min, &pe_optional);
|
||||
image_base = pe_optional.image_base;
|
||||
entry_point = pe_optional.entry_point_va;
|
||||
virt_section_align = pe_optional.section_alignment;
|
||||
file_section_align = pe_optional.file_alignment;
|
||||
reported_data_dir_offset = sizeof(pe_optional);
|
||||
reported_data_dir_count = pe_optional.data_dir_count;
|
||||
}break;
|
||||
case PE_PE32PLUS_MAGIC:
|
||||
{
|
||||
PE_OptionalHeader32Plus pe_optional = {0};
|
||||
dmn_process_read_struct(process, vaddr_range.min + opt_ext_off_range.min, &pe_optional);
|
||||
image_base = pe_optional.image_base;
|
||||
entry_point = pe_optional.entry_point_va;
|
||||
virt_section_align = pe_optional.section_alignment;
|
||||
file_section_align = pe_optional.file_alignment;
|
||||
reported_data_dir_offset = sizeof(pe_optional);
|
||||
reported_data_dir_count = pe_optional.data_dir_count;
|
||||
}break;
|
||||
}
|
||||
|
||||
// rjf: find number of data directories
|
||||
U32 data_dir_max = (opt_ext_size - reported_data_dir_offset) / sizeof(PE_DataDirectory);
|
||||
data_dir_count = ClampTop(reported_data_dir_count, data_dir_max);
|
||||
|
||||
// rjf: grab pdatas from exceptions section
|
||||
if(data_dir_count > PE_DataDirectoryIndex_EXCEPTIONS)
|
||||
{
|
||||
PE_DataDirectory dir = {0};
|
||||
dmn_process_read_struct(process, vaddr_range.min + opt_ext_off_range.min + reported_data_dir_offset + sizeof(PE_DataDirectory)*PE_DataDirectoryIndex_EXCEPTIONS, &dir);
|
||||
Rng1U64 pdatas_voff_range = r1u64((U64)dir.virt_off, (U64)dir.virt_off + (U64)dir.virt_size);
|
||||
pdatas_count = dim_1u64(pdatas_voff_range)/sizeof(PE_IntelPdata);
|
||||
pdatas = push_array(arena, PE_IntelPdata, pdatas_count);
|
||||
dmn_process_read(process, r1u64(vaddr_range.min + pdatas_voff_range.min, vaddr_range.min + pdatas_voff_range.max), pdatas);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: insert into cache
|
||||
//
|
||||
{
|
||||
U64 hash = ctrl_hash_from_machine_id_handle(machine_id, module);
|
||||
U64 slot_idx = hash%ctrl_state->module_image_info_cache.slots_count;
|
||||
U64 stripe_idx = slot_idx%ctrl_state->module_image_info_cache.stripes_count;
|
||||
CTRL_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx];
|
||||
CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_idx];
|
||||
OS_MutexScopeW(stripe->rw_mutex)
|
||||
{
|
||||
CTRL_ModuleImageInfoCacheNode *node = 0;
|
||||
for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(n->machine_id == machine_id && dmn_handle_match(n->module, module))
|
||||
{
|
||||
node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!node)
|
||||
{
|
||||
node = push_array(arena, CTRL_ModuleImageInfoCacheNode, 1);
|
||||
DLLPushBack(slot->first, slot->last, node);
|
||||
node->machine_id = machine_id;
|
||||
node->module = module;
|
||||
node->arena = arena;
|
||||
node->pdatas = pdatas;
|
||||
node->pdatas_count = pdatas_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
ctrl_thread__module_close(CTRL_MachineID machine_id, DMN_Handle module, String8 path)
|
||||
{
|
||||
//////////////////////////////
|
||||
//- rjf: evict module image info from cache
|
||||
//
|
||||
{
|
||||
U64 hash = ctrl_hash_from_machine_id_handle(machine_id, module);
|
||||
U64 slot_idx = hash%ctrl_state->module_image_info_cache.slots_count;
|
||||
U64 stripe_idx = slot_idx%ctrl_state->module_image_info_cache.stripes_count;
|
||||
CTRL_ModuleImageInfoCacheSlot *slot = &ctrl_state->module_image_info_cache.slots[slot_idx];
|
||||
CTRL_ModuleImageInfoCacheStripe *stripe = &ctrl_state->module_image_info_cache.stripes[stripe_idx];
|
||||
OS_MutexScopeW(stripe->rw_mutex)
|
||||
{
|
||||
CTRL_ModuleImageInfoCacheNode *node = 0;
|
||||
for(CTRL_ModuleImageInfoCacheNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(n->machine_id == machine_id && dmn_handle_match(n->module, module))
|
||||
{
|
||||
node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(node)
|
||||
{
|
||||
DLLRemove(slot->first, slot->last, node);
|
||||
arena_release(node->arena);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: close debug info
|
||||
//
|
||||
dbgi_binary_close(path);
|
||||
}
|
||||
|
||||
//- rjf: attached process running/event gathering
|
||||
|
||||
internal DMN_Event *
|
||||
@@ -3220,7 +3330,7 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg,
|
||||
{
|
||||
CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts);
|
||||
String8 module_path = event->string;
|
||||
dbgi_binary_open(module_path);
|
||||
ctrl_thread__module_open(CTRL_MachineID_Local, event->process, event->module, r1u64(event->address, event->address+event->size), module_path);
|
||||
out_evt->kind = CTRL_EventKind_NewModule;
|
||||
out_evt->msg_id = msg->msg_id;
|
||||
out_evt->machine_id = CTRL_MachineID_Local;
|
||||
@@ -3255,7 +3365,7 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg,
|
||||
{
|
||||
CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts);
|
||||
String8 module_path = event->string;
|
||||
dbgi_binary_close(module_path);
|
||||
ctrl_thread__module_close(CTRL_MachineID_Local, event->module, module_path);
|
||||
out_evt->kind = CTRL_EventKind_EndModule;
|
||||
out_evt->msg_id = msg->msg_id;
|
||||
out_evt->machine_id = CTRL_MachineID_Local;
|
||||
|
||||
@@ -497,6 +497,44 @@ struct CTRL_ThreadRegCache
|
||||
CTRL_ThreadRegCacheStripe *stripes;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Module Image Info Cache Types
|
||||
|
||||
typedef struct CTRL_ModuleImageInfoCacheNode CTRL_ModuleImageInfoCacheNode;
|
||||
struct CTRL_ModuleImageInfoCacheNode
|
||||
{
|
||||
CTRL_ModuleImageInfoCacheNode *next;
|
||||
CTRL_ModuleImageInfoCacheNode *prev;
|
||||
CTRL_MachineID machine_id;
|
||||
DMN_Handle module;
|
||||
Arena *arena;
|
||||
PE_IntelPdata *pdatas;
|
||||
U64 pdatas_count;
|
||||
};
|
||||
|
||||
typedef struct CTRL_ModuleImageInfoCacheSlot CTRL_ModuleImageInfoCacheSlot;
|
||||
struct CTRL_ModuleImageInfoCacheSlot
|
||||
{
|
||||
CTRL_ModuleImageInfoCacheNode *first;
|
||||
CTRL_ModuleImageInfoCacheNode *last;
|
||||
};
|
||||
|
||||
typedef struct CTRL_ModuleImageInfoCacheStripe CTRL_ModuleImageInfoCacheStripe;
|
||||
struct CTRL_ModuleImageInfoCacheStripe
|
||||
{
|
||||
Arena *arena;
|
||||
OS_Handle rw_mutex;
|
||||
};
|
||||
|
||||
typedef struct CTRL_ModuleImageInfoCache CTRL_ModuleImageInfoCache;
|
||||
struct CTRL_ModuleImageInfoCache
|
||||
{
|
||||
U64 slots_count;
|
||||
CTRL_ModuleImageInfoCacheSlot *slots;
|
||||
U64 stripes_count;
|
||||
CTRL_ModuleImageInfoCacheStripe *stripes;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Wakeup Hook Function Types
|
||||
|
||||
@@ -519,6 +557,7 @@ struct CTRL_State
|
||||
// rjf: caches
|
||||
CTRL_ProcessMemoryCache process_memory_cache;
|
||||
CTRL_ThreadRegCache thread_reg_cache;
|
||||
CTRL_ModuleImageInfoCache module_image_info_cache;
|
||||
|
||||
// rjf: user -> ctrl msg ring buffer
|
||||
U64 u2c_ring_size;
|
||||
@@ -694,6 +733,12 @@ internal U64 ctrl_query_cached_rip_from_thread(CTRL_EntityStore *store, CTRL_Mac
|
||||
//- rjf: thread register writing
|
||||
internal B32 ctrl_thread_write_reg_block(CTRL_MachineID machine_id, DMN_Handle thread, void *block);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Module Image Info Functions
|
||||
|
||||
//- rjf: cache lookups
|
||||
internal PE_IntelPdata *ctrl_intel_pdata_from_module_voff(Arena *arena, CTRL_MachineID machine_id, DMN_Handle module_handle, U64 voff);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Unwinding Functions
|
||||
|
||||
@@ -745,6 +790,10 @@ internal void ctrl_thread__entry_point(void *p);
|
||||
internal void ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_MachineID machine_id, DMN_Handle process, DMN_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out);
|
||||
internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_MachineID machine_id, DMN_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out);
|
||||
|
||||
//- rjf: module lifetime open/close work
|
||||
internal void ctrl_thread__module_open(CTRL_MachineID machine_id, DMN_Handle process, DMN_Handle module, Rng1U64 vaddr_range, String8 path);
|
||||
internal void ctrl_thread__module_close(CTRL_MachineID machine_id, DMN_Handle module, String8 path);
|
||||
|
||||
//- rjf: attached process running/event gathering
|
||||
internal DMN_Event *ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, DMN_RunCtrls *run_ctrls, CTRL_Spoof *spoof);
|
||||
|
||||
|
||||
@@ -6233,7 +6233,7 @@ df_query_cached_unwind_from_thread(DF_Entity *thread)
|
||||
//- rjf: no node? -> calculate unwind if needed - store if good & return
|
||||
if(node == 0)
|
||||
{
|
||||
CTRL_Unwind current_unwind = ctrl_unwind_from_thread(scratch.arena, df_state->ctrl_entity_store, thread->ctrl_machine_id, thread->ctrl_handle, 0);
|
||||
CTRL_Unwind current_unwind = ctrl_unwind_from_thread(scratch.arena, df_state->ctrl_entity_store, thread->ctrl_machine_id, thread->ctrl_handle, os_now_microseconds()+200);
|
||||
if(!(current_unwind.flags & (CTRL_UnwindFlag_Error|CTRL_UnwindFlag_Stale)))
|
||||
{
|
||||
Architecture arch = df_architecture_from_entity(thread);
|
||||
|
||||
+6
-7
@@ -10059,13 +10059,12 @@ df_entity_desc_button(DF_Window *ws, DF_Entity *entity, FuzzyMatchRangeList *nam
|
||||
ui_set_next_background_color(bg_color);
|
||||
}
|
||||
ui_set_next_hover_cursor(OS_Cursor_HandPoint);
|
||||
UI_Key key = ui_key_from_stringf(ui_top_parent()->key, "entity_ref_button_%p", entity);
|
||||
UI_Box *box = ui_build_box_from_key(UI_BoxFlag_Clickable|
|
||||
UI_BoxFlag_DrawBorder|
|
||||
UI_BoxFlag_DrawBackground|
|
||||
UI_BoxFlag_DrawHotEffects|
|
||||
UI_BoxFlag_DrawActiveEffects,
|
||||
key);
|
||||
UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable|
|
||||
UI_BoxFlag_DrawBorder|
|
||||
UI_BoxFlag_DrawBackground|
|
||||
UI_BoxFlag_DrawHotEffects|
|
||||
UI_BoxFlag_DrawActiveEffects,
|
||||
"entity_ref_button_%p", entity);
|
||||
|
||||
//- rjf: build contents
|
||||
UI_Parent(box) UI_PrefWidth(ui_text_dim(10, 0))
|
||||
|
||||
Reference in New Issue
Block a user