ctrl -> d type pass

This commit is contained in:
Ryan Fleury
2026-04-22 13:37:00 -07:00
parent a90fbc844b
commit 0d8a6a4d3a
21 changed files with 1996 additions and 2132 deletions
+13 -13
View File
@@ -93,7 +93,7 @@ D_DevToggleTable:
//~ rjf: Entity Kinds
@table(name code_name display_string)
CTRL_EntityKindTable:
D_EntityKindTable:
{
{Root root "Root" }
{Machine machine "Machine" }
@@ -108,30 +108,30 @@ CTRL_EntityKindTable:
{AddressRangeAnnotation address_range_annotation "Address Range Annotation" }
}
@enum CTRL_EntityKind:
@enum D_EntityKind:
{
Null,
@expand(CTRL_EntityKindTable a) `$(a.name)`,
@expand(D_EntityKindTable a) `$(a.name)`,
COUNT,
}
@data(String8) ctrl_entity_kind_code_name_table:
{
`{0}`,
@expand(CTRL_EntityKindTable a) `str8_lit_comp("$(a.code_name)")`
@expand(D_EntityKindTable a) `str8_lit_comp("$(a.code_name)")`
}
@data(String8) ctrl_entity_kind_display_string_table:
{
`{0}`,
@expand(CTRL_EntityKindTable a) `str8_lit_comp("$(a.display_name)")`
@expand(D_EntityKindTable a) `str8_lit_comp("$(a.display_name)")`
}
////////////////////////////////
//~ rjf: Exception Codes
@table(name lower_name code default display_string)
CTRL_ExceptionCodeKindTable:
D_ExceptionCodeKindTable:
{
{Win32CtrlC win32_ctrl_c 0x40010005 1 "(Win32) Control-C" }
{Win32CtrlBreak win32_ctrl_break 0x40010008 1 "(Win32) Control-Break" }
@@ -172,42 +172,42 @@ CTRL_ExceptionCodeKindTable:
{Win32DirectXDebugLayer win32_directx_debug_layer 0x0000087a 1 "(Win32) DirectX Debug Layer" }
}
@enum CTRL_ExceptionCodeKind:
@enum D_ExceptionCodeKind:
{
Null,
@expand(CTRL_ExceptionCodeKindTable a) `$(a.name)`,
@expand(D_ExceptionCodeKindTable a) `$(a.name)`,
COUNT,
}
@data(U32) ctrl_exception_code_kind_code_table:
{
`0`;
@expand(CTRL_ExceptionCodeKindTable a) `$(a.code)`;
@expand(D_ExceptionCodeKindTable a) `$(a.code)`;
}
@data(String8) ctrl_exception_code_kind_display_string_table:
{
`{0}`;
@expand(CTRL_ExceptionCodeKindTable a) `str8_lit_comp("$(a.display_string)")`;
@expand(D_ExceptionCodeKindTable a) `str8_lit_comp("$(a.display_string)")`;
}
@data(String8) ctrl_exception_code_kind_lowercase_code_string_table:
{
`{0}`;
@expand(CTRL_ExceptionCodeKindTable a) `str8_lit_comp("$(a.lower_name)")`;
@expand(D_ExceptionCodeKindTable a) `str8_lit_comp("$(a.lower_name)")`;
}
@data(B8) ctrl_exception_code_kind_default_enable_table:
{
`0`;
@expand(CTRL_ExceptionCodeKindTable a) `$(a.default)`;
@expand(D_ExceptionCodeKindTable a) `$(a.default)`;
}
////////////////////////////////
//~ rjf: Exception Sub-Codes
@table(name, value)
CTRL_ExceptionSubCodeKindTable:
DL_ExceptionSubCodeKindTable:
{
{ W32_FAST_FAIL_LEGACY_GS_VIOLATION 0 }
{ W32_FAST_FAIL_VTGUARD_CHECK_FAILURE 1 }
+5 -5
View File
@@ -35,18 +35,18 @@ d_init(void)
}
}
d_ctrl_state->thread_reg_cache.slots_count = 1024;
d_ctrl_state->thread_reg_cache.slots = push_array(arena, CTRL_ThreadRegCacheSlot, d_ctrl_state->thread_reg_cache.slots_count);
d_ctrl_state->thread_reg_cache.slots = push_array(arena, D_ThreadRegCacheSlot, d_ctrl_state->thread_reg_cache.slots_count);
d_ctrl_state->thread_reg_cache.stripes_count = os_get_system_info()->logical_processor_count;
d_ctrl_state->thread_reg_cache.stripes = push_array(arena, CTRL_ThreadRegCacheStripe, d_ctrl_state->thread_reg_cache.stripes_count);
d_ctrl_state->thread_reg_cache.stripes = push_array(arena, D_ThreadRegCacheStripe, d_ctrl_state->thread_reg_cache.stripes_count);
for(U64 idx = 0; idx < d_ctrl_state->thread_reg_cache.stripes_count; idx += 1)
{
d_ctrl_state->thread_reg_cache.stripes[idx].arena = arena_alloc();
d_ctrl_state->thread_reg_cache.stripes[idx].rw_mutex = rw_mutex_alloc();
}
d_ctrl_state->module_image_info_cache.slots_count = 1024;
d_ctrl_state->module_image_info_cache.slots = push_array(arena, CTRL_ModuleImageInfoCacheSlot, d_ctrl_state->module_image_info_cache.slots_count);
d_ctrl_state->module_image_info_cache.slots = push_array(arena, D_ModuleImageInfoCacheSlot, d_ctrl_state->module_image_info_cache.slots_count);
d_ctrl_state->module_image_info_cache.stripes_count = os_get_system_info()->logical_processor_count;
d_ctrl_state->module_image_info_cache.stripes = push_array(arena, CTRL_ModuleImageInfoCacheStripe, d_ctrl_state->module_image_info_cache.stripes_count);
d_ctrl_state->module_image_info_cache.stripes = push_array(arena, D_ModuleImageInfoCacheStripe, d_ctrl_state->module_image_info_cache.stripes_count);
for(U64 idx = 0; idx < d_ctrl_state->module_image_info_cache.stripes_count; idx += 1)
{
d_ctrl_state->module_image_info_cache.stripes[idx].arena = arena_alloc();
@@ -77,7 +77,7 @@ d_init(void)
d_ctrl_state->dmn_event_arena = arena_alloc();
d_ctrl_state->user_entry_point_arena = arena_alloc();
d_ctrl_state->dbg_dir_arena = arena_alloc();
for(CTRL_ExceptionCodeKind k = (CTRL_ExceptionCodeKind)0; k < CTRL_ExceptionCodeKind_COUNT; k = (CTRL_ExceptionCodeKind)(k+1))
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])
{
+96 -154
View File
@@ -7,40 +7,40 @@
////////////////////////////////
//~ rjf: ID Types
typedef U64 CTRL_MsgID;
typedef U64 CTRL_MachineID;
typedef U64 D_MsgID;
typedef U64 D_MachineID;
#define CTRL_MachineID_Local (1)
#define D_MachineID_Local (1)
////////////////////////////////
//~ rjf: Entity Handle Types
typedef struct CTRL_Handle CTRL_Handle;
struct CTRL_Handle
typedef struct D_Handle D_Handle;
struct D_Handle
{
CTRL_MachineID machine_id;
D_MachineID machine_id;
DMN_Handle dmn_handle;
};
typedef struct CTRL_HandleNode CTRL_HandleNode;
struct CTRL_HandleNode
typedef struct D_HandleNode D_HandleNode;
struct D_HandleNode
{
CTRL_HandleNode *next;
CTRL_Handle v;
D_HandleNode *next;
D_Handle v;
};
typedef struct CTRL_HandleList CTRL_HandleList;
struct CTRL_HandleList
typedef struct D_HandleList D_HandleList;
struct D_HandleList
{
CTRL_HandleNode *first;
CTRL_HandleNode *last;
D_HandleNode *first;
D_HandleNode *last;
U64 count;
};
typedef struct CTRL_HandleArray CTRL_HandleArray;
struct CTRL_HandleArray
typedef struct D_HandleArray D_HandleArray;
struct D_HandleArray
{
CTRL_Handle *v;
D_Handle *v;
U64 count;
};
@@ -52,12 +52,12 @@ struct CTRL_HandleArray
////////////////////////////////
//~ rjf: User Breakpoint Types
typedef U32 CTRL_UserBreakpointFlags;
typedef U32 D_BreakpointFlags;
enum
{
CTRL_UserBreakpointFlag_BreakOnWrite = (1<<0),
CTRL_UserBreakpointFlag_BreakOnRead = (1<<1),
CTRL_UserBreakpointFlag_BreakOnExecute = (1<<2),
D_BreakpointFlag_BreakOnWrite = (1<<0),
D_BreakpointFlag_BreakOnRead = (1<<1),
D_BreakpointFlag_BreakOnExecute = (1<<2),
};
typedef enum CTRL_UserBreakpointKind
@@ -73,7 +73,7 @@ typedef struct CTRL_UserBreakpoint CTRL_UserBreakpoint;
struct CTRL_UserBreakpoint
{
CTRL_UserBreakpointKind kind;
CTRL_UserBreakpointFlags flags;
D_BreakpointFlags flags;
U64 id;
String8 string;
TxtPt pt;
@@ -99,86 +99,86 @@ struct CTRL_UserBreakpointList
////////////////////////////////
//~ Dynamic Linker Types
typedef U32 CTRL_TlsModel;
typedef U32 D_TlsModel;
enum
{
CTRL_TlsModel_Null,
CTRL_TlsModel_WinodwsNt,
CTRL_TlsModel_Gnu
D_TlsModel_Null,
D_TlsModel_WinodwsNt,
D_TlsModel_Gnu
};
////////////////////////////////
//~ rjf: Entity Types
typedef struct CTRL_Entity CTRL_Entity;
struct CTRL_Entity
typedef struct D_Entity D_Entity;
struct D_Entity
{
CTRL_Entity *first;
CTRL_Entity *last;
CTRL_Entity *next;
CTRL_Entity *prev;
CTRL_Entity *parent;
CTRL_EntityKind kind;
D_Entity *first;
D_Entity *last;
D_Entity *next;
D_Entity *prev;
D_Entity *parent;
D_EntityKind kind;
Arch arch;
B32 is_frozen;
B32 is_soloed;
U32 rgba;
CTRL_Handle handle;
D_Handle handle;
U64 id;
Rng1U64 vaddr_range;
U64 stack_base;
U64 timestamp;
CTRL_UserBreakpointFlags bp_flags;
D_BreakpointFlags bp_flags;
String8 string;
CTRL_TlsModel tls_model;
D_TlsModel tls_model;
U64 tls_index;
U64 tls_offset;
OperatingSystem target_os;
};
typedef struct CTRL_EntityNode CTRL_EntityNode;
struct CTRL_EntityNode
typedef struct D_EntityNode D_EntityNode;
struct D_EntityNode
{
CTRL_EntityNode *next;
CTRL_Entity *v;
D_EntityNode *next;
D_Entity *v;
};
typedef struct CTRL_EntityList CTRL_EntityList;
struct CTRL_EntityList
typedef struct D_EntityList D_EntityList;
struct D_EntityList
{
CTRL_EntityNode *first;
CTRL_EntityNode *last;
D_EntityNode *first;
D_EntityNode *last;
U64 count;
};
typedef struct CTRL_EntityArray CTRL_EntityArray;
struct CTRL_EntityArray
typedef struct D_EntityArray D_EntityArray;
struct D_EntityArray
{
CTRL_Entity **v;
D_Entity **v;
U64 count;
};
typedef struct CTRL_EntityRec CTRL_EntityRec;
struct CTRL_EntityRec
typedef struct D_EntityRec D_EntityRec;
struct D_EntityRec
{
CTRL_Entity *next;
D_Entity *next;
S32 push_count;
S64 pop_count;
};
typedef struct CTRL_EntityHashNode CTRL_EntityHashNode;
struct CTRL_EntityHashNode
typedef struct D_EntityHashNode D_EntityHashNode;
struct D_EntityHashNode
{
CTRL_EntityHashNode *next;
CTRL_EntityHashNode *prev;
CTRL_Entity *entity;
D_EntityHashNode *next;
D_EntityHashNode *prev;
D_Entity *entity;
};
typedef struct CTRL_EntityHashSlot CTRL_EntityHashSlot;
struct CTRL_EntityHashSlot
typedef struct D_EntityHashSlot D_EntityHashSlot;
struct D_EntityHashSlot
{
CTRL_EntityHashNode *first;
CTRL_EntityHashNode *last;
D_EntityHashNode *first;
D_EntityHashNode *last;
};
typedef struct CTRL_EntityStringChunkNode CTRL_EntityStringChunkNode;
@@ -200,33 +200,33 @@ read_only global U64 ctrl_entity_string_bucket_chunk_sizes[] =
0xffffffffffffffffull,
};
typedef struct CTRL_EntityCtx CTRL_EntityCtx;
struct CTRL_EntityCtx
typedef struct D_EntityCtx D_EntityCtx;
struct D_EntityCtx
{
CTRL_Entity *root;
D_Entity *root;
U64 hash_slots_count;
CTRL_EntityHashSlot *hash_slots;
U64 entity_kind_counts[CTRL_EntityKind_COUNT];
U64 entity_kind_alloc_gens[CTRL_EntityKind_COUNT];
D_EntityHashSlot *hash_slots;
U64 entity_kind_counts[D_EntityKind_COUNT];
U64 entity_kind_alloc_gens[D_EntityKind_COUNT];
};
typedef struct CTRL_EntityCtxRWStore CTRL_EntityCtxRWStore;
struct CTRL_EntityCtxRWStore
typedef struct D_EntityCtxRWStore D_EntityCtxRWStore;
struct D_EntityCtxRWStore
{
Arena *arena;
CTRL_EntityCtx ctx;
CTRL_Entity *free;
CTRL_EntityHashNode *hash_node_free;
D_EntityCtx ctx;
D_Entity *free;
D_EntityHashNode *hash_node_free;
CTRL_EntityStringChunkNode *free_string_chunks[ArrayCount(ctrl_entity_string_bucket_chunk_sizes)];
};
typedef struct CTRL_EntityCtxLookupAccel CTRL_EntityCtxLookupAccel;
struct CTRL_EntityCtxLookupAccel
typedef struct D_EntityCtxLookupAccel D_EntityCtxLookupAccel;
struct D_EntityCtxLookupAccel
{
Arena *arena;
Arena *entity_kind_arrays_arenas[CTRL_EntityKind_COUNT];
CTRL_EntityArray entity_kind_arrays[CTRL_EntityKind_COUNT];
U64 entity_kind_arrays_gens[CTRL_EntityKind_COUNT];
Arena *entity_kind_arrays_arenas[D_EntityKind_COUNT];
D_EntityArray entity_kind_arrays[D_EntityKind_COUNT];
U64 entity_kind_arrays_gens[D_EntityKind_COUNT];
};
////////////////////////////////
@@ -253,14 +253,6 @@ struct D_TargetArray
U64 count;
};
typedef U32 D_BreakpointFlags;
enum
{
D_BreakpointFlag_BreakOnWrite = (1<<0),
D_BreakpointFlag_BreakOnRead = (1<<1),
D_BreakpointFlag_BreakOnExecute = (1<<2),
};
typedef struct D_Breakpoint D_Breakpoint;
struct D_Breakpoint
{
@@ -294,93 +286,43 @@ struct D_PathMapArray
U64 count;
};
////////////////////////////////
//~ rjf: Tick Output Types
typedef enum D_EventKind
{
D_EventKind_Null,
D_EventKind_ModuleLoad,
D_EventKind_ProcessEnd,
D_EventKind_Stop,
D_EventKind_COUNT
}
D_EventKind;
typedef enum D_EventCause
{
D_EventCause_Null,
D_EventCause_UserBreakpoint,
D_EventCause_Halt,
D_EventCause_SoftHalt,
D_EventCause_COUNT
}
D_EventCause;
typedef struct D_Event D_Event;
struct D_Event
{
D_EventKind kind;
D_EventCause cause;
CTRL_Handle module;
CTRL_Handle thread;
U64 vaddr;
U64 code;
U64 id;
};
typedef struct D_EventNode D_EventNode;
struct D_EventNode
{
D_EventNode *next;
D_Event v;
};
typedef struct D_EventList D_EventList;
struct D_EventList
{
D_EventNode *first;
D_EventNode *last;
U64 count;
};
////////////////////////////////
//~ rjf: Trap Types
typedef U32 CTRL_TrapFlags;
typedef U32 D_TrapFlags;
enum
{
CTRL_TrapFlag_IgnoreStackPointerCheck = (1<<0),
CTRL_TrapFlag_SingleStepAfterHit = (1<<1),
CTRL_TrapFlag_SaveStackPointer = (1<<2),
CTRL_TrapFlag_BeginSpoofMode = (1<<3),
CTRL_TrapFlag_EndStepping = (1<<4),
D_TrapFlag_IgnoreStackPointerCheck = (1<<0),
D_TrapFlag_SingleStepAfterHit = (1<<1),
D_TrapFlag_SaveStackPointer = (1<<2),
D_TrapFlag_BeginSpoofMode = (1<<3),
D_TrapFlag_EndStepping = (1<<4),
};
typedef struct CTRL_Trap CTRL_Trap;
struct CTRL_Trap
typedef struct D_Trap D_Trap;
struct D_Trap
{
CTRL_TrapFlags flags;
D_TrapFlags flags;
U64 vaddr;
};
typedef struct CTRL_TrapNode CTRL_TrapNode;
struct CTRL_TrapNode
typedef struct D_TrapNode D_TrapNode;
struct D_TrapNode
{
CTRL_TrapNode *next;
CTRL_Trap v;
D_TrapNode *next;
D_Trap v;
};
typedef struct CTRL_TrapList CTRL_TrapList;
struct CTRL_TrapList
typedef struct D_TrapList D_TrapList;
struct D_TrapList
{
CTRL_TrapNode *first;
CTRL_TrapNode *last;
D_TrapNode *first;
D_TrapNode *last;
U64 count;
};
typedef struct CTRL_Spoof CTRL_Spoof;
struct CTRL_Spoof
typedef struct D_Spoof D_Spoof;
struct D_Spoof
{
DMN_Handle process;
DMN_Handle thread;
@@ -394,7 +336,7 @@ struct CTRL_Spoof
typedef struct D_TrapNet D_TrapNet;
struct D_TrapNet
{
CTRL_TrapList traps;
D_TrapList traps;
B32 good_line_info;
B32 good_read;
};
File diff suppressed because it is too large Load Diff
+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
+108 -182
View File
@@ -204,7 +204,7 @@ d_cmd_list_push_new(Arena *arena, D_CmdList *cmds, D_CmdKind kind, D_CmdParams *
// of debug events which it is passed from the OS.
//
// These are "high-level traps" because they can have specific behavioral info
// attached to them. These are encoded via the `CTRL_TrapFlags` type, which
// attached to them. These are encoded via the `D_TrapFlags` type, which
// allow expression of the following behaviors:
//
// - end-stepping: when this trap is hit, it will end the stepping operation,
@@ -286,13 +286,13 @@ d_cmd_list_push_new(Arena *arena, D_CmdList *cmds, D_CmdKind kind, D_CmdParams *
// at them with the "save-stack-pointer | single-step-after" behaviors.
internal D_TrapNet
d_trap_net_from_thread__step_over_inst(Arena *arena, CTRL_Entity *thread)
d_trap_net_from_thread__step_over_inst(Arena *arena, D_Entity *thread)
{
Temp scratch = scratch_begin(&arena, 1);
D_TrapNet result = {0};
// rjf: thread => unpacked info
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
D_Entity *process = ctrl_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);
@@ -300,7 +300,7 @@ d_trap_net_from_thread__step_over_inst(Arena *arena, CTRL_Entity *thread)
String8 machine_code = {0};
{
Rng1U64 rng = r1u64(ip_vaddr, ip_vaddr+max_instruction_size_from_arch(arch));
CTRL_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 = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, rng, 0, os_now_microseconds()+5000);
machine_code = machine_code_slice.data;
}
@@ -315,7 +315,7 @@ d_trap_net_from_thread__step_over_inst(Arena *arena, CTRL_Entity *thread)
// rjf: call => run until call returns
if(inst.flags & DASM_InstFlag_Call || inst.flags & DASM_InstFlag_Repeats)
{
CTRL_Trap trap = {CTRL_TrapFlag_EndStepping, ip_vaddr+inst.size};
D_Trap trap = {D_TrapFlag_EndStepping, ip_vaddr+inst.size};
ctrl_trap_list_push(arena, &result.traps, &trap);
}
}
@@ -325,7 +325,7 @@ d_trap_net_from_thread__step_over_inst(Arena *arena, CTRL_Entity *thread)
}
internal D_TrapNet
d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread)
d_trap_net_from_thread__step_over_line(Arena *arena, D_Entity *thread)
{
Temp scratch = scratch_begin(&arena, 1);
log_infof("step_over_line:\n{\n");
@@ -334,8 +334,8 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_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);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ip_vaddr);
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);
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]);
@@ -393,7 +393,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread)
B32 good_machine_code = 0;
if(good_line_info)
{
CTRL_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 = ctrl_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")
@@ -440,7 +440,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread)
if(good_machine_code) for(DASM_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next)
{
DASM_CtrlFlowPoint *point = &n->v;
CTRL_TrapFlags flags = 0;
D_TrapFlags flags = 0;
B32 add = 1;
U64 trap_addr = point->vaddr;
@@ -449,7 +449,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread)
DASM_InstFlag_UnconditionalJump|
DASM_InstFlag_Return))
{
flags |= (CTRL_TrapFlag_SingleStepAfterHit|CTRL_TrapFlag_EndStepping);
flags |= (D_TrapFlag_SingleStepAfterHit|D_TrapFlag_EndStepping);
// rjf: omit if this jump stays inside of this line
if(contains_1u64(line_vaddr_rng, point->jump_dest_vaddr))
@@ -471,7 +471,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread)
if(point->jump_dest_vaddr != 0)
{
trap_addr = point->jump_dest_vaddr;
flags &= ~CTRL_TrapFlag_SingleStepAfterHit;
flags &= ~D_TrapFlag_SingleStepAfterHit;
}
}
@@ -479,19 +479,19 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread)
// rjf: call => place spoof at return spot in stack, single-step after hitting
else if(point->inst_flags & DASM_InstFlag_Call)
{
flags |= (CTRL_TrapFlag_BeginSpoofMode|CTRL_TrapFlag_SingleStepAfterHit);
flags |= (D_TrapFlag_BeginSpoofMode|D_TrapFlag_SingleStepAfterHit);
}
// rjf: instruction changes stack pointer => save off the stack pointer, single-step over, keep stepping
else if(point->inst_flags & DASM_InstFlag_ChangesStackPointer)
{
flags |= (CTRL_TrapFlag_SingleStepAfterHit|CTRL_TrapFlag_SaveStackPointer);
flags |= (D_TrapFlag_SingleStepAfterHit|D_TrapFlag_SaveStackPointer);
}
// rjf: add if appropriate
if(add)
{
CTRL_Trap trap = {flags, trap_addr};
D_Trap trap = {flags, trap_addr};
ctrl_trap_list_push(arena, &result.traps, &trap);
}
}
@@ -514,7 +514,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread)
}
if(!opl_in_line)
{
CTRL_Trap trap = {CTRL_TrapFlag_EndStepping, opl};
D_Trap trap = {D_TrapFlag_EndStepping, opl};
ctrl_trap_list_push(arena, &result.traps, &trap);
}
}
@@ -528,7 +528,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread)
}
// rjf: log
LogInfoNamedBlockF("traps") for(CTRL_TrapNode *n = result.traps.first; n != 0; n = n->next)
LogInfoNamedBlockF("traps") for(D_TrapNode *n = result.traps.first; n != 0; n = n->next)
{
log_infof("{flags:0x%x, vaddr:0x%I64x}\n", n->v.flags, n->v.vaddr);
}
@@ -539,7 +539,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread)
}
internal D_TrapNet
d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread)
d_trap_net_from_thread__step_into_line(Arena *arena, D_Entity *thread)
{
Temp scratch = scratch_begin(&arena, 1);
D_TrapNet result = {0};
@@ -547,8 +547,8 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_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);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ip_vaddr);
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);
// rjf: ip => line info
@@ -604,7 +604,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread)
B32 good_machine_code = 0;
if(good_line_info)
{
CTRL_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 = ctrl_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);
}
@@ -638,7 +638,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread)
if(good_machine_code) for(DASM_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next)
{
DASM_CtrlFlowPoint *point = &n->v;
CTRL_TrapFlags flags = 0;
D_TrapFlags flags = 0;
B32 add = 1;
U64 trap_addr = point->vaddr;
@@ -649,7 +649,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread)
point->jump_dest_vaddr != 0)
{
U64 jump_dest_vaddr = point->jump_dest_vaddr;
CTRL_Entity *jump_dest_module = ctrl_module_from_process_vaddr(process, 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_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, jump_dest_dbgi_key, jump_dest_voff);
@@ -665,7 +665,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread)
DASM_InstFlag_UnconditionalJump|
DASM_InstFlag_Return))
{
flags |= (CTRL_TrapFlag_SingleStepAfterHit|CTRL_TrapFlag_EndStepping|CTRL_TrapFlag_IgnoreStackPointerCheck);
flags |= (D_TrapFlag_SingleStepAfterHit|D_TrapFlag_EndStepping|D_TrapFlag_IgnoreStackPointerCheck);
// rjf: omit if this jump stays inside of this line
if(contains_1u64(line_vaddr_rng, point->jump_dest_vaddr))
@@ -687,20 +687,20 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread)
if(point->jump_dest_vaddr != 0)
{
trap_addr = point->jump_dest_vaddr;
flags &= ~CTRL_TrapFlag_SingleStepAfterHit;
flags &= ~D_TrapFlag_SingleStepAfterHit;
}
}
// rjf: instruction changes stack pointer => save off the stack pointer, single-step over, keep stepping
else if(point->inst_flags & DASM_InstFlag_ChangesStackPointer)
{
flags |= (CTRL_TrapFlag_SingleStepAfterHit|CTRL_TrapFlag_SaveStackPointer);
flags |= (D_TrapFlag_SingleStepAfterHit|D_TrapFlag_SaveStackPointer);
}
// rjf: add if appropriate
if(add)
{
CTRL_Trap trap = {flags, trap_addr};
D_Trap trap = {flags, trap_addr};
ctrl_trap_list_push(arena, &result.traps, &trap);
}
}
@@ -723,7 +723,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread)
}
if(!opl_in_line)
{
CTRL_Trap trap = {CTRL_TrapFlag_EndStepping, opl};
D_Trap trap = {D_TrapFlag_EndStepping, opl};
ctrl_trap_list_push(arena, &result.traps, &trap);
}
}
@@ -1064,7 +1064,7 @@ d_lines_from_file_path_line_num(Arena *arena, String8 file_path, S64 line_num)
//~ rjf: Process/Thread/Module Info Lookups
internal U64
d_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64 rip_vaddr)
d_tls_base_vaddr_from_process_root_rip(D_Entity *process, U64 root_vaddr, U64 rip_vaddr)
{
ProfBeginFunction();
U64 base_vaddr = 0;
@@ -1073,18 +1073,18 @@ d_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64
Temp scratch = scratch_begin(0, 0);
//- rjf: unpack module info
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
D_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
U64 addr_size = byte_size_from_arch(process->arch);
switch(process->tls_model)
{
case CTRL_TlsModel_Null: {}break;
case CTRL_TlsModel_WinodwsNt:
case D_TlsModel_Null: {}break;
case D_TlsModel_WinodwsNt:
{
// read thread local base pointer out of TEB
U64 thread_local_base = root_vaddr;
U64 tls_addr_array = 0;
CTRL_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 = ctrl_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(CTRL_Entity *process, U64 root_vaddr, U64
// read thread local storage pointer (array of TLS pointers, one per module)
U64 tls_ptr_vaddr = tls_array_vaddr + module->tls_index * addr_size;
CTRL_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 = ctrl_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)
{
@@ -1101,7 +1101,7 @@ d_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64
}
}
}break;
case CTRL_TlsModel_Gnu:
case D_TlsModel_Gnu:
{
if(module->tls_index > 0) // zero is reserved for the generation counter
{
@@ -1109,7 +1109,7 @@ d_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64
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;
CTRL_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 = ctrl_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)
{
@@ -1139,7 +1139,7 @@ d_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64
//- rjf: stopped info from the control thread
internal CTRL_Event
internal D_Event
d_ctrl_last_stop_event(void)
{
return d_user_state->ctrl_last_stop_event;
@@ -1182,10 +1182,10 @@ internal DI_KeyList
d_push_active_dbgi_key_list(Arena *arena)
{
DI_KeyList dbgis = {0};
CTRL_EntityArray modules = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, CTRL_EntityKind_Module);
D_EntityArray modules = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Module);
for EachIndex(idx, modules.count)
{
CTRL_Entity *module = modules.v[idx];
D_Entity *module = modules.v[idx];
DI_Key key = ctrl_dbgi_key_from_module(module);
di_key_list_push(arena, &dbgis, key);
}
@@ -1195,14 +1195,14 @@ d_push_active_dbgi_key_list(Arena *arena)
//- rjf: per-run caches
internal U64
d_query_cached_rip_from_thread(CTRL_Entity *thread)
d_query_cached_rip_from_thread(D_Entity *thread)
{
U64 result = d_query_cached_rip_from_thread_unwind(thread, 0);
return result;
}
internal U64
d_query_cached_rip_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count)
d_query_cached_rip_from_thread_unwind(D_Entity *thread, U64 unwind_count)
{
U64 result = 0;
if(unwind_count == 0)
@@ -1212,7 +1212,7 @@ d_query_cached_rip_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count)
else
{
Access *access = access_open();
CTRL_CallStack callstack = ctrl_call_stack_from_thread(access, thread->handle, 1, 0);
D_CallStack callstack = ctrl_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);
@@ -1223,11 +1223,11 @@ d_query_cached_rip_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count)
}
internal U64
d_query_cached_cfa_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count)
d_query_cached_cfa_from_thread_unwind(D_Entity *thread, U64 unwind_count)
{
U64 cfa = 0;
Access *access = access_open();
CTRL_CallStack callstack = ctrl_call_stack_from_thread(access, thread->handle, 1, 0);
D_CallStack callstack = ctrl_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;
@@ -1237,7 +1237,7 @@ d_query_cached_cfa_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count)
}
internal U64
d_query_cached_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64 rip_vaddr)
d_query_cached_tls_base_vaddr_from_process_root_rip(D_Entity *process, U64 root_vaddr, U64 rip_vaddr)
{
U64 result = 0;
for(U64 cache_idx = 0; cache_idx < ArrayCount(d_user_state->tls_base_caches); cache_idx += 1)
@@ -1252,7 +1252,7 @@ d_query_cached_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 ro
{
break;
}
CTRL_Handle handle = process->handle;
D_Handle handle = process->handle;
U64 hash = d_hash_from_seed_string(d_hash_from_string(str8_struct(&handle)), str8_struct(&rip_vaddr));
U64 slot_idx = hash%cache->slots_count;
D_RunTLSBaseCacheSlot *slot = &cache->slots[slot_idx];
@@ -1426,16 +1426,16 @@ d_next_cmd(D_Cmd **cmd)
//~ rjf: Main Layer Top-Level Calls
internal D_EventList
d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64])
d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(D_ExceptionCodeKind_COUNT+63)/64])
{
ProfBeginFunction();
Temp scratch = scratch_begin(&arena, 1);
D_EventList result = {0};
d_user_state->frame_index += 1;
//////////////////////////////
//- rjf: sync with ctrl thread
//
D_EventList events = {0};
ProfScope("sync with ctrl thread")
{
//- rjf: grab next reggen/memgen
@@ -1443,13 +1443,13 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
U64 new_reg_gen = ctrl_reg_gen();
//- rjf: consume & process events
CTRL_EventList events = ctrl_c2u_pop_events(scratch.arena);
events = ctrl_c2u_pop_events(arena);
ctrl_entity_store_apply_events(d_user_state->ctrl_entity_store, &events);
for(CTRL_EventNode *event_n = events.first;
for(D_EventNode *event_n = events.first;
event_n != 0;
event_n = event_n->next)
{
CTRL_Event *event = &event_n->v;
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("entity_id: %u\n", event->entity_id);
@@ -1457,31 +1457,26 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
{
default:{}break;
//- rjf: errors
case CTRL_EventKind_Error:
case D_EventKind_Error:
{
log_user_error(event->string);
}break;
//- rjf: starts/stops
case CTRL_EventKind_Started:
case D_EventKind_Started:
{
d_user_state->ctrl_is_running = 1;
d_user_state->ctrl_thread_run_state = 1;
}break;
case CTRL_EventKind_Stopped:
case D_EventKind_Stopped:
{
B32 should_snap = !(d_user_state->ctrl_soft_halt_issued);
d_user_state->ctrl_is_running = 0;
d_user_state->ctrl_thread_run_state = 0;
d_user_state->ctrl_soft_halt_issued = 0;
// rjf: exception or unexpected trap -> push error
if(event->cause == CTRL_EventCause_InterruptedByException ||
event->cause == CTRL_EventCause_InterruptedByTrap)
if(event->cause == D_EventCause_InterruptedByException ||
event->cause == D_EventCause_InterruptedByTrap)
{
log_user_error(str8_zero());
}
@@ -1492,46 +1487,12 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
MemoryCopyStruct(&d_user_state->ctrl_last_stop_event, event);
d_user_state->ctrl_last_stop_event.string = push_str8_copy(d_user_state->ctrl_stop_arena, d_user_state->ctrl_last_stop_event.string);
}
// rjf: push stop event to caller, if this is not a soft-halt
if(should_snap)
{
CTRL_Entity *thread = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, event->entity);
D_EventCause cause = D_EventCause_Null;
switch(event->cause)
{
default:{}break;
case CTRL_EventCause_InterruptedByHalt:
{
if(should_snap)
{
cause = D_EventCause_Halt;
}
else
{
cause = D_EventCause_SoftHalt;
}
}break;
case CTRL_EventCause_UserBreakpoint: {cause = D_EventCause_UserBreakpoint;}break;
}
D_EventNode *n = push_array(arena, D_EventNode, 1);
SLLQueuePush(result.first, result.last, n);
result.count += 1;
D_Event *evt = &n->v;
evt->kind = D_EventKind_Stop;
evt->cause = cause;
evt->thread = thread->kind == CTRL_EntityKind_Thread ? thread->handle : ctrl_handle_zero();
evt->vaddr = event->rip_vaddr;
evt->id = event->u64_code;
}
}break;
//- rjf: entity creation/deletion
case CTRL_EventKind_NewProc:
case D_EventKind_NewProc:
{
// rjf: the first process? -> clear session output
CTRL_EntityArray existing_processes = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process);
D_EntityArray existing_processes = ctrl_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")};
@@ -1539,40 +1500,11 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}
}break;
case CTRL_EventKind_EndProc:
{
D_EventNode *n = push_array(arena, D_EventNode, 1);
SLLQueuePush(result.first, result.last, n);
result.count += 1;
D_Event *evt = &n->v;
evt->kind = D_EventKind_ProcessEnd;
evt->code = event->u64_code;
}break;
case CTRL_EventKind_NewModule:
{
D_EventNode *n = push_array(arena, D_EventNode, 1);
SLLQueuePush(result.first, result.last, n);
result.count += 1;
D_Event *evt = &n->v;
evt->kind = D_EventKind_ModuleLoad;
evt->module = event->entity;
}break;
//- rjf: debug strings
case CTRL_EventKind_DebugString:
case D_EventKind_DebugString:
{
MTX_Op op = {r1u64(max_U64, max_U64), event->string};
mtx_push_op(d_user_state->output_log_key, op);
}break;
//- rjf: memory
case CTRL_EventKind_MemReserve:{}break;
case CTRL_EventKind_MemCommit:{}break;
case CTRL_EventKind_MemDecommit:{}break;
case CTRL_EventKind_MemRelease:{}break;
}
log_infof("}\n\n");
}
@@ -1624,10 +1556,10 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
// rjf: build data strings of all param data
String8List strings = {0};
{
CTRL_EntityArray threads = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, CTRL_EntityKind_Thread);
D_EntityArray threads = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Thread);
for EachIndex(idx, threads.count)
{
CTRL_Entity *thread = threads.v[idx];
D_Entity *thread = threads.v[idx];
if(thread->is_frozen)
{
str8_list_push(scratch.arena, &strings, str8_struct(&thread->id));
@@ -1665,7 +1597,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
//- rjf: process top-level commands
//
D_CmdList deferred_cmds = {0};
CTRL_MsgList ctrl_msgs = {0};
D_MsgList ctrl_msgs = {0};
ProfScope("process top-level commands")
{
D_BreakpointArray run_extra_bps = {0};
@@ -1677,9 +1609,9 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
// rjf: prep ctrl running arguments
B32 need_run = 0;
D_RunKind run_kind = D_RunKind_Run;
CTRL_Entity *run_thread = &ctrl_entity_nil;
CTRL_RunFlags run_flags = 0;
CTRL_TrapList run_traps = {0};
D_Entity *run_thread = &d_entity_nil;
D_RunFlags run_flags = 0;
D_TrapList run_traps = {0};
// rjf: process command
switch(cmd->kind)
@@ -1749,8 +1681,8 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
// rjf: push message to launch
{
CTRL_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = CTRL_MsgKind_Launch;
D_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = D_MsgKind_Launch;
msg->path = working_directory;
msg->cmd_line_string_list = cmdln_strings;
msg->stdout_path = stdout_path;
@@ -1767,8 +1699,8 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
// rjf: run
need_run = 1;
run_kind = D_RunKind_Run;
run_thread = &ctrl_entity_nil;
run_flags = (cmd->kind == D_CmdKind_LaunchAndStepInto) ? CTRL_RunFlag_StopOnEntryPoint : 0;
run_thread = &d_entity_nil;
run_flags = (cmd->kind == D_CmdKind_LaunchAndStepInto) ? D_RunFlag_StopOnEntryPoint : 0;
}
// rjf: no targets -> error
@@ -1779,15 +1711,15 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}break;
case D_CmdKind_Kill:
{
CTRL_Entity *process = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->process);
if(process == &ctrl_entity_nil)
D_Entity *process = ctrl_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
{
CTRL_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = CTRL_MsgKind_Kill;
D_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = D_MsgKind_Kill;
msg->exit_code = 1;
msg->entity = process->handle;
MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
@@ -1795,22 +1727,22 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}break;
case D_CmdKind_KillAll:
{
CTRL_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = CTRL_MsgKind_KillAll;
D_Msg *msg = ctrl_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:
{
CTRL_Entity *process = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->process);
if(process == &ctrl_entity_nil)
D_Entity *process = ctrl_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
{
CTRL_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = CTRL_MsgKind_Detach;
D_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = D_MsgKind_Detach;
msg->entity = process->handle;
MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
}
@@ -1818,12 +1750,12 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_Continue:
{
B32 good_to_run = 0;
CTRL_EntityArray threads = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, CTRL_EntityKind_Thread);
D_EntityArray threads = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Thread);
if(threads.count > 0)
{
for EachIndex(idx, threads.count)
{
CTRL_Entity *thread = threads.v[idx];
D_Entity *thread = threads.v[idx];
if(!thread->is_frozen)
{
good_to_run = 1;
@@ -1848,8 +1780,8 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_StepOverLine:
case D_CmdKind_StepOut:
{
CTRL_Entity *thread = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->thread);
if(thread == &ctrl_entity_nil)
D_Entity *thread = ctrl_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."));
}
@@ -1879,13 +1811,13 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
Access *access = access_open();
// rjf: thread => call stack
CTRL_CallStack callstack = ctrl_call_stack_from_thread(access, thread->handle, 1, os_now_microseconds()+10000);
D_CallStack callstack = ctrl_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);
CTRL_Trap trap = {CTRL_TrapFlag_EndStepping|CTRL_TrapFlag_IgnoreStackPointerCheck, vaddr};
D_Trap trap = {D_TrapFlag_EndStepping|D_TrapFlag_IgnoreStackPointerCheck, vaddr};
ctrl_trap_list_push(scratch.arena, &trap_net.traps, &trap);
trap_net.good_read = 1;
}
@@ -1942,7 +1874,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}break;
case D_CmdKind_SetThreadIP:
{
CTRL_Entity *thread = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->thread);
D_Entity *thread = ctrl_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);
regs_arch_block_write_rip(thread->arch, block, vaddr);
@@ -1968,7 +1900,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}break;
case D_CmdKind_Run:
{
CTRL_EntityArray processes = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process);
D_EntityArray processes = ctrl_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);
@@ -1980,7 +1912,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}break;
case D_CmdKind_Restart:
{
CTRL_EntityArray processes = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process);
D_EntityArray processes = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process);
if(processes.count != 0)
{
d_cmd(D_CmdKind_KillAll);
@@ -1990,7 +1922,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_StepInto:
case D_CmdKind_StepOver:
{
CTRL_EntityArray processes = ctrl_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process);
D_EntityArray processes = ctrl_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
@@ -2028,26 +1960,26 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}break;
case D_CmdKind_FreezeLocalMachine:
{
CTRL_MachineID machine_id = CTRL_MachineID_Local;
D_MachineID machine_id = D_MachineID_Local;
d_cmd(D_CmdKind_FreezeMachine, .entity = ctrl_handle_make(machine_id, dmn_handle_zero()));
}break;
case D_CmdKind_ThawLocalMachine:
{
CTRL_MachineID machine_id = CTRL_MachineID_Local;
D_MachineID machine_id = D_MachineID_Local;
d_cmd(D_CmdKind_ThawMachine, .entity = ctrl_handle_make(machine_id, dmn_handle_zero()));
}break;
case D_CmdKind_FreezeEntity:
case D_CmdKind_ThawEntity:
{
B32 should_freeze = (cmd->kind == D_CmdKind_FreezeEntity);
CTRL_Entity *root = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->entity);
for(CTRL_Entity *e = root; e != &ctrl_entity_nil; e = ctrl_entity_rec_depth_first_pre(e, root).next)
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)
{
if(e->kind == CTRL_EntityKind_Thread)
if(e->kind == D_EntityKind_Thread)
{
e->is_frozen = should_freeze;
CTRL_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = (should_freeze ? CTRL_MsgKind_FreezeThread : CTRL_MsgKind_ThawThread);
D_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = (should_freeze ? D_MsgKind_FreezeThread : D_MsgKind_ThawThread);
msg->entity = e->handle;
}
}
@@ -2064,12 +1996,12 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
//- rjf: entity decoration
case D_CmdKind_SetEntityColor:
{
CTRL_Entity *entity = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->entity);
D_Entity *entity = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->entity);
entity->rgba = params->rgba;
}break;
case D_CmdKind_SetEntityName:
{
CTRL_Entity *entity = ctrl_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->entity);
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);
}break;
@@ -2079,8 +2011,8 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
U32 pid = params->pid;
if(pid != 0)
{
CTRL_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = CTRL_MsgKind_Attach;
D_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
msg->kind = D_MsgKind_Attach;
msg->entity_id = pid;
MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
}
@@ -2096,10 +2028,10 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}
// rjf: push & fill run message
CTRL_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
D_Msg *msg = ctrl_msg_list_push(scratch.arena, &ctrl_msgs);
{
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(run_thread, CTRL_EntityKind_Process);
msg->kind = (run_kind == D_RunKind_Run || run_kind == D_RunKind_Step) ? CTRL_MsgKind_Run : CTRL_MsgKind_SingleStep;
D_Entity *process = ctrl_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;
msg->parent = process->handle;
@@ -2118,12 +2050,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
// rjf: unpack user breakpoint entity
D_Breakpoint *bp = &batch_breakpoints->v[idx];
// rjf: d -> ctrl flags
CTRL_UserBreakpointFlags ctrl_bp_flags = 0;
if(bp->flags & D_BreakpointFlag_BreakOnWrite) { ctrl_bp_flags |= CTRL_UserBreakpointFlag_BreakOnWrite; }
if(bp->flags & D_BreakpointFlag_BreakOnRead) { ctrl_bp_flags |= CTRL_UserBreakpointFlag_BreakOnRead; }
if(bp->flags & D_BreakpointFlag_BreakOnExecute) { ctrl_bp_flags |= CTRL_UserBreakpointFlag_BreakOnExecute; }
// rjf: textual location -> add breakpoints for all possible override locations
if(bp->file_path.size != 0 && bp->pt.line != 0)
{
@@ -2131,7 +2057,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
for(String8Node *n = overrides.first; n != 0; n = n->next)
{
CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_FileNameAndLineColNumber};
ctrl_user_bp.flags = ctrl_bp_flags;
ctrl_user_bp.flags = bp->flags;
ctrl_user_bp.id = bp->id;
ctrl_user_bp.string = n->string;
ctrl_user_bp.pt = bp->pt;
@@ -2145,7 +2071,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
else if(bp->vaddr_expr.size != 0)
{
CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_Expression};
ctrl_user_bp.flags = ctrl_bp_flags;
ctrl_user_bp.flags = bp->flags;
ctrl_user_bp.id = bp->id;
ctrl_user_bp.string = bp->vaddr_expr;
ctrl_user_bp.condition = bp->condition;
@@ -2157,7 +2083,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}
// rjf: copy run traps to scratch (needed, if run_traps can be `d_user_state->ctrl_last_run_traps`)
CTRL_TrapList run_traps_copy = ctrl_trap_list_copy(scratch.arena, &run_traps);
D_TrapList run_traps_copy = ctrl_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
@@ -2195,7 +2121,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
// the next tick)
//
{
CTRL_MsgList msgs_copy = ctrl_msg_list_deep_copy(d_user_state->ctrl_msg_arena, &ctrl_msgs);
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);
if(d_user_state->ctrl_msgs.count != 0)
{
@@ -2214,5 +2140,5 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
ProfEnd();
scratch_end(scratch);
return result;
return events;
}
+118 -118
View File
@@ -57,10 +57,10 @@ D_RunKind;
typedef struct D_CmdParams D_CmdParams;
struct D_CmdParams
{
CTRL_Handle machine;
CTRL_Handle process;
CTRL_Handle thread;
CTRL_Handle entity;
D_Handle machine;
D_Handle process;
D_Handle thread;
D_Handle entity;
String8 string;
String8 file_path;
TxtPt cursor;
@@ -104,7 +104,7 @@ typedef struct D_RunTLSBaseCacheNode D_RunTLSBaseCacheNode;
struct D_RunTLSBaseCacheNode
{
D_RunTLSBaseCacheNode *hash_next;
CTRL_Handle process;
D_Handle process;
U64 root_vaddr;
U64 rip_vaddr;
U64 tls_base_vaddr;
@@ -154,43 +154,43 @@ struct D_RunLocalsCache
////////////////////////////////
//~ rjf: User -> Ctrl Message Types
typedef enum CTRL_MsgKind
typedef enum D_MsgKind
{
CTRL_MsgKind_Null,
CTRL_MsgKind_Launch,
CTRL_MsgKind_Attach,
CTRL_MsgKind_Kill,
CTRL_MsgKind_KillAll,
CTRL_MsgKind_Detach,
CTRL_MsgKind_Run,
CTRL_MsgKind_SingleStep,
CTRL_MsgKind_SetUserEntryPoints,
CTRL_MsgKind_SetModuleDebugInfoPath,
CTRL_MsgKind_FreezeThread,
CTRL_MsgKind_ThawThread,
CTRL_MsgKind_COUNT,
D_MsgKind_Null,
D_MsgKind_Launch,
D_MsgKind_Attach,
D_MsgKind_Kill,
D_MsgKind_KillAll,
D_MsgKind_Detach,
D_MsgKind_Run,
D_MsgKind_SingleStep,
D_MsgKind_SetUserEntryPoints,
D_MsgKind_SetModuleDebugInfoPath,
D_MsgKind_FreezeThread,
D_MsgKind_ThawThread,
D_MsgKind_COUNT,
}
CTRL_MsgKind;
D_MsgKind;
typedef U32 CTRL_RunFlags;
typedef U32 D_RunFlags;
enum
{
CTRL_RunFlag_StopOnEntryPoint = (1<<0),
D_RunFlag_StopOnEntryPoint = (1<<0),
};
typedef struct CTRL_Msg CTRL_Msg;
struct CTRL_Msg
typedef struct D_Msg D_Msg;
struct D_Msg
{
CTRL_MsgKind kind;
CTRL_RunFlags run_flags;
CTRL_MsgID msg_id;
CTRL_Handle entity;
CTRL_Handle parent;
D_MsgKind kind;
D_RunFlags run_flags;
D_MsgID msg_id;
D_Handle entity;
D_Handle parent;
U32 entity_id;
U32 exit_code;
B32 env_inherit;
B32 debug_subprocesses;
U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64];
U64 exception_code_filters[(D_ExceptionCodeKind_COUNT+63)/64];
String8 path;
String8List entry_points;
String8List cmd_line_string_list;
@@ -198,104 +198,104 @@ struct CTRL_Msg
String8 stdout_path;
String8 stderr_path;
String8 stdin_path;
CTRL_TrapList traps;
D_TrapList traps;
CTRL_UserBreakpointList user_bps;
};
typedef struct CTRL_MsgNode CTRL_MsgNode;
struct CTRL_MsgNode
typedef struct D_MsgNode D_MsgNode;
struct D_MsgNode
{
CTRL_MsgNode *next;
CTRL_Msg v;
D_MsgNode *next;
D_Msg v;
};
typedef struct CTRL_MsgList CTRL_MsgList;
struct CTRL_MsgList
typedef struct D_MsgList D_MsgList;
struct D_MsgList
{
CTRL_MsgNode *first;
CTRL_MsgNode *last;
D_MsgNode *first;
D_MsgNode *last;
U64 count;
};
////////////////////////////////
//~ rjf: Ctrl -> User Event Types
typedef enum CTRL_EventKind
typedef enum D_EventKind
{
CTRL_EventKind_Null,
CTRL_EventKind_Error,
D_EventKind_Null,
D_EventKind_Error,
//- rjf: starts/stops
CTRL_EventKind_Started,
CTRL_EventKind_Stopped,
D_EventKind_Started,
D_EventKind_Stopped,
//- rjf: entity creation/deletion
CTRL_EventKind_NewProc,
CTRL_EventKind_NewThread,
CTRL_EventKind_NewModule,
CTRL_EventKind_EndProc,
CTRL_EventKind_EndThread,
CTRL_EventKind_EndModule,
D_EventKind_NewProc,
D_EventKind_NewThread,
D_EventKind_NewModule,
D_EventKind_EndProc,
D_EventKind_EndThread,
D_EventKind_EndModule,
//- rjf: thread freeze state changes
CTRL_EventKind_ThreadFrozen,
CTRL_EventKind_ThreadThawed,
D_EventKind_ThreadFrozen,
D_EventKind_ThreadThawed,
//- rjf: debug info changes
CTRL_EventKind_ModuleDebugInfoPathChange,
D_EventKind_ModuleDebugInfoPathChange,
//- rjf: debug strings / decorations / markup
CTRL_EventKind_DebugString,
CTRL_EventKind_ThreadName,
CTRL_EventKind_ThreadColor,
CTRL_EventKind_SetBreakpoint,
CTRL_EventKind_UnsetBreakpoint,
CTRL_EventKind_SetVAddrRangeNote,
D_EventKind_DebugString,
D_EventKind_ThreadName,
D_EventKind_ThreadColor,
D_EventKind_SetBreakpoint,
D_EventKind_UnsetBreakpoint,
D_EventKind_SetVAddrRangeNote,
//- rjf: memory
CTRL_EventKind_MemReserve,
CTRL_EventKind_MemCommit,
CTRL_EventKind_MemDecommit,
CTRL_EventKind_MemRelease,
D_EventKind_MemReserve,
D_EventKind_MemCommit,
D_EventKind_MemDecommit,
D_EventKind_MemRelease,
CTRL_EventKind_COUNT
D_EventKind_COUNT
}
CTRL_EventKind;
D_EventKind;
typedef enum CTRL_EventCause
typedef enum D_EventCause
{
CTRL_EventCause_Null,
CTRL_EventCause_Error,
CTRL_EventCause_Finished,
CTRL_EventCause_EntryPoint,
CTRL_EventCause_UserBreakpoint,
CTRL_EventCause_InterruptedByTrap,
CTRL_EventCause_InterruptedByException,
CTRL_EventCause_InterruptedByHalt,
CTRL_EventCause_COUNT
D_EventCause_Null,
D_EventCause_Error,
D_EventCause_Finished,
D_EventCause_EntryPoint,
D_EventCause_UserBreakpoint,
D_EventCause_InterruptedByTrap,
D_EventCause_InterruptedByException,
D_EventCause_InterruptedByHalt,
D_EventCause_COUNT
}
CTRL_EventCause;
D_EventCause;
typedef enum CTRL_ExceptionKind
typedef enum D_ExceptionKind
{
CTRL_ExceptionKind_Null,
CTRL_ExceptionKind_MemoryRead,
CTRL_ExceptionKind_MemoryWrite,
CTRL_ExceptionKind_MemoryExecute,
CTRL_ExceptionKind_CppThrow,
CTRL_ExceptionKind_COUNT
D_ExceptionKind_Null,
D_ExceptionKind_MemoryRead,
D_ExceptionKind_MemoryWrite,
D_ExceptionKind_MemoryExecute,
D_ExceptionKind_CppThrow,
D_ExceptionKind_COUNT
}
CTRL_ExceptionKind;
D_ExceptionKind;
typedef struct CTRL_Event CTRL_Event;
struct CTRL_Event
typedef struct D_Event D_Event;
struct D_Event
{
CTRL_EventKind kind;
CTRL_EventCause cause;
CTRL_ExceptionKind exception_kind;
CTRL_MsgID msg_id;
CTRL_Handle entity;
CTRL_Handle parent;
D_EventKind kind;
D_EventCause cause;
D_ExceptionKind exception_kind;
D_MsgID msg_id;
D_Handle entity;
D_Handle parent;
Arch arch;
U64 u64_code;
U32 entity_id;
@@ -308,24 +308,24 @@ struct CTRL_Event
U64 timestamp;
U32 exception_code;
U32 rgba;
CTRL_UserBreakpointFlags bp_flags;
D_BreakpointFlags bp_flags;
String8 string;
OperatingSystem target_os;
CTRL_TlsModel tls_model;
D_TlsModel tls_model;
};
typedef struct CTRL_EventNode CTRL_EventNode;
struct CTRL_EventNode
typedef struct D_EventNode D_EventNode;
struct D_EventNode
{
CTRL_EventNode *next;
CTRL_Event v;
D_EventNode *next;
D_Event v;
};
typedef struct CTRL_EventList CTRL_EventList;
struct CTRL_EventList
typedef struct D_EventList D_EventList;
struct D_EventList
{
CTRL_EventNode *first;
CTRL_EventNode *last;
D_EventNode *first;
D_EventNode *last;
U64 count;
};
@@ -362,21 +362,21 @@ struct D_UserState
Arena *ctrl_last_run_arena;
D_RunKind ctrl_last_run_kind;
U64 ctrl_last_run_frame_idx;
CTRL_Handle ctrl_last_run_thread_handle;
CTRL_RunFlags ctrl_last_run_flags;
CTRL_TrapList ctrl_last_run_traps;
D_Handle ctrl_last_run_thread_handle;
D_RunFlags ctrl_last_run_flags;
D_TrapList ctrl_last_run_traps;
D_BreakpointArray ctrl_last_run_extra_bps;
U128 ctrl_last_run_param_state_hash;
B32 ctrl_is_running;
B32 ctrl_thread_run_state;
B32 ctrl_soft_halt_issued;
Arena *ctrl_msg_arena;
CTRL_MsgList ctrl_msgs;
D_MsgList ctrl_msgs;
// rjf: ctrl -> user reading state
CTRL_EntityCtxRWStore *ctrl_entity_store;
D_EntityCtxRWStore *ctrl_entity_store;
Arena *ctrl_stop_arena;
CTRL_Event ctrl_last_stop_event;
D_Event ctrl_last_stop_event;
};
////////////////////////////////
@@ -419,9 +419,9 @@ internal void d_cmd_list_push_new(Arena *arena, D_CmdList *cmds, D_CmdKind kind,
////////////////////////////////
//~ rjf: Stepping "Trap Net" Builders
internal D_TrapNet d_trap_net_from_thread__step_over_inst(Arena *arena, CTRL_Entity *thread);
internal D_TrapNet d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread);
internal D_TrapNet d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread);
internal D_TrapNet d_trap_net_from_thread__step_over_inst(Arena *arena, D_Entity *thread);
internal D_TrapNet d_trap_net_from_thread__step_over_line(Arena *arena, D_Entity *thread);
internal D_TrapNet d_trap_net_from_thread__step_into_line(Arena *arena, D_Entity *thread);
////////////////////////////////
//~ rjf: Debug Info Lookups
@@ -440,13 +440,13 @@ internal D_LineList d_lines_from_file_path_line_num(Arena *arena, String8 file_p
////////////////////////////////
//~ rjf: Process/Thread/Module Info Lookups
internal U64 d_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64 rip_vaddr);
internal U64 d_tls_base_vaddr_from_process_root_rip(D_Entity *process, U64 root_vaddr, U64 rip_vaddr);
////////////////////////////////
//~ rjf: Target Controls
//- rjf: stopped info from the control thread
internal CTRL_Event d_ctrl_last_stop_event(void);
internal D_Event d_ctrl_last_stop_event(void);
////////////////////////////////
//~ rjf: Main State Accessors/Mutators
@@ -463,10 +463,10 @@ internal B32 d_ctrl_targets_running(void);
internal DI_KeyList d_push_active_dbgi_key_list(Arena *arena);
//- rjf: per-run caches
internal U64 d_query_cached_rip_from_thread(CTRL_Entity *thread);
internal U64 d_query_cached_rip_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count);
internal U64 d_query_cached_cfa_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count);
internal U64 d_query_cached_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64 rip_vaddr);
internal U64 d_query_cached_rip_from_thread(D_Entity *thread);
internal U64 d_query_cached_rip_from_thread_unwind(D_Entity *thread, U64 unwind_count);
internal U64 d_query_cached_cfa_from_thread_unwind(D_Entity *thread, U64 unwind_count);
internal U64 d_query_cached_tls_base_vaddr_from_process_root_rip(D_Entity *process, U64 root_vaddr, U64 rip_vaddr);
internal E_String2NumMap *d_query_cached_locals_map_from_dbgi_key_voff(DI_Key dbgi_key, U64 voff);
internal E_String2NumMap *d_query_cached_member_map_from_dbgi_key_voff(DI_Key dbgi_key, U64 voff);
@@ -480,6 +480,6 @@ internal B32 d_next_cmd(D_Cmd **cmd);
////////////////////////////////
//~ rjf: Main Layer Top-Level Calls
internal D_EventList d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64]);
internal D_EventList d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(D_ExceptionCodeKind_COUNT+63)/64]);
#endif // DBG_ENGINE_USER_H
+56 -56
View File
@@ -44,65 +44,65 @@ D_CmdKind_Attach,
D_CmdKind_COUNT,
} D_CmdKind;
typedef enum CTRL_EntityKind
typedef enum D_EntityKind
{
CTRL_EntityKind_Null,
CTRL_EntityKind_Root,
CTRL_EntityKind_Machine,
CTRL_EntityKind_Process,
CTRL_EntityKind_Thread,
CTRL_EntityKind_Module,
CTRL_EntityKind_EntryPoint,
CTRL_EntityKind_DebugInfoPath,
CTRL_EntityKind_PendingThreadName,
CTRL_EntityKind_PendingThreadColor,
CTRL_EntityKind_Breakpoint,
CTRL_EntityKind_AddressRangeAnnotation,
CTRL_EntityKind_COUNT,
} CTRL_EntityKind;
D_EntityKind_Null,
D_EntityKind_Root,
D_EntityKind_Machine,
D_EntityKind_Process,
D_EntityKind_Thread,
D_EntityKind_Module,
D_EntityKind_EntryPoint,
D_EntityKind_DebugInfoPath,
D_EntityKind_PendingThreadName,
D_EntityKind_PendingThreadColor,
D_EntityKind_Breakpoint,
D_EntityKind_AddressRangeAnnotation,
D_EntityKind_COUNT,
} D_EntityKind;
typedef enum CTRL_ExceptionCodeKind
typedef enum D_ExceptionCodeKind
{
CTRL_ExceptionCodeKind_Null,
CTRL_ExceptionCodeKind_Win32CtrlC,
CTRL_ExceptionCodeKind_Win32CtrlBreak,
CTRL_ExceptionCodeKind_Win32WinRTOriginateError,
CTRL_ExceptionCodeKind_Win32WinRTTransformError,
CTRL_ExceptionCodeKind_Win32RPCCallCancelled,
CTRL_ExceptionCodeKind_Win32DatatypeMisalignment,
CTRL_ExceptionCodeKind_Win32AccessViolation,
CTRL_ExceptionCodeKind_Win32InPageError,
CTRL_ExceptionCodeKind_Win32InvalidHandle,
CTRL_ExceptionCodeKind_Win32NotEnoughQuota,
CTRL_ExceptionCodeKind_Win32IllegalInstruction,
CTRL_ExceptionCodeKind_Win32CannotContinueException,
CTRL_ExceptionCodeKind_Win32InvalidExceptionDisposition,
CTRL_ExceptionCodeKind_Win32ArrayBoundsExceeded,
CTRL_ExceptionCodeKind_Win32FloatingPointDenormalOperand,
CTRL_ExceptionCodeKind_Win32FloatingPointDivisionByZero,
CTRL_ExceptionCodeKind_Win32FloatingPointInexactResult,
CTRL_ExceptionCodeKind_Win32FloatingPointInvalidOperation,
CTRL_ExceptionCodeKind_Win32FloatingPointOverflow,
CTRL_ExceptionCodeKind_Win32FloatingPointStackCheck,
CTRL_ExceptionCodeKind_Win32FloatingPointUnderflow,
CTRL_ExceptionCodeKind_Win32IntegerDivisionByZero,
CTRL_ExceptionCodeKind_Win32IntegerOverflow,
CTRL_ExceptionCodeKind_Win32PrivilegedInstruction,
CTRL_ExceptionCodeKind_Win32StackOverflow,
CTRL_ExceptionCodeKind_Win32UnableToLocateDLL,
CTRL_ExceptionCodeKind_Win32OrdinalNotFound,
CTRL_ExceptionCodeKind_Win32EntryPointNotFound,
CTRL_ExceptionCodeKind_Win32DLLInitializationFailed,
CTRL_ExceptionCodeKind_Win32FloatingPointSSEMultipleFaults,
CTRL_ExceptionCodeKind_Win32FloatingPointSSEMultipleTraps,
CTRL_ExceptionCodeKind_Win32AssertionFailed,
CTRL_ExceptionCodeKind_Win32ModuleNotFound,
CTRL_ExceptionCodeKind_Win32ProcedureNotFound,
CTRL_ExceptionCodeKind_Win32SanitizerErrorDetected,
CTRL_ExceptionCodeKind_Win32SanitizerRawAccessViolation,
CTRL_ExceptionCodeKind_Win32DirectXDebugLayer,
CTRL_ExceptionCodeKind_COUNT,
} CTRL_ExceptionCodeKind;
D_ExceptionCodeKind_Null,
D_ExceptionCodeKind_Win32CtrlC,
D_ExceptionCodeKind_Win32CtrlBreak,
D_ExceptionCodeKind_Win32WinRTOriginateError,
D_ExceptionCodeKind_Win32WinRTTransformError,
D_ExceptionCodeKind_Win32RPCCallCancelled,
D_ExceptionCodeKind_Win32DatatypeMisalignment,
D_ExceptionCodeKind_Win32AccessViolation,
D_ExceptionCodeKind_Win32InPageError,
D_ExceptionCodeKind_Win32InvalidHandle,
D_ExceptionCodeKind_Win32NotEnoughQuota,
D_ExceptionCodeKind_Win32IllegalInstruction,
D_ExceptionCodeKind_Win32CannotContinueException,
D_ExceptionCodeKind_Win32InvalidExceptionDisposition,
D_ExceptionCodeKind_Win32ArrayBoundsExceeded,
D_ExceptionCodeKind_Win32FloatingPointDenormalOperand,
D_ExceptionCodeKind_Win32FloatingPointDivisionByZero,
D_ExceptionCodeKind_Win32FloatingPointInexactResult,
D_ExceptionCodeKind_Win32FloatingPointInvalidOperation,
D_ExceptionCodeKind_Win32FloatingPointOverflow,
D_ExceptionCodeKind_Win32FloatingPointStackCheck,
D_ExceptionCodeKind_Win32FloatingPointUnderflow,
D_ExceptionCodeKind_Win32IntegerDivisionByZero,
D_ExceptionCodeKind_Win32IntegerOverflow,
D_ExceptionCodeKind_Win32PrivilegedInstruction,
D_ExceptionCodeKind_Win32StackOverflow,
D_ExceptionCodeKind_Win32UnableToLocateDLL,
D_ExceptionCodeKind_Win32OrdinalNotFound,
D_ExceptionCodeKind_Win32EntryPointNotFound,
D_ExceptionCodeKind_Win32DLLInitializationFailed,
D_ExceptionCodeKind_Win32FloatingPointSSEMultipleFaults,
D_ExceptionCodeKind_Win32FloatingPointSSEMultipleTraps,
D_ExceptionCodeKind_Win32AssertionFailed,
D_ExceptionCodeKind_Win32ModuleNotFound,
D_ExceptionCodeKind_Win32ProcedureNotFound,
D_ExceptionCodeKind_Win32SanitizerErrorDetected,
D_ExceptionCodeKind_Win32SanitizerRawAccessViolation,
D_ExceptionCodeKind_Win32DirectXDebugLayer,
D_ExceptionCodeKind_COUNT,
} D_ExceptionCodeKind;
global B32 DEV_always_refresh = 0;
global B32 DEV_simulate_lag = 0;