mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
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:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
+513
-182
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
@@ -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,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
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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 = ¶ms->line_infos[line_idx];
|
D_LineList *lines = ¶ms->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));
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user