dbg_engine: shift thread register reads / process memory reads -> abstraction layer, rather than directly calling into demon; cache crash dump info, like thread info & memory ranges; implement thread reg reads & memory reads for dumps by using this acceleration structure when we have a dump handle, instead of regular demon reads.

This commit is contained in:
Ryan Fleury
2026-05-18 14:51:17 -07:00
parent 463a4f8565
commit 4840b46b84
23 changed files with 1035 additions and 401 deletions
+1
View File
@@ -2,6 +2,7 @@
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
#include "arch/arch.c" #include "arch/arch.c"
#include "arch/os/arch_os.c"
#if defined(DWARF_H) #if defined(DWARF_H)
# include "arch/dwarf/arch_dwarf.c" # include "arch/dwarf/arch_dwarf.c"
#endif #endif
+1
View File
@@ -5,6 +5,7 @@
#define ARCH_INC_H #define ARCH_INC_H
#include "arch/arch.h" #include "arch/arch.h"
#include "arch/os/arch_os.h"
#if defined(DWARF_H) #if defined(DWARF_H)
# include "arch/dwarf/arch_dwarf.h" # include "arch/dwarf/arch_dwarf.h"
#endif #endif
+16
View File
@@ -0,0 +1,16 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal B32
arch_os_write_reg_block_from_thread_ctx(Arch arch, OperatingSystem os, void *reg_block, void *thread_ctx)
{
B32 result = 0;
if(0){}
#define Case(arch_, os_, impl) else if((arch) == arch_ && (os) == os_) do {result = impl(reg_block, thread_ctx);}while(0)
#if defined(X64_H) && defined(WIN32_X64_H)
Case(Arch_x64, OperatingSystem_Windows, w32_x64_write_reg_block_from_thread_ctx);
#endif
#undef Case
else{}
return result;
}
+9
View File
@@ -0,0 +1,9 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef ARCH_OS_H
#define ARCH_OS_H
internal B32 arch_os_write_reg_block_from_thread_ctx(Arch arch, OperatingSystem os, void *reg_block, void *thread_ctx);
#endif // ARCH_OS_H
+6
View File
@@ -80,6 +80,9 @@ d_init(void)
} }
d_ctrl_state->ctrl_thread_log = log_alloc(); d_ctrl_state->ctrl_thread_log = log_alloc();
d_ctrl_state->ctrl_thread = thread_launch(d_ctrl_thread__entry_point, 0); d_ctrl_state->ctrl_thread = thread_launch(d_ctrl_thread__entry_point, 0);
d_ctrl_state->dump_cache.slots_count = 64;
d_ctrl_state->dump_cache.slots = push_array(arena, D_DumpSlot, d_ctrl_state->dump_cache.slots_count);
d_ctrl_state->dump_cache.stripes = stripe_array_alloc(arena);
} }
//- rjf: set up user state //- rjf: set up user state
@@ -111,4 +114,7 @@ d_init(void)
// rjf: set up run state // rjf: set up run state
d_user_state->ctrl_last_run_arena = arena_alloc(); d_user_state->ctrl_last_run_arena = arena_alloc();
} }
//- rjf: select user state's entity context
d_select_entity_ctx(&d_user_state->ctrl_entity_store->ctx);
} }
+5 -19
View File
@@ -10,11 +10,12 @@
typedef U64 D_MsgID; typedef U64 D_MsgID;
typedef U32 D_MachineID; typedef U32 D_MachineID;
typedef U32 D_ControllerKind; typedef U32 D_ControllerKind;
enum typedef enum D_ControllerKindEnum
{ {
D_ControllerKind_Demon, D_ControllerKind_Demon,
D_ControllerKind_Dump, D_ControllerKind_Dump,
}; }
D_ControllerKindEnum;
#define D_MachineID_Local (1) #define D_MachineID_Local (1)
@@ -234,21 +235,6 @@ struct D_EntityCtxLookupAccel
U64 entity_kind_arrays_gens[D_EntityKind_COUNT]; U64 entity_kind_arrays_gens[D_EntityKind_COUNT];
}; };
////////////////////////////////
//~ rjf: Opened Dump Cache Types
typedef struct D_DumpNode D_DumpNode;
struct D_DumpNode
{
D_DumpNode *next;
D_DumpNode *prev;
D_Handle process;
File file;
FileProperties props;
FileMap map;
void *base;
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Tick Input Types //~ rjf: Tick Input Types
@@ -325,8 +311,8 @@ struct D_TrapList
typedef struct D_Spoof D_Spoof; typedef struct D_Spoof D_Spoof;
struct D_Spoof struct D_Spoof
{ {
DMN_Handle process; D_Handle process;
DMN_Handle thread; D_Handle thread;
U64 vaddr; U64 vaddr;
U64 new_ip_value; U64 new_ip_value;
}; };
File diff suppressed because it is too large Load Diff
+80 -17
View File
@@ -214,6 +214,55 @@ struct D_ModuleImageInfoCache
D_ModuleImageInfoCacheStripe *stripes; D_ModuleImageInfoCacheStripe *stripes;
}; };
////////////////////////////////
//~ rjf: Opened Dump Cache Types
typedef struct D_DumpMemoryRange D_DumpMemoryRange;
struct D_DumpMemoryRange
{
U64 base_vaddr;
Rng1U64 foff_range;
};
typedef struct D_DumpThread D_DumpThread;
struct D_DumpThread
{
D_Handle thread_handle;
U64 context_foff;
};
typedef struct D_DumpNode D_DumpNode;
struct D_DumpNode
{
D_DumpNode *next;
D_DumpNode *prev;
D_Handle process;
File file;
FileProperties props;
FileMap map;
void *base;
Arena *arena;
D_DumpMemoryRange *memory_ranges;
U64 memory_ranges_count;
D_DumpThread *threads;
U64 threads_count;
};
typedef struct D_DumpSlot D_DumpSlot;
struct D_DumpSlot
{
D_DumpNode *first;
D_DumpNode *last;
};
typedef struct D_DumpCache D_DumpCache;
struct D_DumpCache
{
U64 slots_count;
D_DumpSlot *slots;
StripeArray stripes;
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Touched Debug Info Directory Cache //~ rjf: Touched Debug Info Directory Cache
@@ -275,6 +324,7 @@ struct D_CtrlState
// rjf: caches // rjf: caches
D_ThreadRegCache thread_reg_cache; D_ThreadRegCache thread_reg_cache;
D_ModuleImageInfoCache module_image_info_cache; D_ModuleImageInfoCache module_image_info_cache;
D_DumpCache dump_cache;
// rjf: generations // rjf: generations
U64 run_gen; U64 run_gen;
@@ -327,6 +377,7 @@ struct D_CtrlState
//~ rjf: Globals //~ rjf: Globals
global D_CtrlState *d_ctrl_state = 0; global D_CtrlState *d_ctrl_state = 0;
thread_static D_EntityCtx *d_entity_ctx = 0;
read_only global D_Entity d_entity_nil = read_only global D_Entity d_entity_nil =
{ {
&d_entity_nil, &d_entity_nil,
@@ -413,9 +464,12 @@ internal D_Event d_event_from_serialized_string(Arena *arena, String8 string);
//////////////////////////////// ////////////////////////////////
//~ rjf: Entity Type Functions //~ rjf: Entity Type Functions
//- rjf: entity context selection
internal D_EntityCtx *d_select_entity_ctx(D_EntityCtx *ctx);
//- rjf: entity list data structures //- rjf: entity list data structures
internal void d_entity_list_push(Arena *arena, D_EntityList *list, D_Entity *entity); internal void d_entity_list_push(Arena *arena, D_EntityList *list, D_Entity *entity);
internal D_EntityList d_entity_list_from_handle_list(Arena *arena, D_EntityCtx *ctx, D_HandleList *list); internal D_EntityList d_entity_list_from_handle_list(Arena *arena, D_HandleList *list);
#define d_entity_list_first(list) ((list)->first ? (list)->first->v : &d_entity_nil) #define d_entity_list_first(list) ((list)->first ? (list)->first->v : &d_entity_nil)
//- rjf: entity array data structure //- rjf: entity array data structure
@@ -423,13 +477,13 @@ internal D_EntityArray d_entity_array_from_list(Arena *arena, D_EntityList *list
#define d_entity_array_first(array) ((array)->count != 0 ? (array)->v[0] : &d_entity_nil) #define d_entity_array_first(array) ((array)->count != 0 ? (array)->v[0] : &d_entity_nil)
//- rjf: entity context (entity group read-only) functions //- rjf: entity context (entity group read-only) functions
internal D_Entity *d_entity_from_handle(D_EntityCtx *ctx, D_Handle handle); internal D_Entity *d_entity_from_handle(D_Handle handle);
internal D_Entity *d_entity_child_from_kind(D_Entity *parent, D_EntityKind kind); internal D_Entity *d_entity_child_from_kind(D_Entity *parent, D_EntityKind kind);
internal D_Entity *d_entity_ancestor_from_kind(D_Entity *entity, D_EntityKind kind); internal D_Entity *d_entity_ancestor_from_kind(D_Entity *entity, D_EntityKind kind);
internal D_Entity *d_process_from_entity(D_Entity *entity); internal D_Entity *d_process_from_entity(D_Entity *entity);
internal D_Entity *d_module_from_process_vaddr(D_Entity *process, U64 vaddr); internal D_Entity *d_module_from_process_vaddr(D_Entity *process, U64 vaddr);
internal DI_Key d_dbgi_key_from_module(D_Entity *module); internal DI_Key d_dbgi_key_from_module(D_Entity *module);
internal D_Entity *d_module_from_thread_candidates(D_EntityCtx *ctx, D_Entity *thread, D_EntityList *candidates); internal D_Entity *d_module_from_thread_candidates(D_Entity *thread, D_EntityList *candidates);
internal U64 d_vaddr_from_voff(D_Entity *module, U64 voff); internal U64 d_vaddr_from_voff(D_Entity *module, U64 voff);
internal U64 d_voff_from_vaddr(D_Entity *module, U64 vaddr); internal U64 d_voff_from_vaddr(D_Entity *module, U64 vaddr);
internal Rng1U64 d_vaddr_range_from_voff_range(D_Entity *module, Rng1U64 voff_range); internal Rng1U64 d_vaddr_range_from_voff_range(D_Entity *module, Rng1U64 voff_range);
@@ -458,9 +512,9 @@ internal void d_entity_equip_string(D_EntityCtxRWStore *store, D_Entity *entity,
//- rjf: accelerated entity context lookups //- rjf: accelerated entity context lookups
internal D_EntityCtxLookupAccel *d_thread_entity_ctx_lookup_accel(void); internal D_EntityCtxLookupAccel *d_thread_entity_ctx_lookup_accel(void);
internal D_EntityArray d_entity_array_from_kind(D_EntityCtx *ctx, D_EntityKind kind); internal D_EntityArray d_entity_array_from_kind(D_EntityKind kind);
internal D_EntityList d_modules_from_dbgi_key(Arena *arena, D_EntityCtx *ctx, DI_Key dbgi_key); internal D_EntityList d_modules_from_dbgi_key(Arena *arena, DI_Key dbgi_key);
internal D_Entity *d_thread_from_id(D_EntityCtx *ctx, U64 id); internal D_Entity *d_thread_from_id(U64 id);
//- rjf: applying events to entity caches //- rjf: applying events to entity caches
internal void d_entity_store_apply_events(D_EntityCtxRWStore *store, D_EventList *list); internal void d_entity_store_apply_events(D_EntityCtxRWStore *store, D_EventList *list);
@@ -473,14 +527,15 @@ internal void d_set_wakeup_hook(D_WakeupFunctionType *wakeup_hook);
//////////////////////////////// ////////////////////////////////
//~ rjf: Thread Register Functions //~ rjf: Thread Register Functions
//- rjf: thread register cache reading //- rjf: thread handle read/write
internal void *d_reg_block_from_thread(Arena *arena, D_EntityCtx *ctx, D_Handle handle); internal B32 d_thread_read_reg_block(D_Handle handle, void *reg_block);
internal U64 d_tls_root_vaddr_from_thread(D_EntityCtx *ctx, D_Handle handle); internal B32 d_thread_write_reg_block(D_Handle thread, void *reg_block);
internal U64 d_rip_from_thread(D_EntityCtx *ctx, D_Handle handle);
internal U64 d_rsp_from_thread(D_EntityCtx *ctx, D_Handle handle);
//- rjf: thread register writing //- rjf: thread register cache reading
internal B32 d_thread_write_reg_block(D_Handle thread, void *block); internal void *d_reg_block_from_thread(Arena *arena, D_Handle handle);
internal U64 d_tls_root_vaddr_from_thread(D_Handle handle);
internal U64 d_rip_from_thread(D_Handle handle);
internal U64 d_rsp_from_thread(D_Handle handle);
//////////////////////////////// ////////////////////////////////
//~ rjf: Module Image Info Functions //~ rjf: Module Image Info Functions
@@ -504,7 +559,7 @@ internal U64 *d_unwind_reg_from_pe_gpr_reg__pe_x64(X64_RegBlock *regs, PE_Unwind
internal D_UnwindStepResult d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 module_base_vaddr, X64_RegBlock *regs, U64 endt_us); internal D_UnwindStepResult d_unwind_step__pe_x64(D_Handle process_handle, D_Handle module_handle, U64 module_base_vaddr, X64_RegBlock *regs, U64 endt_us);
//- rjf: abstracted full unwind //- rjf: abstracted full unwind
internal D_Unwind d_unwind_from_thread(Arena *arena, D_EntityCtx *ctx, D_Handle thread, U64 endt_us); internal D_Unwind d_unwind_from_thread(Arena *arena, D_Handle thread, U64 endt_us);
//////////////////////////////// ////////////////////////////////
//~ rjf: Call Stack Building Functions //~ rjf: Call Stack Building Functions
@@ -551,6 +606,9 @@ internal void d_ctrl_thread__append_program_defined_bp_traps(Arena *arena, D_Ent
internal void d_ctrl_thread__module_open(D_Handle process, D_Handle module, Rng1U64 vaddr_range, String8 path, Rng1U64 elf_phdr_vrange, U64 elf_phdr_entsize); internal void d_ctrl_thread__module_open(D_Handle process, D_Handle module, Rng1U64 vaddr_range, String8 path, Rng1U64 elf_phdr_vrange, U64 elf_phdr_entsize);
internal void d_ctrl_thread__module_close(D_Handle process, D_Handle module, Rng1U64 vaddr_range); internal void d_ctrl_thread__module_close(D_Handle process, D_Handle module, Rng1U64 vaddr_range);
//- rjf: dump process closing work
internal void d_ctrl_thread__close_dump_process(D_MsgID msg_id, D_Handle process);
//- rjf: attached process running/event gathering //- rjf: attached process running/event gathering
internal DMN_Event *d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, DMN_RunCtrls *run_ctrls, D_Spoof *spoof); internal DMN_Event *d_ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, D_Msg *msg, DMN_RunCtrls *run_ctrls, D_Spoof *spoof);
@@ -578,6 +636,14 @@ internal void d_ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, D_Msg *msg);
//////////////////////////////// ////////////////////////////////
//~ rjf: Process Memory Artifact Cache Hooks / Lookups //~ rjf: Process Memory Artifact Cache Hooks / Lookups
//- rjf: synchronous process memory reading helpers
internal U64 d_process_read(D_Handle process, Rng1U64 range, void *dst);
internal B32 d_process_write(D_Handle process, Rng1U64 range, void *dst);
internal String8 d_data_from_process_vaddr_range(Arena *arena, D_Handle process, Rng1U64 vaddr_range, B32 zero_terminated);
#define d_process_read_struct(process, vaddr, ptr) d_process_read((process), r1u64((vaddr), (vaddr) + sizeof(*(ptr))), (ptr))
#define d_process_write_struct(process, vaddr, ptr) d_process_write((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), (ptr))
//- rjf: process memory artifact cache
internal AC_Artifact d_memory_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out); internal AC_Artifact d_memory_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out);
internal void d_memory_artifact_destroy(AC_Artifact artifact); internal void d_memory_artifact_destroy(AC_Artifact artifact);
internal C_Key d_key_from_process_vaddr_range(D_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, B32 wait_for_fresh, U64 endt_us, B32 *out_is_stale); internal C_Key d_key_from_process_vaddr_range(D_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, B32 wait_for_fresh, U64 endt_us, B32 *out_is_stale);
@@ -587,9 +653,6 @@ internal D_ProcessMemorySlice d_process_memory_slice_from_vaddr_range(Arena *are
internal B32 d_process_memory_read(D_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 endt_us); internal B32 d_process_memory_read(D_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 endt_us);
#define d_process_memory_read_struct(process, vaddr, is_stale_out, ptr, endt_us) d_process_memory_read((process), r1u64((vaddr), (vaddr)+(sizeof(*(ptr)))), (is_stale_out), (ptr), (endt_us)) #define d_process_memory_read_struct(process, vaddr, is_stale_out, ptr, endt_us) d_process_memory_read((process), r1u64((vaddr), (vaddr)+(sizeof(*(ptr)))), (is_stale_out), (ptr), (endt_us))
//- rjf: process memory writing
internal B32 d_process_write(D_Handle process, Rng1U64 range, void *src);
//////////////////////////////// ////////////////////////////////
//~ rjf: Call Stack Artifact Cache Hooks / Lookups //~ rjf: Call Stack Artifact Cache Hooks / Lookups
+23 -24
View File
@@ -297,7 +297,7 @@ d_trap_net_from_thread__step_over_inst(Arena *arena, D_Entity *thread)
// rjf: thread => unpacked info // rjf: thread => unpacked info
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process); D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
Arch arch = thread->arch; Arch arch = thread->arch;
U64 ip_vaddr = d_rip_from_thread(&d_user_state->ctrl_entity_store->ctx, thread->handle); U64 ip_vaddr = d_rip_from_thread(thread->handle);
// rjf: ip => machine code // rjf: ip => machine code
String8 machine_code = {0}; String8 machine_code = {0};
@@ -336,7 +336,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, D_Entity *thread)
// rjf: thread => info // rjf: thread => info
Arch arch = thread->arch; Arch arch = thread->arch;
U64 ip_vaddr = d_rip_from_thread(&d_user_state->ctrl_entity_store->ctx, thread->handle); U64 ip_vaddr = d_rip_from_thread(thread->handle);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process); D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
D_Entity *module = d_module_from_process_vaddr(process, ip_vaddr); D_Entity *module = d_module_from_process_vaddr(process, ip_vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module); DI_Key dbgi_key = d_dbgi_key_from_module(module);
@@ -549,7 +549,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, D_Entity *thread)
// rjf: thread => info // rjf: thread => info
Arch arch = thread->arch; Arch arch = thread->arch;
U64 ip_vaddr = d_rip_from_thread(&d_user_state->ctrl_entity_store->ctx, thread->handle); U64 ip_vaddr = d_rip_from_thread(thread->handle);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process); D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
D_Entity *module = d_module_from_process_vaddr(process, ip_vaddr); D_Entity *module = d_module_from_process_vaddr(process, ip_vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module); DI_Key dbgi_key = d_dbgi_key_from_module(module);
@@ -750,11 +750,10 @@ d_trap_net_from_thread__step_out_scope(Arena *arena, D_Entity *thread)
U64 read_endt_us = now_time_us() + 1000000; U64 read_endt_us = now_time_us() + 1000000;
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
Access *access = access_open(); Access *access = access_open();
D_EntityCtx *entity_ctx = &d_user_state->ctrl_entity_store->ctx;
// rjf: unpack thread // rjf: unpack thread
Arch arch = thread->arch; Arch arch = thread->arch;
U64 ip_vaddr = d_rip_from_thread(entity_ctx, thread->handle); U64 ip_vaddr = d_rip_from_thread(thread->handle);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process); D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
D_Entity *module = d_module_from_process_vaddr(process, ip_vaddr); D_Entity *module = d_module_from_process_vaddr(process, ip_vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module); DI_Key dbgi_key = d_dbgi_key_from_module(module);
@@ -1303,7 +1302,7 @@ internal DI_KeyList
d_push_active_dbgi_key_list(Arena *arena) d_push_active_dbgi_key_list(Arena *arena)
{ {
DI_KeyList dbgis = {0}; DI_KeyList dbgis = {0};
D_EntityArray modules = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Module); D_EntityArray modules = d_entity_array_from_kind(D_EntityKind_Module);
for EachIndex(idx, modules.count) for EachIndex(idx, modules.count)
{ {
D_Entity *module = modules.v[idx]; D_Entity *module = modules.v[idx];
@@ -1328,7 +1327,7 @@ d_query_cached_rip_from_thread_unwind(D_Entity *thread, U64 unwind_count)
U64 result = 0; U64 result = 0;
if(unwind_count == 0) if(unwind_count == 0)
{ {
result = d_rip_from_thread(&d_user_state->ctrl_entity_store->ctx, thread->handle); result = d_rip_from_thread(thread->handle);
} }
else else
{ {
@@ -1614,7 +1613,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_EventKind_NewProc: case D_EventKind_NewProc:
{ {
// rjf: the first process? -> clear session output // rjf: the first process? -> clear session output
D_EntityArray existing_processes = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process); D_EntityArray existing_processes = d_entity_array_from_kind(D_EntityKind_Process);
if(existing_processes.count == 1) if(existing_processes.count == 1)
{ {
MTX_Op op = {r1u64(0, 0xffffffffffffffffull), str8_lit("[new session]\n")}; MTX_Op op = {r1u64(0, 0xffffffffffffffffull), str8_lit("[new session]\n")};
@@ -1678,7 +1677,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
// rjf: build data strings of all param data // rjf: build data strings of all param data
String8List strings = {0}; String8List strings = {0};
{ {
D_EntityArray threads = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Thread); D_EntityArray threads = d_entity_array_from_kind(D_EntityKind_Thread);
for EachIndex(idx, threads.count) for EachIndex(idx, threads.count)
{ {
D_Entity *thread = threads.v[idx]; D_Entity *thread = threads.v[idx];
@@ -1833,7 +1832,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}break; }break;
case D_CmdKind_Kill: case D_CmdKind_Kill:
{ {
D_Entity *process = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->process); D_Entity *process = d_entity_from_handle(params->process);
if(process == &d_entity_nil) if(process == &d_entity_nil)
{ {
log_user_error(str8_lit("Cannot kill; no process was specified.")); log_user_error(str8_lit("Cannot kill; no process was specified."));
@@ -1856,7 +1855,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}break; }break;
case D_CmdKind_Detach: case D_CmdKind_Detach:
{ {
D_Entity *process = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->process); D_Entity *process = d_entity_from_handle(params->process);
if(process == &d_entity_nil) if(process == &d_entity_nil)
{ {
log_user_error(str8_lit("Cannot detach; no process specified.")); log_user_error(str8_lit("Cannot detach; no process specified."));
@@ -1872,7 +1871,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_Continue: case D_CmdKind_Continue:
{ {
B32 good_to_run = 0; B32 good_to_run = 0;
D_EntityArray threads = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Thread); D_EntityArray threads = d_entity_array_from_kind(D_EntityKind_Thread);
if(threads.count > 0) if(threads.count > 0)
{ {
for EachIndex(idx, threads.count) for EachIndex(idx, threads.count)
@@ -1888,7 +1887,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
{ {
need_run = 1; need_run = 1;
run_kind = D_RunKind_Run; run_kind = D_RunKind_Run;
run_thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->thread); run_thread = d_entity_from_handle(params->thread);
} }
else else
{ {
@@ -1902,7 +1901,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_StepOverLine: case D_CmdKind_StepOverLine:
case D_CmdKind_StepOut: case D_CmdKind_StepOut:
{ {
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->thread); D_Entity *thread = d_entity_from_handle(params->thread);
if(thread == &d_entity_nil) if(thread == &d_entity_nil)
{ {
log_user_error(str8_lit("Must have a selected thread to step.")); log_user_error(str8_lit("Must have a selected thread to step."));
@@ -1969,16 +1968,16 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
{ {
need_run = 1; need_run = 1;
run_kind = d_user_state->ctrl_last_run_kind; run_kind = d_user_state->ctrl_last_run_kind;
run_thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, d_user_state->ctrl_last_run_thread_handle); run_thread = d_entity_from_handle(d_user_state->ctrl_last_run_thread_handle);
run_flags = d_user_state->ctrl_last_run_flags; run_flags = d_user_state->ctrl_last_run_flags;
run_traps = d_user_state->ctrl_last_run_traps; run_traps = d_user_state->ctrl_last_run_traps;
}break; }break;
case D_CmdKind_SetThreadIP: case D_CmdKind_SetThreadIP:
{ {
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->thread); D_Entity *thread = d_entity_from_handle(params->thread);
ARCH_Info *arch_info = arch_info_from_arch(thread->arch); ARCH_Info *arch_info = arch_info_from_arch(thread->arch);
U64 vaddr = params->vaddr; U64 vaddr = params->vaddr;
void *block = d_reg_block_from_thread(scratch.arena, &d_user_state->ctrl_entity_store->ctx, thread->handle); void *block = d_reg_block_from_thread(scratch.arena, thread->handle);
arch_reg_block_write_ip(arch_info, block, vaddr); arch_reg_block_write_ip(arch_info, block, vaddr);
B32 result = d_thread_write_reg_block(thread->handle, block); B32 result = d_thread_write_reg_block(thread->handle, block);
(void)result; (void)result;
@@ -2002,7 +2001,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}break; }break;
case D_CmdKind_Run: case D_CmdKind_Run:
{ {
D_EntityArray processes = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process); D_EntityArray processes = d_entity_array_from_kind(D_EntityKind_Process);
if(processes.count != 0) if(processes.count != 0)
{ {
d_cmd(D_CmdKind_Continue, .machine = params->machine, .process = params->process, .thread = params->thread); d_cmd(D_CmdKind_Continue, .machine = params->machine, .process = params->process, .thread = params->thread);
@@ -2014,7 +2013,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}break; }break;
case D_CmdKind_Restart: case D_CmdKind_Restart:
{ {
D_EntityArray processes = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process); D_EntityArray processes = d_entity_array_from_kind(D_EntityKind_Process);
if(processes.count != 0) if(processes.count != 0)
{ {
d_cmd(D_CmdKind_KillAll); d_cmd(D_CmdKind_KillAll);
@@ -2024,7 +2023,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_StepInto: case D_CmdKind_StepInto:
case D_CmdKind_StepOver: case D_CmdKind_StepOver:
{ {
D_EntityArray processes = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process); D_EntityArray processes = d_entity_array_from_kind(D_EntityKind_Process);
if(processes.count != 0) if(processes.count != 0)
{ {
D_CmdKind step_cmd_kind = (cmd->kind == D_CmdKind_StepInto D_CmdKind step_cmd_kind = (cmd->kind == D_CmdKind_StepInto
@@ -2074,7 +2073,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_ThawEntity: case D_CmdKind_ThawEntity:
{ {
B32 should_freeze = (cmd->kind == D_CmdKind_FreezeEntity); B32 should_freeze = (cmd->kind == D_CmdKind_FreezeEntity);
D_Entity *root = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->entity); D_Entity *root = d_entity_from_handle(params->entity);
for(D_Entity *e = root; e != &d_entity_nil; e = d_entity_rec_depth_first_pre(e, root).next) for(D_Entity *e = root; e != &d_entity_nil; e = d_entity_rec_depth_first_pre(e, root).next)
{ {
if(e->kind == D_EntityKind_Thread) if(e->kind == D_EntityKind_Thread)
@@ -2089,7 +2088,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
{ {
need_run = 1; need_run = 1;
run_kind = d_user_state->ctrl_last_run_kind; run_kind = d_user_state->ctrl_last_run_kind;
run_thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, d_user_state->ctrl_last_run_thread_handle); run_thread = d_entity_from_handle(d_user_state->ctrl_last_run_thread_handle);
run_flags = d_user_state->ctrl_last_run_flags; run_flags = d_user_state->ctrl_last_run_flags;
run_traps = d_user_state->ctrl_last_run_traps; run_traps = d_user_state->ctrl_last_run_traps;
} }
@@ -2098,12 +2097,12 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
//- rjf: entity decoration //- rjf: entity decoration
case D_CmdKind_SetEntityColor: case D_CmdKind_SetEntityColor:
{ {
D_Entity *entity = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->entity); D_Entity *entity = d_entity_from_handle(params->entity);
entity->rgba = params->rgba; entity->rgba = params->rgba;
}break; }break;
case D_CmdKind_SetEntityName: case D_CmdKind_SetEntityName:
{ {
D_Entity *entity = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, params->entity); D_Entity *entity = d_entity_from_handle(params->entity);
d_entity_equip_string(d_user_state->ctrl_entity_store, entity, params->string); d_entity_equip_string(d_user_state->ctrl_entity_store, entity, params->string);
}break; }break;
-47
View File
@@ -162,53 +162,6 @@ dmn_rsp_from_thread(DMN_Handle thread)
//////////////////////////////// ////////////////////////////////
//~ rjf: Process Reading Helper Functions (Helpers, Implemented Once) //~ rjf: Process Reading Helper Functions (Helpers, Implemented Once)
internal String8
dmn_process_read_cstring(Arena *arena, DMN_Handle process, U64 addr)
{
Temp scratch = scratch_begin(&arena, 1);
String8List block_list = {0};
for(U64 cursor = addr, stride = 256;; cursor += stride)
{
U8 *raw_block = push_array_no_zero(scratch.arena, U8, stride);
U64 read_size = dmn_process_read(process, r1u64(cursor, cursor + stride), raw_block);
String8 block = str8_cstring_capped(raw_block, raw_block + read_size);
str8_list_push(scratch.arena, &block_list, block);
if(read_size != stride || (block.size+1 <= read_size && block.str[block.size] == 0))
{
break;
}
}
String8 result = str8_list_join(arena, &block_list, 0);
scratch_end(scratch);
return result;
}
internal String8
dmn_process_read_block(Arena *arena, DMN_Handle process, Rng1U64 vrange)
{
String8 block = {0};
void *raw = dmn_process_read_raw(arena, process, vrange);
if(raw)
{
block = str8(raw, dim_1u64(vrange));
}
return block;
}
internal void *
dmn_process_read_raw(Arena *arena, DMN_Handle process, Rng1U64 vrange)
{
Temp temp = temp_begin(arena);
void *buffer = push_array(arena, U8, dim_1u64(vrange));
U64 read_size = dmn_process_read(process, vrange, buffer);
if(read_size != dim_1u64(vrange))
{
buffer = 0;
temp_end(temp);
}
return buffer;
}
internal String8 internal String8
dmn_get_trap_inst(void) dmn_get_trap_inst(void)
{ {
+1 -5
View File
@@ -219,9 +219,7 @@ internal U64 dmn_rsp_from_thread(DMN_Handle thread);
//////////////////////////////// ////////////////////////////////
//~ rjf: Process Reading Helper Functions (Helpers, Implemented Once) //~ rjf: Process Reading Helper Functions (Helpers, Implemented Once)
internal String8 dmn_process_read_cstring(Arena *arena, DMN_Handle process, U64 addr); internal String8 dmn_data_from_process_vaddr_range(Arena *arena, DMN_Handle process, Rng1U64 vrange);
internal String8 dmn_process_read_block(Arena *arena, DMN_Handle process, Rng1U64 vrange);
internal void * dmn_process_read_raw(Arena *arena, DMN_Handle process, Rng1U64 vrange);
//////////////////////////////// ////////////////////////////////
//~ rjf: @dmn_os_hooks Main Layer Initialization (Implemented Per-OS) //~ rjf: @dmn_os_hooks Main Layer Initialization (Implemented Per-OS)
@@ -262,8 +260,6 @@ internal void dmn_process_memory_release(DMN_Handle process, U64 vaddr, U64 size
internal void dmn_process_memory_protect(DMN_Handle process, U64 vaddr, U64 size, AccessFlags flags); internal void dmn_process_memory_protect(DMN_Handle process, U64 vaddr, U64 size, AccessFlags flags);
internal U64 dmn_process_read(DMN_Handle process, Rng1U64 range, void *dst); internal U64 dmn_process_read(DMN_Handle process, Rng1U64 range, void *dst);
internal B32 dmn_process_write(DMN_Handle process, Rng1U64 range, void *src); internal B32 dmn_process_write(DMN_Handle process, Rng1U64 range, void *src);
#define dmn_process_read_struct(process, vaddr, ptr) dmn_process_read((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
#define dmn_process_write_struct(process, vaddr, ptr) dmn_process_write((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
//- rjf: threads //- rjf: threads
internal Arch dmn_arch_from_thread(DMN_Handle handle); internal Arch dmn_arch_from_thread(DMN_Handle handle);
+1 -1
View File
@@ -2028,7 +2028,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
if(reg_num != 0) if(reg_num != 0)
{ {
string_mapped = 1; string_mapped = 1;
Arch arch = e_base_ctx->primary_module->arch; Arch arch = e_base_ctx->thread_arch;
ARCH_Info *arch_info = arch_info_from_arch(arch); ARCH_Info *arch_info = arch_info_from_arch(arch);
ARCH_RegCode reg_code = reg_num; ARCH_RegCode reg_code = reg_num;
Rng1U16 reg_rng = arch_info->reg_code_rng_table[reg_code]; Rng1U16 reg_rng = arch_info->reg_code_rng_table[reg_code];
+4
View File
@@ -4,6 +4,8 @@
#ifndef MINIDUMP_H #ifndef MINIDUMP_H
#define MINIDUMP_H #define MINIDUMP_H
#pragma pack(push, 1)
typedef enum MDMP_DumpKind typedef enum MDMP_DumpKind
{ {
MDMP_DumpKind_Normal = 0x00000000, MDMP_DumpKind_Normal = 0x00000000,
@@ -226,4 +228,6 @@ struct MDMP_SystemInfo
// CPU_INFORMATION Cpu; (architecture dependent) // CPU_INFORMATION Cpu; (architecture dependent)
}; };
#pragma pack(pop)
#endif // MINIDUMP_H #endif // MINIDUMP_H
+52 -51
View File
@@ -696,7 +696,7 @@ rd_ctrl_entity_from_eval_space(E_Space space)
handle.machine_id = (U32)((space.u64s[0] & 0xffffffff00000000ull) >> 32); handle.machine_id = (U32)((space.u64s[0] & 0xffffffff00000000ull) >> 32);
handle.controller_kind = (U32)((space.u64s[0] & 0x00000000ffffffffull) >> 0); handle.controller_kind = (U32)((space.u64s[0] & 0x00000000ffffffffull) >> 0);
handle.entity_id = space.u64s[1]; handle.entity_id = space.u64s[1];
entity = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, handle); entity = d_entity_from_handle(handle);
} }
return entity; return entity;
} }
@@ -793,7 +793,7 @@ rd_eval_space_read(E_Space space, void *out, E_SpaceRangeInfo *out_range_info, R
void *regs_block = 0; void *regs_block = 0;
if(e_interpret_ctx->reg_unwind_count == 0) if(e_interpret_ctx->reg_unwind_count == 0)
{ {
regs_block = d_reg_block_from_thread(scratch.arena, &d_user_state->ctrl_entity_store->ctx, entity->handle); regs_block = d_reg_block_from_thread(scratch.arena, entity->handle);
} }
else else
{ {
@@ -1042,7 +1042,7 @@ rd_eval_space_write(E_Space space, void *in, Rng1U64 range)
Rng1U64 legal_range = r1u64(0, regs_size); Rng1U64 legal_range = r1u64(0, regs_size);
Rng1U64 write_range = intersect_1u64(legal_range, range); Rng1U64 write_range = intersect_1u64(legal_range, range);
U64 write_size = dim_1u64(write_range); U64 write_size = dim_1u64(write_range);
void *new_regs = d_reg_block_from_thread(scratch.arena, &d_user_state->ctrl_entity_store->ctx, entity->handle); void *new_regs = d_reg_block_from_thread(scratch.arena, entity->handle);
MemoryCopy((U8 *)new_regs + write_range.min, in, write_size); MemoryCopy((U8 *)new_regs + write_range.min, in, write_size);
result = d_thread_write_reg_block(entity->handle, new_regs); result = d_thread_write_reg_block(entity->handle, new_regs);
scratch_end(scratch); scratch_end(scratch);
@@ -1739,7 +1739,7 @@ rd_view_ui(Rng2F32 rect)
UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null) UI_Padding(ui_pct(1, 0)) UI_Focus(UI_FocusKind_Null)
{ {
CFG_NodePtrList targets = cfg_node_top_level_list_from_string(scratch.arena, str8_lit("target")); CFG_NodePtrList targets = cfg_node_top_level_list_from_string(scratch.arena, str8_lit("target"));
D_EntityArray processes = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process); D_EntityArray processes = d_entity_array_from_kind(D_EntityKind_Process);
//- rjf: icon & info //- rjf: icon & info
UI_Padding(ui_em(2.f, 1.f)) UI_TagF("weak") UI_Padding(ui_em(2.f, 1.f)) UI_TagF("weak")
@@ -2397,7 +2397,7 @@ rd_view_ui(Rng2F32 rect)
String8 name = {0}; String8 name = {0};
{ {
U64 vaddr = eval.value.u64; U64 vaddr = eval.value.u64;
D_Entity *process = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->process); D_Entity *process = d_entity_from_handle(rd_regs()->process);
D_Entity *module = d_module_from_process_vaddr(process, vaddr); D_Entity *module = d_module_from_process_vaddr(process, vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module); DI_Key dbgi_key = d_dbgi_key_from_module(module);
U64 voff = d_voff_from_vaddr(module, vaddr); U64 voff = d_voff_from_vaddr(module, vaddr);
@@ -4772,7 +4772,7 @@ rd_arch_from_eval(E_Eval eval)
D_Entity *process = d_process_from_entity(ctrl_entity); D_Entity *process = d_process_from_entity(ctrl_entity);
if(process == &d_entity_nil) if(process == &d_entity_nil)
{ {
process = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->process); process = d_entity_from_handle(rd_regs()->process);
} }
Arch arch = process->arch; Arch arch = process->arch;
if(arch == Arch_Null) if(arch == Arch_Null)
@@ -5530,11 +5530,11 @@ rd_window_frame(void)
//////////////////////// ////////////////////////
//- rjf: control entity tooltips //- rjf: control entity tooltips
// //
case RD_RegSlot_Machine: {ctrl_entity = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, regs->machine); }goto ctrl_entity_tooltip; case RD_RegSlot_Machine: {ctrl_entity = d_entity_from_handle(regs->machine); }goto ctrl_entity_tooltip;
case RD_RegSlot_Process: {ctrl_entity = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, regs->process); }goto ctrl_entity_tooltip; case RD_RegSlot_Process: {ctrl_entity = d_entity_from_handle(regs->process); }goto ctrl_entity_tooltip;
case RD_RegSlot_Module: {ctrl_entity = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, regs->module); }goto ctrl_entity_tooltip; case RD_RegSlot_Module: {ctrl_entity = d_entity_from_handle(regs->module); }goto ctrl_entity_tooltip;
case RD_RegSlot_Thread: {ctrl_entity = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, regs->thread); }goto ctrl_entity_tooltip; case RD_RegSlot_Thread: {ctrl_entity = d_entity_from_handle(regs->thread); }goto ctrl_entity_tooltip;
case RD_RegSlot_CtrlEntity:{ctrl_entity = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, regs->ctrl_entity); }goto ctrl_entity_tooltip; case RD_RegSlot_CtrlEntity:{ctrl_entity = d_entity_from_handle(regs->ctrl_entity); }goto ctrl_entity_tooltip;
ctrl_entity_tooltip:; ctrl_entity_tooltip:;
UI_Tooltip UI_Tooltip
{ {
@@ -7080,7 +7080,7 @@ rd_window_frame(void)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
CFG_NodePtrList targets = cfg_node_top_level_list_from_string(scratch.arena, str8_lit("target")); CFG_NodePtrList targets = cfg_node_top_level_list_from_string(scratch.arena, str8_lit("target"));
D_EntityArray processes = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process); D_EntityArray processes = d_entity_array_from_kind(D_EntityKind_Process);
B32 can_send_signal = !d_ctrl_targets_running(); B32 can_send_signal = !d_ctrl_targets_running();
typedef struct CenterButtonTask CenterButtonTask; typedef struct CenterButtonTask CenterButtonTask;
struct CenterButtonTask struct CenterButtonTask
@@ -9624,7 +9624,7 @@ rd_string_from_exception_code(U32 code)
internal DR_FStrList internal DR_FStrList
rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, D_Event *event) rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, D_Event *event)
{ {
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, event->entity); D_Entity *thread = d_entity_from_handle(event->entity);
DR_FStrList thread_fstrs = rd_title_fstrs_from_ctrl_entity(arena, thread, 0); DR_FStrList thread_fstrs = rd_title_fstrs_from_ctrl_entity(arena, thread, 0);
DR_FStrList fstrs = {0}; DR_FStrList fstrs = {0};
DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()}; DR_FStrParams params = {ui_top_font(), ui_top_text_raster_flags(), ui_color_from_name(str8_lit("text")), ui_top_font_size()};
@@ -9836,14 +9836,14 @@ rd_gather_auto_exprs(Arena *arena)
U64 seen_expr_slots_count = 16; U64 seen_expr_slots_count = 16;
String8Node **seen_expr_slots = push_array(scratch.arena, String8Node *, seen_expr_slots_count); String8Node **seen_expr_slots = push_array(scratch.arena, String8Node *, seen_expr_slots_count);
D_Handle thread_handle = rd_regs()->thread; D_Handle thread_handle = rd_regs()->thread;
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, thread_handle); D_Entity *thread = d_entity_from_handle(thread_handle);
D_CallStack call_stack = d_call_stack_from_thread(access, thread->handle, 0, 0); D_CallStack call_stack = d_call_stack_from_thread(access, thread->handle, 0, 0);
if(call_stack.frames_count != 0) if(call_stack.frames_count != 0)
{ {
//- rjf: unpack thread / module / debug info / lines //- rjf: unpack thread / module / debug info / lines
ARCH_Info *arch_info = arch_info_from_arch(thread->arch); ARCH_Info *arch_info = arch_info_from_arch(thread->arch);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process); D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
U64 thread_ip_vaddr = d_rip_from_thread(&d_user_state->ctrl_entity_store->ctx, thread_handle); U64 thread_ip_vaddr = d_rip_from_thread(thread_handle);
D_Entity *module = d_module_from_process_vaddr(process, thread_ip_vaddr); D_Entity *module = d_module_from_process_vaddr(process, thread_ip_vaddr);
DI_Key dbgi_key = d_dbgi_key_from_module(module); DI_Key dbgi_key = d_dbgi_key_from_module(module);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0); RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0);
@@ -11348,14 +11348,15 @@ rd_frame(void)
//- rjf: unpack basic evaluation context //- rjf: unpack basic evaluation context
// //
ProfBegin("unpack eval-dependent info"); ProfBegin("unpack eval-dependent info");
D_Entity *process = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->process); D_Entity *process = d_entity_from_handle(rd_regs()->process);
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->thread); D_Entity *thread = d_entity_from_handle(rd_regs()->thread);
Arch arch = thread->arch; Arch arch = thread->arch;
E_Space primary_space = rd_eval_space_from_ctrl_entity(process, D_EvalSpaceKind_Entity);
U64 unwind_count = rd_regs()->unwind_count; U64 unwind_count = rd_regs()->unwind_count;
U64 rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, unwind_count); U64 rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, unwind_count);
D_Entity *module = d_module_from_process_vaddr(process, rip_vaddr); D_Entity *module = d_module_from_process_vaddr(process, rip_vaddr);
U64 rip_voff = d_voff_from_vaddr(module, rip_vaddr); U64 rip_voff = d_voff_from_vaddr(module, rip_vaddr);
U64 tls_root_vaddr = d_tls_root_vaddr_from_thread(&d_user_state->ctrl_entity_store->ctx, thread->handle); U64 tls_root_vaddr = d_tls_root_vaddr_from_thread(thread->handle);
ProfEnd(); ProfEnd();
//////////////////////////// ////////////////////////////
@@ -11378,7 +11379,7 @@ rd_frame(void)
//////////////////////////// ////////////////////////////
//- rjf: produce all eval modules //- rjf: produce all eval modules
// //
D_EntityArray all_modules = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Module); D_EntityArray all_modules = d_entity_array_from_kind(D_EntityKind_Module);
U64 eval_modules_count = Max(1, all_modules.count); U64 eval_modules_count = Max(1, all_modules.count);
E_Module *eval_modules = push_array(scratch.arena, E_Module, eval_modules_count); E_Module *eval_modules = push_array(scratch.arena, E_Module, eval_modules_count);
E_Module *eval_modules_primary = &e_module_nil; E_Module *eval_modules_primary = &e_module_nil;
@@ -11787,7 +11788,7 @@ rd_frame(void)
{ {
String8 name = evallable_ctrl_names[idx]; String8 name = evallable_ctrl_names[idx];
D_EntityKind kind = d_entity_kind_from_string(name); D_EntityKind kind = d_entity_kind_from_string(name);
D_EntityArray array = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, kind); D_EntityArray array = d_entity_array_from_kind(kind);
E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name);
for EachIndex(idx, array.count) for EachIndex(idx, array.count)
{ {
@@ -12158,7 +12159,7 @@ rd_frame(void)
//- rjf: gather config from loaded modules //- rjf: gather config from loaded modules
// //
CFG_NodePtrList immediate_type_views = {0}; CFG_NodePtrList immediate_type_views = {0};
D_EntityArray modules = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Module); D_EntityArray modules = d_entity_array_from_kind(D_EntityKind_Module);
ProfScope("gather config from loaded modules") ProfScope("gather config from loaded modules")
{ {
for EachIndex(idx, modules.count) for EachIndex(idx, modules.count)
@@ -12262,7 +12263,7 @@ rd_frame(void)
E_IRCtx *ir_ctx = push_array(scratch.arena, E_IRCtx, 1); E_IRCtx *ir_ctx = push_array(scratch.arena, E_IRCtx, 1);
{ {
E_IRCtx *ctx = ir_ctx; E_IRCtx *ctx = ir_ctx;
ctx->regs_map = d_string2reg_from_arch(eval_base_ctx->primary_module->arch); ctx->regs_map = d_string2reg_from_arch(arch);
ctx->locals_map = d_query_cached_locals_map_from_dbgi_key_voff(eval_base_ctx->primary_dbg_info->dbgi_key, rip_voff); ctx->locals_map = d_query_cached_locals_map_from_dbgi_key_voff(eval_base_ctx->primary_dbg_info->dbgi_key, rip_voff);
ctx->member_map = d_query_cached_member_map_from_dbgi_key_voff(eval_base_ctx->primary_dbg_info->dbgi_key, rip_voff); ctx->member_map = d_query_cached_member_map_from_dbgi_key_voff(eval_base_ctx->primary_dbg_info->dbgi_key, rip_voff);
ctx->macro_map = macro_map; ctx->macro_map = macro_map;
@@ -12276,8 +12277,8 @@ rd_frame(void)
E_InterpretCtx *interpret_ctx = push_array(scratch.arena, E_InterpretCtx, 1); E_InterpretCtx *interpret_ctx = push_array(scratch.arena, E_InterpretCtx, 1);
{ {
E_InterpretCtx *ctx = interpret_ctx; E_InterpretCtx *ctx = interpret_ctx;
ctx->primary_space = eval_modules_primary->space; ctx->primary_space = primary_space;
ctx->reg_arch = eval_modules_primary->arch; ctx->reg_arch = arch;
ctx->reg_space = rd_eval_space_from_ctrl_entity(thread, D_EvalSpaceKind_Entity); ctx->reg_space = rd_eval_space_from_ctrl_entity(thread, D_EvalSpaceKind_Entity);
ctx->reg_unwind_count = unwind_count; ctx->reg_unwind_count = unwind_count;
ctx->module_base = push_array(scratch.arena, U64, 1); ctx->module_base = push_array(scratch.arena, U64, 1);
@@ -12349,7 +12350,7 @@ rd_frame(void)
case RD_CmdKind_Restart: case RD_CmdKind_Restart:
{ {
// rjf: reset hit counts // rjf: reset hit counts
D_EntityArray processes = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process); D_EntityArray processes = d_entity_array_from_kind(D_EntityKind_Process);
if(processes.count == 0 || kind == RD_CmdKind_Restart) if(processes.count == 0 || kind == RD_CmdKind_Restart)
{ {
CFG_NodePtrList bps = cfg_node_top_level_list_from_string(scratch.arena, str8_lit("breakpoint")); CFG_NodePtrList bps = cfg_node_top_level_list_from_string(scratch.arena, str8_lit("breakpoint"));
@@ -12569,7 +12570,7 @@ rd_frame(void)
{ {
// rjf: if control processes are live, but this is not force-confirmed, then // rjf: if control processes are live, but this is not force-confirmed, then
// get confirmation from user // get confirmation from user
D_EntityArray processes = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process); D_EntityArray processes = d_entity_array_from_kind(D_EntityKind_Process);
UI_Key key = ui_key_from_string(ui_key_zero(), str8_lit("lossy_exit_confirmation")); UI_Key key = ui_key_from_string(ui_key_zero(), str8_lit("lossy_exit_confirmation"));
if(processes.count != 0 && !rd_regs()->force_confirm && !ui_key_match(rd_state->popup_key, key)) if(processes.count != 0 && !rd_regs()->force_confirm && !ui_key_match(rd_state->popup_key, key))
{ {
@@ -13907,12 +13908,12 @@ rd_frame(void)
//- rjf: source <-> disasm //- rjf: source <-> disasm
case RD_CmdKind_GoToDisassembly: case RD_CmdKind_GoToDisassembly:
{ {
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->thread); D_Entity *thread = d_entity_from_handle(rd_regs()->thread);
U64 vaddr = 0; U64 vaddr = 0;
for(D_LineNode *n = rd_regs()->lines.first; n != 0; n = n->next) for(D_LineNode *n = rd_regs()->lines.first; n != 0; n = n->next)
{ {
D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, &d_user_state->ctrl_entity_store->ctx, n->v.dbgi_key); D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, n->v.dbgi_key);
D_Entity *module = d_module_from_thread_candidates(&d_user_state->ctrl_entity_store->ctx, thread, &modules); D_Entity *module = d_module_from_thread_candidates(thread, &modules);
if(module != &d_entity_nil) if(module != &d_entity_nil)
{ {
vaddr = d_vaddr_from_voff(module, n->v.voff_range.min); vaddr = d_vaddr_from_voff(module, n->v.voff_range.min);
@@ -14195,7 +14196,7 @@ rd_frame(void)
Access *access = access_open(); Access *access = access_open();
//- rjf: unpack thread info //- rjf: unpack thread info
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->thread); D_Entity *thread = d_entity_from_handle(rd_regs()->thread);
U64 unwind_index = rd_regs()->unwind_count; U64 unwind_index = rd_regs()->unwind_count;
U64 inline_depth = rd_regs()->inline_depth; U64 inline_depth = rd_regs()->inline_depth;
U64 rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, unwind_index); U64 rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, unwind_index);
@@ -14259,7 +14260,7 @@ rd_frame(void)
}break; }break;
case RD_CmdKind_FindSelectedThread: case RD_CmdKind_FindSelectedThread:
{ {
D_Entity *selected_thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_base_regs()->thread); D_Entity *selected_thread = d_entity_from_handle(rd_base_regs()->thread);
rd_cmd(RD_CmdKind_FindThread, rd_cmd(RD_CmdKind_FindThread,
.thread = selected_thread->handle, .thread = selected_thread->handle,
.unwind_count = rd_base_regs()->unwind_count, .unwind_count = rd_base_regs()->unwind_count,
@@ -14368,7 +14369,7 @@ rd_frame(void)
{ {
D_Entity *process = &d_entity_nil; D_Entity *process = &d_entity_nil;
U64 vaddr = 0; U64 vaddr = 0;
D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, &d_user_state->ctrl_entity_store->ctx, voff_dbgi_key); D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, voff_dbgi_key);
D_Entity *module = d_entity_list_first(&modules); D_Entity *module = d_entity_list_first(&modules);
process = d_entity_ancestor_from_kind(module, D_EntityKind_Process); process = d_entity_ancestor_from_kind(module, D_EntityKind_Process);
if(process != &d_entity_nil) if(process != &d_entity_nil)
@@ -14448,8 +14449,8 @@ rd_frame(void)
{ {
file_path = rd_mapped_from_file_path(scratch.arena, rd_regs()->file_path); file_path = rd_mapped_from_file_path(scratch.arena, rd_regs()->file_path);
point = rd_regs()->cursor; point = rd_regs()->cursor;
thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->thread); thread = d_entity_from_handle(rd_regs()->thread);
process = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->process); process = d_entity_from_handle(rd_regs()->process);
vaddr = rd_regs()->vaddr; vaddr = rd_regs()->vaddr;
prefer_new_tab = rd_regs()->prefer_new_tab; prefer_new_tab = rd_regs()->prefer_new_tab;
if(file_path.size == 0) if(file_path.size == 0)
@@ -14471,8 +14472,8 @@ rd_frame(void)
D_LineList lines = d_lines_from_file_path_line_num(scratch.arena, file_path, point.line, max_U64); D_LineList lines = d_lines_from_file_path_line_num(scratch.arena, file_path, point.line, max_U64);
for(D_LineNode *n = lines.first; n != 0; n = n->next) for(D_LineNode *n = lines.first; n != 0; n = n->next)
{ {
D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, &d_user_state->ctrl_entity_store->ctx, n->v.dbgi_key); D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, n->v.dbgi_key);
D_Entity *module = d_module_from_thread_candidates(&d_user_state->ctrl_entity_store->ctx, thread, &modules); D_Entity *module = d_module_from_thread_candidates(thread, &modules);
vaddr = d_vaddr_from_voff(module, n->v.voff_range.min); vaddr = d_vaddr_from_voff(module, n->v.voff_range.min);
break; break;
} }
@@ -15685,7 +15686,7 @@ rd_frame(void)
}break; }break;
case RD_CmdKind_SetNextStatement: case RD_CmdKind_SetNextStatement:
{ {
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->thread); D_Entity *thread = d_entity_from_handle(rd_regs()->thread);
String8 file_path = rd_regs()->file_path; String8 file_path = rd_regs()->file_path;
U64 new_rip_vaddr = rd_regs()->vaddr_range.min; U64 new_rip_vaddr = rd_regs()->vaddr_range.min;
if(file_path.size != 0) if(file_path.size != 0)
@@ -15693,8 +15694,8 @@ rd_frame(void)
D_LineList *lines = &rd_regs()->lines; D_LineList *lines = &rd_regs()->lines;
for(D_LineNode *n = lines->first; n != 0; n = n->next) for(D_LineNode *n = lines->first; n != 0; n = n->next)
{ {
D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, &d_user_state->ctrl_entity_store->ctx, n->v.dbgi_key); D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, n->v.dbgi_key);
D_Entity *module = d_module_from_thread_candidates(&d_user_state->ctrl_entity_store->ctx, thread, &modules); D_Entity *module = d_module_from_thread_candidates(thread, &modules);
if(module != &d_entity_nil) if(module != &d_entity_nil)
{ {
new_rip_vaddr = d_vaddr_from_voff(module, n->v.voff_range.min); new_rip_vaddr = d_vaddr_from_voff(module, n->v.voff_range.min);
@@ -15810,9 +15811,9 @@ rd_frame(void)
}break; }break;
case RD_CmdKind_SelectThread: case RD_CmdKind_SelectThread:
{ {
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->thread); D_Entity *thread = d_entity_from_handle(rd_regs()->thread);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process); D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
D_Entity *module = d_module_from_process_vaddr(process, d_rip_from_thread(&d_user_state->ctrl_entity_store->ctx, thread->handle)); D_Entity *module = d_module_from_process_vaddr(process, d_rip_from_thread(thread->handle));
D_Entity *machine = d_entity_ancestor_from_kind(process, D_EntityKind_Machine); D_Entity *machine = d_entity_ancestor_from_kind(process, D_EntityKind_Machine);
rd_state->base_regs.v.unwind_count = 0; rd_state->base_regs.v.unwind_count = 0;
rd_state->base_regs.v.inline_depth = 0; rd_state->base_regs.v.inline_depth = 0;
@@ -15825,7 +15826,7 @@ rd_frame(void)
case RD_CmdKind_SelectUnwind: case RD_CmdKind_SelectUnwind:
{ {
Access *access = access_open(); Access *access = access_open();
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_base_regs()->thread); D_Entity *thread = d_entity_from_handle(rd_base_regs()->thread);
D_CallStack call_stack = d_call_stack_from_thread(access, thread->handle, 1, now_time_us()+10000); D_CallStack call_stack = d_call_stack_from_thread(access, thread->handle, 1, now_time_us()+10000);
D_CallStackFrame *frame = d_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); D_CallStackFrame *frame = d_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth);
if(frame == 0) if(frame == 0)
@@ -15844,7 +15845,7 @@ rd_frame(void)
case RD_CmdKind_DownOneFrame: case RD_CmdKind_DownOneFrame:
{ {
Access *access = access_open(); Access *access = access_open();
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_base_regs()->thread); D_Entity *thread = d_entity_from_handle(rd_base_regs()->thread);
D_CallStack call_stack = d_call_stack_from_thread(access, thread->handle, 1, now_time_us()+10000); D_CallStack call_stack = d_call_stack_from_thread(access, thread->handle, 1, now_time_us()+10000);
D_CallStackFrame *current_frame = d_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); D_CallStackFrame *current_frame = d_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth);
D_CallStackFrame *next_frame = current_frame; D_CallStackFrame *next_frame = current_frame;
@@ -16576,7 +16577,7 @@ rd_frame(void)
default:{}break; default:{}break;
case D_EventKind_NewProc: case D_EventKind_NewProc:
{ {
D_EntityArray all_processes = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process); D_EntityArray all_processes = d_entity_array_from_kind(D_EntityKind_Process);
if(all_processes.count == 1) if(all_processes.count == 1)
{ {
MemoryZeroStruct(&rd_state->prestop_focused_window); MemoryZeroStruct(&rd_state->prestop_focused_window);
@@ -16593,7 +16594,7 @@ rd_frame(void)
}break; }break;
case D_EventKind_NewModule: case D_EventKind_NewModule:
{ {
D_Entity *module = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, evt->entity); D_Entity *module = d_entity_from_handle(evt->entity);
D_Entity *debug_info_path = d_entity_child_from_kind(module, D_EntityKind_DebugInfoPath); D_Entity *debug_info_path = d_entity_child_from_kind(module, D_EntityKind_DebugInfoPath);
String8 new_path = debug_info_path->string; String8 new_path = debug_info_path->string;
if(new_path.size != 0 && file_path_exists(new_path)) if(new_path.size != 0 && file_path_exists(new_path))
@@ -16637,7 +16638,7 @@ rd_frame(void)
case D_EventKind_EndProc: case D_EventKind_EndProc:
if(rd_state->quit_after_success) if(rd_state->quit_after_success)
{ {
D_EntityArray processes = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process); D_EntityArray processes = d_entity_array_from_kind(D_EntityKind_Process);
if(evt->u64_code == 0 && processes.count == 0) if(evt->u64_code == 0 && processes.count == 0)
{ {
rd_cmd(RD_CmdKind_Exit); rd_cmd(RD_CmdKind_Exit);
@@ -16650,12 +16651,12 @@ rd_frame(void)
case D_EventKind_Stopped: case D_EventKind_Stopped:
{ {
B32 need_refocus = (evt->cause != D_EventCause_InterruptedByHalt || !soft_halt_issued); B32 need_refocus = (evt->cause != D_EventCause_InterruptedByHalt || !soft_halt_issued);
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, evt->entity); D_Entity *thread = d_entity_from_handle(evt->entity);
U64 vaddr = evt->rip_vaddr; U64 vaddr = evt->rip_vaddr;
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process); D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
D_Entity *module = d_module_from_process_vaddr(process, vaddr); D_Entity *module = d_module_from_process_vaddr(process, vaddr);
U64 voff = d_voff_from_vaddr(module, vaddr); U64 voff = d_voff_from_vaddr(module, vaddr);
U64 test_cached_vaddr = d_rip_from_thread(&d_user_state->ctrl_entity_store->ctx, thread->handle); U64 test_cached_vaddr = d_rip_from_thread(thread->handle);
// rjf: valid stop thread? -> select & snap // rjf: valid stop thread? -> select & snap
if(need_refocus && thread->kind == D_EntityKind_Thread && evt->cause != D_EventCause_InterruptedByHalt) if(need_refocus && thread->kind == D_EntityKind_Thread && evt->cause != D_EventCause_InterruptedByHalt)
@@ -16664,7 +16665,7 @@ rd_frame(void)
} }
// rjf: no stop-causing thread, but have selected thread? -> snap to selected // rjf: no stop-causing thread, but have selected thread? -> snap to selected
D_Entity *selected_thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_base_regs()->thread); D_Entity *selected_thread = d_entity_from_handle(rd_base_regs()->thread);
if(need_refocus && (evt->cause == D_EventCause_InterruptedByHalt || thread->kind != D_EntityKind_Thread) && selected_thread != &d_entity_nil) if(need_refocus && (evt->cause == D_EventCause_InterruptedByHalt || thread->kind != D_EntityKind_Thread) && selected_thread != &d_entity_nil)
{ {
rd_cmd(RD_CmdKind_SelectThread, .thread = selected_thread->handle); rd_cmd(RD_CmdKind_SelectThread, .thread = selected_thread->handle);
@@ -16673,7 +16674,7 @@ rd_frame(void)
// rjf: no stop-causing thread, but don't have selected thread? -> snap to first available thread // rjf: no stop-causing thread, but don't have selected thread? -> snap to first available thread
if(need_refocus && thread->kind != D_EntityKind_Thread && selected_thread == &d_entity_nil) if(need_refocus && thread->kind != D_EntityKind_Thread && selected_thread == &d_entity_nil)
{ {
D_EntityArray threads = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Thread); D_EntityArray threads = d_entity_array_from_kind(D_EntityKind_Thread);
D_Entity *first_available_thread = d_entity_array_first(&threads); D_Entity *first_available_thread = d_entity_array_first(&threads);
rd_cmd(RD_CmdKind_SelectThread, .thread = first_available_thread->handle); rd_cmd(RD_CmdKind_SelectThread, .thread = first_available_thread->handle);
} }
@@ -16725,7 +16726,7 @@ rd_frame(void)
// rjf: update the autos-determining code range // rjf: update the autos-determining code range
{ {
D_Handle new_thread_handle = thread->handle; D_Handle new_thread_handle = thread->handle;
U64 new_sp = d_rsp_from_thread(&d_user_state->ctrl_entity_store->ctx, new_thread_handle); U64 new_sp = d_rsp_from_thread(new_thread_handle);
if(thread == &d_entity_nil) if(thread == &d_entity_nil)
{ {
new_thread_handle = selected_thread->handle; new_thread_handle = selected_thread->handle;
+7 -7
View File
@@ -267,7 +267,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(locals)
E_TYPE_EXPAND_INFO_FUNCTION_DEF(registers) E_TYPE_EXPAND_INFO_FUNCTION_DEF(registers)
{ {
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->thread); D_Entity *thread = d_entity_from_handle(rd_regs()->thread);
Arch arch = thread->arch; Arch arch = thread->arch;
ARCH_Info *arch_info = arch_info_from_arch(arch); ARCH_Info *arch_info = arch_info_from_arch(arch);
U64 reg_count = arch_info->reg_code_count; U64 reg_count = arch_info->reg_code_count;
@@ -769,7 +769,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(control)
str8_match(str8_prefix(rhs->string, 1), str8_lit("$"), 0)) str8_match(str8_prefix(rhs->string, 1), str8_lit("$"), 0))
{ {
D_Handle handle = d_handle_from_string(rhs->string); D_Handle handle = d_handle_from_string(rhs->string);
D_Entity *entity = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, handle); D_Entity *entity = d_entity_from_handle(handle);
E_Space space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); E_Space space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity);
result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0)); result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0));
result.type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, d_entity_kind_code_name_table[entity->kind]); result.type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, d_entity_kind_code_name_table[entity->kind]);
@@ -1103,7 +1103,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(call_stack)
D_CallStack *call_stack = &accel->call_stack; D_CallStack *call_stack = &accel->call_stack;
if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->frames_count) if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->frames_count)
{ {
D_Entity *process = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, accel->process); D_Entity *process = d_entity_from_handle(accel->process);
ARCH_Info *arch_info = arch_info_from_arch(accel->arch); ARCH_Info *arch_info = arch_info_from_arch(accel->arch);
D_CallStackFrame *f = &call_stack->frames[rhs_value.u64]; D_CallStackFrame *f = &call_stack->frames[rhs_value.u64];
result.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(process, D_EvalSpaceKind_Entity), e_irtree_const_u(arena, arch_ip_from_reg_block(arch_info, f->regs))); result.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(process, D_EvalSpaceKind_Entity), e_irtree_const_u(arena, arch_ip_from_reg_block(arch_info, f->regs)));
@@ -1565,7 +1565,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(unattached_processes)
} }
else else
{ {
machines = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Machine); machines = d_entity_array_from_kind(D_EntityKind_Machine);
} }
//- rjf: gather system processes from this machine //- rjf: gather system processes from this machine
@@ -1662,7 +1662,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(ctrl_entities)
{ {
String8 rhs_name = expr->first->next->string; String8 rhs_name = expr->first->next->string;
D_Handle handle = d_handle_from_string(rhs_name); D_Handle handle = d_handle_from_string(rhs_name);
entity = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, handle); entity = d_entity_from_handle(handle);
}break; }break;
case E_ExprKind_ArrayIndex: case E_ExprKind_ArrayIndex:
{ {
@@ -1670,7 +1670,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(ctrl_entities)
D_EntityKind kind = d_entity_kind_from_string(rd_singular_from_code_name_plural(type->name)); D_EntityKind kind = d_entity_kind_from_string(rd_singular_from_code_name_plural(type->name));
E_Value rhs_value = e_value_from_expr(expr->first->next); E_Value rhs_value = e_value_from_expr(expr->first->next);
U64 rhs_idx = rhs_value.u64; U64 rhs_idx = rhs_value.u64;
D_EntityArray entities = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, kind); D_EntityArray entities = d_entity_array_from_kind(kind);
if(0 <= rhs_idx && rhs_idx < entities.count) if(0 <= rhs_idx && rhs_idx < entities.count)
{ {
entity = entities.v[rhs_idx]; entity = entities.v[rhs_idx];
@@ -1712,7 +1712,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(ctrl_entities)
D_EntityArray array = {0}; D_EntityArray array = {0};
if(scoping_entity == &d_entity_nil) if(scoping_entity == &d_entity_nil)
{ {
array = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, entity_kind); array = d_entity_array_from_kind(entity_kind);
} }
else else
{ {
+2
View File
@@ -292,6 +292,7 @@
//- rjf: [h] //- rjf: [h]
#include "base/base_inc.h" #include "base/base_inc.h"
#include "x64/x64.h" #include "x64/x64.h"
#include "win32/win32_inc.h"
#include "linker/hash_table.h" #include "linker/hash_table.h"
#include "linker/lf_hash_table.h" #include "linker/lf_hash_table.h"
#include "linker/base_ext/base_bit_array.h" #include "linker/base_ext/base_bit_array.h"
@@ -347,6 +348,7 @@
//- rjf: [c] //- rjf: [c]
#include "base/base_inc.c" #include "base/base_inc.c"
#include "x64/x64.c" #include "x64/x64.c"
#include "win32/win32_inc.c"
#include "linker/hash_table.c" #include "linker/hash_table.c"
#include "linker/lf_hash_table.c" #include "linker/lf_hash_table.c"
#include "linker/base_ext/base_bit_array.c" #include "linker/base_ext/base_bit_array.c"
+12 -12
View File
@@ -44,7 +44,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
F32 scroll_bar_dim = floor_f32(main_font_size*1.5f); F32 scroll_bar_dim = floor_f32(main_font_size*1.5f);
Vec2F32 code_area_dim = v2f32(panel_box_dim.x - scroll_bar_dim, panel_box_dim.y - scroll_bar_dim); Vec2F32 code_area_dim = v2f32(panel_box_dim.x - scroll_bar_dim, panel_box_dim.y - scroll_bar_dim);
S64 num_possible_visible_lines = (S64)(code_area_dim.y/code_line_height)+1; S64 num_possible_visible_lines = (S64)(code_area_dim.y/code_line_height)+1;
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->thread); D_Entity *thread = d_entity_from_handle(rd_regs()->thread);
D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process); D_Entity *process = d_entity_ancestor_from_kind(thread, D_EntityKind_Process);
B32 do_line_numbers = rd_setting_b32_from_name(str8_lit("show_line_numbers")); B32 do_line_numbers = rd_setting_b32_from_name(str8_lit("show_line_numbers"));
@@ -278,8 +278,8 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
// rjf: find live threads mapping to source code // rjf: find live threads mapping to source code
if(!dasm_lines) ProfScope("find live threads mapping to this file") if(!dasm_lines) ProfScope("find live threads mapping to this file")
{ {
D_Entity *selected_thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->thread); D_Entity *selected_thread = d_entity_from_handle(rd_regs()->thread);
D_EntityArray threads = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Thread); D_EntityArray threads = d_entity_array_from_kind(D_EntityKind_Thread);
for EachIndex(idx, threads.count) for EachIndex(idx, threads.count)
{ {
D_Entity *thread = threads.v[idx]; D_Entity *thread = threads.v[idx];
@@ -341,7 +341,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
if(!dasm_lines) ProfScope("find all src -> dasm info for source code") if(!dasm_lines) ProfScope("find all src -> dasm info for source code")
{ {
String8 file_path = rd_regs()->file_path; String8 file_path = rd_regs()->file_path;
D_Entity *module = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->module); D_Entity *module = d_entity_from_handle(rd_regs()->module);
DI_Key dbgi_key = d_dbgi_key_from_module(module); DI_Key dbgi_key = d_dbgi_key_from_module(module);
D_LineListArray lines_array = d_lines_array_from_dbgi_key_file_path_line_range(scratch.arena, dbgi_key, file_path, visible_line_num_range, 8); D_LineListArray lines_array = d_lines_array_from_dbgi_key_file_path_line_range(scratch.arena, dbgi_key, file_path, visible_line_num_range, 8);
if(lines_array.count != 0) if(lines_array.count != 0)
@@ -354,8 +354,8 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
// rjf: find live threads mapping to disasm // rjf: find live threads mapping to disasm
if(dasm_lines) ProfScope("find live threads mapping to this disassembly") if(dasm_lines) ProfScope("find live threads mapping to this disassembly")
{ {
D_Entity *selected_thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->thread); D_Entity *selected_thread = d_entity_from_handle(rd_regs()->thread);
D_EntityArray threads = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Thread); D_EntityArray threads = d_entity_array_from_kind(D_EntityKind_Thread);
for EachIndex(idx, threads.count) for EachIndex(idx, threads.count)
{ {
D_Entity *thread = threads.v[idx]; D_Entity *thread = threads.v[idx];
@@ -2102,7 +2102,7 @@ RD_VIEW_UI_FUNCTION_DEF(text)
if(rd_regs()->lang_kind == TXT_LangKind_Null) if(rd_regs()->lang_kind == TXT_LangKind_Null)
{ {
Access *access = access_open(); Access *access = access_open();
D_Entity *module = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->module); D_Entity *module = d_entity_from_handle(rd_regs()->module);
DI_Key dbgi_key = d_dbgi_key_from_module(module); DI_Key dbgi_key = d_dbgi_key_from_module(module);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0); RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0);
if(rdi != &rdi_parsed_nil) if(rdi != &rdi_parsed_nil)
@@ -2226,7 +2226,7 @@ RD_VIEW_UI_FUNCTION_DEF(text)
// //
if(rd_regs()->file_path.size != 0) if(rd_regs()->file_path.size != 0)
{ {
D_Entity *module = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->module); D_Entity *module = d_entity_from_handle(rd_regs()->module);
DI_Key dbgi_key = d_dbgi_key_from_module(module); DI_Key dbgi_key = d_dbgi_key_from_module(module);
rd_regs()->lines = d_lines_from_dbgi_key_file_path_line_num(rd_frame_arena(), dbgi_key, rd_regs()->file_path, rd_regs()->cursor.line, 8); rd_regs()->lines = d_lines_from_dbgi_key_file_path_line_num(rd_frame_arena(), dbgi_key, rd_regs()->file_path, rd_regs()->cursor.line, 8);
} }
@@ -2436,13 +2436,13 @@ RD_VIEW_UI_FUNCTION_DEF(disasm)
if(dv->temp_look_vaddr != 0 && dv->temp_look_run_gen == d_run_gen()) if(dv->temp_look_vaddr != 0 && dv->temp_look_run_gen == d_run_gen())
{ {
auto_selected = 1; auto_selected = 1;
auto_space = rd_eval_space_from_ctrl_entity(d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, dv->temp_look_process), D_EvalSpaceKind_Entity); auto_space = rd_eval_space_from_ctrl_entity(d_entity_from_handle(dv->temp_look_process), D_EvalSpaceKind_Entity);
eval = e_eval_from_stringf("(0x%I64x & (~(0x4000 - 1)))", dv->temp_look_vaddr); eval = e_eval_from_stringf("(0x%I64x & (~(0x4000 - 1)))", dv->temp_look_vaddr);
} }
else else
{ {
auto_selected = 1; auto_selected = 1;
auto_space = rd_eval_space_from_ctrl_entity(d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->process), D_EvalSpaceKind_Entity); auto_space = rd_eval_space_from_ctrl_entity(d_entity_from_handle(rd_regs()->process), D_EvalSpaceKind_Entity);
eval = e_eval_from_stringf("(reg:rip & (~(0x4000 - 1)))"); eval = e_eval_from_stringf("(reg:rip & (~(0x4000 - 1)))");
} }
} }
@@ -2683,7 +2683,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory)
Rng1U64 view_range = rd_space_range_from_eval(eval); Rng1U64 view_range = rd_space_range_from_eval(eval);
if(eval.space.kind == 0) if(eval.space.kind == 0)
{ {
eval.space = rd_eval_space_from_ctrl_entity(d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->process), D_EvalSpaceKind_Entity); eval.space = rd_eval_space_from_ctrl_entity(d_entity_from_handle(rd_regs()->process), D_EvalSpaceKind_Entity);
view_range = rd_whole_range_from_eval_space(eval.space); view_range = rd_whole_range_from_eval_space(eval.space);
} }
@@ -3257,7 +3257,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory)
AnnotationList *visible_memory_annotations = push_array(scratch.arena, AnnotationList, visible_memory_size); AnnotationList *visible_memory_annotations = push_array(scratch.arena, AnnotationList, visible_memory_size);
{ {
Access *access = access_open(); Access *access = access_open();
D_Entity *selected_thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->thread); D_Entity *selected_thread = d_entity_from_handle(rd_regs()->thread);
D_Entity *selected_process = d_entity_ancestor_from_kind(selected_thread, D_EntityKind_Process); D_Entity *selected_process = d_entity_ancestor_from_kind(selected_thread, D_EntityKind_Process);
D_CallStack selected_call_stack = d_call_stack_from_thread(access, selected_thread->handle, 1, 0); D_CallStack selected_call_stack = d_call_stack_from_thread(access, selected_thread->handle, 1, 0);
D_Entity *eval_process = &d_entity_nil; D_Entity *eval_process = &d_entity_nil;
+8 -8
View File
@@ -109,7 +109,7 @@ rd_title_fstrs_from_cfg(Arena *arena, CFG_Node *cfg, B32 include_extras)
CFG_Node *bp = cfg_node_from_id(stop_event.u64_code); CFG_Node *bp = cfg_node_from_id(stop_event.u64_code);
if(bp == cfg) if(bp == cfg)
{ {
D_Entity *thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, stop_event.entity); D_Entity *thread = d_entity_from_handle(stop_event.entity);
Vec4F32 thread_color = rd_color_from_ctrl_entity(thread); Vec4F32 thread_color = rd_color_from_ctrl_entity(thread);
if(thread_color.w == 0) if(thread_color.w == 0)
{ {
@@ -518,7 +518,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, D_Entity *entity, B32 include_extr
if(entity->kind == D_EntityKind_Thread || if(entity->kind == D_EntityKind_Thread ||
entity->kind == D_EntityKind_Module) entity->kind == D_EntityKind_Module)
{ {
D_EntityArray processes = d_entity_array_from_kind(&d_user_state->ctrl_entity_store->ctx, D_EntityKind_Process); D_EntityArray processes = d_entity_array_from_kind(D_EntityKind_Process);
if(processes.count > 1) if(processes.count > 1)
{ {
D_Entity *process = d_entity_ancestor_from_kind(entity, D_EntityKind_Process); D_Entity *process = d_entity_ancestor_from_kind(entity, D_EntityKind_Process);
@@ -1264,12 +1264,12 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
RD_CodeSliceSignal result = {0}; RD_CodeSliceSignal result = {0};
ProfBeginFunction(); ProfBeginFunction();
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
D_Entity *selected_thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_regs()->thread); D_Entity *selected_thread = d_entity_from_handle(rd_regs()->thread);
D_Entity *selected_thread_process = d_entity_ancestor_from_kind(selected_thread, D_EntityKind_Process); D_Entity *selected_thread_process = d_entity_ancestor_from_kind(selected_thread, D_EntityKind_Process);
U64 selected_thread_rip_unwind_vaddr = d_query_cached_rip_from_thread_unwind(selected_thread, rd_regs()->unwind_count); U64 selected_thread_rip_unwind_vaddr = d_query_cached_rip_from_thread_unwind(selected_thread, rd_regs()->unwind_count);
D_Entity *selected_thread_module = d_module_from_process_vaddr(selected_thread_process, selected_thread_rip_unwind_vaddr); D_Entity *selected_thread_module = d_module_from_process_vaddr(selected_thread_process, selected_thread_rip_unwind_vaddr);
D_Event stop_event = d_ctrl_last_stop_event(); D_Event stop_event = d_ctrl_last_stop_event();
D_Entity *stopper_thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, stop_event.entity); D_Entity *stopper_thread = d_entity_from_handle(stop_event.entity);
B32 is_focused = ui_is_focus_active(); B32 is_focused = ui_is_focus_active();
B32 ctrlified = (wm_get_modifiers() & WM_Modifier_Ctrl); B32 ctrlified = (wm_get_modifiers() & WM_Modifier_Ctrl);
Vec4F32 code_line_bgs[] = Vec4F32 code_line_bgs[] =
@@ -1348,7 +1348,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
if(rd_state->drag_drop_regs_slot == RD_RegSlot_Thread) if(rd_state->drag_drop_regs_slot == RD_RegSlot_Thread)
{ {
drop_can_hit_lines = 1; drop_can_hit_lines = 1;
drop_thread = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, rd_state->drag_drop_regs->thread); drop_thread = d_entity_from_handle(rd_state->drag_drop_regs->thread);
drop_color = rd_color_from_ctrl_entity(drop_thread); drop_color = rd_color_from_ctrl_entity(drop_thread);
if(drop_color.w == 0) if(drop_color.w == 0)
{ {
@@ -2113,8 +2113,8 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
D_LineList *lines = &params->line_infos[line_idx]; D_LineList *lines = &params->line_infos[line_idx];
for(D_LineNode *n = lines->first; n != 0; n = n->next) for(D_LineNode *n = lines->first; n != 0; n = n->next)
{ {
D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, &d_user_state->ctrl_entity_store->ctx, n->v.dbgi_key); D_EntityList modules = d_modules_from_dbgi_key(scratch.arena, n->v.dbgi_key);
D_Entity *module = d_module_from_thread_candidates(&d_user_state->ctrl_entity_store->ctx, thread, &modules); D_Entity *module = d_module_from_thread_candidates(thread, &modules);
if(module != &d_entity_nil) if(module != &d_entity_nil)
{ {
new_rip_vaddr = d_vaddr_from_voff(module, n->v.voff_range.min); new_rip_vaddr = d_vaddr_from_voff(module, n->v.voff_range.min);
@@ -2723,7 +2723,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
Rng1U64 hover_voff_range = hover_regs->voff_range; Rng1U64 hover_voff_range = hover_regs->voff_range;
if(hover_voff_range.min == 0 && hover_voff_range.max == 0) if(hover_voff_range.min == 0 && hover_voff_range.max == 0)
{ {
D_Entity *module = d_entity_from_handle(&d_user_state->ctrl_entity_store->ctx, hover_regs->module); D_Entity *module = d_entity_from_handle(hover_regs->module);
hover_voff_range = d_voff_range_from_vaddr_range(module, hover_regs->vaddr_range); hover_voff_range = d_voff_range_from_vaddr_range(module, hover_regs->vaddr_range);
} }
ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f));
+1 -1
View File
@@ -607,7 +607,7 @@ w32_dmn_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block)
} }
//- rjf: unpack features available on this context //- rjf: unpack features available on this context
if (xstate_enabled) if(xstate_enabled)
{ {
SetXStateFeaturesMask(ctx, XSTATE_MASK_AVX | XSTATE_MASK_AVX512 | XSTATE_MASK_CET_U); SetXStateFeaturesMask(ctx, XSTATE_MASK_AVX | XSTATE_MASK_AVX512 | XSTATE_MASK_CET_U);
} }
+6
View File
@@ -0,0 +1,6 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#if defined(X64_H)
# include "win32/x64/win32_x64.c"
#endif
+11
View File
@@ -0,0 +1,11 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef WIN32_INC_H
#define WIN32_INC_H
#if defined(X64_H)
# include "win32/x64/win32_x64.h"
#endif
#endif // WIN32_INC_H
+139
View File
@@ -0,0 +1,139 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal B32
w32_x64_write_reg_block_from_thread_ctx(void *reg_block, void *thread_ctx)
{
X64_RegBlock *dst = (X64_RegBlock *)reg_block;
W32_X64_ThreadContext *src = (W32_X64_ThreadContext *)thread_ctx;
//- rjf: convert context -> X64_RegBlock
W32_X64_XSaveFormat *xsave = &src->FltSave;
dst->rax = src->Rax;
dst->rcx = src->Rcx;
dst->rdx = src->Rdx;
dst->rbx = src->Rbx;
dst->rsp = src->Rsp;
dst->rbp = src->Rbp;
dst->rsi = src->Rsi;
dst->rdi = src->Rdi;
dst->r8 = src->R8;
dst->r9 = src->R9;
dst->r10 = src->R10;
dst->r11 = src->R11;
dst->r12 = src->R12;
dst->r13 = src->R13;
dst->r14 = src->R14;
dst->r15 = src->R15;
dst->rip = src->Rip;
dst->cs = src->SegCs;
dst->ds = src->SegDs;
dst->es = src->SegEs;
dst->fs = src->SegFs;
dst->gs = src->SegGs;
dst->ss = src->SegSs;
dst->dr0 = src->Dr0;
dst->dr1 = src->Dr1;
dst->dr2 = src->Dr2;
dst->dr3 = src->Dr3;
dst->dr6 = src->Dr6;
dst->dr7 = src->Dr7;
// NOTE(rjf): this bit is "supposed to always be 1", according to old info.
// may need to be investigated.
dst->rflags = src->EFlags | 0x2;
dst->fcw = xsave->ControlWord;
dst->fsw = xsave->StatusWord;
dst->ftw = xsave->TagWord;
dst->fop = xsave->ErrorOpcode;
MemoryCopy(&dst->fip, &xsave->ErrorOffset, sizeof(U64));
MemoryCopy(&dst->fdp, &xsave->DataOffset, sizeof(U64));
dst->mxcsr = xsave->MxCsr;
dst->mxcsr_mask = xsave->MxCsr_Mask;
{
U128 *float_s = xsave->FloatRegisters;
U80 *float_d = &dst->st0;
for(U32 n = 0; n < 8; n += 1, float_s += 1, float_d += 1)
{
MemoryCopy(float_d, float_s, sizeof(*float_d));
}
}
{
U128 *xmm_s = xsave->XmmRegisters;
U512 *zmm_d = &dst->zmm0;
for(U32 n = 0; n < 16; n += 1, xmm_s += 1, zmm_d += 1)
{
MemoryCopy(zmm_d, xmm_s, sizeof(*xmm_s));
}
}
// TODO(rjf): we need to determine how to do LocateXStateFeature without
// actually running on Windows - what is that function actually looking at
// & doing?
#if 0
// AVX
{
DWORD avx_length = 0;
U8 *avx_s = (U8 *)LocateXStateFeature(ctx, XSTATE_AVX, &avx_length);
if(avx_length == 16 * sizeof(U128))
{
U512 *zmm_d = &dst->zmm0;
for(U32 n = 0; n < 16; n += 1, avx_s += sizeof(U128), zmm_d += 1)
{
MemoryCopy(&zmm_d->u8[16], avx_s, sizeof(U128));
}
}
}
// AVX-512
{
// rjf: kmask
DWORD kmask_length = 0;
U64 *kmask_s = (U64*)LocateXStateFeature(ctx, XSTATE_AVX512_KMASK, &kmask_length);
if(kmask_length == 8 * sizeof(U64))
{
U64 *kmask_d = &dst->k0;
for(U32 n = 0; n < 8; n += 1, kmask_s += 1, kmask_d += 1)
{
MemoryCopy(kmask_d, kmask_s, sizeof(*kmask_s));
}
}
// rjf: zmmh
DWORD avx512h_length = 0;
U8 *avx512h_s = (U8*)LocateXStateFeature(ctx, XSTATE_AVX512_ZMM_H, &avx512h_length);
if(avx512h_length == 16 * sizeof(U256))
{
U512 *zmmh_d = &dst->zmm0;
for(U32 n = 0; n < 16; n += 1, avx512h_s += sizeof(U256), zmmh_d += 1)
{
MemoryCopy(&zmmh_d->u8[32], avx512h_s, sizeof(U256));
}
}
// rjf: zmm
DWORD avx512_length = 0;
U8 *avx512_s = (U8 *)LocateXStateFeature(ctx, XSTATE_AVX512_ZMM, &avx512_length);
if(avx512_length == 16 * sizeof(U512))
{
U512 *zmm_d = &dst->zmm16;
for(U32 n = 0; n < 16; n += 1, avx512_s += sizeof(U512), zmm_d += 1)
{
MemoryCopy(zmm_d, avx512_s, sizeof(U512));
}
}
}
// CET / Shadow Stack
if(xstate_mask & XSTATE_MASK_CET_U)
{
DWORD cet_length = 0;
XSAVE_CET_U_FORMAT *cet = LocateXStateFeature(ctx, XSTATE_CET_U, &cet_length);
if (cet_length == sizeof(*cet))
{
dst->cetmsr = cet->Ia32CetUMsr;
dst->cetssp = cet->Ia32Pl3SspMsr;
}
}
#endif
return 1;
}
+110
View File
@@ -0,0 +1,110 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef WIN32_X64_H
#define WIN32_X64_H
#pragma pack(push, 1)
typedef struct W32_X64_XSaveFormat W32_X64_XSaveFormat;
struct W32_X64_XSaveFormat
{
U16 ControlWord;
U16 StatusWord;
U8 TagWord;
U8 Reserved1;
U16 ErrorOpcode;
U32 ErrorOffset;
U16 ErrorSelector;
U16 Reserved2;
U32 DataOffset;
U16 DataSelector;
U16 Reserved3;
U32 MxCsr;
U32 MxCsr_Mask;
U128 FloatRegisters[8];
U128 XmmRegisters[16];
U8 Reserved4[96];
};
typedef struct W32_X64_ThreadContext W32_X64_ThreadContext;
struct W32_X64_ThreadContext
{
U64 P1Home;
U64 P2Home;
U64 P3Home;
U64 P4Home;
U64 P5Home;
U64 P6Home;
U32 ContextFlags;
U32 MxCsr;
U16 SegCs;
U16 SegDs;
U16 SegEs;
U16 SegFs;
U16 SegGs;
U16 SegSs;
U32 EFlags;
U64 Dr0;
U64 Dr1;
U64 Dr2;
U64 Dr3;
U64 Dr6;
U64 Dr7;
U64 Rax;
U64 Rcx;
U64 Rdx;
U64 Rbx;
U64 Rsp;
U64 Rbp;
U64 Rsi;
U64 Rdi;
U64 R8;
U64 R9;
U64 R10;
U64 R11;
U64 R12;
U64 R13;
U64 R14;
U64 R15;
U64 Rip;
union
{
W32_X64_XSaveFormat FltSave;
struct
{
U128 Header[2];
U128 Legacy[8];
U128 Xmm0;
U128 Xmm1;
U128 Xmm2;
U128 Xmm3;
U128 Xmm4;
U128 Xmm5;
U128 Xmm6;
U128 Xmm7;
U128 Xmm8;
U128 Xmm9;
U128 Xmm10;
U128 Xmm11;
U128 Xmm12;
U128 Xmm13;
U128 Xmm14;
U128 Xmm15;
U8 padding_0[96];
};
};
U128 VectorRegister[26];
U64 VectorControl;
U64 DebugControl;
U64 LastBranchToRip;
U64 LastBranchFromRip;
U64 LastExceptionToRip;
U64 LastExceptionFromRip;
};
#pragma pack(pop)
internal B32 w32_x64_write_reg_block_from_thread_ctx(void *reg_block, void *thread_ctx);
#endif // WIN32_X64_H