checkpoint in getting off of d_entities and onto ctrl_entities for frontend paths, including thread selection & df_regs

This commit is contained in:
Ryan Fleury
2024-09-12 16:30:26 -07:00
parent 3641c212b2
commit 71cb03f3be
16 changed files with 622 additions and 525 deletions
+13
View File
@@ -544,6 +544,18 @@ ctrl_entity_list_push(Arena *arena, CTRL_EntityList *list, CTRL_Entity *entity)
list->count += 1;
}
internal CTRL_EntityList
ctrl_entity_list_from_handle_list(Arena *arena, CTRL_EntityStore *store, CTRL_HandleList *list)
{
CTRL_EntityList result = {0};
for(CTRL_HandleNode *n = list->first; n != 0; n = n->next)
{
CTRL_Entity *entity = ctrl_entity_from_handle(store, n->v);
ctrl_entity_list_push(arena, &result, entity);
}
return result;
}
//- rjf: cache creation/destruction
internal CTRL_EntityStore *
@@ -1057,6 +1069,7 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list)
{
CTRL_Entity *process = ctrl_entity_from_handle(store, event->parent);
CTRL_Entity *thread = ctrl_entity_alloc(store, process, CTRL_EntityKind_Thread, event->arch, event->entity, (U64)event->entity_id);
thread->stack_base = event->stack_base;
ctrl_query_cached_rip_from_thread(store, event->entity);
}break;
case CTRL_EventKind_EndThread:
+6 -1
View File
@@ -44,6 +44,7 @@ typedef enum CTRL_EntityKind
{
CTRL_EntityKind_Null,
CTRL_EntityKind_Root,
CTRL_EntityKind_Machine,
CTRL_EntityKind_Process,
CTRL_EntityKind_Thread,
@@ -65,9 +66,11 @@ struct CTRL_Entity
CTRL_EntityKind kind;
Arch arch;
B32 is_frozen;
U32 rgba;
CTRL_Handle handle;
U64 id;
Rng1U64 vaddr_range;
U64 stack_base;
U64 timestamp;
String8 string;
};
@@ -265,7 +268,7 @@ struct CTRL_UserBreakpointList
typedef U64 CTRL_EvalSpaceKind;
enum
{
CTRL_EvalSpaceKind_Entity,
CTRL_EvalSpaceKind_Entity = E_SpaceKind_FirstUserDefined,
};
////////////////////////////////
@@ -728,6 +731,8 @@ internal CTRL_Event ctrl_event_from_serialized_string(Arena *arena, String8 stri
//- rjf: entity list data structures
internal void ctrl_entity_list_push(Arena *arena, CTRL_EntityList *list, CTRL_Entity *entity);
internal CTRL_EntityList ctrl_entity_list_from_handle_list(Arena *arena, CTRL_EntityStore *store, CTRL_HandleList *list);
#define ctrl_entity_list_first(list) ((list)->first ? (list)->first->v : &ctrl_entity_nil)
//- rjf: cache creation/destruction
internal CTRL_EntityStore *ctrl_entity_store_alloc(void);
+2
View File
@@ -276,6 +276,7 @@ D_CmdTable: // | | | |
COUNT,
}
/*
@enum D_CmdParamSlot:
{
Null,
@@ -293,6 +294,7 @@ D_CmdTable: // | | | |
`{0}`,
@expand(D_CmdParamSlotTable a) `{OffsetOf(D_CmdParams, $(a.name_lower)), OffsetOf(D_CmdParams, $(a.name_lower)) + sizeof($(a.c_type))}`,
}
*/
////////////////////////////////
//~ rjf: Built-In View Rules
+220 -113
View File
@@ -335,6 +335,29 @@ d_cmd_params_apply_spec_query(Arena *arena, D_CmdParams *params, D_CmdSpec *spec
}
#endif
//- rjf: command parameters
internal D_CmdParams
d_cmd_params_copy(Arena *arena, D_CmdParams *src)
{
D_CmdParams dst = {0};
MemoryCopyStruct(&dst, src);
dst.processes = ctrl_handle_list_copy(arena, &dst.processes);
dst.file_path = push_str8_copy(arena, dst.file_path);
dst.targets.v = push_array(arena, D_Target, dst.targets.count);
MemoryCopy(dst.targets.v, src->targets.v, sizeof(D_Target)*dst.targets.count);
for(U64 idx = 0; idx < dst.targets.count; idx += 1)
{
D_Target *target = &dst.targets.v[idx];
target->exe = push_str8_copy(arena, target->exe);
target->args = push_str8_copy(arena, target->args);
target->working_directory = push_str8_copy(arena, target->working_directory);
target->custom_entry_point_name = push_str8_copy(arena, target->custom_entry_point_name);
target->env = str8_list_copy(arena, &target->env);
}
return dst;
}
//- rjf: command lists
internal void
@@ -342,7 +365,7 @@ d_cmd_list_push_new(Arena *arena, D_CmdList *cmds, D_CmdKind kind, D_CmdParams *
{
D_CmdNode *n = push_array(arena, D_CmdNode, 1);
n->cmd.kind = kind;
n->cmd.params = df_cmd_params_copy(arena, params);
n->cmd.params = d_cmd_params_copy(arena, params);
DLLPushBack(cmds->first, cmds->last, n);
cmds->count += 1;
}
@@ -711,8 +734,9 @@ d_search_tags_from_entity(Arena *arena, D_Entity *entity)
if(entity->kind == D_EntityKind_Thread)
{
Temp scratch = scratch_begin(&arena, 1);
CTRL_Entity *entity_ctrl = ctrl_entity_from_handle(d_state->ctrl_entity_store, entity->ctrl_handle);
D_Entity *process = d_entity_ancestor_from_kind(entity, D_EntityKind_Process);
CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity);
CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity_ctrl);
String8List strings = {0};
for(U64 frame_num = unwind.frames.count; frame_num > 0; frame_num -= 1)
{
@@ -2102,14 +2126,14 @@ d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, B32 d
}
internal String8
d_symbol_name_from_process_vaddr(Arena *arena, D_Entity *process, U64 vaddr, B32 decorated)
d_symbol_name_from_process_vaddr(Arena *arena, CTRL_Entity *process, U64 vaddr, B32 decorated)
{
ProfBeginFunction();
String8 result = {0};
{
D_Entity *module = d_module_from_process_vaddr(process, vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
U64 voff = d_voff_from_vaddr(module, vaddr);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
U64 voff = ctrl_voff_from_vaddr(module, vaddr);
result = d_symbol_name_from_dbgi_key_voff(arena, &dbgi_key, voff, decorated);
}
ProfEnd();
@@ -2460,6 +2484,7 @@ d_module_from_process_vaddr(D_Entity *process, U64 vaddr)
return module;
}
#if 0 // TODO(rjf): @msgs
internal D_Entity *
d_module_from_thread(D_Entity *thread)
{
@@ -2467,9 +2492,10 @@ d_module_from_thread(D_Entity *thread)
U64 rip = d_query_cached_rip_from_thread(thread);
return d_module_from_process_vaddr(process, rip);
}
#endif
internal U64
d_tls_base_vaddr_from_process_root_rip(D_Entity *process, U64 root_vaddr, U64 rip_vaddr)
d_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64 rip_vaddr)
{
ProfBeginFunction();
U64 base_vaddr = 0;
@@ -2477,15 +2503,15 @@ d_tls_base_vaddr_from_process_root_rip(D_Entity *process, U64 root_vaddr, U64 ri
if(!d_ctrl_targets_running())
{
//- rjf: unpack module info
D_Entity *module = d_module_from_process_vaddr(process, rip_vaddr);
Rng1U64 tls_vaddr_range = ctrl_tls_vaddr_range_from_module(module->ctrl_handle);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
Rng1U64 tls_vaddr_range = ctrl_tls_vaddr_range_from_module(module->handle);
U64 addr_size = bit_size_from_arch(process->arch)/8;
//- rjf: read module's TLS index
U64 tls_index = 0;
if(addr_size != 0)
{
CTRL_ProcessMemorySlice tls_index_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->ctrl_handle, tls_vaddr_range, 0);
CTRL_ProcessMemorySlice tls_index_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->handle, tls_vaddr_range, 0);
if(tls_index_slice.data.size >= addr_size)
{
tls_index = *(U64 *)tls_index_slice.data.str;
@@ -2498,13 +2524,13 @@ d_tls_base_vaddr_from_process_root_rip(D_Entity *process, U64 root_vaddr, U64 ri
U64 thread_info_addr = root_vaddr;
U64 tls_addr_off = tls_index*addr_size;
U64 tls_addr_array = 0;
CTRL_ProcessMemorySlice tls_addr_array_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->ctrl_handle, r1u64(thread_info_addr, thread_info_addr+addr_size), 0);
CTRL_ProcessMemorySlice tls_addr_array_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->handle, r1u64(thread_info_addr, thread_info_addr+addr_size), 0);
String8 tls_addr_array_data = tls_addr_array_slice.data;
if(tls_addr_array_data.size >= 8)
{
MemoryCopy(&tls_addr_array, tls_addr_array_data.str, sizeof(U64));
}
CTRL_ProcessMemorySlice result_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->ctrl_handle, r1u64(tls_addr_array + tls_addr_off, tls_addr_array + tls_addr_off + addr_size), 0);
CTRL_ProcessMemorySlice result_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->handle, r1u64(tls_addr_array + tls_addr_off, tls_addr_array + tls_addr_off + addr_size), 0);
String8 result_data = result_slice.data;
if(result_data.size >= 8)
{
@@ -2573,6 +2599,7 @@ d_push_member_map_from_dbgi_key_voff(Arena *arena, DI_Scope *scope, DI_Key *dbgi
return result;
}
#if 0 // TODO(rjf): @msgs
internal D_Entity *
d_module_from_thread_candidates(D_Entity *thread, D_EntityList *candidates)
{
@@ -2594,11 +2621,12 @@ d_module_from_thread_candidates(D_Entity *thread, D_EntityList *candidates)
}
return module;
}
#endif
internal D_Unwind
d_unwind_from_ctrl_unwind(Arena *arena, DI_Scope *di_scope, D_Entity *process, CTRL_Unwind *base_unwind)
d_unwind_from_ctrl_unwind(Arena *arena, DI_Scope *di_scope, CTRL_Entity *process, CTRL_Unwind *base_unwind)
{
Arch arch = d_arch_from_entity(process);
Arch arch = process->arch;
D_Unwind result = {0};
result.frames.concrete_frame_count = base_unwind->frames.count;
result.frames.total_frame_count = result.frames.concrete_frame_count;
@@ -2608,9 +2636,9 @@ d_unwind_from_ctrl_unwind(Arena *arena, DI_Scope *di_scope, D_Entity *process, C
CTRL_UnwindFrame *src = &base_unwind->frames.v[idx];
D_UnwindFrame *dst = &result.frames.v[idx];
U64 rip_vaddr = regs_rip_from_arch_block(arch, src->regs);
D_Entity *module = d_module_from_process_vaddr(process, rip_vaddr);
U64 rip_voff = d_voff_from_vaddr(module, rip_vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, 0);
RDI_Scope *scope = rdi_scope_from_voff(rdi, rip_voff);
@@ -2650,6 +2678,24 @@ d_ctrl_last_stop_event(void)
////////////////////////////////
//~ rjf: Evaluation Context
//- rjf: ctrl entity <-> eval space
internal CTRL_Entity *
d_ctrl_entity_from_eval_space(E_Space space)
{
CTRL_Entity *entity = &ctrl_entity_nil;
// TODO(rjf): @msgs
return entity;
}
internal E_Space
d_eval_space_from_ctrl_entity(CTRL_Entity *entity)
{
E_Space space = {0};
// TODO(rjf): @msgs
return space;
}
//- rjf: entity <-> eval space
internal D_Entity *
@@ -2677,6 +2723,23 @@ internal B32
d_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range)
{
B32 result = 0;
switch(space.kind)
{
case E_SpaceKind_FileSystem:
{
}break;
case DF_EvalSpaceKind_CtrlEntity:
{
}break;
case DF_EvalSpaceKind_CfgEntity:
{
}break;
}
#if 0 // TODO(rjf): @msgs
D_Entity *entity = d_entity_from_eval_space(space);
switch(entity->kind)
{
@@ -2755,6 +2818,7 @@ d_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range)
scratch_end(scratch);
}break;
}
#endif
return result;
}
@@ -2762,6 +2826,7 @@ internal B32
d_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range)
{
B32 result = 0;
#if 0 // TODO(rjf): @msgs
D_Entity *entity = d_entity_from_eval_space(space);
switch(entity->kind)
{
@@ -2827,6 +2892,7 @@ d_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range)
}
}break;
}
#endif
return result;
}
@@ -2861,7 +2927,9 @@ d_key_from_eval_space_range(E_Space space, Rng1U64 range, B32 zero_terminated)
internal Rng1U64
d_whole_range_from_eval_space(E_Space space)
{
// TODO(rjf): @msgs
Rng1U64 result = r1u64(0, 0);
#if 0
D_Entity *entity = d_entity_from_eval_space(space);
switch(entity->kind)
{
@@ -2889,6 +2957,7 @@ d_whole_range_from_eval_space(E_Space space)
result = r1u64(0, 0x7FFFFFFFFFFFull);
}break;
}
#endif
return result;
}
@@ -3519,7 +3588,7 @@ d_entity_from_ev_key_and_kind(EV_Key key, D_EntityKind kind)
//- rjf: per-run caches
internal CTRL_Unwind
d_query_cached_unwind_from_thread(D_Entity *thread)
d_query_cached_unwind_from_thread(CTRL_Entity *thread)
{
Temp scratch = scratch_begin(0, 0);
CTRL_Unwind result = {0};
@@ -3528,14 +3597,14 @@ d_query_cached_unwind_from_thread(D_Entity *thread)
U64 reg_gen = ctrl_reg_gen();
U64 mem_gen = ctrl_mem_gen();
D_UnwindCache *cache = &d_state->unwind_cache;
D_Handle handle = d_handle_from_entity(thread);
CTRL_Handle handle = thread->handle;
U64 hash = d_hash_from_string(str8_struct(&handle));
U64 slot_idx = hash%cache->slots_count;
D_UnwindCacheSlot *slot = &cache->slots[slot_idx];
D_UnwindCacheNode *node = 0;
for(D_UnwindCacheNode *n = slot->first; n != 0; n = n->next)
{
if(d_handle_match(handle, n->thread))
if(ctrl_handle_match(handle, n->thread))
{
node = n;
break;
@@ -3560,7 +3629,7 @@ d_query_cached_unwind_from_thread(D_Entity *thread)
if(node->reggen != reg_gen ||
node->memgen != mem_gen)
{
CTRL_Unwind new_unwind = ctrl_unwind_from_thread(scratch.arena, d_state->ctrl_entity_store, thread->ctrl_handle, os_now_microseconds()+100);
CTRL_Unwind new_unwind = ctrl_unwind_from_thread(scratch.arena, d_state->ctrl_entity_store, thread->handle, os_now_microseconds()+100);
if(!(new_unwind.flags & (CTRL_UnwindFlag_Error|CTRL_UnwindFlag_Stale)) && new_unwind.frames.count != 0)
{
node->unwind = ctrl_unwind_deep_copy(node->arena, thread->arch, &new_unwind);
@@ -3575,19 +3644,19 @@ d_query_cached_unwind_from_thread(D_Entity *thread)
}
internal U64
d_query_cached_rip_from_thread(D_Entity *thread)
d_query_cached_rip_from_thread(CTRL_Entity *thread)
{
U64 result = d_query_cached_rip_from_thread_unwind(thread, 0);
return result;
}
internal U64
d_query_cached_rip_from_thread_unwind(D_Entity *thread, U64 unwind_count)
d_query_cached_rip_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count)
{
U64 result = 0;
if(unwind_count == 0)
{
result = ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->ctrl_handle);
result = ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle);
}
else
{
@@ -3601,7 +3670,7 @@ d_query_cached_rip_from_thread_unwind(D_Entity *thread, U64 unwind_count)
}
internal U64
d_query_cached_tls_base_vaddr_from_process_root_rip(D_Entity *process, U64 root_vaddr, U64 rip_vaddr)
d_query_cached_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64 rip_vaddr)
{
U64 result = 0;
for(U64 cache_idx = 0; cache_idx < ArrayCount(d_state->tls_base_caches); cache_idx += 1)
@@ -3616,14 +3685,14 @@ d_query_cached_tls_base_vaddr_from_process_root_rip(D_Entity *process, U64 root_
{
break;
}
D_Handle handle = d_handle_from_entity(process);
CTRL_Handle handle = process->handle;
U64 hash = d_hash_from_seed_string(d_hash_from_string(str8_struct(&handle)), str8_struct(&rip_vaddr));
U64 slot_idx = hash%cache->slots_count;
D_RunTLSBaseCacheSlot *slot = &cache->slots[slot_idx];
D_RunTLSBaseCacheNode *node = 0;
for(D_RunTLSBaseCacheNode *n = slot->first; n != 0; n = n->hash_next)
{
if(d_handle_match(n->process, handle) && n->root_vaddr == root_vaddr && n->rip_vaddr == rip_vaddr)
if(ctrl_handle_match(n->process, handle) && n->root_vaddr == root_vaddr && n->rip_vaddr == rip_vaddr)
{
node = n;
break;
@@ -4371,7 +4440,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints)
for(D_UnwindCacheNode *n = slot->first, *next = 0; n != 0; n = next)
{
next = n->next;
if(d_entity_is_nil(d_entity_from_handle(n->thread)))
if(ctrl_entity_from_handle(d_state->ctrl_entity_store, n->thread) == &ctrl_entity_nil)
{
DLLRemove(slot->first, slot->last, n);
arena_release(n->arena);
@@ -4433,7 +4502,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints)
for(D_Cmd *cmd = 0; d_next_cmd(&cmd);)
{
// rjf: unpack command
D_CmdParams params = cmd->params;
D_CmdParams *params = &cmd->params;
// rjf: prep ctrl running arguments
B32 need_run = 0;
@@ -4452,17 +4521,79 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints)
case D_CmdKind_LaunchAndInit:
{
// rjf: get list of targets to launch
D_EntityList targets = d_entity_list_from_handle_list(scratch.arena, params.entity_list);
D_TargetArray *targets_to_launch = &params->targets;
// rjf: no targets => assume all active targets
if(targets.count == 0)
if(targets_to_launch->count == 0)
{
targets = d_push_active_target_list(scratch.arena);
targets_to_launch = targets;
}
// rjf: launch
if(targets.count != 0)
if(targets_to_launch->count != 0)
{
for(U64 idx = 0; idx < targets_to_launch->count; idx += 1)
{
// rjf: unpack target
D_Target *target = &targets_to_launch->v[idx];
String8 exe = str8_skip_chop_whitespace(target->exe);
String8 args = str8_skip_chop_whitespace(target->args);
String8 working_directory = str8_skip_chop_whitespace(target->working_directory);
String8 custom_entry_point_name = str8_skip_chop_whitespace(target->custom_entry_point_name);
String8List env = target->env;
if(working_directory.size == 0)
{
working_directory = os_get_current_path(scratch.arena);
}
// rjf: build launch options
String8List cmdln_strings = {0};
{
str8_list_push(scratch.arena, &cmdln_strings, exe);
{
U64 start_split_idx = 0;
B32 quoted = 0;
for(U64 idx = 0; idx <= args.size; idx += 1)
{
U8 byte = idx < args.size ? args.str[idx] : 0;
if(byte == '"')
{
quoted ^= 1;
}
B32 splitter_found = (!quoted && (byte == 0 || char_is_space(byte)));
if(splitter_found)
{
String8 string = str8_substr(args, r1u64(start_split_idx, idx));
if(string.size > 0)
{
str8_list_push(scratch.arena, &cmdln_strings, string);
}
start_split_idx = idx+1;
}
}
}
}
// rjf: push message to launch
{
CTRL_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = CTRL_MsgKind_Launch;
msg->path = working_directory;
msg->cmd_line_string_list = cmdln_strings;
msg->env_inherit = 1;
MemoryCopyArray(msg->exception_code_filters, d_state->ctrl_exception_code_filters);
str8_list_push(scratch.arena, &msg->entry_points, custom_entry_point_name);
msg->env_string_list = env;
}
}
// rjf: run
need_run = 1;
run_kind = D_RunKind_Run;
run_thread = &ctrl_entity_nil;
run_flags = (cmd->kind == D_CmdKind_LaunchAndInit) ? CTRL_RunFlag_StopOnEntryPoint : 0;
#if 0 // TODO(rjf): @msgs
for(D_EntityNode *n = targets.first; n != 0; n = n->next)
{
// rjf: extract data from target
@@ -4519,40 +4650,35 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints)
str8_list_push(scratch.arena, &msg->entry_points, entry);
}
}
// rjf: run
need_run = 1;
run_kind = D_RunKind_Run;
run_thread = &ctrl_entity_nil;
run_flags = (cmd->kind == D_CmdKind_LaunchAndInit) ? CTRL_RunFlag_StopOnEntryPoint : 0;
#endif
}
// rjf: no targets -> error
if(targets.count == 0)
if(targets_to_launch->count == 0)
{
log_user_error(str8_lit("No active targets exist; cannot launch."));
}
}break;
case D_CmdKind_Kill:
{
D_EntityList processes = d_entity_list_from_handle_list(scratch.arena, params.entity_list);
CTRL_EntityList processes = ctrl_entity_list_from_handle_list(scratch.arena, d_state->ctrl_entity_store, &params->processes);
// rjf: no processes => kill everything
if(processes.count == 0)
{
processes = d_query_cached_entity_list_with_kind(D_EntityKind_Process);
processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process);
}
// rjf: kill processes
if(processes.count != 0)
{
for(D_EntityNode *n = processes.first; n != 0; n = n->next)
for(CTRL_EntityNode *n = processes.first; n != 0; n = n->next)
{
D_Entity *process = n->entity;
CTRL_Entity *process = n->v;
CTRL_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = CTRL_MsgKind_Kill;
msg->exit_code = 1;
msg->entity = process->ctrl_handle;
msg->entity = process->handle;
MemoryCopyArray(msg->exception_code_filters, d_state->ctrl_exception_code_filters);
}
}
@@ -4565,36 +4691,21 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints)
}break;
case D_CmdKind_KillAll:
{
D_EntityList processes = d_query_cached_entity_list_with_kind(D_EntityKind_Process);
if(processes.count != 0)
{
for(D_EntityNode *n = processes.first; n != 0; n = n->next)
{
D_Entity *process = n->entity;
CTRL_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = CTRL_MsgKind_Kill;
msg->exit_code = 1;
msg->entity = process->ctrl_handle;
MemoryCopyArray(msg->exception_code_filters, d_state->ctrl_exception_code_filters);
}
}
if(processes.count == 0)
{
log_user_error(str8_lit("No attached running processes exist; cannot kill."));
}
d_cmd(D_CmdKind_Kill);
}break;
case D_CmdKind_Detach:
{
for(D_HandleNode *n = params.entity_list.first; n != 0; n = n->next)
CTRL_EntityList processes = ctrl_entity_list_from_handle_list(scratch.arena, d_state->ctrl_entity_store, &params->processes);
if(processes.count == 0)
{
D_Entity *entity = d_entity_from_handle(n->handle);
if(entity->kind == D_EntityKind_Process)
{
CTRL_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = CTRL_MsgKind_Detach;
msg->entity = entity->ctrl_handle;
MemoryCopyArray(msg->exception_code_filters, d_state->ctrl_exception_code_filters);
}
log_user_error(str8_lit("Cannot detach; no process specified."));
}
else for(CTRL_EntityNode *n = processes.first; n != 0; n = n->next)
{
CTRL_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = CTRL_MsgKind_Detach;
msg->entity = n->v->handle;
MemoryCopyArray(msg->exception_code_filters, d_state->ctrl_exception_code_filters);
}
}break;
case D_CmdKind_Continue:
@@ -4626,8 +4737,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints)
case D_CmdKind_StepOverLine:
case D_CmdKind_StepOut:
{
D_Entity *d_thread = d_entity_from_handle(params.entity);
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, d_thread->ctrl_handle);
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->thread);
if(d_ctrl_targets_running())
{
if(d_ctrl_last_run_kind() == D_RunKind_Run)
@@ -4703,31 +4813,28 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints)
}break;
case D_CmdKind_SetThreadIP:
{
D_Entity *thread = d_entity_from_handle(params.entity);
U64 vaddr = params.vaddr;
if(thread->kind == D_EntityKind_Thread && vaddr != 0)
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->thread);
U64 vaddr = params->vaddr;
void *block = ctrl_query_cached_reg_block_from_thread(scratch.arena, d_state->ctrl_entity_store, thread->handle);
regs_arch_block_write_rip(thread->arch, block, vaddr);
B32 result = ctrl_thread_write_reg_block(thread->handle, block);
// rjf: early mutation of unwind cache for immediate frontend effect
if(result)
{
void *block = ctrl_query_cached_reg_block_from_thread(scratch.arena, d_state->ctrl_entity_store, thread->ctrl_handle);
regs_arch_block_write_rip(thread->arch, block, vaddr);
B32 result = ctrl_thread_write_reg_block(thread->ctrl_handle, block);
// rjf: early mutation of unwind cache for immediate frontend effect
if(result)
D_UnwindCache *cache = &d_state->unwind_cache;
if(cache->slots_count != 0)
{
D_UnwindCache *cache = &d_state->unwind_cache;
if(cache->slots_count != 0)
CTRL_Handle thread_handle = thread->handle;
U64 hash = d_hash_from_string(str8_struct(&thread_handle));
U64 slot_idx = hash%cache->slots_count;
D_UnwindCacheSlot *slot = &cache->slots[slot_idx];
for(D_UnwindCacheNode *n = slot->first; n != 0; n = n->next)
{
D_Handle thread_handle = d_handle_from_entity(thread);
U64 hash = d_hash_from_string(str8_struct(&thread_handle));
U64 slot_idx = hash%cache->slots_count;
D_UnwindCacheSlot *slot = &cache->slots[slot_idx];
for(D_UnwindCacheNode *n = slot->first; n != 0; n = n->next)
if(ctrl_handle_match(n->thread, thread_handle) && n->unwind.frames.count != 0)
{
if(d_handle_match(n->thread, thread_handle) && n->unwind.frames.count != 0)
{
regs_arch_block_write_rip(thread->arch, n->unwind.frames.v[0].regs, vaddr);
break;
}
regs_arch_block_write_rip(thread->arch, n->unwind.frames.v[0].regs, vaddr);
break;
}
}
}
@@ -4737,8 +4844,8 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints)
//- rjf: high-level composite target control operations
case D_CmdKind_RunToLine:
{
String8 file_path = params.file_path;
TxtPt point = params.text_point;
String8 file_path = params->file_path;
TxtPt point = params->cursor;
D_Entity *bp = d_entity_alloc(d_entity_root(), D_EntityKind_Breakpoint);
d_entity_equip_cfg_src(bp, D_CfgSrc_Transient);
bp->flags |= D_EntityFlag_DiesOnRunStop;
@@ -4753,7 +4860,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints)
d_entity_equip_cfg_src(bp, D_CfgSrc_Transient);
bp->flags |= D_EntityFlag_DiesOnRunStop;
D_Entity *loc = d_entity_alloc(bp, D_EntityKind_Location);
d_entity_equip_vaddr(loc, params.vaddr);
d_entity_equip_vaddr(loc, params->vaddr);
d_cmd(D_CmdKind_Run);
}break;
case D_CmdKind_Run:
@@ -4773,6 +4880,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints)
// rjf: kill all
d_cmd(D_CmdKind_KillAll);
#if 0 // TODO(rjf): @msgs
// rjf: gather targets corresponding to all launched processes
D_EntityList targets = {0};
{
@@ -4790,6 +4898,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints)
// rjf: re-launch targets
d_cmd(D_CmdKind_LaunchAndRun, .entity_list = d_handle_list_from_entity_list(scratch.arena, targets));
#endif
}break;
case D_CmdKind_StepInto:
case D_CmdKind_StepOver:
@@ -4800,19 +4909,18 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints)
D_CmdKind step_cmd_kind = (cmd->kind == D_CmdKind_StepInto
? D_CmdKind_StepIntoLine
: D_CmdKind_StepOverLine);
B32 prefer_dasm = params.prefer_dasm;
if(prefer_dasm)
B32 prefer_disasm = params->prefer_disasm;
if(prefer_disasm)
{
step_cmd_kind = (cmd->kind == D_CmdKind_StepInto
? D_CmdKind_StepIntoInst
: D_CmdKind_StepOverInst);
}
d_cmd(step_cmd_kind, .entity = params.entity);
d_cmd(step_cmd_kind, .thread = params->thread);
}
else if(!d_ctrl_targets_running())
{
D_EntityList targets = d_push_active_target_list(scratch.arena);
d_cmd(D_CmdKind_LaunchAndInit, .entity_list = d_handle_list_from_entity_list(scratch.arena, targets));
d_cmd(D_CmdKind_LaunchAndInit, .targets = *targets);
}
}break;
@@ -4829,32 +4937,31 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints)
cmd->kind == D_CmdKind_FreezeMachine)
? D_CmdKind_FreezeEntity
: D_CmdKind_ThawEntity);
d_push_cmd(disptch_kind, &params);
d_push_cmd(disptch_kind, params);
}break;
case D_CmdKind_FreezeLocalMachine:
{
CTRL_MachineID machine_id = CTRL_MachineID_Local;
d_cmd(D_CmdKind_FreezeMachine, .entity = d_handle_from_entity(d_machine_entity_from_machine_id(machine_id)));
d_cmd(D_CmdKind_FreezeMachine, .machine = ctrl_handle_make(machine_id, dmn_handle_zero()));
}break;
case D_CmdKind_ThawLocalMachine:
{
CTRL_MachineID machine_id = CTRL_MachineID_Local;
d_cmd(D_CmdKind_ThawMachine, .entity = d_handle_from_entity(d_machine_entity_from_machine_id(machine_id)));
d_cmd(D_CmdKind_ThawMachine, .machine = ctrl_handle_make(machine_id, dmn_handle_zero()));
}break;
case D_CmdKind_FreezeEntity:
case D_CmdKind_ThawEntity:
{
B32 should_freeze = (cmd->kind == D_CmdKind_FreezeEntity);
D_Entity *root = d_entity_from_handle(params.entity);
for(D_Entity *e = root; !d_entity_is_nil(e); e = d_entity_rec_depth_first_pre(e, root).next)
CTRL_Entity *root = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->entity);
for(CTRL_Entity *e = root; e != &ctrl_entity_nil; e = ctrl_entity_rec_depth_first_pre(e, root).next)
{
if(e->kind == D_EntityKind_Thread)
if(e->kind == CTRL_EntityKind_Thread)
{
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, e->ctrl_handle);
thread->is_frozen = should_freeze;
e->is_frozen = should_freeze;
CTRL_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = (should_freeze ? CTRL_MsgKind_FreezeThread : CTRL_MsgKind_ThawThread);
msg->entity = thread->handle;
msg->entity = e->handle;
}
}
}break;
@@ -4862,12 +4969,12 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints)
//- rjf: attaching
case D_CmdKind_Attach:
{
U64 pid = params.id;
U32 pid = params->pid;
if(pid != 0)
{
CTRL_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = CTRL_MsgKind_Attach;
msg->entity_id = (U32)pid;
msg->entity_id = pid;
MemoryCopyArray(msg->exception_code_filters, d_state->ctrl_exception_code_filters);
}
}break;
+48 -17
View File
@@ -539,6 +539,33 @@ struct D_CmdSpecInfoArray
////////////////////////////////
//~ rjf: Command Types
typedef struct D_CmdParams D_CmdParams;
struct D_CmdParams
{
CTRL_Handle machine;
CTRL_Handle thread;
CTRL_Handle entity;
CTRL_HandleList processes;
String8 file_path;
TxtPt cursor;
U64 vaddr;
B32 prefer_disasm;
U32 pid;
D_TargetArray targets;
//String8 string;
//String8 file_path;
//MD_Node * params_tree;
//U64 vaddr;
//U64 voff;
//U64 index;
//U64 id;
//B32 prefer_dasm;
//B32 force_confirm;
//Dir2 dir2;
//U64 unwind_index;
//U64 inline_depth;
};
typedef struct D_Cmd D_Cmd;
struct D_Cmd
{
@@ -585,7 +612,7 @@ struct D_UnwindCacheNode
U64 reggen;
U64 memgen;
Arena *arena;
D_Handle thread;
CTRL_Handle thread;
CTRL_Unwind unwind;
};
@@ -610,7 +637,7 @@ typedef struct D_RunTLSBaseCacheNode D_RunTLSBaseCacheNode;
struct D_RunTLSBaseCacheNode
{
D_RunTLSBaseCacheNode *hash_next;
D_Handle process;
CTRL_Handle process;
U64 root_vaddr;
U64 rip_vaddr;
U64 tls_base_vaddr;
@@ -808,6 +835,9 @@ internal D_CmdParams d_cmd_params_zero(void);
internal String8 d_cmd_params_apply_spec_query(Arena *arena, D_CmdParams *params, D_CmdSpec *spec, String8 query);
#endif
//- rjf: command parameters
internal D_CmdParams d_cmd_params_copy(Arena *arena, D_CmdParams *src);
//- rjf: command lists
internal void d_cmd_list_push_new(Arena *arena, D_CmdList *cmds, D_CmdKind kind, D_CmdParams *params);
@@ -958,7 +988,7 @@ internal Rng1U64 d_vaddr_range_from_voff_range(D_Entity *module, Rng1U64 voff_rn
//- rjf: voff|vaddr -> symbol lookups
internal String8 d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, B32 decorated);
internal String8 d_symbol_name_from_process_vaddr(Arena *arena, D_Entity *process, U64 vaddr, B32 decorated);
internal String8 d_symbol_name_from_process_vaddr(Arena *arena, CTRL_Entity *process, U64 vaddr, B32 decorated);
//- rjf: symbol -> voff lookups
internal U64 d_voff_from_dbgi_key_symbol_name(DI_Key *dbgi_key, String8 symbol_name);
@@ -975,13 +1005,17 @@ internal D_LineList d_lines_from_file_path_line_num(Arena *arena, String8 file_p
//~ rjf: Process/Thread/Module Info Lookups
internal D_Entity *d_module_from_process_vaddr(D_Entity *process, U64 vaddr);
#if 0 // TODO(rjf): @msgs
internal D_Entity *d_module_from_thread(D_Entity *thread);
internal U64 d_tls_base_vaddr_from_process_root_rip(D_Entity *process, U64 root_vaddr, U64 rip_vaddr);
#endif
internal U64 d_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64 rip_vaddr);
internal Arch d_arch_from_entity(D_Entity *entity);
internal E_String2NumMap *d_push_locals_map_from_dbgi_key_voff(Arena *arena, DI_Scope *scope, DI_Key *dbgi_key, U64 voff);
internal E_String2NumMap *d_push_member_map_from_dbgi_key_voff(Arena *arena, DI_Scope *scope, DI_Key *dbgi_key, U64 voff);
#if 0 // TODO(rjf): @msgs
internal D_Entity *d_module_from_thread_candidates(D_Entity *thread, D_EntityList *candidates);
internal D_Unwind d_unwind_from_ctrl_unwind(Arena *arena, DI_Scope *di_scope, D_Entity *process, CTRL_Unwind *base_unwind);
#endif
internal D_Unwind d_unwind_from_ctrl_unwind(Arena *arena, DI_Scope *di_scope, CTRL_Entity *process, CTRL_Unwind *base_unwind);
////////////////////////////////
//~ rjf: Target Controls
@@ -992,6 +1026,10 @@ internal CTRL_Event d_ctrl_last_stop_event(void);
////////////////////////////////
//~ rjf: Evaluation Spaces
//- rjf: ctrl entity <-> eval space
internal CTRL_Entity *d_ctrl_entity_from_eval_space(E_Space space);
internal E_Space d_eval_space_from_ctrl_entity(CTRL_Entity *entity);
//- rjf: entity <-> eval space
internal D_Entity *d_entity_from_eval_space(E_Space space);
internal E_Space d_eval_space_from_entity(D_Entity *entity);
@@ -1064,23 +1102,16 @@ internal D_EntityList d_push_active_target_list(Arena *arena);
internal D_Entity *d_entity_from_ev_key_and_kind(EV_Key key, D_EntityKind kind);
//- rjf: per-run caches
internal CTRL_Unwind d_query_cached_unwind_from_thread(D_Entity *thread);
internal U64 d_query_cached_rip_from_thread(D_Entity *thread);
internal U64 d_query_cached_rip_from_thread_unwind(D_Entity *thread, U64 unwind_count);
internal U64 d_query_cached_tls_base_vaddr_from_process_root_rip(D_Entity *process, U64 root_vaddr, U64 rip_vaddr);
internal CTRL_Unwind d_query_cached_unwind_from_thread(CTRL_Entity *thread);
internal U64 d_query_cached_rip_from_thread(CTRL_Entity *thread);
internal U64 d_query_cached_rip_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count);
internal U64 d_query_cached_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64 rip_vaddr);
internal E_String2NumMap *d_query_cached_locals_map_from_dbgi_key_voff(DI_Key *dbgi_key, U64 voff);
internal E_String2NumMap *d_query_cached_member_map_from_dbgi_key_voff(DI_Key *dbgi_key, U64 voff);
//- rjf: top-level command dispatch
internal void d_push_cmd(D_CmdKind kind, D_CmdParams *params);
#define d_cmd(kind, ...) d_push_cmd((kind), \
&(D_CmdParams) \
{ \
.window = d_regs()->window, \
.panel = d_regs()->panel, \
.view = d_regs()->view, \
__VA_ARGS__ \
})
#define d_cmd(kind, ...) d_push_cmd((kind), &(D_CmdParams){.thread = {0}, __VA_ARGS__})
//- rjf: command iteration
internal B32 d_next_cmd(D_Cmd **cmd);
@@ -215,32 +215,6 @@ Rng1U64 d_reg_slot_range_table[29] =
{OffsetOf(D_Regs, params_tree), OffsetOf(D_Regs, params_tree) + sizeof(MD_Node *)},
};
Rng1U64 d_cmd_param_slot_range_table[22] =
{
{0},
{OffsetOf(D_CmdParams, window), OffsetOf(D_CmdParams, window) + sizeof(D_Handle)},
{OffsetOf(D_CmdParams, panel), OffsetOf(D_CmdParams, panel) + sizeof(D_Handle)},
{OffsetOf(D_CmdParams, dest_panel), OffsetOf(D_CmdParams, dest_panel) + sizeof(D_Handle)},
{OffsetOf(D_CmdParams, prev_view), OffsetOf(D_CmdParams, prev_view) + sizeof(D_Handle)},
{OffsetOf(D_CmdParams, view), OffsetOf(D_CmdParams, view) + sizeof(D_Handle)},
{OffsetOf(D_CmdParams, entity), OffsetOf(D_CmdParams, entity) + sizeof(D_Handle)},
{OffsetOf(D_CmdParams, entity_list), OffsetOf(D_CmdParams, entity_list) + sizeof(D_HandleList)},
{OffsetOf(D_CmdParams, string), OffsetOf(D_CmdParams, string) + sizeof(String8)},
{OffsetOf(D_CmdParams, file_path), OffsetOf(D_CmdParams, file_path) + sizeof(String8)},
{OffsetOf(D_CmdParams, text_point), OffsetOf(D_CmdParams, text_point) + sizeof(TxtPt)},
{OffsetOf(D_CmdParams, params_tree), OffsetOf(D_CmdParams, params_tree) + sizeof(MD_Node *)},
{OffsetOf(D_CmdParams, os_event), OffsetOf(D_CmdParams, os_event) + sizeof(struct OS_Event *)},
{OffsetOf(D_CmdParams, vaddr), OffsetOf(D_CmdParams, vaddr) + sizeof(U64)},
{OffsetOf(D_CmdParams, voff), OffsetOf(D_CmdParams, voff) + sizeof(U64)},
{OffsetOf(D_CmdParams, index), OffsetOf(D_CmdParams, index) + sizeof(U64)},
{OffsetOf(D_CmdParams, id), OffsetOf(D_CmdParams, id) + sizeof(U64)},
{OffsetOf(D_CmdParams, prefer_dasm), OffsetOf(D_CmdParams, prefer_dasm) + sizeof(B32)},
{OffsetOf(D_CmdParams, force_confirm), OffsetOf(D_CmdParams, force_confirm) + sizeof(B32)},
{OffsetOf(D_CmdParams, dir2), OffsetOf(D_CmdParams, dir2) + sizeof(Dir2)},
{OffsetOf(D_CmdParams, unwind_index), OffsetOf(D_CmdParams, unwind_index) + sizeof(U64)},
{OffsetOf(D_CmdParams, inline_depth), OffsetOf(D_CmdParams, inline_depth) + sizeof(U64)},
};
D_ViewRuleSpecInfo d_core_view_rule_spec_info_table[21] =
{
{str8_lit_comp("default"), str8_lit_comp("Default"), str8_lit_comp(""), str8_lit_comp(""), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), },
@@ -121,33 +121,6 @@ D_CmdKind_Attach,
D_CmdKind_COUNT,
} D_CmdKind;
typedef enum D_CmdParamSlot
{
D_CmdParamSlot_Null,
D_CmdParamSlot_Window,
D_CmdParamSlot_Panel,
D_CmdParamSlot_DestPanel,
D_CmdParamSlot_PrevView,
D_CmdParamSlot_View,
D_CmdParamSlot_Entity,
D_CmdParamSlot_EntityList,
D_CmdParamSlot_String,
D_CmdParamSlot_FilePath,
D_CmdParamSlot_TextPoint,
D_CmdParamSlot_ParamsTree,
D_CmdParamSlot_OSEvent,
D_CmdParamSlot_VirtualAddr,
D_CmdParamSlot_VirtualOff,
D_CmdParamSlot_Index,
D_CmdParamSlot_ID,
D_CmdParamSlot_PreferDisassembly,
D_CmdParamSlot_ForceConfirm,
D_CmdParamSlot_Dir2,
D_CmdParamSlot_UnwindIndex,
D_CmdParamSlot_InlineDepth,
D_CmdParamSlot_COUNT,
} D_CmdParamSlot;
typedef enum D_ViewRuleKind
{
D_ViewRuleKind_Default,
@@ -207,32 +180,6 @@ String8 string;
MD_Node * params_tree;
};
typedef struct D_CmdParams D_CmdParams;
struct D_CmdParams
{
D_Handle window;
D_Handle panel;
D_Handle dest_panel;
D_Handle prev_view;
D_Handle view;
D_Handle entity;
D_HandleList entity_list;
String8 string;
String8 file_path;
TxtPt text_point;
MD_Node * params_tree;
struct OS_Event * os_event;
U64 vaddr;
U64 voff;
U64 index;
U64 id;
B32 prefer_dasm;
B32 force_confirm;
Dir2 dir2;
U64 unwind_index;
U64 inline_depth;
};
#define d_regs_lit_init_top \
.machine = d_regs()->machine,\
.module = d_regs()->module,\
@@ -294,7 +241,6 @@ extern String8 d_entity_kind_name_lower_plural_table[30];
extern String8 d_entity_kind_name_label_table[30];
extern D_EntityKindFlags d_entity_kind_flags_table[30];
extern Rng1U64 d_reg_slot_range_table[29];
extern Rng1U64 d_cmd_param_slot_range_table[22];
C_LINKAGE_END
+4 -4
View File
@@ -35,10 +35,10 @@
DF_RegTable:
{
// rjf: entity slots
{D_Handle machine Machine }
{D_Handle module Module }
{D_Handle process Process }
{D_Handle thread Thread }
{CTRL_Handle machine Machine }
{CTRL_Handle module Module }
{CTRL_Handle process Process }
{CTRL_Handle thread Thread }
{D_Handle window Window }
{D_Handle panel Panel }
{D_Handle view View }
+125 -129
View File
@@ -505,23 +505,6 @@ df_cmd_params_from_view(DF_Window *window, DF_Panel *panel, DF_View *view)
#endif
internal D_CmdParams
df_cmd_params_copy(Arena *arena, D_CmdParams *src)
{
D_CmdParams dst = {0};
MemoryCopyStruct(&dst, src);
dst.entity_list = d_handle_list_copy(arena, src->entity_list);
if(dst.entity_list.count == 0 && !d_handle_match(src->entity, d_handle_zero()))
{
d_handle_list_push(arena, &dst.entity_list, dst.entity);
}
dst.string = push_str8_copy(arena, src->string);
dst.file_path = push_str8_copy(arena, src->file_path);
if(src->params_tree != 0) {dst.params_tree = md_tree_copy(arena, src->params_tree);}
if(dst.params_tree == 0) {dst.params_tree= &md_nil_node;}
return dst;
}
////////////////////////////////
//~ rjf: Global Cross-Window UI Interaction State Functions
@@ -1486,9 +1469,6 @@ df_window_frame(DF_Window *ws)
Handle(window);
Handle(panel);
Handle(view);
Handle(module);
Handle(process);
Handle(thread);
#undef Handle
ui_labelf("file_path: \"%S\"", regs->file_path);
ui_labelf("cursor: (L:%I64d, C:%I64d)", regs->cursor.line, regs->cursor.column);
@@ -1613,22 +1593,22 @@ df_window_frame(DF_Window *ws)
}
if(range.min.line == range.max.line && ui_clicked(df_icon_buttonf(DF_IconKind_RightArrow, 0, "Set Next Statement")))
{
D_Entity *thread = d_entity_from_handle(df_regs()->thread);
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->thread);
U64 new_rip_vaddr = ws->code_ctx_menu_vaddr;
if(ws->code_ctx_menu_file_path.size != 0)
{
for(D_LineNode *n = lines.first; n != 0; n = n->next)
{
D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, &n->v.dbgi_key);
D_Entity *module = d_module_from_thread_candidates(thread, &modules);
if(!d_entity_is_nil(module))
CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &n->v.dbgi_key);
CTRL_Entity *module = ctrl_module_from_thread_candidates(d_state->ctrl_entity_store, thread, &modules);
if(module != &ctrl_entity_nil)
{
new_rip_vaddr = d_vaddr_from_voff(module, n->v.voff_range.min);
new_rip_vaddr = ctrl_vaddr_from_voff(module, n->v.voff_range.min);
break;
}
}
}
df_cmd(DF_CmdKind_SetThreadIP, .thread = d_handle_from_entity(thread), .vaddr = new_rip_vaddr);
df_cmd(DF_CmdKind_SetThreadIP, .vaddr = new_rip_vaddr);
ui_ctx_menu_close();
}
if(range.min.line == range.max.line && ui_clicked(df_icon_buttonf(DF_IconKind_Play, 0, "Run To Line")))
@@ -1699,19 +1679,19 @@ df_window_frame(DF_Window *ws)
}
if(ws->code_ctx_menu_file_path.size != 0 && range.min.line == range.max.line && ui_clicked(df_icon_buttonf(DF_IconKind_FileOutline, 0, "Go To Disassembly")))
{
D_Entity *thread = d_entity_from_handle(df_regs()->thread);
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->thread);
U64 vaddr = 0;
for(D_LineNode *n = lines.first; n != 0; n = n->next)
{
D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, &n->v.dbgi_key);
D_Entity *module = d_module_from_thread_candidates(thread, &modules);
if(!d_entity_is_nil(module))
CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &n->v.dbgi_key);
CTRL_Entity *module = ctrl_module_from_thread_candidates(d_state->ctrl_entity_store, thread, &modules);
if(module != &ctrl_entity_nil)
{
vaddr = d_vaddr_from_voff(module, n->v.voff_range.min);
vaddr = ctrl_vaddr_from_voff(module, n->v.voff_range.min);
break;
}
}
df_cmd(DF_CmdKind_FindCodeLocation, .entity = d_handle_from_entity(thread), .vaddr = vaddr);
df_cmd(DF_CmdKind_FindCodeLocation, .vaddr = vaddr);
ui_ctx_menu_close();
}
hs_scope_close(hs_scope);
@@ -1953,7 +1933,8 @@ df_window_frame(DF_Window *ws)
{
if(ui_clicked(df_icon_buttonf(DF_IconKind_Clipboard, 0, "Copy Instruction Pointer Address")))
{
U64 rip = d_query_cached_rip_from_thread(entity);
CTRL_Entity *entity_ctrl = ctrl_entity_from_handle(d_state->ctrl_entity_store, entity->ctrl_handle);
U64 rip = d_query_cached_rip_from_thread(entity_ctrl);
String8 string = push_str8f(scratch.arena, "0x%I64x", rip);
os_set_clipboard_text(string);
ui_ctx_menu_close();
@@ -1965,15 +1946,16 @@ df_window_frame(DF_Window *ws)
if(ui_clicked(df_icon_buttonf(DF_IconKind_Clipboard, 0, "Copy Call Stack")))
{
DI_Scope *di_scope = di_scope_open();
D_Entity *process = d_entity_ancestor_from_kind(entity, D_EntityKind_Process);
CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity);
CTRL_Entity *entity_ctrl = ctrl_entity_from_handle(d_state->ctrl_entity_store, entity->ctrl_handle);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity_ctrl, CTRL_EntityKind_Process);
CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity_ctrl);
D_Unwind rich_unwind = d_unwind_from_ctrl_unwind(scratch.arena, di_scope, process, &base_unwind);
String8List lines = {0};
for(U64 frame_idx = 0; frame_idx < rich_unwind.frames.concrete_frame_count; frame_idx += 1)
{
D_UnwindFrame *concrete_frame = &rich_unwind.frames.v[frame_idx];
U64 rip_vaddr = regs_rip_from_arch_block(entity->arch, concrete_frame->regs);
D_Entity *module = d_module_from_process_vaddr(process, rip_vaddr);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
RDI_Parsed *rdi = concrete_frame->rdi;
RDI_Procedure *procedure = concrete_frame->procedure;
for(D_UnwindInlineFrame *inline_frame = concrete_frame->last_inline_frame;
@@ -1983,15 +1965,15 @@ df_window_frame(DF_Window *ws)
RDI_InlineSite *inline_site = inline_frame->inline_site;
String8 name = {0};
name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size);
str8_list_pushf(scratch.arena, &lines, "0x%I64x: [inlined] \"%S\"%s%S", rip_vaddr, name, d_entity_is_nil(module) ? "" : " in ", module->string);
str8_list_pushf(scratch.arena, &lines, "0x%I64x: [inlined] \"%S\"%s%S", rip_vaddr, name, module == &ctrl_entity_nil ? "" : " in ", module->string);
}
if(procedure != 0)
{
String8 name = {0};
name.str = rdi_name_from_procedure(rdi, procedure, &name.size);
str8_list_pushf(scratch.arena, &lines, "0x%I64x: \"%S\"%s%S", rip_vaddr, name, d_entity_is_nil(module) ? "" : " in ", module->string);
str8_list_pushf(scratch.arena, &lines, "0x%I64x: \"%S\"%s%S", rip_vaddr, name, module == &ctrl_entity_nil ? "" : " in ", module->string);
}
else if(!d_entity_is_nil(module))
else if(module != &ctrl_entity_nil)
{
str8_list_pushf(scratch.arena, &lines, "0x%I64x: [??? in %S]", rip_vaddr, module->string);
}
@@ -2348,12 +2330,12 @@ df_window_frame(DF_Window *ws)
Temp scratch = scratch_begin(0, 0);
//- rjf: unpack lister params
D_Entity *thread = d_entity_from_handle(d_base_regs()->thread);
U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, d_base_regs()->unwind_count);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
D_Entity *module = d_module_from_process_vaddr(process, thread_rip_vaddr);
U64 thread_rip_voff = d_voff_from_vaddr(module, thread_rip_vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_base_regs()->thread);
U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, df_base_regs()->unwind_count);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr);
U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
//- rjf: gather lister items
DF_AutoCompListerItemChunkList item_list = {0};
@@ -2394,7 +2376,7 @@ df_window_frame(DF_Window *ws)
//- rjf: gather registers
if(ws->autocomp_lister_params.flags & DF_AutoCompListerFlag_Registers)
{
Arch arch = d_arch_from_entity(thread);
Arch arch = thread->arch;
U64 reg_names_count = regs_reg_code_count_from_arch(arch);
U64 alias_names_count = regs_alias_code_count_from_arch(arch);
String8 *reg_names = regs_reg_code_string_table_from_arch(arch);
@@ -3895,9 +3877,6 @@ df_window_frame(DF_Window *ws)
{
Temp scratch = scratch_begin(0, 0);
DI_Scope *scope = di_scope_open();
D_Entity *thread = d_entity_from_handle(d_base_regs()->thread);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
U64 thread_unwind_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, d_base_regs()->unwind_count);
String8 expr = ws->hover_eval_string;
E_Eval eval = e_eval_from_string(scratch.arena, expr);
EV_ViewRuleList top_level_view_rules = {0};
@@ -6055,8 +6034,8 @@ df_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul
E_Eval value_eval = e_value_eval_from_eval(eval);
B32 ptee_has_content = (direct_type_kind != E_TypeKind_Null && direct_type_kind != E_TypeKind_Void);
B32 ptee_has_string = (E_TypeKind_Char8 <= direct_type_kind && direct_type_kind <= E_TypeKind_UChar32);
D_Entity *thread = d_entity_from_handle(df_regs()->thread);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->thread);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
String8 symbol_name = d_symbol_name_from_process_vaddr(arena, process, value_eval.value.u64, 1);
// rjf: special case: push strings for textual string content
@@ -8030,16 +8009,16 @@ df_frame(void)
//////////////////////////////
//- rjf: unpack eval-dependent info
//
D_Entity *process = d_entity_from_handle(df_regs()->process);
D_Entity *thread = d_entity_from_handle(df_regs()->thread);
Arch arch = d_arch_from_entity(thread);
CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->process);
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->thread);
Arch arch = thread->arch;
U64 unwind_count = df_regs()->unwind_count;
U64 rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, unwind_count);
CTRL_Unwind unwind = d_query_cached_unwind_from_thread(thread);
D_Entity *module = d_module_from_process_vaddr(process, rip_vaddr);
U64 rip_voff = d_voff_from_vaddr(module, rip_vaddr);
U64 tls_root_vaddr = ctrl_query_cached_tls_root_vaddr_from_thread(d_state->ctrl_entity_store, thread->ctrl_handle);
D_EntityList all_modules = d_query_cached_entity_list_with_kind(D_EntityKind_Module);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr);
U64 tls_root_vaddr = ctrl_query_cached_tls_root_vaddr_from_thread(d_state->ctrl_entity_store, thread->handle);
CTRL_EntityList all_modules = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module);
U64 eval_modules_count = Max(1, all_modules.count);
E_Module *eval_modules = push_array(scratch.arena, E_Module, eval_modules_count);
E_Module *eval_modules_primary = &eval_modules[0];
@@ -8048,14 +8027,14 @@ df_frame(void)
DI_Key primary_dbgi_key = {0};
{
U64 eval_module_idx = 0;
for(D_EntityNode *n = all_modules.first; n != 0; n = n->next, eval_module_idx += 1)
for(CTRL_EntityNode *n = all_modules.first; n != 0; n = n->next, eval_module_idx += 1)
{
D_Entity *m = n->entity;
DI_Key dbgi_key = d_dbgi_key_from_module(m);
eval_modules[eval_module_idx].arch = d_arch_from_entity(m);
CTRL_Entity *m = n->v;
DI_Key dbgi_key = ctrl_dbgi_key_from_module(m);
eval_modules[eval_module_idx].arch = m->arch;
eval_modules[eval_module_idx].rdi = di_rdi_from_key(di_scope, &dbgi_key, 0);
eval_modules[eval_module_idx].vaddr_range = m->vaddr_rng;
eval_modules[eval_module_idx].space = d_eval_space_from_entity(d_entity_ancestor_from_kind(m, D_EntityKind_Process));
eval_modules[eval_module_idx].vaddr_range = m->vaddr_range;
eval_modules[eval_module_idx].space = d_eval_space_from_ctrl_entity(ctrl_entity_ancestor_from_kind(m, CTRL_EntityKind_Process));
if(module == m)
{
eval_modules_primary = &eval_modules[eval_module_idx];
@@ -8069,12 +8048,12 @@ df_frame(void)
Rng1U64 *rdis_vaddr_ranges = push_array(scratch.arena, Rng1U64, rdis_count);
{
U64 idx = 0;
for(D_EntityNode *n = all_modules.first; n != 0; n = n->next, idx += 1)
for(CTRL_EntityNode *n = all_modules.first; n != 0; n = n->next, idx += 1)
{
DI_Key dbgi_key = d_dbgi_key_from_module(n->entity);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(n->v);
rdis[idx] = di_rdi_from_key(di_scope, &dbgi_key, 0);
rdis_vaddr_ranges[idx] = n->entity->vaddr_rng;
if(n->entity == module)
rdis_vaddr_ranges[idx] = n->v->vaddr_range;
if(n->v == module)
{
primary_dbgi_key = dbgi_key;
rdis_primary_idx = idx;
@@ -8105,7 +8084,7 @@ df_frame(void)
E_ParseCtx *ctx = parse_ctx;
ctx->ip_vaddr = rip_vaddr;
ctx->ip_voff = rip_voff;
ctx->ip_thread_space = d_eval_space_from_entity(thread);
ctx->ip_thread_space = d_eval_space_from_ctrl_entity(thread);
ctx->modules = eval_modules;
ctx->modules_count = eval_modules_count;
ctx->primary_module = eval_modules_primary;
@@ -8128,18 +8107,18 @@ df_frame(void)
//- rjf: add macros for constants
{
// rjf: pid -> current process' ID
if(!d_entity_is_nil(process))
if(process != &ctrl_entity_nil)
{
E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafU64, 0);
expr->value.u64 = process->ctrl_id;
expr->value.u64 = process->id;
e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("pid"), expr);
}
// rjf: tid -> current thread's ID
if(!d_entity_is_nil(thread))
if(thread != &ctrl_entity_nil)
{
E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafU64, 0);
expr->value.u64 = thread->ctrl_id;
expr->value.u64 = thread->id;
e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("tid"), expr);
}
}
@@ -8211,10 +8190,10 @@ df_frame(void)
ctx->space_write = d_eval_space_write;
ctx->primary_space = eval_modules_primary->space;
ctx->reg_arch = eval_modules_primary->arch;
ctx->reg_space = d_eval_space_from_entity(thread);
ctx->reg_space = d_eval_space_from_ctrl_entity(thread);
ctx->reg_unwind_count = unwind_count;
ctx->module_base = push_array(scratch.arena, U64, 1);
ctx->module_base[0] = module->vaddr_rng.min;
ctx->module_base[0] = module->vaddr_range.min;
ctx->tls_base = push_array(scratch.arena, U64, 1);
ctx->tls_base[0] = d_query_cached_tls_base_vaddr_from_process_root_rip(process, tls_root_vaddr, rip_vaddr);
}
@@ -8271,6 +8250,18 @@ df_frame(void)
if(D_CmdKind_Null < (D_CmdKind)kind && (D_CmdKind)kind < D_CmdKind_COUNT)
{
D_CmdParams params = {0};
params.machine = df_regs()->machine;
params.thread = df_regs()->thread;
// TODO(rjf): @msgs params.entity = ???;
// TODO(rjf): @msgs params.processes = ???;
params.file_path = df_regs()->file_path;
params.cursor = df_regs()->cursor;
params.vaddr = df_regs()->vaddr;
params.prefer_disasm = df_regs()->prefer_disasm;
params.pid = df_regs()->pid;
// TODO(rjf): @msgs params.targets = ???;
// TODO(rjf): @msgs
#if 0
params.window = df_regs()->window;
params.panel = df_regs()->panel;
params.dest_panel = df_regs()->dst_panel;
@@ -8290,6 +8281,7 @@ df_frame(void)
params.dir2 = df_regs()->dir2;
params.unwind_index = df_regs()->unwind_count;
params.inline_depth = df_regs()->inline_depth;
#endif
d_push_cmd((D_CmdKind)kind, &params);
}
@@ -10548,7 +10540,7 @@ df_frame(void)
for(DF_Window *ws = df_state->first_window; ws != 0; ws = ws->next)
{
DI_Scope *scope = di_scope_open();
D_Entity *thread = d_entity_from_handle(df_regs()->entity);
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->thread);
U64 unwind_index = df_regs()->unwind_count;
U64 inline_depth = df_regs()->inline_depth;
if(thread->kind == D_EntityKind_Thread)
@@ -10557,11 +10549,11 @@ df_frame(void)
U64 rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, unwind_index);
// rjf: extract thread/rip info
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
D_Entity *module = d_module_from_process_vaddr(process, rip_vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di_rdi_from_key(scope, &dbgi_key, 0);
U64 rip_voff = d_voff_from_vaddr(module, rip_vaddr);
U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr);
D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, rip_voff);
D_Line line = {0};
{
@@ -10577,18 +10569,18 @@ df_frame(void)
}
// rjf: snap to resolved line
B32 missing_rip = (rip_vaddr == 0);
B32 dbgi_missing = (dbgi_key.min_timestamp == 0 || dbgi_key.path.size == 0);
B32 dbgi_pending = !dbgi_missing && rdi == &di_rdi_parsed_nil;
B32 missing_rip = (rip_vaddr == 0);
B32 dbgi_missing = (dbgi_key.min_timestamp == 0 || dbgi_key.path.size == 0);
B32 dbgi_pending = !dbgi_missing && rdi == &di_rdi_parsed_nil;
B32 has_line_info = (line.voff_range.max != 0);
B32 has_module = !d_entity_is_nil(module);
B32 has_dbg_info = has_module && !dbgi_missing;
B32 has_module = (module != &ctrl_entity_nil);
B32 has_dbg_info = has_module && !dbgi_missing;
if(!dbgi_pending && (has_line_info || has_module))
{
df_cmd(DF_CmdKind_FindCodeLocation,
.file_path = line.file_path,
.cursor = line.pt,
.entity = d_handle_from_entity(thread),
.process = process->handle,
.voff = rip_voff,
.vaddr = rip_vaddr,
.unwind_count = unwind_index,
@@ -10599,9 +10591,10 @@ df_frame(void)
if(!missing_rip && !dbgi_pending && !has_line_info && !has_module)
{
df_cmd(DF_CmdKind_FindCodeLocation,
.entity = d_handle_from_entity(thread),
.voff = rip_voff,
.vaddr = rip_vaddr,
.process = process->handle,
.module = module->handle,
.voff = rip_voff,
.vaddr = rip_vaddr,
.unwind_count = unwind_index,
.inline_depth = inline_depth);
}
@@ -10609,7 +10602,7 @@ df_frame(void)
// rjf: retry on stopped, pending debug info
if(!d_ctrl_targets_running() && (dbgi_pending || missing_rip))
{
df_cmd(DF_CmdKind_FindThread, .entity = d_handle_from_entity(thread));
df_cmd(DF_CmdKind_FindThread, .thread = thread->handle);
}
}
di_scope_close(scope);
@@ -10617,9 +10610,9 @@ df_frame(void)
case DF_CmdKind_FindSelectedThread:
for(DF_Window *ws = df_state->first_window; ws != 0; ws = ws->next)
{
D_Entity *selected_thread = d_entity_from_handle(df_base_regs()->thread);
CTRL_Entity *selected_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_base_regs()->thread);
df_cmd(DF_CmdKind_FindThread,
.entity = d_handle_from_entity(selected_thread),
.thread = selected_thread->handle,
.unwind_count = df_base_regs()->unwind_count,
.inline_depth = df_base_regs()->inline_depth);
}break;
@@ -10755,23 +10748,24 @@ df_frame(void)
D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &voff_dbgi_key, voff);
if(lines.first != 0)
{
D_Entity *process = &d_nil_entity;
CTRL_Entity *process = &ctrl_entity_nil;
U64 vaddr = 0;
if(voff_dbgi_key.path.size != 0)
{
D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, &voff_dbgi_key);
D_Entity *module = d_first_entity_from_list(&modules);
process = d_entity_ancestor_from_kind(module, D_EntityKind_Process);
if(!d_entity_is_nil(process))
CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &voff_dbgi_key);
CTRL_Entity *module = ctrl_entity_list_first(&modules);
process = ctrl_entity_ancestor_from_kind(module, CTRL_EntityKind_Process);
if(process != &ctrl_entity_nil)
{
vaddr = module->vaddr_rng.min + lines.first->v.voff_range.min;
vaddr = module->vaddr_range.min + lines.first->v.voff_range.min;
}
}
df_cmd(DF_CmdKind_FindCodeLocation,
.file_path = lines.first->v.file_path,
.cursor = lines.first->v.pt,
.entity = d_handle_from_entity(process),
.vaddr = module->vaddr_rng.min + lines.first->v.voff_range.min);
.process = process->handle,
.module = module->handle,
.vaddr = module->vaddr_range.min + lines.first->v.voff_range.min);
}
}
@@ -10908,27 +10902,27 @@ df_frame(void)
// rjf: grab things to find. path * point, process * address, etc.
String8 file_path = {0};
TxtPt point = {0};
D_Entity *thread = &d_nil_entity;
D_Entity *process = &d_nil_entity;
CTRL_Entity *thread = &ctrl_entity_nil;
CTRL_Entity *process = &ctrl_entity_nil;
U64 vaddr = 0;
{
file_path = df_regs()->file_path;
point = df_regs()->cursor;
thread = d_entity_from_handle(df_regs()->thread);
process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->thread);
process = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->process);
vaddr = df_regs()->vaddr;
}
// rjf: given a src code location, and a process, if no vaddr is specified,
// rjf: given a src code location, if no vaddr is specified,
// try to map the src coordinates to a vaddr via line info
if(vaddr == 0 && file_path.size != 0 && !d_entity_is_nil(process))
if(vaddr == 0 && file_path.size != 0)
{
D_LineList lines = d_lines_from_file_path_line_num(scratch.arena, file_path, point.line);
for(D_LineNode *n = lines.first; n != 0; n = n->next)
{
D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, &n->v.dbgi_key);
D_Entity *module = d_module_from_thread_candidates(thread, &modules);
vaddr = d_vaddr_from_voff(module, n->v.voff_range.min);
CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &n->v.dbgi_key);
CTRL_Entity *module = ctrl_module_from_thread_candidates(d_state->ctrl_entity_store, thread, &modules);
vaddr = ctrl_vaddr_from_voff(module, n->v.voff_range.min);
break;
}
}
@@ -11102,7 +11096,7 @@ df_frame(void)
}
// rjf: given the above, find disassembly location.
if(!d_entity_is_nil(process) && vaddr != 0)
if(process != &ctrl_entity_nil && vaddr != 0)
{
// rjf: determine which panel we will use to find the disasm loc -
// we *cannot* use the same panel we used for source code, if any.
@@ -11139,7 +11133,7 @@ df_frame(void)
if(!df_panel_is_nil(dst_panel))
{
dst_panel->selected_tab_view = df_handle_from_view(dst_view);
df_cmd(DF_CmdKind_GoToAddress, .entity = d_handle_from_entity(process), .vaddr = vaddr);
df_cmd(DF_CmdKind_GoToAddress, .process = process->handle, .vaddr = vaddr);
df_cmd(cursor_snap_kind);
}
}
@@ -11517,7 +11511,7 @@ df_frame(void)
}break;
case DF_CmdKind_SetNextStatement:
{
D_Entity *thread = d_entity_from_handle(df_regs()->thread);
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->thread);
String8 file_path = df_regs()->file_path;
U64 new_rip_vaddr = df_regs()->vaddr_range.min;
if(file_path.size != 0)
@@ -11525,16 +11519,16 @@ df_frame(void)
D_LineList *lines = &df_regs()->lines;
for(D_LineNode *n = lines->first; n != 0; n = n->next)
{
D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, &n->v.dbgi_key);
D_Entity *module = d_module_from_thread_candidates(thread, &modules);
if(!d_entity_is_nil(module))
CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &n->v.dbgi_key);
CTRL_Entity *module = ctrl_module_from_thread_candidates(d_state->ctrl_entity_store, thread, &modules);
if(module != &ctrl_entity_nil)
{
new_rip_vaddr = d_vaddr_from_voff(module, n->v.voff_range.min);
new_rip_vaddr = ctrl_vaddr_from_voff(module, n->v.voff_range.min);
break;
}
}
}
d_cmd(D_CmdKind_SetThreadIP, .entity = d_handle_from_entity(thread), .vaddr = new_rip_vaddr);
d_cmd(D_CmdKind_SetThreadIP, .vaddr = new_rip_vaddr);
}break;
//- rjf: targets
@@ -11655,21 +11649,23 @@ df_frame(void)
//- rjf: debug control context management operations
case DF_CmdKind_SelectThread:
{
D_Entity *thread = d_entity_from_handle(df_regs()->thread);
D_Entity *module = d_module_from_thread(thread);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->thread);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle));
CTRL_Entity *machine = ctrl_entity_ancestor_from_kind(process, CTRL_EntityKind_Machine);
df_state->base_regs.v.unwind_count = 0;
df_state->base_regs.v.inline_depth = 0;
df_state->base_regs.v.thread = d_handle_from_entity(thread);
df_state->base_regs.v.module = d_handle_from_entity(module);
df_state->base_regs.v.process = d_handle_from_entity(process);
df_cmd(DF_CmdKind_FindThread, .thread = d_handle_from_entity(thread));
df_state->base_regs.v.thread = thread->handle;
df_state->base_regs.v.module = module->handle;
df_state->base_regs.v.process = process->handle;
df_state->base_regs.v.machine = machine->handle;
df_cmd(DF_CmdKind_FindThread, .thread = thread->handle);
}break;
case DF_CmdKind_SelectUnwind:
{
DI_Scope *di_scope = di_scope_open();
D_Entity *thread = d_entity_from_handle(df_base_regs()->thread);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_base_regs()->thread);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread);
D_Unwind rich_unwind = d_unwind_from_ctrl_unwind(scratch.arena, di_scope, process, &base_unwind);
if(df_regs()->unwind_count < rich_unwind.frames.concrete_frame_count)
@@ -11682,15 +11678,15 @@ df_frame(void)
d_state->base_regs.v.inline_depth = df_regs()->inline_depth;
}
}
df_cmd(DF_CmdKind_FindThread, .thread = d_handle_from_entity(thread));
df_cmd(DF_CmdKind_FindThread, .thread = thread->handle);
di_scope_close(di_scope);
}break;
case DF_CmdKind_UpOneFrame:
case DF_CmdKind_DownOneFrame:
{
DI_Scope *di_scope = di_scope_open();
D_Entity *thread = d_entity_from_handle(df_base_regs()->thread);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_base_regs()->thread);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread);
D_Unwind rich_unwind = d_unwind_from_ctrl_unwind(scratch.arena, di_scope, process, &base_unwind);
U64 crnt_unwind_idx = d_state->base_regs.v.unwind_count;
+10 -1
View File
@@ -4,6 +4,16 @@
#ifndef DBG_FRONTEND_CORE_H
#define DBG_FRONTEND_CORE_H
////////////////////////////////
//~ rjf: Evaluation Spaces
typedef U64 DF_EvalSpaceKind;
enum
{
DF_EvalSpaceKind_CtrlEntity = E_SpaceKind_FirstUserDefined,
DF_EvalSpaceKind_CfgEntity,
};
////////////////////////////////
//~ rjf: Binding Types
@@ -902,7 +912,6 @@ internal D_CmdParams df_cmd_params_from_window(DF_Window *window);
internal D_CmdParams df_cmd_params_from_panel(DF_Window *window, DF_Panel *panel);
internal D_CmdParams df_cmd_params_from_view(DF_Window *window, DF_Panel *panel, DF_View *view);
#endif
internal D_CmdParams df_cmd_params_copy(Arena *arena, D_CmdParams *src);
////////////////////////////////
//~ rjf: Global Cross-Window UI Interaction State Functions
+92 -86
View File
@@ -86,8 +86,8 @@ df_code_view_build(Arena *arena, DF_View *view, DF_CodeViewState *cv, DF_CodeVie
F32 scroll_bar_dim = floor_f32(ui_top_font_size()*1.5f);
Vec2F32 code_area_dim = v2f32(panel_box_dim.x - scroll_bar_dim, panel_box_dim.y - scroll_bar_dim);
S64 num_possible_visible_lines = (S64)(code_area_dim.y/code_line_height)+1;
D_Entity *thread = d_entity_from_handle(df_regs()->thread);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->thread);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
//////////////////////////////
//- rjf: determine visible line range / count
@@ -169,7 +169,7 @@ df_code_view_build(Arena *arena, DF_View *view, DF_CodeViewState *cv, DF_CodeVie
code_slice_params.line_ranges = push_array(scratch.arena, Rng1U64, visible_line_count);
code_slice_params.line_tokens = push_array(scratch.arena, TXT_TokenArray, visible_line_count);
code_slice_params.line_bps = push_array(scratch.arena, D_EntityList, visible_line_count);
code_slice_params.line_ips = push_array(scratch.arena, D_EntityList, visible_line_count);
code_slice_params.line_ips = push_array(scratch.arena, CTRL_EntityList, visible_line_count);
code_slice_params.line_pins = push_array(scratch.arena, D_EntityList, visible_line_count);
code_slice_params.line_vaddrs = push_array(scratch.arena, U64, visible_line_count);
code_slice_params.line_infos = push_array(scratch.arena, D_LineList, visible_line_count);
@@ -217,26 +217,26 @@ df_code_view_build(Arena *arena, DF_View *view, DF_CodeViewState *cv, DF_CodeVie
ProfScope("find live threads mapping to this file")
{
String8 file_path = df_regs()->file_path;
D_Entity *selected_thread = d_entity_from_handle(df_regs()->thread);
D_EntityList threads = d_query_cached_entity_list_with_kind(D_EntityKind_Thread);
for(D_EntityNode *thread_n = threads.first; thread_n != 0; thread_n = thread_n->next)
CTRL_Entity *selected_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->thread);
CTRL_EntityList threads = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread);
for(CTRL_EntityNode *thread_n = threads.first; thread_n != 0; thread_n = thread_n->next)
{
D_Entity *thread = thread_n->entity;
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
CTRL_Entity *thread = thread_n->v;
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
U64 unwind_count = (thread == selected_thread) ? df_regs()->unwind_count : 0;
U64 inline_depth = (thread == selected_thread) ? df_regs()->inline_depth : 0;
U64 rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, unwind_count);
U64 last_inst_on_unwound_rip_vaddr = rip_vaddr - !!unwind_count;
D_Entity *module = d_module_from_process_vaddr(process, last_inst_on_unwound_rip_vaddr);
U64 rip_voff = d_voff_from_vaddr(module, last_inst_on_unwound_rip_vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, last_inst_on_unwound_rip_vaddr);
U64 rip_voff = ctrl_voff_from_vaddr(module, last_inst_on_unwound_rip_vaddr);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, rip_voff);
for(D_LineNode *n = lines.first; n != 0; n = n->next)
{
if(path_match_normalized(n->v.file_path, file_path) && visible_line_num_range.min <= n->v.pt.line && n->v.pt.line <= visible_line_num_range.max)
{
U64 slice_line_idx = n->v.pt.line-visible_line_num_range.min;
d_entity_list_push(scratch.arena, &code_slice_params.line_ips[slice_line_idx], thread);
ctrl_entity_list_push(scratch.arena, &code_slice_params.line_ips[slice_line_idx], thread);
}
}
}
@@ -274,21 +274,21 @@ df_code_view_build(Arena *arena, DF_View *view, DF_CodeViewState *cv, DF_CodeVie
// rjf: find live threads mapping to disasm
if(dasm_lines) ProfScope("find live threads mapping to this disassembly")
{
D_Entity *selected_thread = d_entity_from_handle(df_regs()->thread);
D_EntityList threads = d_query_cached_entity_list_with_kind(D_EntityKind_Thread);
for(D_EntityNode *thread_n = threads.first; thread_n != 0; thread_n = thread_n->next)
CTRL_Entity *selected_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->thread);
CTRL_EntityList threads = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread);
for(CTRL_EntityNode *thread_n = threads.first; thread_n != 0; thread_n = thread_n->next)
{
D_Entity *thread = thread_n->entity;
CTRL_Entity *thread = thread_n->v;
U64 unwind_count = (thread == selected_thread) ? df_regs()->unwind_count : 0;
U64 rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, unwind_count);
if(d_entity_ancestor_from_kind(thread, D_EntityKind_Process) == process && contains_1u64(dasm_vaddr_range, rip_vaddr))
if(ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process) == process && contains_1u64(dasm_vaddr_range, rip_vaddr))
{
U64 rip_off = rip_vaddr - dasm_vaddr_range.min;
S64 line_num = dasm_line_array_idx_from_code_off__linear_scan(dasm_lines, rip_off)+1;
if(contains_1s64(visible_line_num_range, line_num))
{
U64 slice_line_idx = (line_num-visible_line_num_range.min);
d_entity_list_push(scratch.arena, &code_slice_params.line_ips[slice_line_idx], thread);
ctrl_entity_list_push(scratch.arena, &code_slice_params.line_ips[slice_line_idx], thread);
}
}
}
@@ -341,12 +341,12 @@ df_code_view_build(Arena *arena, DF_View *view, DF_CodeViewState *cv, DF_CodeVie
// rjf: fill dasm -> src info
if(dasm_lines)
{
D_Entity *module = d_module_from_process_vaddr(process, dasm_vaddr_range.min);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, dasm_vaddr_range.min);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
for(S64 line_num = visible_line_num_range.min; line_num < visible_line_num_range.max; line_num += 1)
{
U64 vaddr = dasm_vaddr_range.min + dasm_line_array_code_off_from_idx(dasm_lines, line_num-1);
U64 voff = d_voff_from_vaddr(module, vaddr);
U64 voff = ctrl_voff_from_vaddr(module, vaddr);
U64 slice_idx = line_num-visible_line_num_range.min;
code_slice_params.line_vaddrs[slice_idx] = vaddr;
code_slice_params.line_infos[slice_idx] = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff);
@@ -834,9 +834,9 @@ df_string_from_eval_viz_row_column(Arena *arena, EV_View *ev, EV_Row *row, DF_Wa
case DF_WatchViewColumnKind_Module:
{
E_Eval eval = e_eval_from_expr(arena, row->expr);
D_Entity *process = d_entity_from_handle(df_regs()->process);
D_Entity *module = d_module_from_process_vaddr(process, eval.value.u64);
result = d_display_string_from_entity(arena, module);
CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->process);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, eval.value.u64);
result = push_str8_copy(arena, module->string);
}break;
case DF_WatchViewColumnKind_Member:
{
@@ -938,12 +938,6 @@ df_watch_view_build(DF_View *view, DF_WatchViewState *ewv, B32 modifiable, U32 d
//- rjf: unpack arguments
//
FNT_Tag code_font = df_font_from_slot(DF_FontSlot_Code);
D_Entity *thread = d_entity_from_handle(df_regs()->thread);
Arch arch = d_arch_from_entity(thread);
CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
D_Unwind rich_unwind = d_unwind_from_ctrl_unwind(scratch.arena, di_scope, process, &base_unwind);
U64 thread_ip_vaddr = d_query_cached_rip_from_thread_unwind(thread, df_regs()->unwind_count);
String8 eval_view_key_string = push_str8f(scratch.arena, "eval_view_watch_%p", ewv);
EV_View *eval_view = df_ev_view_from_key(d_hash_from_string(eval_view_key_string));
String8 filter = str8(view->query_buffer, view->query_string_size);
@@ -1116,6 +1110,10 @@ df_watch_view_build(DF_View *view, DF_WatchViewState *ewv, B32 modifiable, U32 d
case DF_WatchViewFillKind_CallStack:
{
//- rjf: produce per-row info for callstack
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->thread);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(thread);
D_Unwind rich_unwind = d_unwind_from_ctrl_unwind(scratch.arena, di_scope, process, &base_unwind);
frame_rows_count = rich_unwind.frames.total_frame_count;
frame_rows = push_array(scratch.arena, FrameRow, frame_rows_count);
{
@@ -1165,14 +1163,14 @@ df_watch_view_build(DF_View *view, DF_WatchViewState *ewv, B32 modifiable, U32 d
{
type_key = e_type_key_ext(E_TypeKind_Function, row->inline_site->type_idx, e_parse_ctx_module_idx_from_rdi(row->rdi));
}
U64 row_vaddr = regs_rip_from_arch_block(arch, row->regs);
U64 row_vaddr = regs_rip_from_arch_block(thread->arch, row->regs);
E_OpList ops = {0};
e_oplist_push_op(scratch.arena, &ops, RDI_EvalOp_ConstU64, e_value_u64(row_vaddr));
String8 bytecode = e_bytecode_from_oplist(scratch.arena, &ops);
E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafBytecode, 0);
expr->bytecode = bytecode;
expr->mode = E_Mode_Value;
expr->space = d_eval_space_from_entity(process);
expr->space = d_eval_space_from_ctrl_entity(process);
expr->type_key = type_key;
block->expr = expr;
block->visual_idx_range = r1u64(row_idx, row_idx+1);
@@ -1187,8 +1185,8 @@ df_watch_view_build(DF_View *view, DF_WatchViewState *ewv, B32 modifiable, U32 d
//
case DF_WatchViewFillKind_Registers:
{
D_Entity *thread = d_entity_from_handle(df_regs()->thread);
Arch arch = d_arch_from_entity(thread);
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->thread);
Arch arch = thread->arch;
U64 reg_count = regs_reg_code_count_from_arch(arch);
String8 *reg_strings = regs_reg_code_string_table_from_arch(arch);
U64 alias_count = regs_alias_code_count_from_arch(arch);
@@ -1624,28 +1622,31 @@ df_watch_view_build(DF_View *view, DF_WatchViewState *ewv, B32 modifiable, U32 d
{
E_Eval eval = e_eval_from_expr(scratch.arena, row->expr);
U64 vaddr = eval.value.u64;
D_Entity *module = d_module_from_process_vaddr(process, vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
U64 voff = d_voff_from_vaddr(module, vaddr);
D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff);
String8 file_path = {0};
TxtPt pt = {0};
if(lines.first != 0)
CTRL_Entity *eval_space_ctrl_entity = d_ctrl_entity_from_eval_space(eval.space);
if(eval_space_ctrl_entity->kind == CTRL_EntityKind_Process)
{
file_path = lines.first->v.file_path;
pt = lines.first->v.pt;
CTRL_Entity *module = ctrl_module_from_process_vaddr(eval_space_ctrl_entity, vaddr);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
U64 voff = ctrl_voff_from_vaddr(module, vaddr);
D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff);
String8 file_path = {0};
TxtPt pt = {0};
if(lines.first != 0)
{
file_path = lines.first->v.file_path;
pt = lines.first->v.pt;
}
df_cmd(DF_CmdKind_FindCodeLocation,
.process = eval_space_ctrl_entity->handle,
.vaddr = vaddr,
.file_path = file_path,
.cursor = pt);
}
df_cmd(DF_CmdKind_FindCodeLocation,
.entity = d_handle_from_entity(process),
.vaddr = vaddr,
.file_path = file_path,
.cursor = pt);
}
if(1 <= selection_tbl.min.y && selection_tbl.min.y <= frame_rows_count)
{
FrameRow *frame_row = &frame_rows[selection_tbl.min.y-1];
df_cmd(DF_CmdKind_SelectUnwind,
.entity = df_regs()->thread,
.unwind_count = frame_row->unwind_idx,
.inline_depth = frame_row->inline_depth);
}
@@ -2507,7 +2508,11 @@ df_watch_view_build(DF_View *view, DF_WatchViewState *ewv, B32 modifiable, U32 d
if(semantic_idx == df_regs()->unwind_count - df_regs()->inline_depth)
{
cell_icon = DF_IconKind_RightArrow;
cell_base_color = d_rgba_from_entity(d_entity_from_handle(df_regs()->thread));
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->thread);
if(thread->rgba != 0)
{
cell_base_color = rgba_from_u32(thread->rgba);
}
}
}break;
}
@@ -2640,9 +2645,10 @@ df_watch_view_build(DF_View *view, DF_WatchViewState *ewv, B32 modifiable, U32 d
if(ui_double_clicked(sig) && !cell_can_edit)
{
U64 vaddr = cell_eval.value.u64;
D_Entity *module = d_module_from_process_vaddr(process, vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
U64 voff = d_voff_from_vaddr(module, vaddr);
CTRL_Entity *process = d_ctrl_entity_from_eval_space(cell_eval.space);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
U64 voff = ctrl_voff_from_vaddr(module, vaddr);
D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff);
String8 file_path = {0};
TxtPt pt = {0};
@@ -2652,7 +2658,7 @@ df_watch_view_build(DF_View *view, DF_WatchViewState *ewv, B32 modifiable, U32 d
pt = lines.first->v.pt;
}
df_cmd(DF_CmdKind_FindCodeLocation,
.entity = d_handle_from_entity(process),
.process = process->handle,
.vaddr = vaddr,
.file_path = file_path,
.cursor = pt);
@@ -2663,7 +2669,6 @@ df_watch_view_build(DF_View *view, DF_WatchViewState *ewv, B32 modifiable, U32 d
{
FrameRow *frame_row = &frame_rows[semantic_idx];
df_cmd(DF_CmdKind_SelectUnwind,
.entity = df_regs()->thread,
.unwind_count = frame_row->unwind_idx,
.inline_depth = frame_row->inline_depth);
}
@@ -5704,8 +5709,9 @@ DF_VIEW_UI_FUNCTION_DEF(scheduler)
{
UI_TableCellSized(ui_children_sum(1.f)) UI_FocusHot((row_is_selected && cursor.x >= 2) ? UI_FocusKind_On : UI_FocusKind_Off)
{
CTRL_Entity *entity_ctrl = ctrl_entity_from_handle(d_state->ctrl_entity_store, entity->ctrl_handle);
D_Entity *process = d_entity_ancestor_from_kind(entity, D_EntityKind_Process);
U64 rip_vaddr = d_query_cached_rip_from_thread(entity);
U64 rip_vaddr = d_query_cached_rip_from_thread(entity_ctrl);
D_Entity *module = d_module_from_process_vaddr(process, rip_vaddr);
U64 rip_voff = d_voff_from_vaddr(module, rip_vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
@@ -6669,23 +6675,23 @@ DF_VIEW_CMD_FUNCTION_DEF(disasm)
E_Space space = eval.space;
if(auto_selected_thread)
{
space = d_eval_space_from_entity(d_entity_from_handle(df_regs()->process));
space = d_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->process));
}
Rng1U64 range = d_range_from_eval_params(eval, params);
Arch arch = d_arch_from_eval_params(eval, params);
D_Entity *space_entity = d_entity_from_eval_space(space);
D_Entity *dasm_module = &d_nil_entity;
CTRL_Entity *space_entity = d_ctrl_entity_from_eval_space(space);
CTRL_Entity *dasm_module = &ctrl_entity_nil;
DI_Key dbgi_key = {0};
U64 base_vaddr = 0;
switch(space_entity->kind)
{
default:{}break;
case D_EntityKind_Process:
case CTRL_EntityKind_Process:
{
arch = d_arch_from_entity(space_entity);
dasm_module = d_module_from_process_vaddr(space_entity, range.min);
dbgi_key = d_dbgi_key_from_module(dasm_module);
base_vaddr = dasm_module->vaddr_rng.min;
arch = space_entity->arch;
dasm_module = ctrl_module_from_process_vaddr(space_entity, range.min);
dbgi_key = ctrl_dbgi_key_from_module(dasm_module);
base_vaddr = dasm_module->vaddr_range.min;
}break;
}
U128 dasm_key = d_key_from_eval_space_range(space, range, 0);
@@ -6798,23 +6804,23 @@ DF_VIEW_UI_FUNCTION_DEF(disasm)
E_Space space = eval.space;
if(auto_selected_thread)
{
space = d_eval_space_from_entity(d_entity_from_handle(df_regs()->process));
space = d_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->process));
}
Rng1U64 range = d_range_from_eval_params(eval, params);
Arch arch = d_arch_from_eval_params(eval, params);
D_Entity *space_entity = d_entity_from_eval_space(space);
D_Entity *dasm_module = &d_nil_entity;
CTRL_Entity *space_entity = d_ctrl_entity_from_eval_space(space);
CTRL_Entity *dasm_module = &ctrl_entity_nil;
DI_Key dbgi_key = {0};
U64 base_vaddr = 0;
switch(space_entity->kind)
{
default:{}break;
case D_EntityKind_Process:
case CTRL_EntityKind_Process:
{
arch = d_arch_from_entity(space_entity);
dasm_module = d_module_from_process_vaddr(space_entity, range.min);
dbgi_key = d_dbgi_key_from_module(dasm_module);
base_vaddr = dasm_module->vaddr_rng.min;
arch = space_entity->arch;
dasm_module = ctrl_module_from_process_vaddr(space_entity, range.min);
dbgi_key = ctrl_dbgi_key_from_module(dasm_module);
base_vaddr = dasm_module->vaddr_range.min;
}break;
}
U128 dasm_key = d_key_from_eval_space_range(space, range, 0);
@@ -6872,7 +6878,7 @@ DF_VIEW_UI_FUNCTION_DEF(disasm)
{
U64 off = dasm_line_array_code_off_from_idx(&dasm_info.lines, df_regs()->cursor.line-1);
df_regs()->vaddr_range = r1u64(base_vaddr+off, base_vaddr+off);
df_regs()->voff_range = d_voff_range_from_vaddr_range(dasm_module, df_regs()->vaddr_range);
df_regs()->voff_range = ctrl_voff_range_from_vaddr_range(dasm_module, df_regs()->vaddr_range);
df_regs()->lines = d_lines_from_dbgi_key_voff(d_frame_arena(), &dbgi_key, df_regs()->voff_range.min);
}
@@ -6890,7 +6896,7 @@ DF_VIEW_UI_FUNCTION_DEF(disasm)
DF_Font(DF_FontSlot_Code)
{
U64 cursor_vaddr = (1 <= df_regs()->cursor.line && df_regs()->cursor.line <= dasm_info.lines.count) ? (range.min+dasm_info.lines.v[df_regs()->cursor.line-1].code_off) : 0;
if(!d_entity_is_nil(dasm_module))
if(dasm_module != &ctrl_entity_nil)
{
ui_labelf("%S", path_normalized_from_string(scratch.arena, dasm_module->string));
ui_spacer(ui_em(1.5f, 1));
@@ -7068,13 +7074,13 @@ DF_VIEW_UI_FUNCTION_DEF(memory)
E_Eval eval = e_eval_from_string(scratch.arena, string);
if(eval.space.kind == 0)
{
eval.space = d_eval_space_from_entity(d_entity_from_handle(df_regs()->process));
eval.space = d_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->process));
}
Rng1U64 space_range = d_whole_range_from_eval_space(eval.space);
U64 cursor = d_value_from_params_key(params, str8_lit("cursor_vaddr")).u64;
U64 mark = d_value_from_params_key(params, str8_lit("mark_vaddr")).u64;
U64 bytes_per_cell = d_value_from_params_key(params, str8_lit("bytes_per_cell")).u64;
U64 num_columns = d_value_from_params_key(params, str8_lit("num_columns")).u64;
U64 cursor = d_value_from_params_key(params, str8_lit("cursor_vaddr")).u64;
U64 mark = d_value_from_params_key(params, str8_lit("mark_vaddr")).u64;
U64 bytes_per_cell = d_value_from_params_key(params, str8_lit("bytes_per_cell")).u64;
U64 num_columns = d_value_from_params_key(params, str8_lit("num_columns")).u64;
if(num_columns == 0)
{
num_columns = 16;
@@ -7290,8 +7296,8 @@ DF_VIEW_UI_FUNCTION_DEF(memory)
};
AnnotationList *visible_memory_annotations = push_array(scratch.arena, AnnotationList, visible_memory_size);
{
D_Entity *thread = d_entity_from_handle(df_regs()->thread);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->thread);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
CTRL_Unwind unwind = d_query_cached_unwind_from_thread(thread);
//- rjf: fill unwind frame annotations
@@ -7308,9 +7314,9 @@ DF_VIEW_UI_FUNCTION_DEF(memory)
if(dim_1u64(frame_vaddr_range_in_viz) != 0)
{
U64 f_rip = regs_rip_from_arch_block(thread->arch, f->regs);
D_Entity *module = d_module_from_process_vaddr(process, f_rip);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
U64 rip_voff = d_voff_from_vaddr(module, f_rip);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, f_rip);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
U64 rip_voff = ctrl_voff_from_vaddr(module, f_rip);
String8 symbol_name = d_symbol_name_from_dbgi_key_voff(scratch.arena, &dbgi_key, rip_voff, 1);
Annotation *annotation = push_array(scratch.arena, Annotation, 1);
annotation->name_string = symbol_name.size != 0 ? symbol_name : str8_lit("[external code]");
@@ -7336,9 +7342,9 @@ DF_VIEW_UI_FUNCTION_DEF(memory)
if(dim_1u64(stack_vaddr_range_in_viz) != 0)
{
Annotation *annotation = push_array(scratch.arena, Annotation, 1);
annotation->name_string = d_display_string_from_entity(scratch.arena, thread);
annotation->name_string = thread->string.size ? thread->string : push_str8f(scratch.arena, "TID: %I64u", thread->id);
annotation->kind_string = str8_lit("Stack");
annotation->color = thread->flags & D_EntityFlag_HasColor ? d_rgba_from_entity(thread) : df_rgba_from_theme_color(DF_ThemeColor_Text);
annotation->color = (thread->rgba != 0) ? rgba_from_u32(thread->rgba) : df_rgba_from_theme_color(DF_ThemeColor_Text);
annotation->vaddr_range = stack_vaddr_range;
for(U64 vaddr = stack_vaddr_range_in_viz.min; vaddr < stack_vaddr_range_in_viz.max; vaddr += 1)
{
+92 -84
View File
@@ -431,8 +431,9 @@ df_entity_tooltips(D_Entity *entity)
UI_Tooltip UI_PrefWidth(ui_text_dim(10, 1))
{
String8 display_string = d_display_string_from_entity(scratch.arena, entity);
U64 rip_vaddr = d_query_cached_rip_from_thread(entity);
Arch arch = d_arch_from_entity(entity);
CTRL_Entity *entity_ctrl = ctrl_entity_from_handle(d_state->ctrl_entity_store, entity->ctrl_handle);
U64 rip_vaddr = d_query_cached_rip_from_thread(entity_ctrl);
Arch arch = entity_ctrl->arch;
String8 arch_str = string_from_arch(arch);
U32 pid_or_tid = entity->ctrl_id;
if(display_string.size != 0) UI_PrefWidth(ui_children_sum(1)) UI_Row
@@ -484,8 +485,8 @@ df_entity_tooltips(D_Entity *entity)
}
ui_spacer(ui_em(1.5f, 1.f));
DI_Scope *di_scope = di_scope_open();
D_Entity *process = d_entity_ancestor_from_kind(entity, D_EntityKind_Process);
CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity_ctrl, CTRL_EntityKind_Process);
CTRL_Unwind base_unwind = d_query_cached_unwind_from_thread(entity_ctrl);
D_Unwind rich_unwind = d_unwind_from_ctrl_unwind(scratch.arena, di_scope, process, &base_unwind);
for(U64 idx = 0; idx < rich_unwind.frames.concrete_frame_count; idx += 1)
{
@@ -493,8 +494,8 @@ df_entity_tooltips(D_Entity *entity)
RDI_Parsed *rdi = f->rdi;
RDI_Procedure *procedure = f->procedure;
U64 rip_vaddr = regs_rip_from_arch_block(entity->arch, f->regs);
D_Entity *module = d_module_from_process_vaddr(process, rip_vaddr);
String8 module_name = d_entity_is_nil(module) ? str8_lit("???") : str8_skip_last_slash(module->string);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
String8 module_name = module == &ctrl_entity_nil ? str8_lit("???") : str8_skip_last_slash(module->string);
// rjf: inline frames
for(D_UnwindInlineFrame *fin = f->last_inline_frame; fin != 0; fin = fin->prev)
@@ -688,18 +689,19 @@ df_entity_desc_button(D_Entity *entity, FuzzyMatchRangeList *name_matches, Strin
UI_Palette(ui_build_palette(ui_top_palette(), .text = df_rgba_from_theme_color(DF_ThemeColor_CodeSymbol)))
UI_Flags(UI_BoxFlag_DisableTruncatedHover)
{
CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity);
D_Entity *process = d_entity_ancestor_from_kind(entity, D_EntityKind_Process);
CTRL_Entity *entity_ctrl = ctrl_entity_from_handle(d_state->ctrl_entity_store, entity->ctrl_handle);
CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity_ctrl);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity_ctrl, CTRL_EntityKind_Process);
U64 idx = 0;
U64 limit = 3;
ui_spacer(ui_em(1.f, 1.f));
for(U64 num = unwind.frames.count; num > 0; num -= 1)
{
CTRL_UnwindFrame *f = &unwind.frames.v[num-1];
U64 rip_vaddr = regs_rip_from_arch_block(entity->arch, f->regs);
D_Entity *module = d_module_from_process_vaddr(process, rip_vaddr);
U64 rip_voff = d_voff_from_vaddr(module, rip_vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
U64 rip_vaddr = regs_rip_from_arch_block(entity_ctrl->arch, f->regs);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
String8 procedure_name = d_symbol_name_from_dbgi_key_voff(scratch.arena, &dbgi_key, rip_voff, 0);
if(procedure_name.size != 0)
{
@@ -949,12 +951,13 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
DF_CodeSliceSignal result = {0};
ProfBeginFunction();
Temp scratch = scratch_begin(0, 0);
D_Entity *selected_thread = d_entity_from_handle(df_regs()->thread);
D_Entity *selected_thread_process = d_entity_ancestor_from_kind(selected_thread, D_EntityKind_Process);
CTRL_Entity *selected_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->thread);
CTRL_Entity *selected_thread_process = ctrl_entity_ancestor_from_kind(selected_thread, CTRL_EntityKind_Process);
U64 selected_thread_rip_unwind_vaddr = d_query_cached_rip_from_thread_unwind(selected_thread, df_regs()->unwind_count);
D_Entity *selected_thread_module = d_module_from_process_vaddr(selected_thread_process, selected_thread_rip_unwind_vaddr);
CTRL_Entity *selected_thread_module = ctrl_module_from_process_vaddr(selected_thread_process, selected_thread_rip_unwind_vaddr);
F32 selected_thread_module_alive_t = ui_anim(ui_key_from_stringf(ui_key_zero(), "###module_alive_t_%p", selected_thread_module), 1.f);
CTRL_Event stop_event = d_ctrl_last_stop_event();
D_Entity *stopper_thread = d_entity_from_ctrl_handle(stop_event.entity);
CTRL_Entity *stopper_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, stop_event.entity);
B32 is_focused = ui_is_focus_active();
B32 ctrlified = (os_get_event_flags() & OS_EventFlag_Ctrl);
Vec4F32 code_line_bgs[] =
@@ -1000,10 +1003,10 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
line_num < params->line_num_range.max;
line_num += 1, line_idx += 1)
{
D_EntityList threads = params->line_ips[line_idx];
for(D_EntityNode *n = threads.first; n != 0; n = n->next)
CTRL_EntityList threads = params->line_ips[line_idx];
for(CTRL_EntityNode *n = threads.first; n != 0; n = n->next)
{
if(n->entity == stopper_thread && (stop_event.cause == CTRL_EventCause_InterruptedByTrap || stop_event.cause == CTRL_EventCause_InterruptedByException))
if(n->v == stopper_thread && (stop_event.cause == CTRL_EventCause_InterruptedByTrap || stop_event.cause == CTRL_EventCause_InterruptedByException))
{
line_bg_colors[line_idx] = df_rgba_from_theme_color(DF_ThemeColor_HighlightOverlayError);
}
@@ -1035,30 +1038,29 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
line_num <= params->line_num_range.max;
line_num += 1, line_idx += 1)
{
D_EntityList line_ips = params->line_ips[line_idx];
CTRL_EntityList line_ips = params->line_ips[line_idx];
ui_set_next_hover_cursor(OS_Cursor_HandPoint);
UI_Box *line_margin_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable)|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawActiveEffects, "line_margin_%I64x", line_num);
UI_Parent(line_margin_box)
{
//- rjf: build margin thread ip ui
for(D_EntityNode *n = line_ips.first; n != 0; n = n->next)
for(CTRL_EntityNode *n = line_ips.first; n != 0; n = n->next)
{
// rjf: unpack thread
D_Entity *thread = n->entity;
CTRL_Entity *thread = n->v;
if(thread != selected_thread)
{
continue;
}
CTRL_Entity *thread_ctrl = ctrl_entity_from_handle(d_state->ctrl_entity_store, thread->ctrl_handle);
U64 unwind_count = (thread == selected_thread) ? df_regs()->unwind_count : 0;
U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, unwind_count);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
D_Entity *module = d_module_from_process_vaddr(process, thread_rip_vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
U64 thread_rip_voff = d_voff_from_vaddr(module, thread_rip_vaddr);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, D_EntityKind_Process);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr);
// rjf: thread info => color
Vec4F32 color = v4f32(1, 1, 1, 1);
Vec4F32 color = df_rgba_from_theme_color(DF_ThemeColor_Text);
{
if(unwind_count != 0)
{
@@ -1071,9 +1073,9 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
{
color = df_rgba_from_theme_color(DF_ThemeColor_ThreadError);
}
else if(thread->flags & D_EntityFlag_HasColor)
else if(thread->rgba != 0)
{
color = d_rgba_from_entity(thread);
color = rgba_from_u32(thread->rgba);
}
if(d_ctrl_targets_running() && d_ctrl_last_run_frame_idx() < df_state->frame_index)
{
@@ -1106,11 +1108,11 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
{
DF_ThreadBoxDrawExtData *u = push_array(ui_build_arena(), DF_ThreadBoxDrawExtData, 1);
u->thread_color = color;
u->alive_t = thread->alive_t;
u->is_selected = (thread == selected_thread);
u->is_frozen = !!thread_ctrl->is_frozen;
u->do_lines = df_setting_val_from_code(DF_SettingCode_ThreadLines).s32;
u->do_glow = df_setting_val_from_code(DF_SettingCode_ThreadGlow).s32;
u->alive_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###thread_alive_t_%p", thread), 1.f);
u->is_selected = (thread == selected_thread);
u->is_frozen = !!thread->is_frozen;
u->do_lines = df_setting_val_from_code(DF_SettingCode_ThreadLines).s32;
u->do_glow = df_setting_val_from_code(DF_SettingCode_ThreadGlow).s32;
ui_box_equip_custom_draw(thread_box, df_thread_box_draw_extensions, u);
// rjf: fill out progress t (progress into range of current line's
@@ -1142,25 +1144,27 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
// rjf: hover tooltips
if(ui_hovering(thread_sig) && !df_drag_is_active())
{
df_entity_tooltips(thread);
// TODO(rjf): @msgs df_entity_tooltips(thread); set rich hover info here!!!
}
// rjf: ip right-click menu
if(ui_right_clicked(thread_sig))
{
D_Handle handle = d_handle_from_entity(thread);
ui_ctx_menu_open(df_state->entity_ctx_menu_key, thread_box->key, v2f32(0, thread_box->rect.y1-thread_box->rect.y0));
DF_Window *window = df_window_from_handle(df_regs()->window);
window->entity_ctx_menu_entity = handle;
// TODO(rjf): @msgs top-level regs-based ctx menu here!!!!
// D_Handle handle = d_handle_from_entity(thread);
// ui_ctx_menu_open(df_state->entity_ctx_menu_key, thread_box->key, v2f32(0, thread_box->rect.y1-thread_box->rect.y0));
// DF_Window *window = df_window_from_handle(df_regs()->window);
// window->entity_ctx_menu_entity = handle;
}
// rjf: drag start
if(ui_dragging(thread_sig) && !contains_2f32(thread_box->rect, ui_mouse()))
{
DF_DragDropPayload payload = {0};
payload.key = thread_box->key;
payload.entity = d_handle_from_entity(thread);
df_drag_begin(&payload);
// TODO(rjf): @msgs top-level regs-based drag/drop here!!!
// DF_DragDropPayload payload = {0};
// payload.key = thread_box->key;
// payload.entity = d_handle_from_entity(thread);
// df_drag_begin(&payload);
}
}
}
@@ -1192,7 +1196,7 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
line_num <= params->line_num_range.max;
line_num += 1, line_idx += 1)
{
D_EntityList line_ips = params->line_ips[line_idx];
CTRL_EntityList line_ips = params->line_ips[line_idx];
D_EntityList line_bps = params->line_bps[line_idx];
D_EntityList line_pins = params->line_pins[line_idx];
ui_set_next_hover_cursor(OS_Cursor_HandPoint);
@@ -1200,21 +1204,20 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
UI_Parent(line_margin_box)
{
//- rjf: build margin thread ip ui
for(D_EntityNode *n = line_ips.first; n != 0; n = n->next)
for(CTRL_EntityNode *n = line_ips.first; n != 0; n = n->next)
{
// rjf: unpack thread
D_Entity *thread = n->entity;
CTRL_Entity *thread = n->v;
if(thread == selected_thread)
{
continue;
}
CTRL_Entity *thread_ctrl = ctrl_entity_from_handle(d_state->ctrl_entity_store, thread->ctrl_handle);
U64 unwind_count = (thread == selected_thread) ? df_regs()->unwind_count : 0;
U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, unwind_count);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
D_Entity *module = d_module_from_process_vaddr(process, thread_rip_vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
U64 thread_rip_voff = d_voff_from_vaddr(module, thread_rip_vaddr);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, D_EntityKind_Process);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr);
// rjf: thread info => color
Vec4F32 color = v4f32(1, 1, 1, 1);
@@ -1230,9 +1233,9 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
{
color = df_rgba_from_theme_color(DF_ThemeColor_ThreadError);
}
else if(thread->flags & D_EntityFlag_HasColor)
else if(thread->rgba != 0)
{
color = d_rgba_from_entity(thread);
color = rgba_from_u32(thread->rgba);
}
if(d_ctrl_targets_running() && d_ctrl_last_run_frame_idx() < df_state->frame_index)
{
@@ -1265,9 +1268,9 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
{
DF_ThreadBoxDrawExtData *u = push_array(ui_build_arena(), DF_ThreadBoxDrawExtData, 1);
u->thread_color = color;
u->alive_t = thread->alive_t;
u->is_selected = (thread == selected_thread);
u->is_frozen = !!thread_ctrl->is_frozen;
u->alive_t = ui_anim(ui_key_from_stringf(top_container_box->key, "###thread_alive_t_%p", thread), 1.f);
u->is_selected = (thread == selected_thread);
u->is_frozen = !!thread->is_frozen;
ui_box_equip_custom_draw(thread_box, df_thread_box_draw_extensions, u);
// rjf: fill out progress t (progress into range of current line's
@@ -1299,32 +1302,34 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
// rjf: hover tooltips
if(ui_hovering(thread_sig) && !df_drag_is_active())
{
df_entity_tooltips(thread);
// TODO(rjf): @msgs df_entity_tooltips(thread); set rich hover info here!!!
}
// rjf: ip right-click menu
if(ui_right_clicked(thread_sig))
{
D_Handle handle = d_handle_from_entity(thread);
ui_ctx_menu_open(df_state->entity_ctx_menu_key, thread_box->key, v2f32(0, thread_box->rect.y1-thread_box->rect.y0));
DF_Window *window = df_window_from_handle(df_regs()->window);
window->entity_ctx_menu_entity = handle;
// TODO(rjf): @msgs top-level regs-based ctx menu here!!!!
// D_Handle handle = d_handle_from_entity(thread);
// ui_ctx_menu_open(df_state->entity_ctx_menu_key, thread_box->key, v2f32(0, thread_box->rect.y1-thread_box->rect.y0));
// DF_Window *window = df_window_from_handle(df_regs()->window);
// window->entity_ctx_menu_entity = handle;
}
// rjf: double click => select
if(ui_double_clicked(thread_sig))
{
df_cmd(DF_CmdKind_SelectThread, .entity = d_handle_from_entity(thread));
df_cmd(DF_CmdKind_SelectThread, .thread = thread->handle);
ui_kill_action();
}
// rjf: drag start
if(ui_dragging(thread_sig) && !contains_2f32(thread_box->rect, ui_mouse()))
{
DF_DragDropPayload payload = {0};
payload.key = thread_box->key;
payload.entity = d_handle_from_entity(thread);
df_drag_begin(&payload);
// TODO(rjf): @msgs top-level regs-based drag/drop here!!!
// DF_DragDropPayload payload = {0};
// payload.key = thread_box->key;
// payload.entity = d_handle_from_entity(thread);
// df_drag_begin(&payload);
}
}
@@ -1516,7 +1521,7 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
{
U64 best_stamp = 0;
S64 line_info_line_num = 0;
F32 line_info_t = selected_thread_module->alive_t;
F32 line_info_t = selected_thread_module_alive_t;
D_LineList *lines = &params->line_infos[line_idx];
for(D_LineNode *n = lines->first; n != 0; n = n->next)
{
@@ -1609,10 +1614,10 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
line_num < params->line_num_range.max;
line_num += 1, line_idx += 1)
{
D_EntityList threads = params->line_ips[line_idx];
for(D_EntityNode *n = threads.first; n != 0; n = n->next)
CTRL_EntityList threads = params->line_ips[line_idx];
for(CTRL_EntityNode *n = threads.first; n != 0; n = n->next)
{
D_Entity *thread = n->entity;
CTRL_Entity *thread = n->v;
if(thread == stopper_thread &&
(stop_event.cause == CTRL_EventCause_InterruptedByException ||
stop_event.cause == CTRL_EventCause_InterruptedByTrap))
@@ -1886,22 +1891,23 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
}break;
case D_EntityKind_Thread:
{
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, dropped_entity->ctrl_handle);
U64 new_rip_vaddr = line_vaddr;
if(df_regs()->file_path.size != 0)
{
D_LineList *lines = &params->line_infos[line_idx];
for(D_LineNode *n = lines->first; n != 0; n = n->next)
{
D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, &n->v.dbgi_key);
D_Entity *module = d_module_from_thread_candidates(dropped_entity, &modules);
if(!d_entity_is_nil(module))
CTRL_EntityList modules = ctrl_modules_from_dbgi_key(scratch.arena, d_state->ctrl_entity_store, &n->v.dbgi_key);
CTRL_Entity *module = ctrl_module_from_thread_candidates(d_state->ctrl_entity_store, thread, &modules);
if(module != &ctrl_entity_nil)
{
new_rip_vaddr = d_vaddr_from_voff(module, n->v.voff_range.min);
new_rip_vaddr = ctrl_vaddr_from_voff(module, n->v.voff_range.min);
break;
}
}
}
df_cmd(DF_CmdKind_SetThreadIP, .entity = d_handle_from_entity(dropped_entity), .vaddr = new_rip_vaddr);
df_cmd(DF_CmdKind_SetThreadIP, .thread = thread->handle, .vaddr = new_rip_vaddr);
}break;
}
}
@@ -1956,6 +1962,7 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
//////////////////////////////
//- rjf: mouse -> set global frontend hovered line info
//
#if 0 // TODO(rjf): @msgs
if(ui_hovering(text_container_sig) && contains_1s64(params->line_num_range, mouse_pt.line) && (ui_mouse().x - text_container_box->rect.x0 < params->line_num_width_px + line_num_padding_px))
{
U64 line_slice_idx = mouse_pt.line-params->line_num_range.min;
@@ -1971,6 +1978,7 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
df_set_rich_hover_info(&info);
}
}
#endif
//////////////////////////////
//- rjf: hover eval
@@ -2150,7 +2158,7 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
{
mapped_special = 1;
new_color_kind = DF_ThemeColor_CodeSymbol;
mix_t = selected_thread_module->alive_t;
mix_t = selected_thread_module_alive_t;
}
}
if(!mapped_special && token->kind == TXT_TokenKind_Identifier)
@@ -2160,7 +2168,7 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
{
mapped_special = 1;
new_color_kind = DF_ThemeColor_CodeType;
mix_t = selected_thread_module->alive_t;
mix_t = selected_thread_module_alive_t;
}
}
break;
@@ -2172,7 +2180,7 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
{
mapped_special = 1;
new_color_kind = DF_ThemeColor_CodeLocal;
mix_t = selected_thread_module->alive_t;
mix_t = selected_thread_module_alive_t;
}
}
if(!mapped_special && token->kind == TXT_TokenKind_Identifier)
@@ -2182,7 +2190,7 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
{
mapped_special = 1;
new_color_kind = DF_ThemeColor_CodeLocal;
mix_t = selected_thread_module->alive_t;
mix_t = selected_thread_module_alive_t;
}
}
if(!mapped_special)
@@ -2192,7 +2200,7 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
{
mapped_special = 1;
new_color_kind = DF_ThemeColor_CodeRegister;
mix_t = selected_thread_module->alive_t;
mix_t = selected_thread_module_alive_t;
}
}
if(!mapped_special)
@@ -2202,7 +2210,7 @@ df_code_slice(DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
{
mapped_special = 1;
new_color_kind = DF_ThemeColor_CodeRegister;
mix_t = selected_thread_module->alive_t;
mix_t = selected_thread_module_alive_t;
}
}
}
@@ -2729,8 +2737,8 @@ df_fancy_string_list_from_code_string(Arena *arena, F32 alpha, B32 indirection_s
}
else
{
D_Entity *module = d_entity_from_handle(df_regs()->module);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
CTRL_Entity *module = ctrl_entity_from_handle(d_state->ctrl_entity_store, df_regs()->module);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
U64 symbol_voff = d_voff_from_dbgi_key_symbol_name(&dbgi_key, token_string);
if(symbol_voff != 0)
{
+1 -1
View File
@@ -43,7 +43,7 @@ struct DF_CodeSliceParams
Rng1U64 *line_ranges;
TXT_TokenArray *line_tokens;
D_EntityList *line_bps;
D_EntityList *line_ips;
CTRL_EntityList *line_ips;
D_EntityList *line_pins;
U64 *line_vaddrs;
D_LineList *line_infos;
@@ -31,10 +31,10 @@ DF_CmdKind_Null,
Rng1U64 df_reg_slot_range_table[32] =
{
{0},
{OffsetOf(DF_Regs, machine), OffsetOf(DF_Regs, machine) + sizeof(D_Handle)},
{OffsetOf(DF_Regs, module), OffsetOf(DF_Regs, module) + sizeof(D_Handle)},
{OffsetOf(DF_Regs, process), OffsetOf(DF_Regs, process) + sizeof(D_Handle)},
{OffsetOf(DF_Regs, thread), OffsetOf(DF_Regs, thread) + sizeof(D_Handle)},
{OffsetOf(DF_Regs, machine), OffsetOf(DF_Regs, machine) + sizeof(CTRL_Handle)},
{OffsetOf(DF_Regs, module), OffsetOf(DF_Regs, module) + sizeof(CTRL_Handle)},
{OffsetOf(DF_Regs, process), OffsetOf(DF_Regs, process) + sizeof(CTRL_Handle)},
{OffsetOf(DF_Regs, thread), OffsetOf(DF_Regs, thread) + sizeof(CTRL_Handle)},
{OffsetOf(DF_Regs, window), OffsetOf(DF_Regs, window) + sizeof(D_Handle)},
{OffsetOf(DF_Regs, panel), OffsetOf(DF_Regs, panel) + sizeof(D_Handle)},
{OffsetOf(DF_Regs, view), OffsetOf(DF_Regs, view) + sizeof(D_Handle)},
@@ -501,10 +501,10 @@ DF_SettingCode_COUNT,
typedef struct DF_Regs DF_Regs;
struct DF_Regs
{
D_Handle machine;
D_Handle module;
D_Handle process;
D_Handle thread;
CTRL_Handle machine;
CTRL_Handle module;
CTRL_Handle process;
CTRL_Handle thread;
D_Handle window;
D_Handle panel;
D_Handle view;
+1 -1
View File
@@ -2958,7 +2958,7 @@ ui_anim_(UI_Key key, UI_AnimParams *params)
{
U64 slot_idx = key.u64[0]%ui_state->anim_slots_count;
UI_AnimSlot *slot = &ui_state->anim_slots[slot_idx];
for(UI_AnimNode *n = slot->first; n != &ui_nil_anim_node; n = n->slot_next)
for(UI_AnimNode *n = slot->first; n != &ui_nil_anim_node && n != 0; n = n->slot_next)
{
if(ui_key_match(n->key, key))
{