ctrl -> d

This commit is contained in:
Ryan Fleury
2026-04-22 14:53:37 -07:00
parent 0e3c821e28
commit 2eb0b8b233
14 changed files with 988 additions and 1051 deletions
+6 -6
View File
@@ -115,13 +115,13 @@ D_EntityKindTable:
COUNT,
}
@data(String8) ctrl_entity_kind_code_name_table:
@data(String8) d_entity_kind_code_name_table:
{
`{0}`,
@expand(D_EntityKindTable a) `str8_lit_comp("$(a.code_name)")`
}
@data(String8) ctrl_entity_kind_display_string_table:
@data(String8) d_entity_kind_display_string_table:
{
`{0}`,
@expand(D_EntityKindTable a) `str8_lit_comp("$(a.display_name)")`
@@ -179,25 +179,25 @@ D_ExceptionCodeKindTable:
COUNT,
}
@data(U32) ctrl_exception_code_kind_code_table:
@data(U32) d_exception_code_kind_code_table:
{
`0`;
@expand(D_ExceptionCodeKindTable a) `$(a.code)`;
}
@data(String8) ctrl_exception_code_kind_display_string_table:
@data(String8) d_exception_code_kind_display_string_table:
{
`{0}`;
@expand(D_ExceptionCodeKindTable a) `str8_lit_comp("$(a.display_string)")`;
}
@data(String8) ctrl_exception_code_kind_lowercase_code_string_table:
@data(String8) d_exception_code_kind_lowercase_code_string_table:
{
`{0}`;
@expand(D_ExceptionCodeKindTable a) `str8_lit_comp("$(a.lower_name)")`;
}
@data(B8) ctrl_exception_code_kind_default_enable_table:
@data(B8) d_exception_code_kind_default_enable_table:
{
`0`;
@expand(D_ExceptionCodeKindTable a) `$(a.default)`;
+4 -4
View File
@@ -71,7 +71,7 @@ d_init(void)
scratch_end(scratch);
}
d_ctrl_state->ctrl_thread_entity_ctx_rw_mutex = rw_mutex_alloc();
d_ctrl_state->ctrl_thread_entity_store = ctrl_entity_ctx_rw_store_alloc();
d_ctrl_state->ctrl_thread_entity_store = d_entity_ctx_rw_store_alloc();
d_ctrl_state->ctrl_thread_eval_cache = e_cache_alloc();
d_ctrl_state->ctrl_thread_msg_process_arena = arena_alloc();
d_ctrl_state->dmn_event_arena = arena_alloc();
@@ -79,13 +79,13 @@ d_init(void)
d_ctrl_state->dbg_dir_arena = arena_alloc();
for(D_ExceptionCodeKind k = (D_ExceptionCodeKind)0; k < D_ExceptionCodeKind_COUNT; k = (D_ExceptionCodeKind)(k+1))
{
if(ctrl_exception_code_kind_default_enable_table[k])
if(d_exception_code_kind_default_enable_table[k])
{
d_ctrl_state->exception_code_filters[k/64] |= 1ull<<(k%64);
}
}
d_ctrl_state->ctrl_thread_log = log_alloc();
d_ctrl_state->ctrl_thread = thread_launch(ctrl_thread__entry_point, 0);
d_ctrl_state->ctrl_thread = thread_launch(d_ctrl_thread__entry_point, 0);
}
//- rjf: set up user state
@@ -96,7 +96,7 @@ d_init(void)
d_user_state->cmds_arena = arena_alloc();
d_user_state->output_log_key = c_key_make(c_root_alloc(), c_id_make(0, 0));
c_submit_data(d_user_state->output_log_key, 0, str8_zero());
d_user_state->ctrl_entity_store = ctrl_entity_ctx_rw_store_alloc();
d_user_state->ctrl_entity_store = d_entity_ctx_rw_store_alloc();
d_user_state->ctrl_stop_arena = arena_alloc();
d_user_state->ctrl_msg_arena = arena_alloc();
+5 -5
View File
@@ -179,14 +179,14 @@ struct D_EntityHashSlot
D_EntityHashNode *last;
};
typedef struct CTRL_EntityStringChunkNode CTRL_EntityStringChunkNode;
struct CTRL_EntityStringChunkNode
typedef struct D_EntityStringChunkNode D_EntityStringChunkNode;
struct D_EntityStringChunkNode
{
CTRL_EntityStringChunkNode *next;
D_EntityStringChunkNode *next;
U64 size;
};
read_only global U64 ctrl_entity_string_bucket_chunk_sizes[] =
read_only global U64 d_entity_string_bucket_chunk_sizes[] =
{
16,
64,
@@ -215,7 +215,7 @@ struct D_EntityCtxRWStore
D_EntityCtx ctx;
D_Entity *free;
D_EntityHashNode *hash_node_free;
CTRL_EntityStringChunkNode *free_string_chunks[ArrayCount(ctrl_entity_string_bucket_chunk_sizes)];
D_EntityStringChunkNode *free_string_chunks[ArrayCount(d_entity_string_bucket_chunk_sizes)];
};
typedef struct D_EntityCtxLookupAccel D_EntityCtxLookupAccel;
File diff suppressed because it is too large Load Diff
+124 -133
View File
@@ -349,267 +349,258 @@ 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(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);
internal U64 d_hash_from_handle(D_Handle handle);
internal D_EventCause d_event_cause_from_dmn_event_kind(DMN_EventKind event_kind);
internal D_ExceptionKind d_exception_kind_from_dmn(DMN_ExceptionKind kind);
internal D_TlsModel d_dynamic_linker_type_from_dmn(DMN_TlsModel type);
internal String8 d_string_from_event_kind(D_EventKind kind);
internal String8 d_string_from_msg_kind(D_MsgKind kind);
internal D_EntityKind d_entity_kind_from_string(String8 string);
internal DMN_TrapFlags d_dmn_trap_flags_from_breakpoint_flags(D_BreakpointFlags flags);
internal D_BreakpointFlags d_breakpoint_flags_from_dmn_trap_flags(DMN_TrapFlags flags);
////////////////////////////////
//~ rjf: Handle Type Functions
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);
internal D_Handle d_handle_zero(void);
internal D_Handle d_handle_make(D_MachineID machine_id, DMN_Handle dmn_handle);
internal B32 d_handle_match(D_Handle a, D_Handle b);
internal void d_handle_list_push(Arena *arena, D_HandleList *list, D_Handle *pair);
internal D_HandleList d_handle_list_copy(Arena *arena, D_HandleList *src);
internal D_HandleArray d_handle_array_from_list(Arena *arena, D_HandleList *src);
internal String8 d_string_from_handle(Arena *arena, D_Handle handle);
internal D_Handle d_handle_from_string(String8 string);
////////////////////////////////
//~ rjf: Trap Type Functions
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);
internal void d_trap_list_push(Arena *arena, D_TrapList *list, D_Trap *trap);
internal D_TrapList d_trap_list_copy(Arena *arena, D_TrapList *src);
////////////////////////////////
//~ rjf: User Breakpoint Type Functions
internal void ctrl_user_breakpoint_list_push(Arena *arena, D_BreakpointList *list, D_Breakpoint *bp);
internal D_BreakpointList ctrl_user_breakpoint_list_copy(Arena *arena, D_BreakpointList *src);
internal void d_breakpoint_list_push(Arena *arena, D_BreakpointList *list, D_Breakpoint *bp);
internal D_BreakpointList d_breakpoint_list_copy(Arena *arena, D_BreakpointList *src);
////////////////////////////////
//~ rjf: Message Type Functions
//- rjf: deep copying
internal void ctrl_msg_deep_copy(Arena *arena, D_Msg *dst, D_Msg *src);
internal void d_msg_deep_copy(Arena *arena, D_Msg *dst, D_Msg *src);
//- rjf: list building
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);
internal D_Msg *d_msg_list_push(Arena *arena, D_MsgList *list);
internal D_MsgList d_msg_list_deep_copy(Arena *arena, D_MsgList *src);
internal void d_msg_list_concat_in_place(D_MsgList *dst, D_MsgList *src);
//- rjf: serialization
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);
internal String8 d_serialized_string_from_msg_list(Arena *arena, D_MsgList *msgs);
internal D_MsgList d_msg_list_from_serialized_string(Arena *arena, String8 string);
////////////////////////////////
//~ rjf: Event Type Functions
//- rjf: list building
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);
internal D_Event *d_event_list_push(Arena *arena, D_EventList *list);
internal void d_event_list_concat_in_place(D_EventList *dst, D_EventList *to_push);
//- rjf: serialization
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);
internal String8 d_serialized_string_from_event(Arena *arena, D_Event *event, U64 max);
internal D_Event d_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, 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)
internal void d_entity_list_push(Arena *arena, D_EntityList *list, D_Entity *entity);
internal D_EntityList d_entity_list_from_handle_list(Arena *arena, D_EntityCtx *ctx, D_HandleList *list);
#define d_entity_list_first(list) ((list)->first ? (list)->first->v : &d_entity_nil)
//- rjf: entity array data structure
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)
internal D_EntityArray d_entity_array_from_list(Arena *arena, D_EntityList *list);
#define d_entity_array_first(array) ((array)->count != 0 ? (array)->v[0] : &d_entity_nil)
//- rjf: entity context (entity group read-only) functions
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);
internal D_Entity *d_entity_from_handle(D_EntityCtx *ctx, D_Handle handle);
internal D_Entity *d_entity_child_from_kind(D_Entity *parent, D_EntityKind kind);
internal D_Entity *d_entity_ancestor_from_kind(D_Entity *entity, D_EntityKind kind);
internal D_Entity *d_process_from_entity(D_Entity *entity);
internal D_Entity *d_module_from_process_vaddr(D_Entity *process, U64 vaddr);
internal DI_Key d_dbgi_key_from_module(D_Entity *module);
internal D_Entity *d_module_from_thread_candidates(D_EntityCtx *ctx, D_Entity *thread, D_EntityList *candidates);
internal U64 d_vaddr_from_voff(D_Entity *module, U64 voff);
internal U64 d_voff_from_vaddr(D_Entity *module, U64 vaddr);
internal Rng1U64 d_vaddr_range_from_voff_range(D_Entity *module, Rng1U64 voff_range);
internal Rng1U64 d_voff_range_from_vaddr_range(D_Entity *module, Rng1U64 vaddr_range);
internal B32 d_entity_tree_is_frozen(D_Entity *root);
//- rjf: entity tree iteration
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))
internal D_EntityRec d_entity_rec_depth_first(D_Entity *entity, D_Entity *subtree_root, U64 sib_off, U64 child_off);
#define d_entity_rec_depth_first_pre(entity, subtree_root) d_entity_rec_depth_first((entity), (subtree_root), OffsetOf(D_Entity, next), OffsetOf(D_Entity, first))
//- rjf: entity ctx r/w store state functions
internal D_EntityCtxRWStore *ctrl_entity_ctx_rw_store_alloc(void);
internal void ctrl_entity_ctx_rw_store_release(D_EntityCtxRWStore *store);
internal D_EntityCtxRWStore *d_entity_ctx_rw_store_alloc(void);
internal void d_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(D_EntityCtxRWStore *store, String8 string);
internal void ctrl_entity_string_release(D_EntityCtxRWStore *store, String8 string);
internal U64 d_name_bucket_num_from_string_size(U64 size);
internal String8 d_entity_string_alloc(D_EntityCtxRWStore *store, String8 string);
internal void d_entity_string_release(D_EntityCtxRWStore *store, String8 string);
//- rjf: entity construction/deletion
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);
internal D_Entity *d_entity_alloc(D_EntityCtxRWStore *store, D_Entity *parent, D_EntityKind kind, Arch arch, D_Handle handle, U64 id);
internal void d_entity_release(D_EntityCtxRWStore *store, D_Entity *entity);
//- rjf: entity equipment
internal void ctrl_entity_equip_string(D_EntityCtxRWStore *store, D_Entity *entity, String8 string);
internal void d_entity_equip_string(D_EntityCtxRWStore *store, D_Entity *entity, String8 string);
//- rjf: accelerated entity context lookups
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);
internal D_EntityCtxLookupAccel *d_thread_entity_ctx_lookup_accel(void);
internal D_EntityArray d_entity_array_from_kind(D_EntityCtx *ctx, D_EntityKind kind);
internal D_EntityList d_modules_from_dbgi_key(Arena *arena, D_EntityCtx *ctx, DI_Key dbgi_key);
internal D_Entity *d_thread_from_id(D_EntityCtx *ctx, U64 id);
//- rjf: applying events to entity caches
internal void ctrl_entity_store_apply_events(D_EntityCtxRWStore *store, D_EventList *list);
internal void d_entity_store_apply_events(D_EntityCtxRWStore *store, D_EventList *list);
////////////////////////////////
//~ rjf: Wakeup Callback Registration
internal void ctrl_set_wakeup_hook(D_WakeupFunctionType *wakeup_hook);
internal void d_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, 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);
internal void *d_reg_block_from_thread(Arena *arena, D_EntityCtx *ctx, D_Handle handle);
internal U64 d_tls_root_vaddr_from_thread(D_EntityCtx *ctx, D_Handle handle);
internal U64 d_rip_from_thread(D_EntityCtx *ctx, D_Handle handle);
internal U64 d_rsp_from_thread(D_EntityCtx *ctx, D_Handle handle);
//- rjf: thread register writing
internal B32 ctrl_thread_write_reg_block(D_Handle thread, void *block);
internal B32 d_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, 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(D_Handle process_handle);
internal PE_IntelPdata *d_intel_pdata_from_module_voff(Arena *arena, D_Handle module_handle, U64 voff);
internal U64 d_entry_point_voff_from_module(D_Handle module_handle);
internal String8 d_initial_debug_info_path_from_module(Arena *arena, D_Handle module_handle);
internal String8 d_raddbg_data_from_module(Arena *arena, D_Handle module_handle);
////////////////////////////////
//~ rjf: Unwinding Functions
//- rjf: unwind deep copier
internal D_Unwind ctrl_unwind_deep_copy(Arena *arena, Arch arch, D_Unwind *src);
//- DWARF
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: [dwarf]
internal D_UnwindStepResult d_unwind_step_result_from_machine_op_result(MachineOpResult s);
internal D_UnwindStepResult d_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 d_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 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);
internal REGS_Reg64 *d_unwind_reg_from_pe_gpr_reg__pe_x64(REGS_RegBlockX64 *regs, PE_UnwindGprRegX64 gpr_reg);
internal D_UnwindStepResult d_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 D_Unwind ctrl_unwind_from_thread(Arena *arena, D_EntityCtx *ctx, D_Handle thread, U64 endt_us);
internal D_Unwind d_unwind_from_thread(Arena *arena, D_EntityCtx *ctx, D_Handle thread, U64 endt_us);
////////////////////////////////
//~ rjf: Call Stack Building Functions
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);
internal D_CallStack d_call_stack_from_unwind(Arena *arena, D_Entity *process, D_Unwind *base_unwind);
internal D_CallStackFrame *d_call_stack_frame_from_unwind_and_inline_depth(D_CallStack *call_stack, U64 unwind_count, U64 inline_depth);
////////////////////////////////
//~ rjf: Halting All Attached Processes
internal void ctrl_halt(void);
internal void d_halt(void);
////////////////////////////////
//~ rjf: Shared Accessor Functions
//- rjf: generation counters
internal U64 ctrl_run_gen(void);
internal U64 ctrl_mem_gen(void);
internal U64 ctrl_reg_gen(void);
internal U64 d_run_gen(void);
internal U64 d_mem_gen(void);
internal U64 d_reg_gen(void);
//- rjf: name -> register/alias hash tables, for eval
internal E_String2NumMap *ctrl_string2reg_from_arch(Arch arch);
internal E_String2NumMap *ctrl_string2alias_from_arch(Arch arch);
internal E_String2NumMap *d_string2reg_from_arch(Arch arch);
internal E_String2NumMap *d_string2alias_from_arch(Arch arch);
////////////////////////////////
//~ rjf: Control-Thread Functions
//- rjf: user -> control thread communication
internal B32 ctrl_u2c_push_msgs(D_MsgList *msgs, U64 endt_us);
internal D_MsgList ctrl_u2c_pop_msgs(Arena *arena);
internal B32 d_u2c_push_msgs(D_MsgList *msgs, U64 endt_us);
internal D_MsgList d_u2c_pop_msgs(Arena *arena);
//- rjf: control -> user thread communication
internal void ctrl_c2u_push_events(D_EventList *events);
internal D_EventList ctrl_c2u_pop_events(Arena *arena);
internal void d_c2u_push_events(D_EventList *events);
internal D_EventList d_c2u_pop_events(Arena *arena);
//- rjf: entry point
internal void ctrl_thread__entry_point(void *p);
internal void d_ctrl_thread__entry_point(void *p);
//- rjf: breakpoint resolution
internal void ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, D_EvalScope *eval_scope, D_Handle process, D_Handle module, D_BreakpointList *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, D_BreakpointList *user_bps, DMN_TrapChunkList *traps_out);
internal void ctrl_thread__append_program_defined_bp_traps(Arena *arena, D_Entity *bp, DMN_TrapChunkList *traps_out);
internal void d_ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, D_EvalScope *eval_scope, D_Handle process, D_Handle module, D_BreakpointList *user_bps, DMN_TrapChunkList *traps_out);
internal void d_ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, D_EvalScope *eval_scope, D_Handle process, D_BreakpointList *user_bps, DMN_TrapChunkList *traps_out);
internal void d_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(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);
internal void d_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 d_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, D_Msg *msg, DMN_RunCtrls *run_ctrls, D_Spoof *spoof);
internal DMN_Event *d_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);
internal U64 d_ctrl_eval_space_gen(E_Space space);
internal B32 d_ctrl_eval_space_read(E_Space space, void *out, Rng1U64 vaddr_range);
//- rjf: control thread eval scopes
internal D_EvalScope *ctrl_thread__eval_scope_begin(Arena *arena, D_BreakpointList *user_bps, D_Entity *thread);
internal void ctrl_thread__eval_scope_end(D_EvalScope *scope);
internal D_EvalScope *d_ctrl_thread__eval_scope_begin(Arena *arena, D_BreakpointList *user_bps, D_Entity *thread);
internal void d_ctrl_thread__eval_scope_end(D_EvalScope *scope);
//- rjf: log flusher
internal void ctrl_thread__end_and_flush_log(void);
internal void d_ctrl_thread__end_and_flush_log(void);
//- rjf: msg kind implementations
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);
internal void d_ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg);
internal void d_ctrl_thread__attach(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg);
internal void d_ctrl_thread__kill(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg);
internal void d_ctrl_thread__kill_all(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg);
internal void d_ctrl_thread__detach(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg);
internal void d_ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg);
internal void d_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(D_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, B32 wait_for_fresh, U64 endt_us, B32 *out_is_stale);
internal AC_Artifact d_memory_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out);
internal void d_memory_artifact_destroy(AC_Artifact artifact);
internal C_Key d_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 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))
internal D_ProcessMemorySlice d_process_memory_slice_from_vaddr_range(Arena *arena, D_Handle process, Rng1U64 range, B32 wait_for_fresh, U64 endt_us);
internal B32 d_process_memory_read(D_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 endt_us);
#define d_process_memory_read_struct(process, vaddr, is_stale_out, ptr, endt_us) d_process_memory_read((process), r1u64((vaddr), (vaddr)+(sizeof(*(ptr)))), (is_stale_out), (ptr), (endt_us))
//- rjf: process memory writing
internal B32 ctrl_process_write(D_Handle process, Rng1U64 range, void *src);
internal B32 d_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 D_CallStack ctrl_call_stack_from_thread(Access *access, D_Handle thread_handle, B32 high_priority, U64 endt_us);
internal AC_Artifact d_call_stack_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out);
internal void d_call_stack_artifact_destroy(AC_Artifact artifact);
internal D_CallStack d_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 D_CallStackTree ctrl_call_stack_tree(Access *access, U64 endt_us);
internal AC_Artifact d_call_stack_tree_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out);
internal void d_call_stack_tree_artifact_destroy(AC_Artifact artifact);
internal D_CallStackTree d_call_stack_tree(Access *access, U64 endt_us);
#endif // DBG_ENGINE_CTRL_H
+88 -88
View File
@@ -292,15 +292,15 @@ d_trap_net_from_thread__step_over_inst(Arena *arena, D_Entity *thread)
D_TrapNet result = {0};
// rjf: thread => unpacked info
D_Entity *process = ctrl_entity_ancestor_from_kind(thread, D_EntityKind_Process);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
Arch arch = thread->arch;
U64 ip_vaddr = ctrl_rip_from_thread(&d_user_state->ctrl_entity_store->ctx, thread->handle);
U64 ip_vaddr = d_rip_from_thread(&d_user_state->ctrl_entity_store->ctx, thread->handle);
// rjf: ip => machine code
String8 machine_code = {0};
{
Rng1U64 rng = r1u64(ip_vaddr, ip_vaddr+max_instruction_size_from_arch(arch));
D_ProcessMemorySlice machine_code_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, rng, 0, os_now_microseconds()+5000);
D_ProcessMemorySlice machine_code_slice = d_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, rng, 0, os_now_microseconds()+5000);
machine_code = machine_code_slice.data;
}
@@ -316,7 +316,7 @@ d_trap_net_from_thread__step_over_inst(Arena *arena, D_Entity *thread)
if(inst.flags & DASM_InstFlag_Call || inst.flags & DASM_InstFlag_Repeats)
{
D_Trap trap = {D_TrapFlag_EndStepping, ip_vaddr+inst.size};
ctrl_trap_list_push(arena, &result.traps, &trap);
d_trap_list_push(arena, &result.traps, &trap);
}
}
@@ -333,10 +333,10 @@ d_trap_net_from_thread__step_over_line(Arena *arena, D_Entity *thread)
// rjf: thread => info
Arch arch = thread->arch;
U64 ip_vaddr = ctrl_rip_from_thread(&d_user_state->ctrl_entity_store->ctx, thread->handle);
D_Entity *process = ctrl_entity_ancestor_from_kind(thread, D_EntityKind_Process);
D_Entity *module = ctrl_module_from_process_vaddr(process, ip_vaddr);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
U64 ip_vaddr = d_rip_from_thread(&d_user_state->ctrl_entity_store->ctx, thread->handle);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
D_Entity *module = d_module_from_process_vaddr(process, ip_vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
log_infof("ip_vaddr: 0x%I64x\n", ip_vaddr);
log_infof("dbgi_key: {0x%I64x, 0x%I64x}\n", dbgi_key.u64[0], dbgi_key.u64[1]);
@@ -345,7 +345,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, D_Entity *thread)
S64 line_num = 0;
Rng1U64 line_vaddr_rng = {0};
{
U64 ip_voff = ctrl_voff_from_vaddr(module, ip_vaddr);
U64 ip_voff = d_voff_from_vaddr(module, ip_vaddr);
D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, dbgi_key, ip_voff);
Rng1U64 line_voff_rng = {0};
if(lines.first != 0)
@@ -353,7 +353,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, D_Entity *thread)
line_voff_rng = lines.first->v.voff_range;
file_path = lines.first->v.file_path;
line_num = lines.first->v.pt.line;
line_vaddr_rng = ctrl_vaddr_range_from_voff_range(module, line_voff_rng);
line_vaddr_rng = d_vaddr_range_from_voff_range(module, line_voff_rng);
log_infof("line: {%S:%I64i}\n", lines.first->v.file_path, lines.first->v.pt.line);
}
log_infof("voff_range: {0x%I64x, 0x%I64x}\n", line_voff_rng.min, line_voff_rng.max);
@@ -367,7 +367,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, D_Entity *thread)
for EachNode(n, D_LineNode, lines.first)
{
Rng1U64 voff_range = n->v.voff_range;
Rng1U64 vaddr_range = ctrl_vaddr_range_from_voff_range(module, voff_range);
Rng1U64 vaddr_range = d_vaddr_range_from_voff_range(module, voff_range);
rng1u64_list_push(scratch.arena, &all_vaddr_ranges_on_same_line, vaddr_range);
}
}
@@ -377,11 +377,11 @@ d_trap_net_from_thread__step_over_line(Arena *arena, D_Entity *thread)
// MSVC exports line info at these line numbers when /JMC (Just My Code) debugging
// is enabled. This is enabled by default normally.
{
U64 opl_line_voff_rng = ctrl_voff_from_vaddr(module, line_vaddr_rng.max);
U64 opl_line_voff_rng = d_voff_from_vaddr(module, line_vaddr_rng.max);
D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, dbgi_key, opl_line_voff_rng);
if(lines.first != 0 && (lines.first->v.pt.line == 0xf00f00 || lines.first->v.pt.line == 0xfeefee))
{
line_vaddr_rng.max = ctrl_vaddr_from_voff(module, lines.first->v.voff_range.max);
line_vaddr_rng.max = d_vaddr_from_voff(module, lines.first->v.voff_range.max);
}
}
@@ -393,7 +393,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, D_Entity *thread)
B32 good_machine_code = 0;
if(good_line_info)
{
D_ProcessMemorySlice machine_code_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, 0, os_now_microseconds()+50000);
D_ProcessMemorySlice machine_code_slice = d_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, 0, os_now_microseconds()+50000);
machine_code = machine_code_slice.data;
good_machine_code = (machine_code.size >= dim_1u64(line_vaddr_rng) && !machine_code_slice.any_byte_bad);
LogInfoNamedBlockF("machine_code_slice")
@@ -492,7 +492,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, D_Entity *thread)
if(add)
{
D_Trap trap = {flags, trap_addr};
ctrl_trap_list_push(arena, &result.traps, &trap);
d_trap_list_push(arena, &result.traps, &trap);
}
}
@@ -515,7 +515,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, D_Entity *thread)
if(!opl_in_line)
{
D_Trap trap = {D_TrapFlag_EndStepping, opl};
ctrl_trap_list_push(arena, &result.traps, &trap);
d_trap_list_push(arena, &result.traps, &trap);
}
}
}
@@ -546,17 +546,17 @@ d_trap_net_from_thread__step_into_line(Arena *arena, D_Entity *thread)
// rjf: thread => info
Arch arch = thread->arch;
U64 ip_vaddr = ctrl_rip_from_thread(&d_user_state->ctrl_entity_store->ctx, thread->handle);
D_Entity *process = ctrl_entity_ancestor_from_kind(thread, D_EntityKind_Process);
D_Entity *module = ctrl_module_from_process_vaddr(process, ip_vaddr);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
U64 ip_vaddr = d_rip_from_thread(&d_user_state->ctrl_entity_store->ctx, thread->handle);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
D_Entity *module = d_module_from_process_vaddr(process, ip_vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module);
// rjf: ip => line info
String8 file_path = {0};
S64 line_num = 0;
Rng1U64 line_vaddr_rng = {0};
{
U64 ip_voff = ctrl_voff_from_vaddr(module, ip_vaddr);
U64 ip_voff = d_voff_from_vaddr(module, ip_vaddr);
D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, dbgi_key, ip_voff);
Rng1U64 line_voff_rng = {0};
if(lines.first != 0)
@@ -564,7 +564,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, D_Entity *thread)
line_voff_rng = lines.first->v.voff_range;
file_path = lines.first->v.file_path;
line_num = lines.first->v.pt.line;
line_vaddr_rng = ctrl_vaddr_range_from_voff_range(module, line_voff_rng);
line_vaddr_rng = d_vaddr_range_from_voff_range(module, line_voff_rng);
log_infof("line: {%S:%I64i}\n", lines.first->v.file_path, lines.first->v.pt.line);
}
log_infof("voff_range: {0x%I64x, 0x%I64x}\n", line_voff_rng.min, line_voff_rng.max);
@@ -578,7 +578,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, D_Entity *thread)
for EachNode(n, D_LineNode, lines.first)
{
Rng1U64 voff_range = n->v.voff_range;
Rng1U64 vaddr_range = ctrl_vaddr_range_from_voff_range(module, voff_range);
Rng1U64 vaddr_range = d_vaddr_range_from_voff_range(module, voff_range);
rng1u64_list_push(scratch.arena, &all_vaddr_ranges_on_same_line, vaddr_range);
}
}
@@ -588,11 +588,11 @@ d_trap_net_from_thread__step_into_line(Arena *arena, D_Entity *thread)
// MSVC exports line info at these line numbers when /JMC (Just My Code) debugging
// is enabled. This is enabled by default normally.
{
U64 opl_line_voff_rng = ctrl_voff_from_vaddr(module, line_vaddr_rng.max);
U64 opl_line_voff_rng = d_voff_from_vaddr(module, line_vaddr_rng.max);
D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, dbgi_key, opl_line_voff_rng);
if(lines.first != 0 && (lines.first->v.pt.line == 0xf00f00 || lines.first->v.pt.line == 0xfeefee))
{
line_vaddr_rng.max = ctrl_vaddr_from_voff(module, lines.first->v.voff_range.max);
line_vaddr_rng.max = d_vaddr_from_voff(module, lines.first->v.voff_range.max);
}
}
@@ -604,7 +604,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, D_Entity *thread)
B32 good_machine_code = 0;
if(good_line_info)
{
D_ProcessMemorySlice machine_code_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, 0, os_now_microseconds()+5000);
D_ProcessMemorySlice machine_code_slice = d_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, 0, os_now_microseconds()+5000);
machine_code = machine_code_slice.data;
good_machine_code = (machine_code.size >= dim_1u64(line_vaddr_rng) && !machine_code_slice.any_byte_bad);
}
@@ -649,9 +649,9 @@ d_trap_net_from_thread__step_into_line(Arena *arena, D_Entity *thread)
point->jump_dest_vaddr != 0)
{
U64 jump_dest_vaddr = point->jump_dest_vaddr;
D_Entity *jump_dest_module = ctrl_module_from_process_vaddr(process, jump_dest_vaddr);
U64 jump_dest_voff = ctrl_voff_from_vaddr(jump_dest_module, jump_dest_vaddr);
DI_Key jump_dest_dbgi_key = ctrl_dbgi_key_from_module(jump_dest_module);
D_Entity *jump_dest_module = d_module_from_process_vaddr(process, jump_dest_vaddr);
U64 jump_dest_voff = d_voff_from_vaddr(jump_dest_module, jump_dest_vaddr);
DI_Key jump_dest_dbgi_key = d_dbgi_key_from_module(jump_dest_module);
D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, jump_dest_dbgi_key, jump_dest_voff);
if(lines.count == 0)
{
@@ -701,7 +701,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, D_Entity *thread)
if(add)
{
D_Trap trap = {flags, trap_addr};
ctrl_trap_list_push(arena, &result.traps, &trap);
d_trap_list_push(arena, &result.traps, &trap);
}
}
@@ -724,7 +724,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, D_Entity *thread)
if(!opl_in_line)
{
D_Trap trap = {D_TrapFlag_EndStepping, opl};
ctrl_trap_list_push(arena, &result.traps, &trap);
d_trap_list_push(arena, &result.traps, &trap);
}
}
}
@@ -1073,8 +1073,8 @@ d_tls_base_vaddr_from_process_root_rip(D_Entity *process, U64 root_vaddr, U64 ri
Temp scratch = scratch_begin(0, 0);
//- rjf: unpack module info
D_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
U64 addr_size = byte_size_from_arch(process->arch);
D_Entity *module = d_module_from_process_vaddr(process, rip_vaddr);
U64 addr_size = byte_size_from_arch(process->arch);
switch(process->tls_model)
{
@@ -1084,7 +1084,7 @@ d_tls_base_vaddr_from_process_root_rip(D_Entity *process, U64 root_vaddr, U64 ri
// read thread local base pointer out of TEB
U64 thread_local_base = root_vaddr;
U64 tls_addr_array = 0;
D_ProcessMemorySlice tls_addr_array_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, r1u64(thread_local_base, thread_local_base + addr_size), 0, 0);
D_ProcessMemorySlice tls_addr_array_slice = d_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, r1u64(thread_local_base, thread_local_base + addr_size), 0, 0);
String8 tls_array_vaddr_data = tls_addr_array_slice.data;
if(tls_array_vaddr_data.size == addr_size)
{
@@ -1093,7 +1093,7 @@ d_tls_base_vaddr_from_process_root_rip(D_Entity *process, U64 root_vaddr, U64 ri
// read thread local storage pointer (array of TLS pointers, one per module)
U64 tls_ptr_vaddr = tls_array_vaddr + module->tls_index * addr_size;
D_ProcessMemorySlice result_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, r1u64(tls_ptr_vaddr, tls_ptr_vaddr + addr_size), 0, 0);
D_ProcessMemorySlice result_slice = d_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, r1u64(tls_ptr_vaddr, tls_ptr_vaddr + addr_size), 0, 0);
String8 result_data = result_slice.data;
if(result_data.size == addr_size)
{
@@ -1109,7 +1109,7 @@ d_tls_base_vaddr_from_process_root_rip(D_Entity *process, U64 root_vaddr, U64 ri
U64 dtv_base = root_vaddr;
U64 dtv_size = addr_size * 2; // union dtv { size_t counter; struct dtv_pointer { void *val, *to_free; }; };
U64 dtv_pointer_vaddr = dtv_base + module->tls_index * dtv_size;
D_ProcessMemorySlice dtv_pointer_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, r1u64(dtv_pointer_vaddr, dtv_pointer_vaddr + dtv_size), 0, 0);
D_ProcessMemorySlice dtv_pointer_slice = d_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, r1u64(dtv_pointer_vaddr, dtv_pointer_vaddr + dtv_size), 0, 0);
String8 dtv_pointer_data = dtv_pointer_slice.data;
if(dtv_pointer_data.size == dtv_size)
{
@@ -1182,11 +1182,11 @@ internal DI_KeyList
d_push_active_dbgi_key_list(Arena *arena)
{
DI_KeyList dbgis = {0};
D_EntityArray modules = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Module);
D_EntityArray modules = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Module);
for EachIndex(idx, modules.count)
{
D_Entity *module = modules.v[idx];
DI_Key key = ctrl_dbgi_key_from_module(module);
DI_Key key = d_dbgi_key_from_module(module);
di_key_list_push(arena, &dbgis, key);
}
return dbgis;
@@ -1207,12 +1207,12 @@ d_query_cached_rip_from_thread_unwind(D_Entity *thread, U64 unwind_count)
U64 result = 0;
if(unwind_count == 0)
{
result = ctrl_rip_from_thread(&d_user_state->ctrl_entity_store->ctx, thread->handle);
result = d_rip_from_thread(&d_user_state->ctrl_entity_store->ctx, thread->handle);
}
else
{
Access *access = access_open();
D_CallStack callstack = ctrl_call_stack_from_thread(access, thread->handle, 1, 0);
D_CallStack callstack = d_call_stack_from_thread(access, thread->handle, 1, 0);
if(callstack.concrete_frames_count != 0)
{
result = regs_rip_from_arch_block(thread->arch, callstack.concrete_frames[unwind_count%callstack.concrete_frames_count]->regs);
@@ -1227,7 +1227,7 @@ d_query_cached_cfa_from_thread_unwind(D_Entity *thread, U64 unwind_count)
{
U64 cfa = 0;
Access *access = access_open();
D_CallStack callstack = ctrl_call_stack_from_thread(access, thread->handle, 1, 0);
D_CallStack callstack = d_call_stack_from_thread(access, thread->handle, 1, 0);
if(callstack.concrete_frames_count != 0)
{
cfa = callstack.concrete_frames[unwind_count%callstack.concrete_frames_count]->cfa;
@@ -1259,7 +1259,7 @@ d_query_cached_tls_base_vaddr_from_process_root_rip(D_Entity *process, U64 root_
D_RunTLSBaseCacheNode *node = 0;
for(D_RunTLSBaseCacheNode *n = slot->first; n != 0; n = n->hash_next)
{
if(ctrl_handle_match(n->process, handle) && n->root_vaddr == root_vaddr && n->rip_vaddr == rip_vaddr)
if(d_handle_match(n->process, handle) && n->root_vaddr == root_vaddr && n->rip_vaddr == rip_vaddr)
{
node = n;
break;
@@ -1439,19 +1439,19 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
ProfScope("sync with ctrl thread")
{
//- rjf: grab next reggen/memgen
U64 new_mem_gen = ctrl_mem_gen();
U64 new_reg_gen = ctrl_reg_gen();
U64 new_mem_gen = d_mem_gen();
U64 new_reg_gen = d_reg_gen();
//- rjf: consume & process events
events = ctrl_c2u_pop_events(arena);
ctrl_entity_store_apply_events(d_user_state->ctrl_entity_store, &events);
events = d_c2u_pop_events(arena);
d_entity_store_apply_events(d_user_state->ctrl_entity_store, &events);
for(D_EventNode *event_n = events.first;
event_n != 0;
event_n = event_n->next)
{
D_Event *event = &event_n->v;
log_infof("ctrl_event:\n{\n");
log_infof("kind: \"%S\"\n", ctrl_string_from_event_kind(event->kind));
log_infof("kind: \"%S\"\n", d_string_from_event_kind(event->kind));
log_infof("entity_id: %u\n", event->entity_id);
switch(event->kind)
{
@@ -1492,7 +1492,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_EventKind_NewProc:
{
// rjf: the first process? -> clear session output
D_EntityArray existing_processes = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process);
D_EntityArray existing_processes = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process);
if(existing_processes.count == 1)
{
MTX_Op op = {r1u64(0, 0xffffffffffffffffull), str8_lit("[new session]\n")};
@@ -1556,7 +1556,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
// rjf: build data strings of all param data
String8List strings = {0};
{
D_EntityArray threads = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Thread);
D_EntityArray threads = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Thread);
for EachIndex(idx, threads.count)
{
D_Entity *thread = threads.v[idx];
@@ -1681,7 +1681,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
// rjf: push message to launch
{
D_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
D_Msg *msg = d_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = D_MsgKind_Launch;
msg->path = working_directory;
msg->cmd_line_string_list = cmdln_strings;
@@ -1711,14 +1711,14 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}break;
case D_CmdKind_Kill:
{
D_Entity *process = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->process);
D_Entity *process = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->process);
if(process == &d_entity_nil)
{
log_user_error(str8_lit("Cannot kill; no process was specified."));
}
else
{
D_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
D_Msg *msg = d_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = D_MsgKind_Kill;
msg->exit_code = 1;
msg->entity = process->handle;
@@ -1727,21 +1727,21 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}break;
case D_CmdKind_KillAll:
{
D_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
D_Msg *msg = d_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = D_MsgKind_KillAll;
msg->exit_code = 1;
MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
}break;
case D_CmdKind_Detach:
{
D_Entity *process = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->process);
D_Entity *process = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->process);
if(process == &d_entity_nil)
{
log_user_error(str8_lit("Cannot detach; no process specified."));
}
else
{
D_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
D_Msg *msg = d_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = D_MsgKind_Detach;
msg->entity = process->handle;
MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
@@ -1750,7 +1750,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_Continue:
{
B32 good_to_run = 0;
D_EntityArray threads = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Thread);
D_EntityArray threads = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Thread);
if(threads.count > 0)
{
for EachIndex(idx, threads.count)
@@ -1766,7 +1766,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
{
need_run = 1;
run_kind = D_RunKind_Run;
run_thread = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->thread);
run_thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->thread);
}
else
{
@@ -1780,7 +1780,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_StepOverLine:
case D_CmdKind_StepOut:
{
D_Entity *thread = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->thread);
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->thread);
if(thread == &d_entity_nil)
{
log_user_error(str8_lit("Must have a selected thread to step."));
@@ -1811,14 +1811,14 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
Access *access = access_open();
// rjf: thread => call stack
D_CallStack callstack = ctrl_call_stack_from_thread(access, thread->handle, 1, os_now_microseconds()+10000);
D_CallStack callstack = d_call_stack_from_thread(access, thread->handle, 1, os_now_microseconds()+10000);
// rjf: use first unwind frame to generate trap
if(callstack.concrete_frames_count > 1)
{
U64 vaddr = regs_rip_from_arch_block(thread->arch, callstack.concrete_frames[1]->regs);
D_Trap trap = {D_TrapFlag_EndStepping|D_TrapFlag_IgnoreStackPointerCheck, vaddr};
ctrl_trap_list_push(scratch.arena, &trap_net.traps, &trap);
d_trap_list_push(scratch.arena, &trap_net.traps, &trap);
trap_net.good_read = 1;
}
else
@@ -1861,24 +1861,24 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_Halt:
if(d_ctrl_targets_running())
{
ctrl_halt();
d_halt();
}break;
case D_CmdKind_SoftHaltRefresh:
if(d_ctrl_targets_running())
{
need_run = 1;
run_kind = d_user_state->ctrl_last_run_kind;
run_thread = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, d_user_state->ctrl_last_run_thread_handle);
run_thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, d_user_state->ctrl_last_run_thread_handle);
run_flags = d_user_state->ctrl_last_run_flags;
run_traps = d_user_state->ctrl_last_run_traps;
}break;
case D_CmdKind_SetThreadIP:
{
D_Entity *thread = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->thread);
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->thread);
U64 vaddr = params->vaddr;
void *block = ctrl_reg_block_from_thread(scratch.arena, &d_user_state->ctrl_entity_store->ctx, thread->handle);
void *block = d_reg_block_from_thread(scratch.arena, &d_user_state->ctrl_entity_store->ctx, thread->handle);
regs_arch_block_write_rip(thread->arch, block, vaddr);
B32 result = ctrl_thread_write_reg_block(thread->handle, block);
B32 result = d_thread_write_reg_block(thread->handle, block);
(void)result;
}break;
@@ -1900,7 +1900,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}break;
case D_CmdKind_Run:
{
D_EntityArray processes = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process);
D_EntityArray processes = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process);
if(processes.count != 0)
{
d_cmd(D_CmdKind_Continue, .machine = params->machine, .process = params->process, .thread = params->thread);
@@ -1912,7 +1912,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}break;
case D_CmdKind_Restart:
{
D_EntityArray processes = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process);
D_EntityArray processes = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process);
if(processes.count != 0)
{
d_cmd(D_CmdKind_KillAll);
@@ -1922,7 +1922,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_StepInto:
case D_CmdKind_StepOver:
{
D_EntityArray processes = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process);
D_EntityArray processes = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process);
if(processes.count != 0)
{
D_CmdKind step_cmd_kind = (cmd->kind == D_CmdKind_StepInto
@@ -1961,24 +1961,24 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_FreezeLocalMachine:
{
D_MachineID machine_id = D_MachineID_Local;
d_cmd(D_CmdKind_FreezeMachine, .entity = ctrl_handle_make(machine_id, dmn_handle_zero()));
d_cmd(D_CmdKind_FreezeMachine, .entity = d_handle_make(machine_id, dmn_handle_zero()));
}break;
case D_CmdKind_ThawLocalMachine:
{
D_MachineID machine_id = D_MachineID_Local;
d_cmd(D_CmdKind_ThawMachine, .entity = ctrl_handle_make(machine_id, dmn_handle_zero()));
d_cmd(D_CmdKind_ThawMachine, .entity = d_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 = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->entity);
for(D_Entity *e = root; e != &d_entity_nil; e = ctrl_entity_rec_depth_first_pre(e, root).next)
D_Entity *root = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->entity);
for(D_Entity *e = root; e != &d_entity_nil; e = d_entity_rec_depth_first_pre(e, root).next)
{
if(e->kind == D_EntityKind_Thread)
{
e->is_frozen = should_freeze;
D_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
D_Msg *msg = d_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = (should_freeze ? D_MsgKind_FreezeThread : D_MsgKind_ThawThread);
msg->entity = e->handle;
}
@@ -1987,7 +1987,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
{
need_run = 1;
run_kind = d_user_state->ctrl_last_run_kind;
run_thread = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, d_user_state->ctrl_last_run_thread_handle);
run_thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, d_user_state->ctrl_last_run_thread_handle);
run_flags = d_user_state->ctrl_last_run_flags;
run_traps = d_user_state->ctrl_last_run_traps;
}
@@ -1996,13 +1996,13 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
//- rjf: entity decoration
case D_CmdKind_SetEntityColor:
{
D_Entity *entity = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->entity);
D_Entity *entity = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->entity);
entity->rgba = params->rgba;
}break;
case D_CmdKind_SetEntityName:
{
D_Entity *entity = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->entity);
ctrl_entity_equip_string(d_user_state->ctrl_entity_store, entity, params->string);
D_Entity *entity = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->entity);
d_entity_equip_string(d_user_state->ctrl_entity_store, entity, params->string);
}break;
//- rjf: attaching
@@ -2011,7 +2011,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
U32 pid = params->pid;
if(pid != 0)
{
D_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
D_Msg *msg = d_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = D_MsgKind_Attach;
msg->entity_id = pid;
MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
@@ -2028,9 +2028,9 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}
// rjf: push & fill run message
D_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
D_Msg *msg = d_msg_list_push(scratch.arena, &ctrl_msgs);
{
D_Entity *process = ctrl_entity_ancestor_from_kind(run_thread, D_EntityKind_Process);
D_Entity *process = d_entity_ancestor_from_kind(run_thread, D_EntityKind_Process);
msg->kind = (run_kind == D_RunKind_Run || run_kind == D_RunKind_Step) ? D_MsgKind_Run : D_MsgKind_SingleStep;
msg->run_flags = run_flags;
msg->entity = run_thread->handle;
@@ -2059,21 +2059,21 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
D_Breakpoint dst_bp = {0};
MemoryCopyStruct(&dst_bp, bp);
dst_bp.file_path = n->string;
ctrl_user_breakpoint_list_push(scratch.arena, &msg->user_bps, &dst_bp);
d_breakpoint_list_push(scratch.arena, &msg->user_bps, &dst_bp);
}
}
// rjf: all other cases - just copy the breakpoint info
else
{
ctrl_user_breakpoint_list_push(scratch.arena, &msg->user_bps, bp);
d_breakpoint_list_push(scratch.arena, &msg->user_bps, bp);
}
}
}
}
// rjf: copy run traps to scratch (needed, if run_traps can be `d_user_state->ctrl_last_run_traps`)
D_TrapList run_traps_copy = ctrl_trap_list_copy(scratch.arena, &run_traps);
D_TrapList run_traps_copy = d_trap_list_copy(scratch.arena, &run_traps);
D_BreakpointArray run_extra_bps_copy = d_breakpoint_array_copy(scratch.arena, &run_extra_bps);
// rjf: store last run info
@@ -2082,7 +2082,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
d_user_state->ctrl_last_run_frame_idx = d_frame_index();
d_user_state->ctrl_last_run_thread_handle = run_thread->handle;
d_user_state->ctrl_last_run_flags = run_flags;
d_user_state->ctrl_last_run_traps = ctrl_trap_list_copy(d_user_state->ctrl_last_run_arena, &run_traps_copy);
d_user_state->ctrl_last_run_traps = d_trap_list_copy(d_user_state->ctrl_last_run_arena, &run_traps_copy);
d_user_state->ctrl_last_run_extra_bps = d_breakpoint_array_copy(d_user_state->ctrl_last_run_arena, &run_extra_bps_copy);
d_user_state->ctrl_is_running = 1;
}
@@ -2111,16 +2111,16 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
// the next tick)
//
{
D_MsgList msgs_copy = ctrl_msg_list_deep_copy(d_user_state->ctrl_msg_arena, &ctrl_msgs);
ctrl_msg_list_concat_in_place(&d_user_state->ctrl_msgs, &msgs_copy);
D_MsgList msgs_copy = d_msg_list_deep_copy(d_user_state->ctrl_msg_arena, &ctrl_msgs);
d_msg_list_concat_in_place(&d_user_state->ctrl_msgs, &msgs_copy);
if(d_user_state->ctrl_msgs.count != 0)
{
if(!d_user_state->ctrl_soft_halt_issued && d_user_state->ctrl_thread_run_state)
{
d_user_state->ctrl_soft_halt_issued = 1;
ctrl_halt();
d_halt();
}
if(ctrl_u2c_push_msgs(&d_user_state->ctrl_msgs, os_now_microseconds()+100))
if(d_u2c_push_msgs(&d_user_state->ctrl_msgs, os_now_microseconds()+100))
{
MemoryZeroStruct(&d_user_state->ctrl_msgs);
arena_clear(d_user_state->ctrl_msg_arena);
+6 -6
View File
@@ -4,7 +4,7 @@
//- GENERATED CODE
C_LINKAGE_BEGIN
String8 ctrl_entity_kind_code_name_table[12] =
String8 d_entity_kind_code_name_table[12] =
{
{0},
str8_lit_comp("root"),
@@ -20,7 +20,7 @@ str8_lit_comp("breakpoint"),
str8_lit_comp("address_range_annotation"),
};
String8 ctrl_entity_kind_display_string_table[12] =
String8 d_entity_kind_display_string_table[12] =
{
{0},
str8_lit_comp("Root"),
@@ -36,7 +36,7 @@ str8_lit_comp("Breakpoint"),
str8_lit_comp("AddressRangeAnnotation"),
};
U32 ctrl_exception_code_kind_code_table[38] =
U32 d_exception_code_kind_code_table[38] =
{
0,
0x40010005,
@@ -78,7 +78,7 @@ U32 ctrl_exception_code_kind_code_table[38] =
0x0000087a,
};
String8 ctrl_exception_code_kind_display_string_table[38] =
String8 d_exception_code_kind_display_string_table[38] =
{
{0},
str8_lit_comp("(Win32) Control-C"),
@@ -120,7 +120,7 @@ str8_lit_comp("(Win32) Sanitizer Raw Access Violation"),
str8_lit_comp("(Win32) DirectX Debug Layer"),
};
String8 ctrl_exception_code_kind_lowercase_code_string_table[38] =
String8 d_exception_code_kind_lowercase_code_string_table[38] =
{
{0},
str8_lit_comp("win32_ctrl_c"),
@@ -162,7 +162,7 @@ str8_lit_comp("win32_sanitizer_raw_access_violation"),
str8_lit_comp("win32_directx_debug_layer"),
};
B8 ctrl_exception_code_kind_default_enable_table[38] =
B8 d_exception_code_kind_default_enable_table[38] =
{
0,
1,
+6 -6
View File
@@ -126,12 +126,12 @@ struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] =
{&DEV_updating_indicator, str8_lit_comp("updating_indicator")},
};
C_LINKAGE_BEGIN
extern String8 ctrl_entity_kind_code_name_table[12];
extern String8 ctrl_entity_kind_display_string_table[12];
extern U32 ctrl_exception_code_kind_code_table[38];
extern String8 ctrl_exception_code_kind_display_string_table[38];
extern String8 ctrl_exception_code_kind_lowercase_code_string_table[38];
extern B8 ctrl_exception_code_kind_default_enable_table[38];
extern String8 d_entity_kind_code_name_table[12];
extern String8 d_entity_kind_display_string_table[12];
extern U32 d_exception_code_kind_code_table[38];
extern String8 d_exception_code_kind_display_string_table[38];
extern String8 d_exception_code_kind_lowercase_code_string_table[38];
extern B8 d_exception_code_kind_default_enable_table[38];
C_LINKAGE_END