fold ctrl layer into dbg engine - no benefit to disallowing dependence on debug engine types inside of ctrl, and it has been causing unnecessary barriers for eventual eval magic.

This commit is contained in:
Ryan Fleury
2026-04-22 12:44:18 -07:00
parent d2eb9628ba
commit 2388db3998
17 changed files with 11279 additions and 11378 deletions
+190
View File
@@ -88,3 +88,193 @@ D_DevToggleTable:
@expand(D_DevToggleTable a) `{&DEV_$(a.name), str8_lit_comp("$(a.name)")},`
`};`;
}
////////////////////////////////
//~ rjf: Entity Kinds
@table(name code_name display_string)
CTRL_EntityKindTable:
{
{Root root "Root" }
{Machine machine "Machine" }
{Process process "Process" }
{Thread thread "Thread" }
{Module module "Module" }
{EntryPoint entry_point "Entry Point" }
{DebugInfoPath debug_info_path "Debug Info Path" }
{PendingThreadName pending_thread_name "Pending Thread Name" }
{PendingThreadColor pending_thread_color "Pending Thread Color" }
{Breakpoint breakpoint "Breakpoint" }
{AddressRangeAnnotation address_range_annotation "Address Range Annotation" }
}
@enum CTRL_EntityKind:
{
Null,
@expand(CTRL_EntityKindTable a) `$(a.name)`,
COUNT,
}
@data(String8) ctrl_entity_kind_code_name_table:
{
`{0}`,
@expand(CTRL_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)")`
}
////////////////////////////////
//~ rjf: Exception Codes
@table(name lower_name code default display_string)
CTRL_ExceptionCodeKindTable:
{
{Win32CtrlC win32_ctrl_c 0x40010005 1 "(Win32) Control-C" }
{Win32CtrlBreak win32_ctrl_break 0x40010008 1 "(Win32) Control-Break" }
{Win32WinRTOriginateError win32_win_rt_originate_error 0x40080201 0 "(Win32) WinRT Originate Error" }
{Win32WinRTTransformError win32_win_rt_transform_error 0x40080202 0 "(Win32) WinRT Transform Error" }
{Win32RPCCallCancelled win32_rpc_call_cancelled 0x0000071a 0 "(Win32) RPC Call Cancelled" }
{Win32DatatypeMisalignment win32_datatype_misalignment 0x80000002 0 "(Win32) Data Type Misalignment" }
{Win32AccessViolation win32_access_violation 0xc0000005 1 "(Win32) Access Violation" }
{Win32InPageError win32_in_page_error 0xc0000006 0 "(Win32) In Page Error" }
{Win32InvalidHandle win32_invalid_handle 0xc0000008 1 "(Win32) Invalid Handle Specified" }
{Win32NotEnoughQuota win32_not_enough_quota 0xc0000017 0 "(Win32) Not Enough Quota" }
{Win32IllegalInstruction win32_illegal_instruction 0xc000001d 0 "(Win32) Illegal Instruction" }
{Win32CannotContinueException win32_cannot_continue_exception 0xc0000025 0 "(Win32) Cannot Continue From Exception" }
{Win32InvalidExceptionDisposition win32_invalid_exception_disposition 0xc0000026 0 "(Win32) Invalid Exception Disposition Returned By Handler" }
{Win32ArrayBoundsExceeded win32_array_bounds_exceeded 0xc000008c 0 "(Win32) Array Bounds Exceeded" }
{Win32FloatingPointDenormalOperand win32_floating_point_denormal_operand 0xc000008d 0 "(Win32) Floating-Point Denormal Operand" }
{Win32FloatingPointDivisionByZero win32_floating_point_division_by_zero 0xc000008e 0 "(Win32) Floating-Point Division By Zero" }
{Win32FloatingPointInexactResult win32_floating_point_inexact_result 0xc000008f 0 "(Win32) Floating-Point Inexact Result" }
{Win32FloatingPointInvalidOperation win32_floating_point_invalid_operation 0xc0000090 0 "(Win32) Floating-Point Invalid Operation" }
{Win32FloatingPointOverflow win32_floating_point_overflow 0xc0000091 0 "(Win32) Floating-Point Overflow" }
{Win32FloatingPointStackCheck win32_floating_point_stack_check 0xc0000092 0 "(Win32) Floating-Point Stack Check" }
{Win32FloatingPointUnderflow win32_floating_point_underflow 0xc0000093 0 "(Win32) Floating-Point Underflow" }
{Win32IntegerDivisionByZero win32_integer_division_by_zero 0xc0000094 0 "(Win32) Integer Division By Zero" }
{Win32IntegerOverflow win32_integer_overflow 0xc0000095 0 "(Win32) Integer Overflow" }
{Win32PrivilegedInstruction win32_privileged_instruction 0xc0000096 0 "(Win32) Privileged Instruction" }
{Win32StackOverflow win32_stack_overflow 0xc00000fd 0 "(Win32) Stack Overflow" }
{Win32UnableToLocateDLL win32_unable_to_locate_dll 0xc0000135 0 "(Win32) Unable To Locate DLL" }
{Win32OrdinalNotFound win32_ordinal_not_found 0xc0000138 0 "(Win32) Ordinal Not Found" }
{Win32EntryPointNotFound win32_entry_point_not_found 0xc0000139 0 "(Win32) Entry Point Not Found" }
{Win32DLLInitializationFailed win32_dll_initialization_failed 0xc0000142 0 "(Win32) DLL Initialization Failed" }
{Win32FloatingPointSSEMultipleFaults win32_floating_point_sse_multiple_faults 0xc00002b4 0 "(Win32) Floating Point SSE Multiple Faults" }
{Win32FloatingPointSSEMultipleTraps win32_floating_point_sse_multiple_traps 0xc00002b5 0 "(Win32) Floating Point SSE Multiple Traps" }
{Win32AssertionFailed win32_assertion_failed 0xc0000420 1 "(Win32) Assertion Failed" }
{Win32ModuleNotFound win32_module_not_found 0xc06d007e 0 "(Win32) Module Not Found" }
{Win32ProcedureNotFound win32_procedure_not_found 0xc06d007f 0 "(Win32) Procedure Not Found" }
{Win32SanitizerErrorDetected win32_sanitizer_error_detected 0xe073616e 1 "(Win32) Sanitizer Error Detected" }
{Win32SanitizerRawAccessViolation win32_sanitizer_raw_access_violation 0xe0736171 0 "(Win32) Sanitizer Raw Access Violation" }
{Win32DirectXDebugLayer win32_directx_debug_layer 0x0000087a 1 "(Win32) DirectX Debug Layer" }
}
@enum CTRL_ExceptionCodeKind:
{
Null,
@expand(CTRL_ExceptionCodeKindTable a) `$(a.name)`,
COUNT,
}
@data(U32) ctrl_exception_code_kind_code_table:
{
`0`;
@expand(CTRL_ExceptionCodeKindTable a) `$(a.code)`;
}
@data(String8) ctrl_exception_code_kind_display_string_table:
{
`{0}`;
@expand(CTRL_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)")`;
}
@data(B8) ctrl_exception_code_kind_default_enable_table:
{
`0`;
@expand(CTRL_ExceptionCodeKindTable a) `$(a.default)`;
}
////////////////////////////////
//~ rjf: Exception Sub-Codes
@table(name, value)
CTRL_ExceptionSubCodeKindTable:
{
{ W32_FAST_FAIL_LEGACY_GS_VIOLATION 0 }
{ W32_FAST_FAIL_VTGUARD_CHECK_FAILURE 1 }
{ W32_FAST_FAIL_STACK_COOKIE_CHECK_FAILURE 2 }
{ W32_FAST_FAIL_CORRUPT_LIST_ENTRY 3 }
{ W32_FAST_FAIL_INCORRECT_STACK 4 }
{ W32_FAST_FAIL_INVALID_ARG 5 }
{ W32_FAST_FAIL_GS_COOKIE_INIT 6 }
{ W32_FAST_FAIL_FATAL_APP_EXIT 7 }
{ W32_FAST_FAIL_RANGE_CHECK_FAILURE 8 }
{ W32_FAST_FAIL_UNSAFE_REGISTRY_ACCESS 9 }
{ W32_FAST_FAIL_GUARD_ICALL_CHECK_FAILURE 10 }
{ W32_FAST_FAIL_GUARD_WRITE_CHECK_FAILURE 11 }
{ W32_FAST_FAIL_INVALID_FIBER_SWITCH 12 }
{ W32_FAST_FAIL_INVALID_SET_OF_CONTEXT 13 }
{ W32_FAST_FAIL_INVALID_REFERENCE_COUNT 14 }
{ W32_FAST_FAIL_INVALID_JUMP_BUFFER 18 }
{ W32_FAST_FAIL_MRDATA_MODIFIED 19 }
{ W32_FAST_FAIL_CERTIFICATION_FAILURE 20 }
{ W32_FAST_FAIL_INVALID_EXCEPTION_CHAIN 21 }
{ W32_FAST_FAIL_CRYPTO_LIBRARY 22 }
{ W32_FAST_FAIL_INVALID_CALL_IN_DLL_CALLOUT 23 }
{ W32_FAST_FAIL_INVALID_IMAGE_BASE 24 }
{ W32_FAST_FAIL_DLOAD_PROTECTION_FAILURE 25 }
{ W32_FAST_FAIL_UNSAFE_EXTENSION_CALL 26 }
{ W32_FAST_FAIL_DEPRECATED_SERVICE_INVOKED 27 }
{ W32_FAST_FAIL_INVALID_BUFFER_ACCESS 28 }
{ W32_FAST_FAIL_INVALID_BALANCED_TREE 29 }
{ W32_FAST_FAIL_INVALID_NEXT_THREAD 30 }
{ W32_FAST_FAIL_GUARD_ICALL_CHECK_SUPPRESSED 31 }
{ W32_FAST_FAIL_APCS_DISABLED 32 }
{ W32_FAST_FAIL_INVALID_IDLE_STATE 33 }
{ W32_FAST_FAIL_MRDATA_PROTECTION_FAILURE 34 }
{ W32_FAST_FAIL_UNEXPECTED_HEAP_EXCEPTION 35 }
{ W32_FAST_FAIL_INVALID_LOCK_STATE 36 }
{ W32_FAST_FAIL_GUARD_JUMPTABLE 37 }
{ W32_FAST_FAIL_INVALID_LONGJUMP_TARGET 38 }
{ W32_FAST_FAIL_INVALID_DISPATCH_CONTEXT 39 }
{ W32_FAST_FAIL_INVALID_THREAD 40 }
{ W32_FAST_FAIL_INVALID_SYSCALL_NUMBER 41 }
{ W32_FAST_FAIL_INVALID_FILE_OPERATION 42 }
{ W32_FAST_FAIL_LPAC_ACCESS_DENIED 43 }
{ W32_FAST_FAIL_GUARD_SS_FAILURE 44 }
{ W32_FAST_FAIL_LOADER_CONTINUITY_FAILURE 45 }
{ W32_FAST_FAIL_GUARD_EXPORT_SUPPRESSION_FAILURE 46 }
{ W32_FAST_FAIL_INVALID_CONTROL_STACK 47 }
{ W32_FAST_FAIL_SET_CONTEXT_DENIED 48 }
{ W32_FAST_FAIL_INVALID_IAT 49 }
{ W32_FAST_FAIL_HEAP_METADATA_CORRUPTION 50 }
{ W32_FAST_FAIL_PAYLOAD_RESTRICTION_VIOLATION 51 }
{ W32_FAST_FAIL_LOW_LABEL_ACCESS_DENIED 52 }
{ W32_FAST_FAIL_ENCLAVE_CALL_FAILURE 53 }
{ W32_FAST_FAIL_UNHANDLED_LSS_EXCEPTON 54 }
{ W32_FAST_FAIL_ADMINLESS_ACCESS_DENIED 55 }
{ W32_FAST_FAIL_UNEXPECTED_CALL 56 }
{ W32_FAST_FAIL_CONTROL_INVALID_RETURN_ADDRESS 57 }
{ W32_FAST_FAIL_UNEXPECTED_HOST_BEHAVIOR 58 }
{ W32_FAST_FAIL_FLAGS_CORRUPTION 59 }
{ W32_FAST_FAIL_VEH_CORRUPTION 60 }
{ W32_FAST_FAIL_ETW_CORRUPTION 61 }
{ W32_FAST_FAIL_RIO_ABORT 62 }
{ W32_FAST_FAIL_INVALID_PFN 63 }
{ W32_FAST_FAIL_GUARD_ICALL_CHECK_FAILURE_XFG 64 }
{ W32_FAST_FAIL_CAST_GUARD 65 }
{ W32_FAST_FAIL_HOST_VISIBILITY_CHANGE 66 }
{ W32_FAST_FAIL_KERNEL_CET_SHADOW_STACK_ASSIST 67 }
{ W32_FAST_FAIL_PATCH_CALLBACK_FAILED 68 }
{ W32_FAST_FAIL_NTDLL_PATCH_FAILED 69 }
{ W32_FAST_FAIL_INVALID_FLS_DATA 70 }
}
File diff suppressed because it is too large Load Diff
+256 -293
View File
@@ -4,6 +4,231 @@
#ifndef DBG_ENGINE_CORE_H
#define DBG_ENGINE_CORE_H
////////////////////////////////
//~ rjf: ID Types
typedef U64 CTRL_MsgID;
typedef U64 CTRL_MachineID;
#define CTRL_MachineID_Local (1)
////////////////////////////////
//~ rjf: Entity Handle Types
typedef struct CTRL_Handle CTRL_Handle;
struct CTRL_Handle
{
CTRL_MachineID machine_id;
DMN_Handle dmn_handle;
};
typedef struct CTRL_HandleNode CTRL_HandleNode;
struct CTRL_HandleNode
{
CTRL_HandleNode *next;
CTRL_Handle v;
};
typedef struct CTRL_HandleList CTRL_HandleList;
struct CTRL_HandleList
{
CTRL_HandleNode *first;
CTRL_HandleNode *last;
U64 count;
};
typedef struct CTRL_HandleArray CTRL_HandleArray;
struct CTRL_HandleArray
{
CTRL_Handle *v;
U64 count;
};
////////////////////////////////
//~ rjf: Generated Code
#include "generated/dbg_engine.meta.h"
////////////////////////////////
//~ rjf: User Breakpoint Types
typedef U32 CTRL_UserBreakpointFlags;
enum
{
CTRL_UserBreakpointFlag_BreakOnWrite = (1<<0),
CTRL_UserBreakpointFlag_BreakOnRead = (1<<1),
CTRL_UserBreakpointFlag_BreakOnExecute = (1<<2),
};
typedef enum CTRL_UserBreakpointKind
{
CTRL_UserBreakpointKind_Null,
CTRL_UserBreakpointKind_FileNameAndLineColNumber,
CTRL_UserBreakpointKind_Expression,
CTRL_UserBreakpointKind_COUNT
}
CTRL_UserBreakpointKind;
typedef struct CTRL_UserBreakpoint CTRL_UserBreakpoint;
struct CTRL_UserBreakpoint
{
CTRL_UserBreakpointKind kind;
CTRL_UserBreakpointFlags flags;
U64 id;
String8 string;
TxtPt pt;
U64 size;
String8 condition;
};
typedef struct CTRL_UserBreakpointNode CTRL_UserBreakpointNode;
struct CTRL_UserBreakpointNode
{
CTRL_UserBreakpointNode *next;
CTRL_UserBreakpoint v;
};
typedef struct CTRL_UserBreakpointList CTRL_UserBreakpointList;
struct CTRL_UserBreakpointList
{
CTRL_UserBreakpointNode *first;
CTRL_UserBreakpointNode *last;
U64 count;
};
////////////////////////////////
//~ Dynamic Linker Types
typedef U32 CTRL_TlsModel;
enum
{
CTRL_TlsModel_Null,
CTRL_TlsModel_WinodwsNt,
CTRL_TlsModel_Gnu
};
////////////////////////////////
//~ rjf: Entity Types
typedef struct CTRL_Entity CTRL_Entity;
struct CTRL_Entity
{
CTRL_Entity *first;
CTRL_Entity *last;
CTRL_Entity *next;
CTRL_Entity *prev;
CTRL_Entity *parent;
CTRL_EntityKind kind;
Arch arch;
B32 is_frozen;
B32 is_soloed;
U32 rgba;
CTRL_Handle handle;
U64 id;
Rng1U64 vaddr_range;
U64 stack_base;
U64 timestamp;
CTRL_UserBreakpointFlags bp_flags;
String8 string;
CTRL_TlsModel tls_model;
U64 tls_index;
U64 tls_offset;
OperatingSystem target_os;
};
typedef struct CTRL_EntityNode CTRL_EntityNode;
struct CTRL_EntityNode
{
CTRL_EntityNode *next;
CTRL_Entity *v;
};
typedef struct CTRL_EntityList CTRL_EntityList;
struct CTRL_EntityList
{
CTRL_EntityNode *first;
CTRL_EntityNode *last;
U64 count;
};
typedef struct CTRL_EntityArray CTRL_EntityArray;
struct CTRL_EntityArray
{
CTRL_Entity **v;
U64 count;
};
typedef struct CTRL_EntityRec CTRL_EntityRec;
struct CTRL_EntityRec
{
CTRL_Entity *next;
S32 push_count;
S64 pop_count;
};
typedef struct CTRL_EntityHashNode CTRL_EntityHashNode;
struct CTRL_EntityHashNode
{
CTRL_EntityHashNode *next;
CTRL_EntityHashNode *prev;
CTRL_Entity *entity;
};
typedef struct CTRL_EntityHashSlot CTRL_EntityHashSlot;
struct CTRL_EntityHashSlot
{
CTRL_EntityHashNode *first;
CTRL_EntityHashNode *last;
};
typedef struct CTRL_EntityStringChunkNode CTRL_EntityStringChunkNode;
struct CTRL_EntityStringChunkNode
{
CTRL_EntityStringChunkNode *next;
U64 size;
};
read_only global U64 ctrl_entity_string_bucket_chunk_sizes[] =
{
16,
64,
256,
1024,
4096,
16384,
65536,
0xffffffffffffffffull,
};
typedef struct CTRL_EntityCtx CTRL_EntityCtx;
struct CTRL_EntityCtx
{
CTRL_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];
};
typedef struct CTRL_EntityCtxRWStore CTRL_EntityCtxRWStore;
struct CTRL_EntityCtxRWStore
{
Arena *arena;
CTRL_EntityCtx ctx;
CTRL_Entity *free;
CTRL_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
{
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];
};
////////////////////////////////
//~ rjf: Tick Input Types
@@ -69,17 +294,6 @@ struct D_PathMapArray
U64 count;
};
////////////////////////////////
//~ rjf: Trap Nets
typedef struct D_TrapNet D_TrapNet;
struct D_TrapNet
{
CTRL_TrapList traps;
B32 good_line_info;
B32 good_read;
};
////////////////////////////////
//~ rjf: Tick Output Types
@@ -131,309 +345,58 @@ struct D_EventList
};
////////////////////////////////
//~ rjf: Line Info Types
//~ rjf: Trap Types
typedef struct D_Line D_Line;
struct D_Line
typedef U32 CTRL_TrapFlags;
enum
{
String8 file_path;
TxtPt pt;
Rng1U64 voff_range;
DI_Key dbgi_key;
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),
};
typedef struct D_LineNode D_LineNode;
struct D_LineNode
typedef struct CTRL_Trap CTRL_Trap;
struct CTRL_Trap
{
D_LineNode *next;
D_Line v;
};
typedef struct D_LineList D_LineList;
struct D_LineList
{
D_LineNode *first;
D_LineNode *last;
U64 count;
};
typedef struct D_LineListArray D_LineListArray;
struct D_LineListArray
{
D_LineList *v;
U64 count;
DI_KeyList dbgi_keys;
};
////////////////////////////////
//~ rjf: Debug Engine Control Communication Types
typedef enum D_RunKind
{
D_RunKind_Run,
D_RunKind_SingleStep,
D_RunKind_Step,
D_RunKind_COUNT
}
D_RunKind;
////////////////////////////////
//~ rjf: Generated Code
#include "dbg_engine/generated/dbg_engine.meta.h"
////////////////////////////////
//~ rjf: Command Types
typedef struct D_CmdParams D_CmdParams;
struct D_CmdParams
{
CTRL_Handle machine;
CTRL_Handle process;
CTRL_Handle thread;
CTRL_Handle entity;
String8 string;
String8 file_path;
TxtPt cursor;
CTRL_TrapFlags flags;
U64 vaddr;
B32 prefer_disasm;
U32 pid;
U32 rgba;
D_TargetArray targets;
U64 retry_idx;
};
typedef struct D_Cmd D_Cmd;
struct D_Cmd
typedef struct CTRL_TrapNode CTRL_TrapNode;
struct CTRL_TrapNode
{
D_CmdKind kind;
D_CmdParams params;
CTRL_TrapNode *next;
CTRL_Trap v;
};
typedef struct D_CmdNode D_CmdNode;
struct D_CmdNode
typedef struct CTRL_TrapList CTRL_TrapList;
struct CTRL_TrapList
{
D_CmdNode *next;
D_CmdNode *prev;
D_Cmd cmd;
};
typedef struct D_CmdList D_CmdList;
struct D_CmdList
{
D_CmdNode *first;
D_CmdNode *last;
CTRL_TrapNode *first;
CTRL_TrapNode *last;
U64 count;
};
////////////////////////////////
//~ rjf: Main State Caches
//- rjf: per-run tls-base-vaddr cache
typedef struct D_RunTLSBaseCacheNode D_RunTLSBaseCacheNode;
struct D_RunTLSBaseCacheNode
typedef struct CTRL_Spoof CTRL_Spoof;
struct CTRL_Spoof
{
D_RunTLSBaseCacheNode *hash_next;
CTRL_Handle process;
U64 root_vaddr;
U64 rip_vaddr;
U64 tls_base_vaddr;
};
typedef struct D_RunTLSBaseCacheSlot D_RunTLSBaseCacheSlot;
struct D_RunTLSBaseCacheSlot
{
D_RunTLSBaseCacheNode *first;
D_RunTLSBaseCacheNode *last;
};
typedef struct D_RunTLSBaseCache D_RunTLSBaseCache;
struct D_RunTLSBaseCache
{
Arena *arena;
U64 slots_count;
D_RunTLSBaseCacheSlot *slots;
};
//- rjf: per-run locals cache
typedef struct D_RunLocalsCacheNode D_RunLocalsCacheNode;
struct D_RunLocalsCacheNode
{
D_RunLocalsCacheNode *hash_next;
DI_Key dbgi_key;
U64 voff;
E_String2NumMap *locals_map;
};
typedef struct D_RunLocalsCacheSlot D_RunLocalsCacheSlot;
struct D_RunLocalsCacheSlot
{
D_RunLocalsCacheNode *first;
D_RunLocalsCacheNode *last;
};
typedef struct D_RunLocalsCache D_RunLocalsCache;
struct D_RunLocalsCache
{
Arena *arena;
U64 table_size;
D_RunLocalsCacheSlot *table;
DMN_Handle process;
DMN_Handle thread;
U64 vaddr;
U64 new_ip_value;
};
////////////////////////////////
//~ rjf: Main State Types
//~ rjf: Trap Nets
typedef struct D_State D_State;
struct D_State
typedef struct D_TrapNet D_TrapNet;
struct D_TrapNet
{
// rjf: top-level state
Arena *arena;
U64 frame_index;
// rjf: commands
Arena *cmds_arena;
D_CmdList cmds;
// rjf: output log key
C_Key output_log_key;
// rjf: per-run caches
U64 tls_base_cache_reggen_idx;
U64 tls_base_cache_memgen_idx;
D_RunTLSBaseCache tls_base_caches[2];
U64 tls_base_cache_gen;
U64 locals_cache_reggen_idx;
D_RunLocalsCache locals_caches[2];
U64 locals_cache_gen;
U64 member_cache_reggen_idx;
D_RunLocalsCache member_caches[2];
U64 member_cache_gen;
// rjf: user -> ctrl driving state
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_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;
// rjf: ctrl -> user reading state
CTRL_EntityCtxRWStore *ctrl_entity_store;
Arena *ctrl_stop_arena;
CTRL_Event ctrl_last_stop_event;
CTRL_TrapList traps;
B32 good_line_info;
B32 good_read;
};
////////////////////////////////
//~ rjf: Globals
global D_State *d_state = 0;
////////////////////////////////
//~ rjf: Basic Helpers
internal U64 d_hash_from_seed_string(U64 seed, String8 string);
internal U64 d_hash_from_string(String8 string);
internal U64 d_hash_from_seed_string__case_insensitive(U64 seed, String8 string);
internal U64 d_hash_from_string__case_insensitive(String8 string);
////////////////////////////////
//~ rjf: Breakpoints
internal D_BreakpointArray d_breakpoint_array_copy(Arena *arena, D_BreakpointArray *src);
////////////////////////////////
//~ rjf: Path Map Application
internal String8List d_possible_path_overrides_from_maps_path(Arena *arena, D_PathMapArray *path_maps, String8 file_path);
////////////////////////////////
//~ rjf: Debug Info Extraction Type Pure Functions
internal D_LineList d_line_list_copy(Arena *arena, D_LineList *list);
////////////////////////////////
//~ rjf: Command Type Functions
//- rjf: command parameters
internal D_CmdParams d_cmd_params_copy(Arena *arena, D_CmdParams *src);
//- rjf: command lists
internal void d_cmd_list_push_new(Arena *arena, D_CmdList *cmds, D_CmdKind kind, D_CmdParams *params);
////////////////////////////////
//~ 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);
////////////////////////////////
//~ rjf: Debug Info Lookups
//- rjf: voff -> line info
internal D_LineList d_lines_from_dbgi_key_voff(Arena *arena, DI_Key dbgi_key, U64 voff);
//- rjf: file:line -> line info
// TODO(rjf): this depends on file path maps, needs to move
// TODO(rjf): need to clean this up & dedup
internal D_LineListArray d_lines_array_from_dbgi_key_file_path_line_range(Arena *arena, DI_Key dbgi_key, String8 file_path, Rng1S64 line_num_range);
internal D_LineListArray d_lines_array_from_file_path_line_range(Arena *arena, String8 file_path, Rng1S64 line_num_range);
internal D_LineList d_lines_from_dbgi_key_file_path_line_num(Arena *arena, DI_Key dbgi_key, String8 file_path, S64 line_num);
internal D_LineList 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);
////////////////////////////////
//~ rjf: Target Controls
//- rjf: stopped info from the control thread
internal CTRL_Event d_ctrl_last_stop_event(void);
////////////////////////////////
//~ rjf: Main State Accessors/Mutators
//- rjf: frame data
internal U64 d_frame_index(void);
//- rjf: control state
internal D_RunKind d_ctrl_last_run_kind(void);
internal U64 d_ctrl_last_run_frame_idx(void);
internal B32 d_ctrl_targets_running(void);
//- rjf: active entity based queries
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 E_String2NumMap *d_query_cached_locals_map_from_dbgi_key_voff(DI_Key dbgi_key, U64 voff);
internal E_String2NumMap *d_query_cached_member_map_from_dbgi_key_voff(DI_Key dbgi_key, U64 voff);
//- rjf: top-level command dispatch
internal void d_push_cmd(D_CmdKind kind, D_CmdParams *params);
#define d_cmd(kind, ...) d_push_cmd((kind), &(D_CmdParams){.thread = {0}, __VA_ARGS__})
//- rjf: command iteration
internal B32 d_next_cmd(D_Cmd **cmd);
////////////////////////////////
//~ rjf: Main Layer Top-Level Calls
internal void d_init(void);
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]);
#endif // DBG_ENGINE_CORE_H
File diff suppressed because it is too large Load Diff
+625
View File
@@ -0,0 +1,625 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef CTRL_CORE_H
#define CTRL_CORE_H
////////////////////////////////
//~ rjf: Unwind Types
typedef U32 CTRL_UnwindFlags;
enum
{
CTRL_UnwindFlag_Error = (1<<0),
CTRL_UnwindFlag_Stale = (1<<1),
};
typedef struct CTRL_UnwindStepResult CTRL_UnwindStepResult;
struct CTRL_UnwindStepResult
{
CTRL_UnwindFlags flags;
};
typedef struct CTRL_UnwindFrame CTRL_UnwindFrame;
struct CTRL_UnwindFrame
{
void *regs;
U64 cfa;
};
typedef struct CTRL_UnwindFrameNode CTRL_UnwindFrameNode;
struct CTRL_UnwindFrameNode
{
CTRL_UnwindFrameNode *next;
CTRL_UnwindFrameNode *prev;
CTRL_UnwindFrame v;
};
typedef struct CTRL_UnwindFrameArray CTRL_UnwindFrameArray;
struct CTRL_UnwindFrameArray
{
CTRL_UnwindFrame *v;
U64 count;
};
typedef struct CTRL_Unwind CTRL_Unwind;
struct CTRL_Unwind
{
CTRL_UnwindFrameArray frames;
CTRL_UnwindFlags flags;
};
typedef struct CTRL_FrameUnwindContext CTRL_FrameUnwindContext;
struct CTRL_FrameUnwindContext
{
// DWARF
U64 cfa;
DW_CFI_Row *cfi_row;
U64 ret_addr_reg;
};
////////////////////////////////
//~ rjf: Call Stack Types
typedef struct CTRL_CallStackFrame CTRL_CallStackFrame;
struct CTRL_CallStackFrame
{
U64 unwind_count;
U64 inline_depth;
void *regs;
U64 cfa;
};
typedef struct CTRL_CallStack CTRL_CallStack;
struct CTRL_CallStack
{
CTRL_CallStackFrame *frames;
U64 frames_count;
CTRL_CallStackFrame **concrete_frames;
U64 concrete_frames_count;
};
////////////////////////////////
//~ rjf: Call Stack Tree Types
typedef struct CTRL_CallStackTreeNode CTRL_CallStackTreeNode;
struct CTRL_CallStackTreeNode
{
CTRL_CallStackTreeNode *hash_next;
CTRL_CallStackTreeNode *first;
CTRL_CallStackTreeNode *last;
CTRL_CallStackTreeNode *next;
CTRL_CallStackTreeNode *parent;
U64 child_count;
U64 id;
CTRL_Handle process;
U64 vaddr;
U64 depth;
CTRL_HandleList threads;
U64 all_descendant_threads_count;
};
typedef struct CTRL_CallStackTree CTRL_CallStackTree;
struct CTRL_CallStackTree
{
CTRL_CallStackTreeNode *root;
U64 slots_count;
CTRL_CallStackTreeNode **slots;
};
////////////////////////////////
//~ rjf: Evaluation Spaces
typedef U64 CTRL_EvalSpaceKind;
enum
{
CTRL_EvalSpaceKind_Entity = E_SpaceKind_FirstUserDefined,
CTRL_EvalSpaceKind_FirstUserDefined,
};
////////////////////////////////
//~ rjf: Process Memory Types
typedef struct CTRL_ProcessMemorySlice CTRL_ProcessMemorySlice;
struct CTRL_ProcessMemorySlice
{
String8 data;
U64 *byte_bad_flags;
U64 *byte_changed_flags;
B32 stale;
B32 any_byte_bad;
B32 any_byte_changed;
};
////////////////////////////////
//~ rjf: Thread Register Cache Types
typedef struct CTRL_ThreadRegCacheNode CTRL_ThreadRegCacheNode;
struct CTRL_ThreadRegCacheNode
{
CTRL_ThreadRegCacheNode *next;
CTRL_ThreadRegCacheNode *prev;
CTRL_Handle handle;
U64 block_size;
void *block;
U64 reg_gen;
};
typedef struct CTRL_ThreadRegCacheSlot CTRL_ThreadRegCacheSlot;
struct CTRL_ThreadRegCacheSlot
{
CTRL_ThreadRegCacheNode *first;
CTRL_ThreadRegCacheNode *last;
};
typedef struct CTRL_ThreadRegCacheStripe CTRL_ThreadRegCacheStripe;
struct CTRL_ThreadRegCacheStripe
{
Arena *arena;
RWMutex rw_mutex;
};
typedef struct CTRL_ThreadRegCache CTRL_ThreadRegCache;
struct CTRL_ThreadRegCache
{
U64 slots_count;
CTRL_ThreadRegCacheSlot *slots;
U64 stripes_count;
CTRL_ThreadRegCacheStripe *stripes;
};
////////////////////////////////
//~ rjf: Module Image Info Cache Types
typedef struct CTRL_ModuleImageInfoCacheNode CTRL_ModuleImageInfoCacheNode;
struct CTRL_ModuleImageInfoCacheNode
{
CTRL_ModuleImageInfoCacheNode *next;
CTRL_ModuleImageInfoCacheNode *prev;
CTRL_Handle module;
Arena *arena;
PE_IntelPdata *pdatas;
U64 pdatas_count;
U64 cfi_rebase;
B32 is_unwind_eh;
String8 dwarf_unwind_data;
EH_FrameHdr eh_frame_hdr;
EH_PtrCtx eh_ptr_ctx;
U64 entry_point_voff;
String8 initial_debug_info_path;
U64 raddbg_attached_marker_voff;
String8 raddbg_data;
};
typedef struct CTRL_ModuleImageInfoCacheSlot CTRL_ModuleImageInfoCacheSlot;
struct CTRL_ModuleImageInfoCacheSlot
{
CTRL_ModuleImageInfoCacheNode *first;
CTRL_ModuleImageInfoCacheNode *last;
};
typedef struct CTRL_ModuleImageInfoCacheStripe CTRL_ModuleImageInfoCacheStripe;
struct CTRL_ModuleImageInfoCacheStripe
{
Arena *arena;
RWMutex rw_mutex;
};
typedef struct CTRL_ModuleImageInfoCache CTRL_ModuleImageInfoCache;
struct CTRL_ModuleImageInfoCache
{
U64 slots_count;
CTRL_ModuleImageInfoCacheSlot *slots;
U64 stripes_count;
CTRL_ModuleImageInfoCacheStripe *stripes;
};
////////////////////////////////
//~ rjf: Touched Debug Info Directory Cache
typedef struct CTRL_DbgDirNode CTRL_DbgDirNode;
struct CTRL_DbgDirNode
{
CTRL_DbgDirNode *first;
CTRL_DbgDirNode *last;
CTRL_DbgDirNode *next;
CTRL_DbgDirNode *prev;
CTRL_DbgDirNode *parent;
String8 name;
U64 search_count;
U64 child_count;
U64 module_direct_count;
};
////////////////////////////////
//~ rjf: Control Thread Evaluation Scopes
typedef struct CTRL_EvalScope CTRL_EvalScope;
struct CTRL_EvalScope
{
Access *access;
E_BaseCtx base_ctx;
E_IRCtx ir_ctx;
E_InterpretCtx interpret_ctx;
};
////////////////////////////////
//~ rjf: Module Requirement Cache Types
typedef struct CTRL_ModuleReqCacheNode CTRL_ModuleReqCacheNode;
struct CTRL_ModuleReqCacheNode
{
CTRL_ModuleReqCacheNode *next;
CTRL_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);
////////////////////////////////
//~ rjf: Main State Types
typedef struct CTRL_State CTRL_State;
struct CTRL_State
{
Arena *arena;
CTRL_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;
// rjf: generations
U64 run_gen;
U64 mem_gen;
U64 reg_gen;
// rjf: user -> ctrl msg ring buffer
U64 u2c_ring_size;
U8 *u2c_ring_base;
U64 u2c_ring_write_pos;
U64 u2c_ring_read_pos;
Mutex u2c_ring_mutex;
CondVar u2c_ring_cv;
// rjf: ctrl -> user event ring buffer
U64 c2u_ring_size;
U64 c2u_ring_max_string_size;
U8 *c2u_ring_base;
U64 c2u_ring_write_pos;
U64 c2u_ring_read_pos;
Mutex c2u_ring_mutex;
CondVar c2u_ring_cv;
// rjf: ctrl thread state
U64 ctrl_thread_run_state;
String8 ctrl_thread_log_path;
Thread ctrl_thread;
Log *ctrl_thread_log;
RWMutex ctrl_thread_entity_ctx_rw_mutex;
CTRL_EntityCtxRWStore *ctrl_thread_entity_store;
E_Cache *ctrl_thread_eval_cache;
Arena *ctrl_thread_msg_process_arena;
Arena *dmn_event_arena;
DMN_EventNode *first_dmn_event_node;
DMN_EventNode *last_dmn_event_node;
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 process_counter;
Arena *dbg_dir_arena;
CTRL_DbgDirNode *dbg_dir_root;
U64 module_req_cache_slots_count;
CTRL_ModuleReqCacheNode **module_req_cache_slots;
String8List msg_user_bp_touched_files;
String8List msg_user_bp_touched_symbols;
};
////////////////////////////////
//~ rjf: Globals
global CTRL_State *ctrl_state = 0;
read_only global CTRL_Entity ctrl_entity_nil =
{
&ctrl_entity_nil,
&ctrl_entity_nil,
&ctrl_entity_nil,
&ctrl_entity_nil,
&ctrl_entity_nil,
};
read_only global CTRL_CallStackTreeNode ctrl_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,
};
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())
////////////////////////////////
//~ 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);
////////////////////////////////
//~ 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);
////////////////////////////////
//~ 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);
////////////////////////////////
//~ rjf: User Breakpoint Type Functions
internal void ctrl_user_breakpoint_list_push(Arena *arena, CTRL_UserBreakpointList *list, CTRL_UserBreakpoint *bp);
internal CTRL_UserBreakpointList ctrl_user_breakpoint_list_copy(Arena *arena, CTRL_UserBreakpointList *src);
////////////////////////////////
//~ rjf: Message Type Functions
//- rjf: deep copying
internal void ctrl_msg_deep_copy(Arena *arena, CTRL_Msg *dst, CTRL_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);
//- 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);
////////////////////////////////
//~ 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);
//- 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);
////////////////////////////////
//~ 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)
//- 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)
//- 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);
//- 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))
//- 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);
//- 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);
//- 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);
//- rjf: entity equipment
internal void ctrl_entity_equip_string(CTRL_EntityCtxRWStore *store, CTRL_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);
//- rjf: applying events to entity caches
internal void ctrl_entity_store_apply_events(CTRL_EntityCtxRWStore *store, CTRL_EventList *list);
////////////////////////////////
//~ rjf: Main Layer Initialization
internal void ctrl_init(void);
////////////////////////////////
//~ rjf: Wakeup Callback Registration
internal void ctrl_set_wakeup_hook(CTRL_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);
//- rjf: thread register writing
internal B32 ctrl_thread_write_reg_block(CTRL_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);
////////////////////////////////
//~ Process Info Functions
internal Arch ctrl_arch_from_process_handle(CTRL_Handle process_handle);
////////////////////////////////
//~ rjf: Unwinding Functions
//- rjf: unwind deep copier
internal CTRL_Unwind ctrl_unwind_deep_copy(Arena *arena, Arch arch, CTRL_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);
//- 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);
//- rjf: abstracted full unwind
internal CTRL_Unwind ctrl_unwind_from_thread(Arena *arena, CTRL_EntityCtx *ctx, CTRL_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);
////////////////////////////////
//~ rjf: Halting All Attached Processes
internal void ctrl_halt(void);
////////////////////////////////
//~ rjf: Shared Accessor Functions
//- rjf: generation counters
internal U64 ctrl_run_gen(void);
internal U64 ctrl_mem_gen(void);
internal U64 ctrl_reg_gen(void);
//- rjf: name -> register/alias hash tables, for eval
internal E_String2NumMap *ctrl_string2reg_from_arch(Arch arch);
internal E_String2NumMap *ctrl_string2alias_from_arch(Arch arch);
////////////////////////////////
//~ 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);
//- rjf: control -> user thread communication
internal void ctrl_c2u_push_events(CTRL_EventList *events);
internal CTRL_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);
//- 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);
//- 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);
//- 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);
//- 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);
////////////////////////////////
//~ 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);
//- 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);
#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);
////////////////////////////////
//~ 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);
////////////////////////////////
//~ 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);
#endif // CTRL_CORE_H
+2
View File
@@ -2,3 +2,5 @@
// Licensed under the MIT license (https://opensource.org/license/mit/)
#include "dbg_engine_core.c"
#include "dbg_engine_user.c"
#include "dbg_engine_ctrl.c"
+2
View File
@@ -5,5 +5,7 @@
#define DBG_ENGINE_INC_H
#include "dbg_engine_core.h"
#include "dbg_engine_user.h"
#include "dbg_engine_ctrl.h"
#endif // DBG_ENGINE_INC_H
File diff suppressed because it is too large Load Diff
+486
View File
@@ -0,0 +1,486 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DBG_ENGINE_USER_H
#define DBG_ENGINE_USER_H
////////////////////////////////
//~ rjf: Line Info Types
typedef struct D_Line D_Line;
struct D_Line
{
String8 file_path;
TxtPt pt;
Rng1U64 voff_range;
DI_Key dbgi_key;
};
typedef struct D_LineNode D_LineNode;
struct D_LineNode
{
D_LineNode *next;
D_Line v;
};
typedef struct D_LineList D_LineList;
struct D_LineList
{
D_LineNode *first;
D_LineNode *last;
U64 count;
};
typedef struct D_LineListArray D_LineListArray;
struct D_LineListArray
{
D_LineList *v;
U64 count;
DI_KeyList dbgi_keys;
};
////////////////////////////////
//~ rjf: Debug Engine Control Communication Types
typedef enum D_RunKind
{
D_RunKind_Run,
D_RunKind_SingleStep,
D_RunKind_Step,
D_RunKind_COUNT
}
D_RunKind;
////////////////////////////////
//~ rjf: Command Types
typedef struct D_CmdParams D_CmdParams;
struct D_CmdParams
{
CTRL_Handle machine;
CTRL_Handle process;
CTRL_Handle thread;
CTRL_Handle entity;
String8 string;
String8 file_path;
TxtPt cursor;
U64 vaddr;
B32 prefer_disasm;
U32 pid;
U32 rgba;
D_TargetArray targets;
U64 retry_idx;
};
typedef struct D_Cmd D_Cmd;
struct D_Cmd
{
D_CmdKind kind;
D_CmdParams params;
};
typedef struct D_CmdNode D_CmdNode;
struct D_CmdNode
{
D_CmdNode *next;
D_CmdNode *prev;
D_Cmd cmd;
};
typedef struct D_CmdList D_CmdList;
struct D_CmdList
{
D_CmdNode *first;
D_CmdNode *last;
U64 count;
};
////////////////////////////////
//~ rjf: Main State Caches
//- rjf: per-run tls-base-vaddr cache
typedef struct D_RunTLSBaseCacheNode D_RunTLSBaseCacheNode;
struct D_RunTLSBaseCacheNode
{
D_RunTLSBaseCacheNode *hash_next;
CTRL_Handle process;
U64 root_vaddr;
U64 rip_vaddr;
U64 tls_base_vaddr;
};
typedef struct D_RunTLSBaseCacheSlot D_RunTLSBaseCacheSlot;
struct D_RunTLSBaseCacheSlot
{
D_RunTLSBaseCacheNode *first;
D_RunTLSBaseCacheNode *last;
};
typedef struct D_RunTLSBaseCache D_RunTLSBaseCache;
struct D_RunTLSBaseCache
{
Arena *arena;
U64 slots_count;
D_RunTLSBaseCacheSlot *slots;
};
//- rjf: per-run locals cache
typedef struct D_RunLocalsCacheNode D_RunLocalsCacheNode;
struct D_RunLocalsCacheNode
{
D_RunLocalsCacheNode *hash_next;
DI_Key dbgi_key;
U64 voff;
E_String2NumMap *locals_map;
};
typedef struct D_RunLocalsCacheSlot D_RunLocalsCacheSlot;
struct D_RunLocalsCacheSlot
{
D_RunLocalsCacheNode *first;
D_RunLocalsCacheNode *last;
};
typedef struct D_RunLocalsCache D_RunLocalsCache;
struct D_RunLocalsCache
{
Arena *arena;
U64 table_size;
D_RunLocalsCacheSlot *table;
};
////////////////////////////////
//~ rjf: User -> Ctrl Message Types
typedef enum CTRL_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,
}
CTRL_MsgKind;
typedef U32 CTRL_RunFlags;
enum
{
CTRL_RunFlag_StopOnEntryPoint = (1<<0),
};
typedef struct CTRL_Msg CTRL_Msg;
struct CTRL_Msg
{
CTRL_MsgKind kind;
CTRL_RunFlags run_flags;
CTRL_MsgID msg_id;
CTRL_Handle entity;
CTRL_Handle parent;
U32 entity_id;
U32 exit_code;
B32 env_inherit;
B32 debug_subprocesses;
U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64];
String8 path;
String8List entry_points;
String8List cmd_line_string_list;
String8List env_string_list;
String8 stdout_path;
String8 stderr_path;
String8 stdin_path;
CTRL_TrapList traps;
CTRL_UserBreakpointList user_bps;
};
typedef struct CTRL_MsgNode CTRL_MsgNode;
struct CTRL_MsgNode
{
CTRL_MsgNode *next;
CTRL_Msg v;
};
typedef struct CTRL_MsgList CTRL_MsgList;
struct CTRL_MsgList
{
CTRL_MsgNode *first;
CTRL_MsgNode *last;
U64 count;
};
////////////////////////////////
//~ rjf: Ctrl -> User Event Types
typedef enum CTRL_EventKind
{
CTRL_EventKind_Null,
CTRL_EventKind_Error,
//- rjf: starts/stops
CTRL_EventKind_Started,
CTRL_EventKind_Stopped,
//- rjf: entity creation/deletion
CTRL_EventKind_NewProc,
CTRL_EventKind_NewThread,
CTRL_EventKind_NewModule,
CTRL_EventKind_EndProc,
CTRL_EventKind_EndThread,
CTRL_EventKind_EndModule,
//- rjf: thread freeze state changes
CTRL_EventKind_ThreadFrozen,
CTRL_EventKind_ThreadThawed,
//- rjf: debug info changes
CTRL_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,
//- rjf: memory
CTRL_EventKind_MemReserve,
CTRL_EventKind_MemCommit,
CTRL_EventKind_MemDecommit,
CTRL_EventKind_MemRelease,
CTRL_EventKind_COUNT
}
CTRL_EventKind;
typedef enum CTRL_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
}
CTRL_EventCause;
typedef enum CTRL_ExceptionKind
{
CTRL_ExceptionKind_Null,
CTRL_ExceptionKind_MemoryRead,
CTRL_ExceptionKind_MemoryWrite,
CTRL_ExceptionKind_MemoryExecute,
CTRL_ExceptionKind_CppThrow,
CTRL_ExceptionKind_COUNT
}
CTRL_ExceptionKind;
typedef struct CTRL_Event CTRL_Event;
struct CTRL_Event
{
CTRL_EventKind kind;
CTRL_EventCause cause;
CTRL_ExceptionKind exception_kind;
CTRL_MsgID msg_id;
CTRL_Handle entity;
CTRL_Handle parent;
Arch arch;
U64 u64_code;
U32 entity_id;
Rng1U64 vaddr_rng;
U64 rip_vaddr;
U64 stack_base;
U64 tls_root;
U64 tls_index;
U64 tls_offset;
U64 timestamp;
U32 exception_code;
U32 rgba;
CTRL_UserBreakpointFlags bp_flags;
String8 string;
OperatingSystem target_os;
CTRL_TlsModel tls_model;
};
typedef struct CTRL_EventNode CTRL_EventNode;
struct CTRL_EventNode
{
CTRL_EventNode *next;
CTRL_Event v;
};
typedef struct CTRL_EventList CTRL_EventList;
struct CTRL_EventList
{
CTRL_EventNode *first;
CTRL_EventNode *last;
U64 count;
};
////////////////////////////////
//~ rjf: Main State Types
typedef struct D_State D_State;
struct D_State
{
// rjf: top-level state
Arena *arena;
U64 frame_index;
// rjf: commands
Arena *cmds_arena;
D_CmdList cmds;
// rjf: output log key
C_Key output_log_key;
// rjf: per-run caches
U64 tls_base_cache_reggen_idx;
U64 tls_base_cache_memgen_idx;
D_RunTLSBaseCache tls_base_caches[2];
U64 tls_base_cache_gen;
U64 locals_cache_reggen_idx;
D_RunLocalsCache locals_caches[2];
U64 locals_cache_gen;
U64 member_cache_reggen_idx;
D_RunLocalsCache member_caches[2];
U64 member_cache_gen;
// rjf: user -> ctrl driving state
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_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;
// rjf: ctrl -> user reading state
CTRL_EntityCtxRWStore *ctrl_entity_store;
Arena *ctrl_stop_arena;
CTRL_Event ctrl_last_stop_event;
};
////////////////////////////////
//~ rjf: Globals
global D_State *d_state = 0;
////////////////////////////////
//~ rjf: Basic Helpers
internal U64 d_hash_from_seed_string(U64 seed, String8 string);
internal U64 d_hash_from_string(String8 string);
internal U64 d_hash_from_seed_string__case_insensitive(U64 seed, String8 string);
internal U64 d_hash_from_string__case_insensitive(String8 string);
////////////////////////////////
//~ rjf: Breakpoints
internal D_BreakpointArray d_breakpoint_array_copy(Arena *arena, D_BreakpointArray *src);
////////////////////////////////
//~ rjf: Path Map Application
internal String8List d_possible_path_overrides_from_maps_path(Arena *arena, D_PathMapArray *path_maps, String8 file_path);
////////////////////////////////
//~ rjf: Debug Info Extraction Type Pure Functions
internal D_LineList d_line_list_copy(Arena *arena, D_LineList *list);
////////////////////////////////
//~ rjf: Command Type Functions
//- rjf: command parameters
internal D_CmdParams d_cmd_params_copy(Arena *arena, D_CmdParams *src);
//- rjf: command lists
internal void d_cmd_list_push_new(Arena *arena, D_CmdList *cmds, D_CmdKind kind, D_CmdParams *params);
////////////////////////////////
//~ 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);
////////////////////////////////
//~ rjf: Debug Info Lookups
//- rjf: voff -> line info
internal D_LineList d_lines_from_dbgi_key_voff(Arena *arena, DI_Key dbgi_key, U64 voff);
//- rjf: file:line -> line info
// TODO(rjf): this depends on file path maps, needs to move
// TODO(rjf): need to clean this up & dedup
internal D_LineListArray d_lines_array_from_dbgi_key_file_path_line_range(Arena *arena, DI_Key dbgi_key, String8 file_path, Rng1S64 line_num_range);
internal D_LineListArray d_lines_array_from_file_path_line_range(Arena *arena, String8 file_path, Rng1S64 line_num_range);
internal D_LineList d_lines_from_dbgi_key_file_path_line_num(Arena *arena, DI_Key dbgi_key, String8 file_path, S64 line_num);
internal D_LineList 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);
////////////////////////////////
//~ rjf: Target Controls
//- rjf: stopped info from the control thread
internal CTRL_Event d_ctrl_last_stop_event(void);
////////////////////////////////
//~ rjf: Main State Accessors/Mutators
//- rjf: frame data
internal U64 d_frame_index(void);
//- rjf: control state
internal D_RunKind d_ctrl_last_run_kind(void);
internal U64 d_ctrl_last_run_frame_idx(void);
internal B32 d_ctrl_targets_running(void);
//- rjf: active entity based queries
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 E_String2NumMap *d_query_cached_locals_map_from_dbgi_key_voff(DI_Key dbgi_key, U64 voff);
internal E_String2NumMap *d_query_cached_member_map_from_dbgi_key_voff(DI_Key dbgi_key, U64 voff);
//- rjf: top-level command dispatch
internal void d_push_cmd(D_CmdKind kind, D_CmdParams *params);
#define d_cmd(kind, ...) d_push_cmd((kind), &(D_CmdParams){.thread = {0}, __VA_ARGS__})
//- rjf: command iteration
internal B32 d_next_cmd(D_Cmd **cmd);
////////////////////////////////
//~ rjf: Main Layer Top-Level Calls
internal void d_init(void);
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]);
#endif // DBG_ENGINE_USER_H
+203
View File
@@ -3,3 +3,206 @@
//- GENERATED CODE
C_LINKAGE_BEGIN
String8 ctrl_entity_kind_code_name_table[12] =
{
{0},
str8_lit_comp("root"),
str8_lit_comp("machine"),
str8_lit_comp("process"),
str8_lit_comp("thread"),
str8_lit_comp("module"),
str8_lit_comp("entry_point"),
str8_lit_comp("debug_info_path"),
str8_lit_comp("pending_thread_name"),
str8_lit_comp("pending_thread_color"),
str8_lit_comp("breakpoint"),
str8_lit_comp("address_range_annotation"),
};
String8 ctrl_entity_kind_display_string_table[12] =
{
{0},
str8_lit_comp("Root"),
str8_lit_comp("Machine"),
str8_lit_comp("Process"),
str8_lit_comp("Thread"),
str8_lit_comp("Module"),
str8_lit_comp("EntryPoint"),
str8_lit_comp("DebugInfoPath"),
str8_lit_comp("PendingThreadName"),
str8_lit_comp("PendingThreadColor"),
str8_lit_comp("Breakpoint"),
str8_lit_comp("AddressRangeAnnotation"),
};
U32 ctrl_exception_code_kind_code_table[38] =
{
0,
0x40010005,
0x40010008,
0x40080201,
0x40080202,
0x0000071a,
0x80000002,
0xc0000005,
0xc0000006,
0xc0000008,
0xc0000017,
0xc000001d,
0xc0000025,
0xc0000026,
0xc000008c,
0xc000008d,
0xc000008e,
0xc000008f,
0xc0000090,
0xc0000091,
0xc0000092,
0xc0000093,
0xc0000094,
0xc0000095,
0xc0000096,
0xc00000fd,
0xc0000135,
0xc0000138,
0xc0000139,
0xc0000142,
0xc00002b4,
0xc00002b5,
0xc0000420,
0xc06d007e,
0xc06d007f,
0xe073616e,
0xe0736171,
0x0000087a,
};
String8 ctrl_exception_code_kind_display_string_table[38] =
{
{0},
str8_lit_comp("(Win32) Control-C"),
str8_lit_comp("(Win32) Control-Break"),
str8_lit_comp("(Win32) WinRT Originate Error"),
str8_lit_comp("(Win32) WinRT Transform Error"),
str8_lit_comp("(Win32) RPC Call Cancelled"),
str8_lit_comp("(Win32) Data Type Misalignment"),
str8_lit_comp("(Win32) Access Violation"),
str8_lit_comp("(Win32) In Page Error"),
str8_lit_comp("(Win32) Invalid Handle Specified"),
str8_lit_comp("(Win32) Not Enough Quota"),
str8_lit_comp("(Win32) Illegal Instruction"),
str8_lit_comp("(Win32) Cannot Continue From Exception"),
str8_lit_comp("(Win32) Invalid Exception Disposition Returned By Handler"),
str8_lit_comp("(Win32) Array Bounds Exceeded"),
str8_lit_comp("(Win32) Floating-Point Denormal Operand"),
str8_lit_comp("(Win32) Floating-Point Division By Zero"),
str8_lit_comp("(Win32) Floating-Point Inexact Result"),
str8_lit_comp("(Win32) Floating-Point Invalid Operation"),
str8_lit_comp("(Win32) Floating-Point Overflow"),
str8_lit_comp("(Win32) Floating-Point Stack Check"),
str8_lit_comp("(Win32) Floating-Point Underflow"),
str8_lit_comp("(Win32) Integer Division By Zero"),
str8_lit_comp("(Win32) Integer Overflow"),
str8_lit_comp("(Win32) Privileged Instruction"),
str8_lit_comp("(Win32) Stack Overflow"),
str8_lit_comp("(Win32) Unable To Locate DLL"),
str8_lit_comp("(Win32) Ordinal Not Found"),
str8_lit_comp("(Win32) Entry Point Not Found"),
str8_lit_comp("(Win32) DLL Initialization Failed"),
str8_lit_comp("(Win32) Floating Point SSE Multiple Faults"),
str8_lit_comp("(Win32) Floating Point SSE Multiple Traps"),
str8_lit_comp("(Win32) Assertion Failed"),
str8_lit_comp("(Win32) Module Not Found"),
str8_lit_comp("(Win32) Procedure Not Found"),
str8_lit_comp("(Win32) Sanitizer Error Detected"),
str8_lit_comp("(Win32) Sanitizer Raw Access Violation"),
str8_lit_comp("(Win32) DirectX Debug Layer"),
};
String8 ctrl_exception_code_kind_lowercase_code_string_table[38] =
{
{0},
str8_lit_comp("win32_ctrl_c"),
str8_lit_comp("win32_ctrl_break"),
str8_lit_comp("win32_win_rt_originate_error"),
str8_lit_comp("win32_win_rt_transform_error"),
str8_lit_comp("win32_rpc_call_cancelled"),
str8_lit_comp("win32_datatype_misalignment"),
str8_lit_comp("win32_access_violation"),
str8_lit_comp("win32_in_page_error"),
str8_lit_comp("win32_invalid_handle"),
str8_lit_comp("win32_not_enough_quota"),
str8_lit_comp("win32_illegal_instruction"),
str8_lit_comp("win32_cannot_continue_exception"),
str8_lit_comp("win32_invalid_exception_disposition"),
str8_lit_comp("win32_array_bounds_exceeded"),
str8_lit_comp("win32_floating_point_denormal_operand"),
str8_lit_comp("win32_floating_point_division_by_zero"),
str8_lit_comp("win32_floating_point_inexact_result"),
str8_lit_comp("win32_floating_point_invalid_operation"),
str8_lit_comp("win32_floating_point_overflow"),
str8_lit_comp("win32_floating_point_stack_check"),
str8_lit_comp("win32_floating_point_underflow"),
str8_lit_comp("win32_integer_division_by_zero"),
str8_lit_comp("win32_integer_overflow"),
str8_lit_comp("win32_privileged_instruction"),
str8_lit_comp("win32_stack_overflow"),
str8_lit_comp("win32_unable_to_locate_dll"),
str8_lit_comp("win32_ordinal_not_found"),
str8_lit_comp("win32_entry_point_not_found"),
str8_lit_comp("win32_dll_initialization_failed"),
str8_lit_comp("win32_floating_point_sse_multiple_faults"),
str8_lit_comp("win32_floating_point_sse_multiple_traps"),
str8_lit_comp("win32_assertion_failed"),
str8_lit_comp("win32_module_not_found"),
str8_lit_comp("win32_procedure_not_found"),
str8_lit_comp("win32_sanitizer_error_detected"),
str8_lit_comp("win32_sanitizer_raw_access_violation"),
str8_lit_comp("win32_directx_debug_layer"),
};
B8 ctrl_exception_code_kind_default_enable_table[38] =
{
0,
1,
1,
0,
0,
0,
0,
1,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
1,
0,
1,
};
C_LINKAGE_END
@@ -44,6 +44,66 @@ D_CmdKind_Attach,
D_CmdKind_COUNT,
} D_CmdKind;
typedef enum CTRL_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;
typedef enum CTRL_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;
global B32 DEV_always_refresh = 0;
global B32 DEV_simulate_lag = 0;
global B32 DEV_draw_ui_text_pos = 0;
@@ -65,4 +125,14 @@ struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] =
{&DEV_cmd_context_tooltips, str8_lit_comp("cmd_context_tooltips")},
{&DEV_updating_indicator, str8_lit_comp("updating_indicator")},
};
C_LINKAGE_BEGIN
extern String8 ctrl_entity_kind_code_name_table[12];
extern String8 ctrl_entity_kind_display_string_table[12];
extern U32 ctrl_exception_code_kind_code_table[38];
extern String8 ctrl_exception_code_kind_display_string_table[38];
extern String8 ctrl_exception_code_kind_lowercase_code_string_table[38];
extern B8 ctrl_exception_code_kind_default_enable_table[38];
C_LINKAGE_END
#endif // DBG_ENGINE_META_H