ctrl -> d type pass

This commit is contained in:
Ryan Fleury committed 2026-04-22 13:37:00 -07:00
1 parent a90fbc844b
commit 0d8a6a4d3a
21 files changed
+1996 -2132

No files matched your search

+217 -222
View File
@@ -1,56 +1,56 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef CTRL_CORE_H
#define CTRL_CORE_H
#ifndef DBG_ENGINE_CTRL_H
#define DBG_ENGINE_CTRL_H
////////////////////////////////
//~ rjf: Unwind Types
typedef U32 CTRL_UnwindFlags;
typedef U32 D_UnwindFlags;
enum
{
CTRL_UnwindFlag_Error = (1<<0),
CTRL_UnwindFlag_Stale = (1<<1),
D_UnwindFlag_Error = (1<<0),
D_UnwindFlag_Stale = (1<<1),
};
typedef struct CTRL_UnwindStepResult CTRL_UnwindStepResult;
struct CTRL_UnwindStepResult
typedef struct D_UnwindStepResult D_UnwindStepResult;
struct D_UnwindStepResult
{
CTRL_UnwindFlags flags;
D_UnwindFlags flags;
};
typedef struct CTRL_UnwindFrame CTRL_UnwindFrame;
struct CTRL_UnwindFrame
typedef struct D_UnwindFrame D_UnwindFrame;
struct D_UnwindFrame
{
void *regs;
U64 cfa;
};
typedef struct CTRL_UnwindFrameNode CTRL_UnwindFrameNode;
struct CTRL_UnwindFrameNode
typedef struct D_UnwindFrameNode D_UnwindFrameNode;
struct D_UnwindFrameNode
{
CTRL_UnwindFrameNode *next;
CTRL_UnwindFrameNode *prev;
CTRL_UnwindFrame v;
D_UnwindFrameNode *next;
D_UnwindFrameNode *prev;
D_UnwindFrame v;
};
typedef struct CTRL_UnwindFrameArray CTRL_UnwindFrameArray;
struct CTRL_UnwindFrameArray
typedef struct D_UnwindFrameArray D_UnwindFrameArray;
struct D_UnwindFrameArray
{
CTRL_UnwindFrame *v;
D_UnwindFrame *v;
U64 count;
};
typedef struct CTRL_Unwind CTRL_Unwind;
struct CTRL_Unwind
typedef struct D_Unwind D_Unwind;
struct D_Unwind
{
CTRL_UnwindFrameArray frames;
CTRL_UnwindFlags flags;
D_UnwindFrameArray frames;
D_UnwindFlags flags;
};
typedef struct CTRL_FrameUnwindContext CTRL_FrameUnwindContext;
struct CTRL_FrameUnwindContext
typedef struct D_FrameUnwindContext D_FrameUnwindContext;
struct D_FrameUnwindContext
{
// DWARF
U64 cfa;
@@ -61,8 +61,8 @@ struct CTRL_FrameUnwindContext
////////////////////////////////
//~ rjf: Call Stack Types
typedef struct CTRL_CallStackFrame CTRL_CallStackFrame;
struct CTRL_CallStackFrame
typedef struct D_CallStackFrame D_CallStackFrame;
struct D_CallStackFrame
{
U64 unwind_count;
U64 inline_depth;
@@ -70,58 +70,58 @@ struct CTRL_CallStackFrame
U64 cfa;
};
typedef struct CTRL_CallStack CTRL_CallStack;
struct CTRL_CallStack
typedef struct D_CallStack D_CallStack;
struct D_CallStack
{
CTRL_CallStackFrame *frames;
D_CallStackFrame *frames;
U64 frames_count;
CTRL_CallStackFrame **concrete_frames;
D_CallStackFrame **concrete_frames;
U64 concrete_frames_count;
};
////////////////////////////////
//~ rjf: Call Stack Tree Types
typedef struct CTRL_CallStackTreeNode CTRL_CallStackTreeNode;
struct CTRL_CallStackTreeNode
typedef struct D_CallStackTreeNode D_CallStackTreeNode;
struct D_CallStackTreeNode
{
CTRL_CallStackTreeNode *hash_next;
CTRL_CallStackTreeNode *first;
CTRL_CallStackTreeNode *last;
CTRL_CallStackTreeNode *next;
CTRL_CallStackTreeNode *parent;
D_CallStackTreeNode *hash_next;
D_CallStackTreeNode *first;
D_CallStackTreeNode *last;
D_CallStackTreeNode *next;
D_CallStackTreeNode *parent;
U64 child_count;
U64 id;
CTRL_Handle process;
D_Handle process;
U64 vaddr;
U64 depth;
CTRL_HandleList threads;
D_HandleList threads;
U64 all_descendant_threads_count;
};
typedef struct CTRL_CallStackTree CTRL_CallStackTree;
struct CTRL_CallStackTree
typedef struct D_CallStackTree D_CallStackTree;
struct D_CallStackTree
{
CTRL_CallStackTreeNode *root;
D_CallStackTreeNode *root;
U64 slots_count;
CTRL_CallStackTreeNode **slots;
D_CallStackTreeNode **slots;
};
////////////////////////////////
//~ rjf: Evaluation Spaces
typedef U64 CTRL_EvalSpaceKind;
typedef U64 D_EvalSpaceKind;
enum
{
CTRL_EvalSpaceKind_Entity = E_SpaceKind_FirstUserDefined,
CTRL_EvalSpaceKind_FirstUserDefined,
D_EvalSpaceKind_Entity = E_SpaceKind_FirstUserDefined,
D_EvalSpaceKind_FirstUserDefined,
};
////////////////////////////////
//~ rjf: Process Memory Types
typedef struct CTRL_ProcessMemorySlice CTRL_ProcessMemorySlice;
struct CTRL_ProcessMemorySlice
typedef struct D_ProcessMemorySlice D_ProcessMemorySlice;
struct D_ProcessMemorySlice
{
String8 data;
U64 *byte_bad_flags;
@@ -134,49 +134,49 @@ struct CTRL_ProcessMemorySlice
////////////////////////////////
//~ rjf: Thread Register Cache Types
typedef struct CTRL_ThreadRegCacheNode CTRL_ThreadRegCacheNode;
struct CTRL_ThreadRegCacheNode
typedef struct D_ThreadRegCacheNode D_ThreadRegCacheNode;
struct D_ThreadRegCacheNode
{
CTRL_ThreadRegCacheNode *next;
CTRL_ThreadRegCacheNode *prev;
CTRL_Handle handle;
D_ThreadRegCacheNode *next;
D_ThreadRegCacheNode *prev;
D_Handle handle;
U64 block_size;
void *block;
U64 reg_gen;
};
typedef struct CTRL_ThreadRegCacheSlot CTRL_ThreadRegCacheSlot;
struct CTRL_ThreadRegCacheSlot
typedef struct D_ThreadRegCacheSlot D_ThreadRegCacheSlot;
struct D_ThreadRegCacheSlot
{
CTRL_ThreadRegCacheNode *first;
CTRL_ThreadRegCacheNode *last;
D_ThreadRegCacheNode *first;
D_ThreadRegCacheNode *last;
};
typedef struct CTRL_ThreadRegCacheStripe CTRL_ThreadRegCacheStripe;
struct CTRL_ThreadRegCacheStripe
typedef struct D_ThreadRegCacheStripe D_ThreadRegCacheStripe;
struct D_ThreadRegCacheStripe
{
Arena *arena;
RWMutex rw_mutex;
};
typedef struct CTRL_ThreadRegCache CTRL_ThreadRegCache;
struct CTRL_ThreadRegCache
typedef struct D_ThreadRegCache D_ThreadRegCache;
struct D_ThreadRegCache
{
U64 slots_count;
CTRL_ThreadRegCacheSlot *slots;
D_ThreadRegCacheSlot *slots;
U64 stripes_count;
CTRL_ThreadRegCacheStripe *stripes;
D_ThreadRegCacheStripe *stripes;
};
////////////////////////////////
//~ rjf: Module Image Info Cache Types
typedef struct CTRL_ModuleImageInfoCacheNode CTRL_ModuleImageInfoCacheNode;
struct CTRL_ModuleImageInfoCacheNode
typedef struct D_ModuleImageInfoCacheNode D_ModuleImageInfoCacheNode;
struct D_ModuleImageInfoCacheNode
{
CTRL_ModuleImageInfoCacheNode *next;
CTRL_ModuleImageInfoCacheNode *prev;
CTRL_Handle module;
D_ModuleImageInfoCacheNode *next;
D_ModuleImageInfoCacheNode *prev;
D_Handle module;
Arena *arena;
PE_IntelPdata *pdatas;
U64 pdatas_count;
@@ -191,40 +191,40 @@ struct CTRL_ModuleImageInfoCacheNode
String8 raddbg_data;
};
typedef struct CTRL_ModuleImageInfoCacheSlot CTRL_ModuleImageInfoCacheSlot;
struct CTRL_ModuleImageInfoCacheSlot
typedef struct D_ModuleImageInfoCacheSlot D_ModuleImageInfoCacheSlot;
struct D_ModuleImageInfoCacheSlot
{
CTRL_ModuleImageInfoCacheNode *first;
CTRL_ModuleImageInfoCacheNode *last;
D_ModuleImageInfoCacheNode *first;
D_ModuleImageInfoCacheNode *last;
};
typedef struct CTRL_ModuleImageInfoCacheStripe CTRL_ModuleImageInfoCacheStripe;
struct CTRL_ModuleImageInfoCacheStripe
typedef struct D_ModuleImageInfoCacheStripe D_ModuleImageInfoCacheStripe;
struct D_ModuleImageInfoCacheStripe
{
Arena *arena;
RWMutex rw_mutex;
};
typedef struct CTRL_ModuleImageInfoCache CTRL_ModuleImageInfoCache;
struct CTRL_ModuleImageInfoCache
typedef struct D_ModuleImageInfoCache D_ModuleImageInfoCache;
struct D_ModuleImageInfoCache
{
U64 slots_count;
CTRL_ModuleImageInfoCacheSlot *slots;
D_ModuleImageInfoCacheSlot *slots;
U64 stripes_count;
CTRL_ModuleImageInfoCacheStripe *stripes;
D_ModuleImageInfoCacheStripe *stripes;
};
////////////////////////////////
//~ rjf: Touched Debug Info Directory Cache
typedef struct CTRL_DbgDirNode CTRL_DbgDirNode;
struct CTRL_DbgDirNode
typedef struct D_DbgDirNode D_DbgDirNode;
struct D_DbgDirNode
{
CTRL_DbgDirNode *first;
CTRL_DbgDirNode *last;
CTRL_DbgDirNode *next;
CTRL_DbgDirNode *prev;
CTRL_DbgDirNode *parent;
D_DbgDirNode *first;
D_DbgDirNode *last;
D_DbgDirNode *next;
D_DbgDirNode *prev;
D_DbgDirNode *parent;
String8 name;
U64 search_count;
U64 child_count;
@@ -234,8 +234,8 @@ struct CTRL_DbgDirNode
////////////////////////////////
//~ rjf: Control Thread Evaluation Scopes
typedef struct CTRL_EvalScope CTRL_EvalScope;
struct CTRL_EvalScope
typedef struct D_EvalScope D_EvalScope;
struct D_EvalScope
{
Access *access;
E_BaseCtx base_ctx;
@@ -246,19 +246,19 @@ struct CTRL_EvalScope
////////////////////////////////
//~ rjf: Module Requirement Cache Types
typedef struct CTRL_ModuleReqCacheNode CTRL_ModuleReqCacheNode;
struct CTRL_ModuleReqCacheNode
typedef struct D_ModuleReqCacheNode D_ModuleReqCacheNode;
struct D_ModuleReqCacheNode
{
CTRL_ModuleReqCacheNode *next;
CTRL_Handle module;
D_ModuleReqCacheNode *next;
D_Handle module;
B32 required;
};
////////////////////////////////
//~ rjf: Wakeup Hook Function Types
#define CTRL_WAKEUP_FUNCTION_DEF(name) void name(void)
typedef CTRL_WAKEUP_FUNCTION_DEF(CTRL_WakeupFunctionType);
#define D_WAKEUP_FUNCTION_DEF(name) void name(void)
typedef D_WAKEUP_FUNCTION_DEF(D_WakeupFunctionType);
////////////////////////////////
//~ rjf: Main State Types
@@ -267,15 +267,15 @@ typedef struct D_CtrlState D_CtrlState;
struct D_CtrlState
{
Arena *arena;
CTRL_WakeupFunctionType *wakeup_hook;
D_WakeupFunctionType *wakeup_hook;
// rjf: name -> register/alias hash tables for eval
E_String2NumMap arch_string2reg_tables[Arch_COUNT];
E_String2NumMap arch_string2alias_tables[Arch_COUNT];
// rjf: caches
CTRL_ThreadRegCache thread_reg_cache;
CTRL_ModuleImageInfoCache module_image_info_cache;
D_ThreadRegCache thread_reg_cache;
D_ModuleImageInfoCache module_image_info_cache;
// rjf: generations
U64 run_gen;
@@ -305,7 +305,7 @@ struct D_CtrlState
Thread ctrl_thread;
Log *ctrl_thread_log;
RWMutex ctrl_thread_entity_ctx_rw_mutex;
CTRL_EntityCtxRWStore *ctrl_thread_entity_store;
D_EntityCtxRWStore *ctrl_thread_entity_store;
E_Cache *ctrl_thread_eval_cache;
Arena *ctrl_thread_msg_process_arena;
Arena *dmn_event_arena;
@@ -314,12 +314,12 @@ struct D_CtrlState
DMN_EventNode *free_dmn_event_node;
Arena *user_entry_point_arena;
String8List user_entry_points;
U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64];
U64 exception_code_filters[(D_ExceptionCodeKind_COUNT+63)/64];
U64 process_counter;
Arena *dbg_dir_arena;
CTRL_DbgDirNode *dbg_dir_root;
D_DbgDirNode *dbg_dir_root;
U64 module_req_cache_slots_count;
CTRL_ModuleReqCacheNode **module_req_cache_slots;
D_ModuleReqCacheNode **module_req_cache_slots;
String8List msg_user_bp_touched_files;
String8List msg_user_bp_touched_symbols;
};
@@ -328,60 +328,55 @@ struct D_CtrlState
//~ rjf: Globals
global D_CtrlState *d_ctrl_state = 0;
read_only global CTRL_Entity ctrl_entity_nil =
read_only global D_Entity d_entity_nil =
{
&ctrl_entity_nil,
&ctrl_entity_nil,
&ctrl_entity_nil,
&ctrl_entity_nil,
&ctrl_entity_nil,
&d_entity_nil,
&d_entity_nil,
&d_entity_nil,
&d_entity_nil,
&d_entity_nil,
};
read_only global CTRL_CallStackTreeNode ctrl_call_stack_tree_node_nil =
read_only global D_CallStackTreeNode d_call_stack_tree_node_nil =
{
0,
&ctrl_call_stack_tree_node_nil,
&ctrl_call_stack_tree_node_nil,
&ctrl_call_stack_tree_node_nil,
&ctrl_call_stack_tree_node_nil,
&d_call_stack_tree_node_nil,
&d_call_stack_tree_node_nil,
&d_call_stack_tree_node_nil,
&d_call_stack_tree_node_nil,
};
thread_static CTRL_EntityCtxLookupAccel *ctrl_entity_ctx_lookup_accel = 0;
////////////////////////////////
//~ rjf: Logging Markup
#define CTRL_CtrlThreadLogScope DeferLoop(log_scope_begin(), ctrl_thread__end_and_flush_log())
thread_static D_EntityCtxLookupAccel *d_entity_ctx_lookup_accel = 0;
////////////////////////////////
//~ rjf: Basic Type Functions
internal U64 ctrl_hash_from_string(String8 string);
internal U64 ctrl_hash_from_handle(CTRL_Handle handle);
internal CTRL_EventCause ctrl_event_cause_from_dmn_event_kind(DMN_EventKind event_kind);
internal CTRL_ExceptionKind ctrl_exception_kind_from_dmn(DMN_ExceptionKind kind);
internal CTRL_TlsModel ctrl_dynamic_linker_type_from_dmn(DMN_TlsModel type);
internal String8 ctrl_string_from_event_kind(CTRL_EventKind kind);
internal String8 ctrl_string_from_msg_kind(CTRL_MsgKind kind);
internal CTRL_EntityKind ctrl_entity_kind_from_string(String8 string);
internal DMN_TrapFlags ctrl_dmn_trap_flags_from_user_breakpoint_flags(CTRL_UserBreakpointFlags flags);
internal CTRL_UserBreakpointFlags ctrl_user_breakpoint_flags_from_dmn_trap_flags(DMN_TrapFlags flags);
internal U64 ctrl_hash_from_handle(D_Handle handle);
internal D_EventCause ctrl_event_cause_from_dmn_event_kind(DMN_EventKind event_kind);
internal D_ExceptionKind ctrl_exception_kind_from_dmn(DMN_ExceptionKind kind);
internal D_TlsModel ctrl_dynamic_linker_type_from_dmn(DMN_TlsModel type);
internal String8 ctrl_string_from_event_kind(D_EventKind kind);
internal String8 ctrl_string_from_msg_kind(D_MsgKind kind);
internal D_EntityKind ctrl_entity_kind_from_string(String8 string);
internal DMN_TrapFlags ctrl_dmn_trap_flags_from_user_breakpoint_flags(D_BreakpointFlags flags);
internal D_BreakpointFlags ctrl_user_breakpoint_flags_from_dmn_trap_flags(DMN_TrapFlags flags);
////////////////////////////////
//~ rjf: Handle Type Functions
internal CTRL_Handle ctrl_handle_zero(void);
internal CTRL_Handle ctrl_handle_make(CTRL_MachineID machine_id, DMN_Handle dmn_handle);
internal B32 ctrl_handle_match(CTRL_Handle a, CTRL_Handle b);
internal void ctrl_handle_list_push(Arena *arena, CTRL_HandleList *list, CTRL_Handle *pair);
internal CTRL_HandleList ctrl_handle_list_copy(Arena *arena, CTRL_HandleList *src);
internal CTRL_HandleArray ctrl_handle_array_from_list(Arena *arena, CTRL_HandleList *src);
internal String8 ctrl_string_from_handle(Arena *arena, CTRL_Handle handle);
internal CTRL_Handle ctrl_handle_from_string(String8 string);
internal D_Handle ctrl_handle_zero(void);
internal D_Handle ctrl_handle_make(D_MachineID machine_id, DMN_Handle dmn_handle);
internal B32 ctrl_handle_match(D_Handle a, D_Handle b);
internal void ctrl_handle_list_push(Arena *arena, D_HandleList *list, D_Handle *pair);
internal D_HandleList ctrl_handle_list_copy(Arena *arena, D_HandleList *src);
internal D_HandleArray ctrl_handle_array_from_list(Arena *arena, D_HandleList *src);
internal String8 ctrl_string_from_handle(Arena *arena, D_Handle handle);
internal D_Handle ctrl_handle_from_string(String8 string);
////////////////////////////////
//~ rjf: Trap Type Functions
internal void ctrl_trap_list_push(Arena *arena, CTRL_TrapList *list, CTRL_Trap *trap);
internal CTRL_TrapList ctrl_trap_list_copy(Arena *arena, CTRL_TrapList *src);
internal void ctrl_trap_list_push(Arena *arena, D_TrapList *list, D_Trap *trap);
internal D_TrapList ctrl_trap_list_copy(Arena *arena, D_TrapList *src);
////////////////////////////////
//~ rjf: User Breakpoint Type Functions
@@ -393,137 +388,137 @@ internal CTRL_UserBreakpointList ctrl_user_breakpoint_list_copy(Arena *arena, CT
//~ rjf: Message Type Functions
//- rjf: deep copying
internal void ctrl_msg_deep_copy(Arena *arena, CTRL_Msg *dst, CTRL_Msg *src);
internal void ctrl_msg_deep_copy(Arena *arena, D_Msg *dst, D_Msg *src);
//- rjf: list building
internal CTRL_Msg *ctrl_msg_list_push(Arena *arena, CTRL_MsgList *list);
internal CTRL_MsgList ctrl_msg_list_deep_copy(Arena *arena, CTRL_MsgList *src);
internal void ctrl_msg_list_concat_in_place(CTRL_MsgList *dst, CTRL_MsgList *src);
internal D_Msg *ctrl_msg_list_push(Arena *arena, D_MsgList *list);
internal D_MsgList ctrl_msg_list_deep_copy(Arena *arena, D_MsgList *src);
internal void ctrl_msg_list_concat_in_place(D_MsgList *dst, D_MsgList *src);
//- rjf: serialization
internal String8 ctrl_serialized_string_from_msg_list(Arena *arena, CTRL_MsgList *msgs);
internal CTRL_MsgList ctrl_msg_list_from_serialized_string(Arena *arena, String8 string);
internal String8 ctrl_serialized_string_from_msg_list(Arena *arena, D_MsgList *msgs);
internal D_MsgList ctrl_msg_list_from_serialized_string(Arena *arena, String8 string);
////////////////////////////////
//~ rjf: Event Type Functions
//- rjf: list building
internal CTRL_Event *ctrl_event_list_push(Arena *arena, CTRL_EventList *list);
internal void ctrl_event_list_concat_in_place(CTRL_EventList *dst, CTRL_EventList *to_push);
internal D_Event *ctrl_event_list_push(Arena *arena, D_EventList *list);
internal void ctrl_event_list_concat_in_place(D_EventList *dst, D_EventList *to_push);
//- rjf: serialization
internal String8 ctrl_serialized_string_from_event(Arena *arena, CTRL_Event *event, U64 max);
internal CTRL_Event ctrl_event_from_serialized_string(Arena *arena, String8 string);
internal String8 ctrl_serialized_string_from_event(Arena *arena, D_Event *event, U64 max);
internal D_Event ctrl_event_from_serialized_string(Arena *arena, String8 string);
////////////////////////////////
//~ rjf: Entity Type Functions
//- 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_EntityCtx *ctx, CTRL_HandleList *list);
#define ctrl_entity_list_first(list) ((list)->first ? (list)->first->v : &ctrl_entity_nil)
internal void ctrl_entity_list_push(Arena *arena, D_EntityList *list, D_Entity *entity);
internal D_EntityList ctrl_entity_list_from_handle_list(Arena *arena, D_EntityCtx *ctx, D_HandleList *list);
#define ctrl_entity_list_first(list) ((list)->first ? (list)->first->v : &d_entity_nil)
//- rjf: entity array data structure
internal CTRL_EntityArray ctrl_entity_array_from_list(Arena *arena, CTRL_EntityList *list);
#define ctrl_entity_array_first(array) ((array)->count != 0 ? (array)->v[0] : &ctrl_entity_nil)
internal D_EntityArray ctrl_entity_array_from_list(Arena *arena, D_EntityList *list);
#define ctrl_entity_array_first(array) ((array)->count != 0 ? (array)->v[0] : &d_entity_nil)
//- rjf: entity context (entity group read-only) functions
internal CTRL_Entity *ctrl_entity_from_handle(CTRL_EntityCtx *ctx, CTRL_Handle handle);
internal CTRL_Entity *ctrl_entity_child_from_kind(CTRL_Entity *parent, CTRL_EntityKind kind);
internal CTRL_Entity *ctrl_entity_ancestor_from_kind(CTRL_Entity *entity, CTRL_EntityKind kind);
internal CTRL_Entity *ctrl_process_from_entity(CTRL_Entity *entity);
internal CTRL_Entity *ctrl_module_from_process_vaddr(CTRL_Entity *process, U64 vaddr);
internal DI_Key ctrl_dbgi_key_from_module(CTRL_Entity *module);
internal CTRL_Entity *ctrl_module_from_thread_candidates(CTRL_EntityCtx *ctx, CTRL_Entity *thread, CTRL_EntityList *candidates);
internal U64 ctrl_vaddr_from_voff(CTRL_Entity *module, U64 voff);
internal U64 ctrl_voff_from_vaddr(CTRL_Entity *module, U64 vaddr);
internal Rng1U64 ctrl_vaddr_range_from_voff_range(CTRL_Entity *module, Rng1U64 voff_range);
internal Rng1U64 ctrl_voff_range_from_vaddr_range(CTRL_Entity *module, Rng1U64 vaddr_range);
internal B32 ctrl_entity_tree_is_frozen(CTRL_Entity *root);
internal D_Entity *ctrl_entity_from_handle(D_EntityCtx *ctx, D_Handle handle);
internal D_Entity *ctrl_entity_child_from_kind(D_Entity *parent, D_EntityKind kind);
internal D_Entity *ctrl_entity_ancestor_from_kind(D_Entity *entity, D_EntityKind kind);
internal D_Entity *ctrl_process_from_entity(D_Entity *entity);
internal D_Entity *ctrl_module_from_process_vaddr(D_Entity *process, U64 vaddr);
internal DI_Key ctrl_dbgi_key_from_module(D_Entity *module);
internal D_Entity *ctrl_module_from_thread_candidates(D_EntityCtx *ctx, D_Entity *thread, D_EntityList *candidates);
internal U64 ctrl_vaddr_from_voff(D_Entity *module, U64 voff);
internal U64 ctrl_voff_from_vaddr(D_Entity *module, U64 vaddr);
internal Rng1U64 ctrl_vaddr_range_from_voff_range(D_Entity *module, Rng1U64 voff_range);
internal Rng1U64 ctrl_voff_range_from_vaddr_range(D_Entity *module, Rng1U64 vaddr_range);
internal B32 ctrl_entity_tree_is_frozen(D_Entity *root);
//- rjf: entity tree iteration
internal CTRL_EntityRec ctrl_entity_rec_depth_first(CTRL_Entity *entity, CTRL_Entity *subtree_root, U64 sib_off, U64 child_off);
#define ctrl_entity_rec_depth_first_pre(entity, subtree_root) ctrl_entity_rec_depth_first((entity), (subtree_root), OffsetOf(CTRL_Entity, next), OffsetOf(CTRL_Entity, first))
#define ctrl_entity_rec_depth_first_post(entity, subtree_root) ctrl_entity_rec_depth_first((entity), (subtree_root), OffsetOf(CTRL_Entity, prev), OffsetOf(CTRL_Entity, last))
internal D_EntityRec ctrl_entity_rec_depth_first(D_Entity *entity, D_Entity *subtree_root, U64 sib_off, U64 child_off);
#define ctrl_entity_rec_depth_first_pre(entity, subtree_root) ctrl_entity_rec_depth_first((entity), (subtree_root), OffsetOf(D_Entity, next), OffsetOf(D_Entity, first))
#define ctrl_entity_rec_depth_first_post(entity, subtree_root) ctrl_entity_rec_depth_first((entity), (subtree_root), OffsetOf(D_Entity, prev), OffsetOf(D_Entity, last))
//- rjf: entity ctx r/w store state functions
internal CTRL_EntityCtxRWStore *ctrl_entity_ctx_rw_store_alloc(void);
internal void ctrl_entity_ctx_rw_store_release(CTRL_EntityCtxRWStore *store);
internal D_EntityCtxRWStore *ctrl_entity_ctx_rw_store_alloc(void);
internal void ctrl_entity_ctx_rw_store_release(D_EntityCtxRWStore *store);
//- rjf: string allocation/deletion
internal U64 ctrl_name_bucket_num_from_string_size(U64 size);
internal String8 ctrl_entity_string_alloc(CTRL_EntityCtxRWStore *store, String8 string);
internal void ctrl_entity_string_release(CTRL_EntityCtxRWStore *store, String8 string);
internal String8 ctrl_entity_string_alloc(D_EntityCtxRWStore *store, String8 string);
internal void ctrl_entity_string_release(D_EntityCtxRWStore *store, String8 string);
//- rjf: entity construction/deletion
internal CTRL_Entity *ctrl_entity_alloc(CTRL_EntityCtxRWStore *store, CTRL_Entity *parent, CTRL_EntityKind kind, Arch arch, CTRL_Handle handle, U64 id);
internal void ctrl_entity_release(CTRL_EntityCtxRWStore *store, CTRL_Entity *entity);
internal D_Entity *ctrl_entity_alloc(D_EntityCtxRWStore *store, D_Entity *parent, D_EntityKind kind, Arch arch, D_Handle handle, U64 id);
internal void ctrl_entity_release(D_EntityCtxRWStore *store, D_Entity *entity);
//- rjf: entity equipment
internal void ctrl_entity_equip_string(CTRL_EntityCtxRWStore *store, CTRL_Entity *entity, String8 string);
internal void ctrl_entity_equip_string(D_EntityCtxRWStore *store, D_Entity *entity, String8 string);
//- rjf: accelerated entity context lookups
internal CTRL_EntityCtxLookupAccel *ctrl_thread_entity_ctx_lookup_accel(void);
internal CTRL_EntityArray ctrl_entity_array_from_kind(CTRL_EntityCtx *ctx, CTRL_EntityKind kind);
internal CTRL_EntityList ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityCtx *ctx, DI_Key dbgi_key);
internal CTRL_Entity *ctrl_thread_from_id(CTRL_EntityCtx *ctx, U64 id);
internal D_EntityCtxLookupAccel *ctrl_thread_entity_ctx_lookup_accel(void);
internal D_EntityArray ctrl_entity_array_from_kind(D_EntityCtx *ctx, D_EntityKind kind);
internal D_EntityList ctrl_modules_from_dbgi_key(Arena *arena, D_EntityCtx *ctx, DI_Key dbgi_key);
internal D_Entity *ctrl_thread_from_id(D_EntityCtx *ctx, U64 id);
//- rjf: applying events to entity caches
internal void ctrl_entity_store_apply_events(CTRL_EntityCtxRWStore *store, CTRL_EventList *list);
internal void ctrl_entity_store_apply_events(D_EntityCtxRWStore *store, D_EventList *list);
////////////////////////////////
//~ rjf: Wakeup Callback Registration
internal void ctrl_set_wakeup_hook(CTRL_WakeupFunctionType *wakeup_hook);
internal void ctrl_set_wakeup_hook(D_WakeupFunctionType *wakeup_hook);
////////////////////////////////
//~ rjf: Thread Register Functions
//- rjf: thread register cache reading
internal void *ctrl_reg_block_from_thread(Arena *arena, CTRL_EntityCtx *ctx, CTRL_Handle handle);
internal U64 ctrl_tls_root_vaddr_from_thread(CTRL_EntityCtx *ctx, CTRL_Handle handle);
internal U64 ctrl_rip_from_thread(CTRL_EntityCtx *ctx, CTRL_Handle handle);
internal U64 ctrl_rsp_from_thread(CTRL_EntityCtx *ctx, CTRL_Handle handle);
internal void *ctrl_reg_block_from_thread(Arena *arena, D_EntityCtx *ctx, D_Handle handle);
internal U64 ctrl_tls_root_vaddr_from_thread(D_EntityCtx *ctx, D_Handle handle);
internal U64 ctrl_rip_from_thread(D_EntityCtx *ctx, D_Handle handle);
internal U64 ctrl_rsp_from_thread(D_EntityCtx *ctx, D_Handle handle);
//- rjf: thread register writing
internal B32 ctrl_thread_write_reg_block(CTRL_Handle thread, void *block);
internal B32 ctrl_thread_write_reg_block(D_Handle thread, void *block);
////////////////////////////////
//~ rjf: Module Image Info Functions
//- rjf: cache lookups
internal PE_IntelPdata *ctrl_intel_pdata_from_module_voff(Arena *arena, CTRL_Handle module_handle, U64 voff);
internal U64 ctrl_entry_point_voff_from_module(CTRL_Handle module_handle);
internal String8 ctrl_initial_debug_info_path_from_module(Arena *arena, CTRL_Handle module_handle);
internal String8 ctrl_raddbg_data_from_module(Arena *arena, CTRL_Handle module_handle);
internal PE_IntelPdata *ctrl_intel_pdata_from_module_voff(Arena *arena, D_Handle module_handle, U64 voff);
internal U64 ctrl_entry_point_voff_from_module(D_Handle module_handle);
internal String8 ctrl_initial_debug_info_path_from_module(Arena *arena, D_Handle module_handle);
internal String8 ctrl_raddbg_data_from_module(Arena *arena, D_Handle module_handle);
////////////////////////////////
//~ Process Info Functions
internal Arch ctrl_arch_from_process_handle(CTRL_Handle process_handle);
internal Arch ctrl_arch_from_process_handle(D_Handle process_handle);
////////////////////////////////
//~ rjf: Unwinding Functions
//- rjf: unwind deep copier
internal CTRL_Unwind ctrl_unwind_deep_copy(Arena *arena, Arch arch, CTRL_Unwind *src);
internal D_Unwind ctrl_unwind_deep_copy(Arena *arena, Arch arch, D_Unwind *src);
//- DWARF
internal CTRL_UnwindStepResult ctrl_establish_frame_unwind_context__dwarf(Arena *arena, CTRL_Handle process_handle, CTRL_Handle module_handle, Arch arch, void *regs, U64 endt_us, CTRL_FrameUnwindContext *ctx_out);
internal CTRL_UnwindStepResult ctrl_unwind_step__dwarf(CTRL_Handle process_handle, Arch arch, void *regs, CTRL_FrameUnwindContext *frame_ctx, U64 endt_us);
internal D_UnwindStepResult ctrl_establish_frame_unwind_context__dwarf(Arena *arena, D_Handle process_handle, D_Handle module_handle, Arch arch, void *regs, U64 endt_us, D_FrameUnwindContext *ctx_out);
internal D_UnwindStepResult ctrl_unwind_step__dwarf(D_Handle process_handle, Arch arch, void *regs, D_FrameUnwindContext *frame_ctx, U64 endt_us);
//- rjf: [x64]
internal REGS_Reg64 *ctrl_unwind_reg_from_pe_gpr_reg__pe_x64(REGS_RegBlockX64 *regs, PE_UnwindGprRegX64 gpr_reg);
internal CTRL_UnwindStepResult ctrl_unwind_step__pe_x64(CTRL_Handle process_handle, CTRL_Handle module_handle, U64 module_base_vaddr, REGS_RegBlockX64 *regs, U64 endt_us);
internal D_UnwindStepResult ctrl_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 module_base_vaddr, REGS_RegBlockX64 *regs, U64 endt_us);
//- rjf: abstracted full unwind
internal CTRL_Unwind ctrl_unwind_from_thread(Arena *arena, CTRL_EntityCtx *ctx, CTRL_Handle thread, U64 endt_us);
internal D_Unwind ctrl_unwind_from_thread(Arena *arena, D_EntityCtx *ctx, D_Handle thread, U64 endt_us);
////////////////////////////////
//~ rjf: Call Stack Building Functions
internal CTRL_CallStack ctrl_call_stack_from_unwind(Arena *arena, CTRL_Entity *process, CTRL_Unwind *base_unwind);
internal CTRL_CallStackFrame *ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U64 unwind_count, U64 inline_depth);
internal D_CallStack ctrl_call_stack_from_unwind(Arena *arena, D_Entity *process, D_Unwind *base_unwind);
internal D_CallStackFrame *ctrl_call_stack_frame_from_unwind_and_inline_depth(D_CallStack *call_stack, U64 unwind_count, U64 inline_depth);
////////////////////////////////
//~ rjf: Halting All Attached Processes
@@ -546,75 +541,75 @@ internal E_String2NumMap *ctrl_string2alias_from_arch(Arch arch);
//~ rjf: Control-Thread Functions
//- rjf: user -> control thread communication
internal B32 ctrl_u2c_push_msgs(CTRL_MsgList *msgs, U64 endt_us);
internal CTRL_MsgList ctrl_u2c_pop_msgs(Arena *arena);
internal B32 ctrl_u2c_push_msgs(D_MsgList *msgs, U64 endt_us);
internal D_MsgList ctrl_u2c_pop_msgs(Arena *arena);
//- rjf: control -> user thread communication
internal void ctrl_c2u_push_events(CTRL_EventList *events);
internal CTRL_EventList ctrl_c2u_pop_events(Arena *arena);
internal void ctrl_c2u_push_events(D_EventList *events);
internal D_EventList ctrl_c2u_pop_events(Arena *arena);
//- rjf: entry point
internal void ctrl_thread__entry_point(void *p);
//- rjf: breakpoint resolution
internal void ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_EvalScope *eval_scope, CTRL_Handle process, CTRL_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out);
internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_EvalScope *eval_scope, CTRL_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out);
internal void ctrl_thread__append_program_defined_bp_traps(Arena *arena, CTRL_Entity *bp, DMN_TrapChunkList *traps_out);
internal void ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, D_EvalScope *eval_scope, D_Handle process, D_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out);
internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, D_EvalScope *eval_scope, D_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out);
internal void ctrl_thread__append_program_defined_bp_traps(Arena *arena, D_Entity *bp, DMN_TrapChunkList *traps_out);
//- rjf: module lifetime open/close work
internal void ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range, String8 path, Rng1U64 elf_phdr_vrange, U64 elf_phdr_entsize);
internal void ctrl_thread__module_close(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range);
internal void ctrl_thread__module_open(D_Handle process, D_Handle module, Rng1U64 vaddr_range, String8 path, Rng1U64 elf_phdr_vrange, U64 elf_phdr_entsize);
internal void ctrl_thread__module_close(D_Handle process, D_Handle module, Rng1U64 vaddr_range);
//- rjf: attached process running/event gathering
internal DMN_Event *ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, DMN_RunCtrls *run_ctrls, CTRL_Spoof *spoof);
internal DMN_Event *ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, DMN_RunCtrls *run_ctrls, D_Spoof *spoof);
//- rjf: eval helpers
internal U64 ctrl_eval_space_gen(E_Space space);
internal B32 ctrl_eval_space_read(E_Space space, void *out, Rng1U64 vaddr_range);
//- rjf: control thread eval scopes
internal CTRL_EvalScope *ctrl_thread__eval_scope_begin(Arena *arena, CTRL_UserBreakpointList *user_bps, CTRL_Entity *thread);
internal void ctrl_thread__eval_scope_end(CTRL_EvalScope *scope);
internal D_EvalScope *ctrl_thread__eval_scope_begin(Arena *arena, CTRL_UserBreakpointList *user_bps, D_Entity *thread);
internal void ctrl_thread__eval_scope_end(D_EvalScope *scope);
//- rjf: log flusher
internal void ctrl_thread__end_and_flush_log(void);
//- rjf: msg kind implementations
internal void ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
internal void ctrl_thread__attach(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
internal void ctrl_thread__kill(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
internal void ctrl_thread__kill_all(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
internal void ctrl_thread__detach(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
internal void ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
internal void ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
internal void ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg);
internal void ctrl_thread__attach(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg);
internal void ctrl_thread__kill(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg);
internal void ctrl_thread__kill_all(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg);
internal void ctrl_thread__detach(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg);
internal void ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg);
internal void ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg);
////////////////////////////////
//~ rjf: Process Memory Artifact Cache Hooks / Lookups
internal AC_Artifact ctrl_memory_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out);
internal void ctrl_memory_artifact_destroy(AC_Artifact artifact);
internal C_Key ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, B32 wait_for_fresh, U64 endt_us, B32 *out_is_stale);
internal C_Key ctrl_key_from_process_vaddr_range(D_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, B32 wait_for_fresh, U64 endt_us, B32 *out_is_stale);
//- rjf: process memory reading helpers
internal CTRL_ProcessMemorySlice ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rng1U64 range, B32 wait_for_fresh, U64 endt_us);
internal B32 ctrl_process_memory_read(CTRL_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 endt_us);
internal D_ProcessMemorySlice ctrl_process_memory_slice_from_vaddr_range(Arena *arena, D_Handle process, Rng1U64 range, B32 wait_for_fresh, U64 endt_us);
internal B32 ctrl_process_memory_read(D_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 endt_us);
#define ctrl_process_memory_read_struct(process, vaddr, is_stale_out, ptr, endt_us) ctrl_process_memory_read((process), r1u64((vaddr), (vaddr)+(sizeof(*(ptr)))), (is_stale_out), (ptr), (endt_us))
//- rjf: process memory writing
internal B32 ctrl_process_write(CTRL_Handle process, Rng1U64 range, void *src);
internal B32 ctrl_process_write(D_Handle process, Rng1U64 range, void *src);
////////////////////////////////
//~ rjf: Call Stack Artifact Cache Hooks / Lookups
internal AC_Artifact ctrl_call_stack_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out);
internal void ctrl_call_stack_artifact_destroy(AC_Artifact artifact);
internal CTRL_CallStack ctrl_call_stack_from_thread(Access *access, CTRL_Handle thread_handle, B32 high_priority, U64 endt_us);
internal D_CallStack ctrl_call_stack_from_thread(Access *access, D_Handle thread_handle, B32 high_priority, U64 endt_us);
////////////////////////////////
//~ rjf: Call Stack Tree Artifact Cache Hooks / Lookups
internal AC_Artifact ctrl_call_stack_tree_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out);
internal void ctrl_call_stack_tree_artifact_destroy(AC_Artifact artifact);
internal CTRL_CallStackTree ctrl_call_stack_tree(Access *access, U64 endt_us);
internal D_CallStackTree ctrl_call_stack_tree(Access *access, U64 endt_us);
#endif // CTRL_CORE_H
#endif // DBG_ENGINE_CTRL_H