mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-07-15 22:11:28 -07:00
Merge remote-tracking branch 'EpicGames/dev' into odin
This commit is contained in:
@@ -21,10 +21,10 @@ jobs:
|
||||
run: |
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
|
||||
call build raddbg msvc debug || exit /b 1
|
||||
call build raddbgi_from_pdb msvc debug || exit /b 1
|
||||
call build raddbgi_from_dwarf msvc debug || exit /b 1
|
||||
call build raddbgi_dump msvc debug || exit /b 1
|
||||
call build rdi_from_pdb msvc debug || exit /b 1
|
||||
call build rdi_from_dwarf msvc debug || exit /b 1
|
||||
call build rdi_dump msvc debug || exit /b 1
|
||||
call build raddbg clang debug || exit /b 1
|
||||
call build raddbgi_from_pdb clang debug || exit /b 1
|
||||
call build raddbgi_from_dwarf clang debug || exit /b 1
|
||||
call build raddbgi_dump clang debug || exit /b 1
|
||||
call build rdi_from_pdb clang debug || exit /b 1
|
||||
call build rdi_from_dwarf clang debug || exit /b 1
|
||||
call build rdi_dump clang debug || exit /b 1
|
||||
|
||||
@@ -33,7 +33,8 @@ if "%debug%"=="1" set release=0 && echo [debug mode]
|
||||
if "%release%"=="1" set debug=0 && echo [release mode]
|
||||
if "%msvc%"=="1" set clang=0 && echo [msvc compile]
|
||||
if "%clang%"=="1" set msvc=0 && echo [clang compile]
|
||||
if "%~1"=="" echo [default mode, assuming `raddbg` build] && set raddbg=1
|
||||
if "%~1"=="" echo [default mode, assuming `raddbg` build] && set raddbg=1
|
||||
if "%~1"=="release" if "%~2"=="" echo [default mode, assuming `raddbg` build] && set raddbg=1
|
||||
|
||||
:: --- Unpack Command Line Build Arguments ------------------------------------
|
||||
set auto_compile_flags=
|
||||
@@ -98,18 +99,19 @@ if not "%no_meta%"=="1" (
|
||||
|
||||
:: --- Build Everything (@build_targets) --------------------------------------
|
||||
pushd build
|
||||
if "%raddbg%"=="1" %compile% ..\src\raddbg\raddbg_main.c %compile_link% %out%raddbg.exe || exit /b 1
|
||||
if "%rdi_from_pdb%"=="1" %compile% ..\src\rdi_from_pdb\rdi_from_pdb_main.c %compile_link% %out%rdi_from_pdb.exe || exit /b 1
|
||||
if "%rdi_from_dwarf%"=="1" %compile% ..\src\rdi_from_dwarf\rdi_from_dwarf.c %compile_link% %out%rdi_from_dwarf.exe || exit /b 1
|
||||
if "%rdi_dump%"=="1" %compile% ..\src\rdi_dump\rdi_dump_main.c %compile_link% %out%rdi_dump.exe || exit /b 1
|
||||
if "%rdi_breakpad_from_pdb%"=="1" %compile% ..\src\rdi_breakpad_from_pdb\rdi_breakpad_from_pdb_main.c %compile_link% %out%rdi_breakpad_from_pdb.exe || exit /b 1
|
||||
if "%ryan_scratch%"=="1" %compile% ..\src\scratch\ryan_scratch.c %compile_link% %out%ryan_scratch.exe || exit /b 1
|
||||
if "%cpp_tests%"=="1" %compile% ..\src\scratch\i_hate_c_plus_plus.cpp %compile_link% %out%cpp_tests.exe || exit /b 1
|
||||
if "%look_at_raddbg%"=="1" %compile% ..\src\scratch\look_at_raddbg.c %compile_link% %out%look_at_raddbg.exe || exit /b 1
|
||||
if "%mule_main%"=="1" del vc*.pdb mule*.pdb && %compile_release% %only_compile% ..\src\mule\mule_inline.cpp && %compile_release% %only_compile% ..\src\mule\mule_o2.cpp && %compile_debug% %EHsc% ..\src\mule\mule_main.cpp ..\src\mule\mule_c.c mule_inline.obj mule_o2.obj %compile_link% %no_aslr% %out%mule_main.exe || exit /b 1
|
||||
if "%mule_module%"=="1" %compile% ..\src\mule\mule_module.cpp %compile_link% %link_dll% %out%mule_module.dll || exit /b 1
|
||||
if "%mule_hotload%"=="1" %compile% ..\src\mule\mule_hotload_main.c %compile_link% %out%mule_hotload.exe & %compile% ..\src\mule\mule_hotload_module_main.c %compile_link% %link_dll% %out%mule_hotload_module.dll || exit /b 1
|
||||
if "%raddbg%"=="1" set didbuild=1 && %compile% ..\src\raddbg\raddbg_main.c %compile_link% %out%raddbg.exe || exit /b 1
|
||||
if "%rdi_from_pdb%"=="1" set didbuild=1 && %compile% ..\src\rdi_from_pdb\rdi_from_pdb_main.c %compile_link% %out%rdi_from_pdb.exe || exit /b 1
|
||||
if "%rdi_from_dwarf%"=="1" set didbuild=1 && %compile% ..\src\rdi_from_dwarf\rdi_from_dwarf.c %compile_link% %out%rdi_from_dwarf.exe || exit /b 1
|
||||
if "%rdi_dump%"=="1" set didbuild=1 && %compile% ..\src\rdi_dump\rdi_dump_main.c %compile_link% %out%rdi_dump.exe || exit /b 1
|
||||
if "%rdi_breakpad_from_pdb%"=="1" set didbuild=1 && %compile% ..\src\rdi_breakpad_from_pdb\rdi_breakpad_from_pdb_main.c %compile_link% %out%rdi_breakpad_from_pdb.exe || exit /b 1
|
||||
if "%ryan_scratch%"=="1" set didbuild=1 && %compile% ..\src\scratch\ryan_scratch.c %compile_link% %out%ryan_scratch.exe || exit /b 1
|
||||
if "%cpp_tests%"=="1" set didbuild=1 && %compile% ..\src\scratch\i_hate_c_plus_plus.cpp %compile_link% %out%cpp_tests.exe || exit /b 1
|
||||
if "%look_at_raddbg%"=="1" set didbuild=1 && %compile% ..\src\scratch\look_at_raddbg.c %compile_link% %out%look_at_raddbg.exe || exit /b 1
|
||||
if "%mule_main%"=="1" set didbuild=1 && del vc*.pdb mule*.pdb && %compile_release% %only_compile% ..\src\mule\mule_inline.cpp && %compile_release% %only_compile% ..\src\mule\mule_o2.cpp && %compile_debug% %EHsc% ..\src\mule\mule_main.cpp ..\src\mule\mule_c.c mule_inline.obj mule_o2.obj %compile_link% %no_aslr% %out%mule_main.exe || exit /b 1
|
||||
if "%mule_module%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_module.cpp %compile_link% %link_dll% %out%mule_module.dll || exit /b 1
|
||||
if "%mule_hotload%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_hotload_main.c %compile_link% %out%mule_hotload.exe & %compile% ..\src\mule\mule_hotload_module_main.c %compile_link% %link_dll% %out%mule_hotload_module.dll || exit /b 1
|
||||
if "%mule_peb_trample%"=="1" (
|
||||
set didbuild=1
|
||||
if exist mule_peb_trample.exe move mule_peb_trample.exe mule_peb_trample_old_%random%.exe
|
||||
if exist mule_peb_trample_new.pdb move mule_peb_trample_new.pdb mule_peb_trample_old_%random%.pdb
|
||||
if exist mule_peb_trample_new.rdi move mule_peb_trample_new.rdi mule_peb_trample_old_%random%.rdi
|
||||
@@ -126,3 +128,10 @@ set compile_link=
|
||||
set out=
|
||||
set msvc=
|
||||
set debug=
|
||||
set release=
|
||||
|
||||
:: --- Warn On No Builds ------------------------------------------------------
|
||||
if "%didbuild%"=="" (
|
||||
echo [WARNING] no valid build target specified; must use build target names as arguments to this script, like `build raddbg` or `build rdi_from_pdb`.
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
+4
-1
@@ -90,7 +90,10 @@ log_scope_end(Arena *arena)
|
||||
{
|
||||
for(EachEnumVal(LogMsgKind, kind))
|
||||
{
|
||||
result.strings[kind] = str8_list_join(arena, &scope->strings[kind], 0);
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
String8 result_unindented = str8_list_join(scratch.arena, &scope->strings[kind], 0);
|
||||
result.strings[kind] = indented_from_string(arena, result_unindented);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
}
|
||||
arena_pop_to(log_active->arena, scope->pos);
|
||||
|
||||
@@ -53,6 +53,9 @@ internal void log_msgf(LogMsgKind kind, char *fmt, ...);
|
||||
#define log_user_error(s) log_msg(LogMsgKind_UserError, (s))
|
||||
#define log_user_errorf(fmt, ...) log_msgf(LogMsgKind_UserError, (fmt), __VA_ARGS__)
|
||||
|
||||
#define LogInfoNamedBlock(s) DeferLoop(log_infof("%S:\n{\n", (s)), log_infof("}\n"))
|
||||
#define LogInfoNamedBlockF(fmt, ...) DeferLoop((log_infof(fmt, __VA_ARGS__), log_infof(":\n{\n")), log_infof("}\n"))
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Log Scopes
|
||||
|
||||
|
||||
@@ -2,20 +2,20 @@
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
internal void
|
||||
thread_name(String8 string)
|
||||
set_thread_name(String8 string)
|
||||
{
|
||||
ProfThreadName("%.*s", str8_varg(string));
|
||||
os_set_thread_name(string);
|
||||
}
|
||||
|
||||
internal void
|
||||
thread_namef(char *fmt, ...)
|
||||
set_thread_namef(char *fmt, ...)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
String8 string = push_str8fv(scratch.arena, fmt, args);
|
||||
thread_name(string);
|
||||
set_thread_name(string);
|
||||
va_end(args);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
#ifndef BASE_MARKUP_H
|
||||
#define BASE_MARKUP_H
|
||||
|
||||
internal void thread_name(String8 string);
|
||||
internal void thread_namef(char *fmt, ...);
|
||||
#define ThreadNameF(...) (ProfThreadName(__VA_ARGS__), thread_namef(__VA_ARGS__))
|
||||
#define ThreadName(str) (ProfThreadName("%.*s", str8_varg(str)), thread_name(str))
|
||||
internal void set_thread_name(String8 string);
|
||||
internal void set_thread_namef(char *fmt, ...);
|
||||
#define ThreadNameF(...) (set_thread_namef(__VA_ARGS__))
|
||||
#define ThreadName(str) (set_thread_name(str))
|
||||
|
||||
#endif // BASE_MARKUP_H
|
||||
|
||||
+39
-1
@@ -1566,7 +1566,45 @@ string_from_elapsed_time(Arena *arena, DateTime dt){
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Textual String Wrapping
|
||||
//~ rjf: Basic Text Indentation
|
||||
|
||||
internal String8
|
||||
indented_from_string(Arena *arena, String8 string)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
read_only local_persist U8 indentation_bytes[] = " ";
|
||||
String8List indented_strings = {0};
|
||||
S64 depth = 0;
|
||||
S64 next_depth = 0;
|
||||
U64 line_begin_off = 0;
|
||||
for(U64 off = 0; off <= string.size; off += 1)
|
||||
{
|
||||
U8 byte = off<string.size ? string.str[off] : 0;
|
||||
switch(byte)
|
||||
{
|
||||
default:{}break;
|
||||
case '{':case '[':case '(':{next_depth += 1; next_depth = Max(0, next_depth);}break;
|
||||
case '}':case ']':case ')':{next_depth -= 1; next_depth = Max(0, next_depth); depth = next_depth;}break;
|
||||
case '\n':
|
||||
case 0:
|
||||
{
|
||||
String8 line = str8_skip_chop_whitespace(str8_substr(string, r1u64(line_begin_off, off)));
|
||||
if(line.size != 0)
|
||||
{
|
||||
str8_list_pushf(scratch.arena, &indented_strings, "%.*s%S\n", (int)depth*2, indentation_bytes, line);
|
||||
}
|
||||
line_begin_off = off+1;
|
||||
depth = next_depth;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
String8 result = str8_list_join(arena, &indented_strings, 0);
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Text Wrapping
|
||||
|
||||
internal String8List
|
||||
wrapped_lines_from_string(Arena *arena, String8 string, U64 first_line_max_width, U64 max_width, U64 wrap_indent)
|
||||
|
||||
@@ -327,7 +327,12 @@ internal String8 push_file_name_date_time_string(Arena *arena, DateTime *date_ti
|
||||
internal String8 string_from_elapsed_time(Arena *arena, DateTime dt);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Textual String Wrapping
|
||||
//~ rjf: Basic Text Indentation
|
||||
|
||||
internal String8 indented_from_string(Arena *arena, String8 string);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Text Wrapping
|
||||
|
||||
internal String8List wrapped_lines_from_string(Arena *arena, String8 string, U64 first_line_max_width, U64 max_width, U64 wrap_indent);
|
||||
|
||||
|
||||
+314
-187
@@ -43,6 +43,34 @@ ctrl_event_cause_from_dmn_event_kind(DMN_EventKind event_kind)
|
||||
return cause;
|
||||
}
|
||||
|
||||
internal String8
|
||||
ctrl_string_from_event_kind(CTRL_EventKind kind)
|
||||
{
|
||||
String8 result = {0};
|
||||
switch(kind)
|
||||
{
|
||||
default:{}break;
|
||||
case CTRL_EventKind_Null: { result = str8_lit("Null");}break;
|
||||
case CTRL_EventKind_Error: { result = str8_lit("Error");}break;
|
||||
case CTRL_EventKind_Started: { result = str8_lit("Started");}break;
|
||||
case CTRL_EventKind_Stopped: { result = str8_lit("Stopped");}break;
|
||||
case CTRL_EventKind_NewProc: { result = str8_lit("NewProc");}break;
|
||||
case CTRL_EventKind_NewThread: { result = str8_lit("NewThread");}break;
|
||||
case CTRL_EventKind_NewModule: { result = str8_lit("NewModule");}break;
|
||||
case CTRL_EventKind_EndProc: { result = str8_lit("EndProc");}break;
|
||||
case CTRL_EventKind_EndThread: { result = str8_lit("EndThread");}break;
|
||||
case CTRL_EventKind_EndModule: { result = str8_lit("EndModule");}break;
|
||||
case CTRL_EventKind_ModuleDebugInfoPathChange: { result = str8_lit("ModuleDebugInfoPathChange");}break;
|
||||
case CTRL_EventKind_DebugString: { result = str8_lit("DebugString");}break;
|
||||
case CTRL_EventKind_ThreadName: { result = str8_lit("ThreadName");}break;
|
||||
case CTRL_EventKind_MemReserve: { result = str8_lit("MemReserve");}break;
|
||||
case CTRL_EventKind_MemCommit: { result = str8_lit("MemCommit");}break;
|
||||
case CTRL_EventKind_MemDecommit: { result = str8_lit("MemDecommit");}break;
|
||||
case CTRL_EventKind_MemRelease: { result = str8_lit("MemRelease");}break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
ctrl_string_from_msg_kind(CTRL_MsgKind kind)
|
||||
{
|
||||
@@ -1524,6 +1552,18 @@ ctrl_query_cached_rip_from_thread(CTRL_EntityStore *store, CTRL_MachineID machin
|
||||
return result;
|
||||
}
|
||||
|
||||
internal U64
|
||||
ctrl_query_cached_rsp_from_thread(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle thread)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
CTRL_Entity *thread_entity = ctrl_entity_from_machine_id_handle(store, machine_id, thread);
|
||||
Architecture arch = thread_entity->arch;
|
||||
void *block = ctrl_query_cached_reg_block_from_thread(scratch.arena, store, machine_id, thread);
|
||||
U64 result = regs_rsp_from_arch_block(arch, block);
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
//- rjf: thread register writing
|
||||
|
||||
internal B32
|
||||
@@ -2612,7 +2652,8 @@ ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_MachineID ma
|
||||
unwind.flags |= step.flags;
|
||||
if(step.flags & CTRL_UnwindFlag_Error ||
|
||||
regs_rsp_from_arch_block(arch, regs_block) == 0 ||
|
||||
regs_rip_from_arch_block(arch, regs_block) == 0)
|
||||
regs_rip_from_arch_block(arch, regs_block) == 0 ||
|
||||
regs_rip_from_arch_block(arch, regs_block) == rip)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -2846,7 +2887,7 @@ ctrl_thread__entry_point(void *p)
|
||||
{
|
||||
CTRL_Msg *msg = &msg_n->v;
|
||||
{
|
||||
log_infof("[user -> ctrl %S message]\n", ctrl_string_from_msg_kind(msg->kind));
|
||||
log_infof("user2ctrl_msg:{kind:\"%S\"}\n", ctrl_string_from_msg_kind(msg->kind));
|
||||
}
|
||||
MemoryCopyArray(ctrl_state->exception_code_filters, msg->exception_code_filters);
|
||||
switch(msg->kind)
|
||||
@@ -2881,6 +2922,7 @@ ctrl_thread__entry_point(void *p)
|
||||
di_close(&old_dbgi_key);
|
||||
ctrl_entity_equip_string(ctrl_state->ctrl_thread_entity_store, debug_info_path, path);
|
||||
U64 new_dbgi_timestamp = os_properties_from_file_path(path).modified;
|
||||
debug_info_path->timestamp = new_dbgi_timestamp;
|
||||
DI_Key new_dbgi_key = {debug_info_path->string, new_dbgi_timestamp};
|
||||
di_open(&new_dbgi_key);
|
||||
CTRL_EventList evts = {0};
|
||||
@@ -2889,6 +2931,7 @@ ctrl_thread__entry_point(void *p)
|
||||
evt->machine_id = msg->machine_id;
|
||||
evt->entity = msg->entity;
|
||||
evt->string = path;
|
||||
evt->timestamp = new_dbgi_timestamp;
|
||||
ctrl_c2u_push_events(&evts);
|
||||
}break;
|
||||
}
|
||||
@@ -3304,7 +3347,7 @@ ctrl_thread__module_open(CTRL_MachineID machine_id, DMN_Handle process, DMN_Hand
|
||||
}
|
||||
|
||||
internal void
|
||||
ctrl_thread__module_close(CTRL_MachineID machine_id, DMN_Handle module, String8 path)
|
||||
ctrl_thread__module_close(CTRL_MachineID machine_id, DMN_Handle module)
|
||||
{
|
||||
//////////////////////////////
|
||||
//- rjf: evict module image info from cache
|
||||
@@ -3333,19 +3376,6 @@ ctrl_thread__module_close(CTRL_MachineID machine_id, DMN_Handle module, String8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: close debug info
|
||||
//
|
||||
{
|
||||
CTRL_Entity *module_ent = ctrl_entity_from_machine_id_handle(ctrl_state->ctrl_thread_entity_store, machine_id, module);
|
||||
CTRL_Entity *debug_info_path_ent = ctrl_entity_child_from_kind(module_ent, CTRL_EntityKind_DebugInfoPath);
|
||||
if(debug_info_path_ent != &ctrl_entity_nil)
|
||||
{
|
||||
DI_Key dbgi_key = {debug_info_path_ent->string, debug_info_path_ent->timestamp};
|
||||
di_close(&dbgi_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: attached process running/event gathering
|
||||
@@ -3368,19 +3398,21 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg,
|
||||
DMN_EventNode *next_event_node = ctrl_state->first_dmn_event_node;
|
||||
|
||||
// rjf: log event
|
||||
if(next_event_node != 0) CTRL_CtrlThreadLogScope
|
||||
if(next_event_node != 0)
|
||||
{
|
||||
DMN_Event *ev = &next_event_node->v;
|
||||
log_infof("--- event ---\n");
|
||||
log_infof("kind: %S\n", dmn_event_kind_string_table[ev->kind]);
|
||||
log_infof("exception_kind: %S\n", dmn_exception_kind_string_table[ev->exception_kind]);
|
||||
log_infof("process: [%I64u]\n", ev->process.u64[0]);
|
||||
log_infof("thread: [%I64u]\n", ev->thread.u64[0]);
|
||||
log_infof("module: [%I64u]\n", ev->module.u64[0]);
|
||||
log_infof("arch: %S\n", string_from_architecture(ev->arch));
|
||||
log_infof("address: 0x%I64x\n", ev->address);
|
||||
log_infof("string: \"%S\"\n", ev->string);
|
||||
log_infof("ip_vaddr: 0x%I64x\n", ev->instruction_pointer);
|
||||
LogInfoNamedBlockF("dmn_event")
|
||||
{
|
||||
log_infof("kind: %S\n", dmn_event_kind_string_table[ev->kind]);
|
||||
log_infof("exception_kind: %S\n", dmn_exception_kind_string_table[ev->exception_kind]);
|
||||
log_infof("process: [%I64u]\n", ev->process.u64[0]);
|
||||
log_infof("thread: [%I64u]\n", ev->thread.u64[0]);
|
||||
log_infof("module: [%I64u]\n", ev->module.u64[0]);
|
||||
log_infof("arch: %S\n", string_from_architecture(ev->arch));
|
||||
log_infof("address: 0x%I64x\n", ev->address);
|
||||
log_infof("string: \"%S\"\n", ev->string);
|
||||
log_infof("ip_vaddr: 0x%I64x\n", ev->instruction_pointer);
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: determine if we should filter
|
||||
@@ -3532,9 +3564,27 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg,
|
||||
// rjf: run for new events
|
||||
ProfScope("run for new events")
|
||||
{
|
||||
CTRL_CtrlThreadLogScope log_infof("{dmn_ctrl_run ...");
|
||||
LogInfoNamedBlockF("dmn_ctrl_run")
|
||||
{
|
||||
log_infof("single_step_thread: [0x%I64x]\n", run_ctrls->single_step_thread);
|
||||
log_infof("ignore_previous_exception: %i\n", !!run_ctrls->ignore_previous_exception);
|
||||
log_infof("run_entities_are_unfrozen: %i\n", !!run_ctrls->run_entities_are_unfrozen);
|
||||
log_infof("run_entities_are_processes: %i\n", !!run_ctrls->run_entities_are_processes);
|
||||
log_infof("run_entity_count: %I64u\n", run_ctrls->run_entity_count);
|
||||
LogInfoNamedBlockF("run_entities") for(U64 idx = 0; idx < run_ctrls->run_entity_count; idx += 1)
|
||||
{
|
||||
log_infof("[0x%I64x]\n", run_ctrls->run_entities[idx]);
|
||||
}
|
||||
log_infof("trap_count: %I64u\n", run_ctrls->traps.trap_count);
|
||||
LogInfoNamedBlockF("traps") for(DMN_TrapChunkNode *n = run_ctrls->traps.first; n != 0; n = n->next)
|
||||
{
|
||||
for(U64 idx = 0; idx < n->count; idx += 1)
|
||||
{
|
||||
log_infof("{process:[0x%I64x], vaddr:0x%I64x, id:0x%I64x}\n", n->v[idx].process.u64[0], n->v[idx].vaddr, n->v[idx].id);
|
||||
}
|
||||
}
|
||||
}
|
||||
DMN_EventList events = dmn_ctrl_run(scratch.arena, ctrl_ctx, run_ctrls);
|
||||
CTRL_CtrlThreadLogScope log_infof("}\n");
|
||||
for(DMN_EventNode *src_n = events.first; src_n != 0; src_n = src_n->next)
|
||||
{
|
||||
DMN_EventNode *dst_n = ctrl_state->free_dmn_event_node;
|
||||
@@ -3573,7 +3623,7 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg,
|
||||
if(spoof_thread_rip == spoof->new_ip_value)
|
||||
{
|
||||
regs_arch_block_write_rip(arch, regs_block, spoof_old_ip_value);
|
||||
dmn_thread_write_reg_block(spoof->thread, regs_block);
|
||||
ctrl_thread_write_reg_block(CTRL_MachineID_Local, spoof->thread, regs_block);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3661,12 +3711,19 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg,
|
||||
{
|
||||
CTRL_Event *out_evt = ctrl_event_list_push(scratch.arena, &evts);
|
||||
String8 module_path = event->string;
|
||||
ctrl_thread__module_close(CTRL_MachineID_Local, event->module, module_path);
|
||||
ctrl_thread__module_close(CTRL_MachineID_Local, event->module);
|
||||
out_evt->kind = CTRL_EventKind_EndModule;
|
||||
out_evt->msg_id = msg->msg_id;
|
||||
out_evt->machine_id = CTRL_MachineID_Local;
|
||||
out_evt->entity = event->module;
|
||||
out_evt->string = module_path;
|
||||
CTRL_Entity *module_ent = ctrl_entity_from_machine_id_handle(ctrl_state->ctrl_thread_entity_store, CTRL_MachineID_Local, event->module);
|
||||
CTRL_Entity *debug_info_path_ent = ctrl_entity_child_from_kind(module_ent, CTRL_EntityKind_DebugInfoPath);
|
||||
if(debug_info_path_ent != &ctrl_entity_nil)
|
||||
{
|
||||
DI_Key dbgi_key = {debug_info_path_ent->string, debug_info_path_ent->timestamp};
|
||||
di_close(&dbgi_key);
|
||||
}
|
||||
}break;
|
||||
case DMN_EventKind_DebugString:
|
||||
{
|
||||
@@ -3949,7 +4006,9 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
CTRL_EventCause stop_cause = CTRL_EventCause_Null;
|
||||
DMN_Handle target_thread = msg->entity;
|
||||
DMN_Handle target_process = msg->parent;
|
||||
CTRL_Entity *target_process_entity = ctrl_entity_from_machine_id_handle(ctrl_state->ctrl_thread_entity_store, msg->machine_id, target_process);
|
||||
U64 spoof_ip_vaddr = 911;
|
||||
log_infof("ctrl_thread__run:\n{\n");
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: gather all initial breakpoints
|
||||
@@ -3984,6 +4043,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
// causes e.g. entrance into a function via a call instruction.
|
||||
//
|
||||
U64 sp_check_value = dmn_rsp_from_thread(target_thread);
|
||||
log_infof("sp_check_value := 0x%I64x\n", sp_check_value);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: single step "stuck threads"
|
||||
@@ -4068,11 +4128,22 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
node != 0;
|
||||
node = node->next)
|
||||
{
|
||||
DMN_RunCtrls run_ctrls = {0};
|
||||
run_ctrls.single_step_thread = node->v;
|
||||
for(B32 done = 0; done == 0;)
|
||||
DMN_Handle thread = node->v;
|
||||
U64 thread_pre_rip = dmn_rip_from_thread(thread);
|
||||
U64 thread_post_rip = thread_pre_rip;
|
||||
for(B32 done = 0; !done;)
|
||||
{
|
||||
log_infof("single_step_stuck_thread([0x%I64x])\n", thread.u64[0]);
|
||||
DMN_RunCtrls run_ctrls = {0};
|
||||
run_ctrls.run_entities_are_unfrozen = 1;
|
||||
run_ctrls.run_entities = &thread;
|
||||
run_ctrls.run_entity_count = 1;
|
||||
if(thread_post_rip == thread_pre_rip)
|
||||
{
|
||||
run_ctrls.single_step_thread = thread;
|
||||
}
|
||||
DMN_Event *event = ctrl_thread__next_dmn_event(scratch.arena, ctrl_ctx, msg, &run_ctrls, 0);
|
||||
thread_post_rip = dmn_rip_from_thread(thread);
|
||||
switch(event->kind)
|
||||
{
|
||||
default:{}break;
|
||||
@@ -4087,7 +4158,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
}break;
|
||||
case DMN_EventKind_SingleStep:
|
||||
{
|
||||
done = 1;
|
||||
done = dmn_handle_match(node->v, event->thread);
|
||||
}break;
|
||||
}
|
||||
}
|
||||
@@ -4173,9 +4244,11 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
run_ctrls.traps = *trap_list;
|
||||
|
||||
//////////////////////////
|
||||
//- rjf: get next event
|
||||
//- rjf: get next run-related event
|
||||
//
|
||||
log_infof("get_next_event:\n{\n");
|
||||
DMN_Event *event = ctrl_thread__next_dmn_event(scratch.arena, ctrl_ctx, msg, &run_ctrls, run_spoof);
|
||||
log_infof("}\n\n");
|
||||
|
||||
//////////////////////////
|
||||
//- rjf: determine event handling
|
||||
@@ -4184,7 +4257,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
B32 hard_stop = 0;
|
||||
CTRL_EventCause hard_stop_cause = ctrl_event_cause_from_dmn_event_kind(event->kind);
|
||||
B32 use_stepping_logic = 0;
|
||||
CTRL_CtrlThreadLogScope switch(event->kind)
|
||||
switch(event->kind)
|
||||
{
|
||||
default:{}break;
|
||||
case DMN_EventKind_Error:
|
||||
@@ -4193,27 +4266,29 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
case DMN_EventKind_Trap:
|
||||
{
|
||||
hard_stop = 1;
|
||||
log_infof(">>> stepping >>> hard stop\n");
|
||||
log_infof("step_rule: unexpected -> hard_stop\n");
|
||||
}break;
|
||||
case DMN_EventKind_Exception:
|
||||
case DMN_EventKind_Breakpoint:
|
||||
{
|
||||
use_stepping_logic = 1;
|
||||
log_infof(">>> stepping >>> exception or breakpoint - begin stepping logic\n");
|
||||
log_infof("step_rule: exception/breakpoint -> stepping_logic\n");
|
||||
}break;
|
||||
case DMN_EventKind_CreateProcess:
|
||||
{
|
||||
DMN_TrapChunkList new_traps = {0};
|
||||
ctrl_thread__append_resolved_process_user_bp_traps(scratch.arena, CTRL_MachineID_Local, event->process, &msg->user_bps, &new_traps);
|
||||
log_infof(">>> stepping >>> create process -> resolve new BPs\n");
|
||||
log_infof("step_rule: create_process -> resolve traps\n");
|
||||
log_infof("new_traps:\n{\n");
|
||||
for(DMN_TrapChunkNode *n = new_traps.first; n != 0; n = n->next)
|
||||
{
|
||||
for(U64 idx = 0; idx < n->count; idx += 1)
|
||||
{
|
||||
DMN_Trap *trap = &n->v[idx];
|
||||
log_infof(" trap: {process:%I64d, vaddr:0x%I64x}\n", trap->process.u64[0], trap->vaddr);
|
||||
log_infof("{process:[0x%I64x], vaddr:0x%I64x}\n", trap->process.u64[0], trap->vaddr);
|
||||
}
|
||||
}
|
||||
log_infof("}\n\n");
|
||||
dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &joined_traps, &new_traps);
|
||||
dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &user_traps, &new_traps);
|
||||
}break;
|
||||
@@ -4221,9 +4296,19 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
{
|
||||
DMN_TrapChunkList new_traps = {0};
|
||||
ctrl_thread__append_resolved_module_user_bp_traps(scratch.arena, CTRL_MachineID_Local, event->process, event->module, &msg->user_bps, &new_traps);
|
||||
log_infof("step_rule: load_module -> resolve traps\n");
|
||||
log_infof("new_traps:\n{\n");
|
||||
for(DMN_TrapChunkNode *n = new_traps.first; n != 0; n = n->next)
|
||||
{
|
||||
for(U64 idx = 0; idx < n->count; idx += 1)
|
||||
{
|
||||
DMN_Trap *trap = &n->v[idx];
|
||||
log_infof("{process:[0x%I64x], vaddr:0x%I64x}\n", trap->process.u64[0], trap->vaddr);
|
||||
}
|
||||
}
|
||||
log_infof("}\n\n");
|
||||
dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &joined_traps, &new_traps);
|
||||
dmn_trap_chunk_list_concat_shallow_copy(scratch.arena, &user_traps, &new_traps);
|
||||
log_infof(">>> stepping >>> load module -> resolve new BPs\n");
|
||||
}break;
|
||||
}
|
||||
|
||||
@@ -4458,35 +4543,32 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
//{
|
||||
|
||||
//////////////////////////
|
||||
//- rjf: handle if hitting a spoof or baked in trap
|
||||
//- rjf: handle if hitting a spoof
|
||||
//
|
||||
B32 hit_spoof = 0;
|
||||
B32 exception_stop = 0;
|
||||
if(!hard_stop && use_stepping_logic)
|
||||
B32 hit_spoof = 0;
|
||||
if(!hard_stop && use_stepping_logic && event->kind == DMN_EventKind_Exception)
|
||||
{
|
||||
if(event->kind == DMN_EventKind_Exception)
|
||||
if(spoof_mode &&
|
||||
dmn_handle_match(target_process, event->process) &&
|
||||
dmn_handle_match(target_thread, event->thread) &&
|
||||
spoof.new_ip_value == event->instruction_pointer)
|
||||
{
|
||||
// rjf: spoof check
|
||||
if(spoof_mode &&
|
||||
dmn_handle_match(target_process, event->process) &&
|
||||
dmn_handle_match(target_thread, event->thread) &&
|
||||
spoof.new_ip_value == event->instruction_pointer)
|
||||
{
|
||||
hit_spoof = 1;
|
||||
}
|
||||
|
||||
// rjf: other exceptions cause stop
|
||||
if(!hit_spoof)
|
||||
{
|
||||
exception_stop = 1;
|
||||
use_stepping_logic = 0;
|
||||
}
|
||||
hit_spoof = 1;
|
||||
log_infof("hit_spoof\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
exception_stop = 1;
|
||||
use_stepping_logic = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: handle spoof hit
|
||||
if(hit_spoof)
|
||||
{
|
||||
log_infof("exit_spoof_mode\n");
|
||||
|
||||
// rjf: clear spoof mode
|
||||
spoof_mode = 0;
|
||||
MemoryZeroStruct(&spoof);
|
||||
@@ -4501,120 +4583,123 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
B32 hit_trap_net_bp = 0;
|
||||
B32 hit_conditional_bp_but_filtered = 0;
|
||||
CTRL_TrapFlags hit_trap_flags = 0;
|
||||
if(!hard_stop && use_stepping_logic) CTRL_CtrlThreadLogScope
|
||||
if(!hard_stop && use_stepping_logic && event->kind == DMN_EventKind_Breakpoint)
|
||||
ProfScope("for breakpoint events, gather bp info")
|
||||
{
|
||||
if(event->kind == DMN_EventKind_Breakpoint)
|
||||
Temp temp = temp_begin(scratch.arena);
|
||||
String8List conditions = {0};
|
||||
|
||||
// rjf: entry breakpoints
|
||||
for(DMN_TrapChunkNode *n = entry_traps.first; n != 0; n = n->next)
|
||||
{
|
||||
Temp temp = temp_begin(scratch.arena);
|
||||
String8List conditions = {0};
|
||||
|
||||
// rjf: entry breakpoints
|
||||
for(DMN_TrapChunkNode *n = entry_traps.first; n != 0; n = n->next)
|
||||
DMN_Trap *trap = n->v;
|
||||
DMN_Trap *opl = n->v + n->count;
|
||||
for(;trap < opl; trap += 1)
|
||||
{
|
||||
DMN_Trap *trap = n->v;
|
||||
DMN_Trap *opl = n->v + n->count;
|
||||
for(;trap < opl; trap += 1)
|
||||
if(dmn_handle_match(trap->process, event->process) && trap->vaddr == event->instruction_pointer)
|
||||
{
|
||||
if(dmn_handle_match(trap->process, event->process) && trap->vaddr == event->instruction_pointer)
|
||||
hit_entry = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: user breakpoints
|
||||
for(DMN_TrapChunkNode *n = user_traps.first; n != 0; n = n->next)
|
||||
{
|
||||
DMN_Trap *trap = n->v;
|
||||
DMN_Trap *opl = n->v + n->count;
|
||||
for(;trap < opl; trap += 1)
|
||||
{
|
||||
if(dmn_handle_match(trap->process, event->process) &&
|
||||
trap->vaddr == event->instruction_pointer &&
|
||||
(!dmn_handle_match(event->thread, target_thread) || !target_thread_is_on_user_bp_and_trap_net_trap))
|
||||
{
|
||||
CTRL_UserBreakpoint *user_bp = (CTRL_UserBreakpoint *)trap->id;
|
||||
hit_user_bp = 1;
|
||||
if(user_bp != 0 && user_bp->condition.size != 0)
|
||||
{
|
||||
hit_entry = 1;
|
||||
str8_list_push(temp.arena, &conditions, user_bp->condition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: user breakpoints
|
||||
for(DMN_TrapChunkNode *n = user_traps.first; n != 0; n = n->next)
|
||||
}
|
||||
|
||||
// rjf: evaluate hit stop conditions
|
||||
if(conditions.node_count != 0) ProfScope("evaluate hit stop conditions")
|
||||
{
|
||||
DI_Key dbgi_key = {dbg_path->string, dbg_path->timestamp};
|
||||
RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, max_U64);
|
||||
for(String8Node *condition_n = conditions.first; condition_n != 0; condition_n = condition_n->next)
|
||||
{
|
||||
DMN_Trap *trap = n->v;
|
||||
DMN_Trap *opl = n->v + n->count;
|
||||
for(;trap < opl; trap += 1)
|
||||
ProfBegin("compile expression");
|
||||
String8 string = condition_n->string;
|
||||
EVAL_ParseCtx parse_ctx = zero_struct;
|
||||
{
|
||||
if(dmn_handle_match(trap->process, event->process) &&
|
||||
trap->vaddr == event->instruction_pointer &&
|
||||
(!dmn_handle_match(event->thread, target_thread) || !target_thread_is_on_user_bp_and_trap_net_trap))
|
||||
{
|
||||
CTRL_UserBreakpoint *user_bp = (CTRL_UserBreakpoint *)trap->id;
|
||||
hit_user_bp = 1;
|
||||
if(user_bp != 0 && user_bp->condition.size != 0)
|
||||
{
|
||||
str8_list_push(temp.arena, &conditions, user_bp->condition);
|
||||
}
|
||||
}
|
||||
parse_ctx.arch = arch;
|
||||
parse_ctx.ip_voff = thread_rip_voff;
|
||||
parse_ctx.rdi = rdi;
|
||||
parse_ctx.type_graph = tg_graph_begin(bit_size_from_arch(arch)/8, 256);
|
||||
parse_ctx.regs_map = ctrl_string2reg_from_arch(arch);
|
||||
parse_ctx.reg_alias_map = ctrl_string2alias_from_arch(arch);
|
||||
parse_ctx.locals_map = eval_push_locals_map_from_rdi_voff(temp.arena, rdi, thread_rip_voff);
|
||||
parse_ctx.member_map = eval_push_member_map_from_rdi_voff(temp.arena, rdi, thread_rip_voff);
|
||||
}
|
||||
EVAL_TokenArray tokens = eval_token_array_from_text(temp.arena, string);
|
||||
EVAL_ParseResult parse = eval_parse_expr_from_text_tokens(temp.arena, &parse_ctx, string, &tokens);
|
||||
EVAL_ErrorList errors = parse.errors;
|
||||
B32 parse_has_expr = (parse.expr != &eval_expr_nil);
|
||||
B32 parse_is_type = (parse_has_expr && parse.expr->kind == EVAL_ExprKind_TypeIdent);
|
||||
EVAL_IRTreeAndType ir_tree_and_type = {&eval_irtree_nil};
|
||||
if(parse_has_expr && errors.count == 0)
|
||||
{
|
||||
ir_tree_and_type = eval_irtree_and_type_from_expr(temp.arena, parse_ctx.type_graph, rdi, &eval_string2expr_map_nil, parse.expr, &errors);
|
||||
}
|
||||
EVAL_OpList op_list = {0};
|
||||
if(parse_has_expr && ir_tree_and_type.tree != &eval_irtree_nil)
|
||||
{
|
||||
eval_oplist_from_irtree(scratch.arena, ir_tree_and_type.tree, &op_list);
|
||||
}
|
||||
String8 bytecode = {0};
|
||||
if(parse_has_expr && parse_is_type == 0 && op_list.encoded_size != 0)
|
||||
{
|
||||
bytecode = eval_bytecode_from_oplist(scratch.arena, &op_list);
|
||||
}
|
||||
ProfEnd();
|
||||
EVAL_Result eval = {0};
|
||||
if(bytecode.size != 0) ProfScope("evaluate expression")
|
||||
{
|
||||
U64 module_base = module->vaddr_range.min;
|
||||
U64 tls_base = dmn_tls_root_vaddr_from_thread(event->thread);
|
||||
EVAL_Machine machine = {0};
|
||||
machine.u = &event->process;
|
||||
machine.arch = arch;
|
||||
machine.memory_read = ctrl_eval_memory_read;
|
||||
machine.reg_size = regs_block_size_from_architecture(arch);
|
||||
machine.reg_data = push_array(scratch.arena, U8, machine.reg_size);
|
||||
dmn_thread_read_reg_block(event->thread, machine.reg_data);
|
||||
machine.module_base = &module_base;
|
||||
machine.tls_base = &tls_base;
|
||||
eval = eval_interpret(&machine, bytecode);
|
||||
}
|
||||
if(eval.code == EVAL_ResultCode_Good && eval.value.u64 == 0)
|
||||
{
|
||||
hit_user_bp = 0;
|
||||
hit_conditional_bp_but_filtered = 1;
|
||||
log_infof("conditional_breakpoint_hit: 'condition eval'd to 0, and so filtered'\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
hit_user_bp = 1;
|
||||
hit_conditional_bp_but_filtered = 0;
|
||||
log_infof("conditional_breakpoint_hit: 'conditional eval'd to nonzero, hit'\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: evaluate hit stop conditions
|
||||
if(conditions.node_count != 0)
|
||||
{
|
||||
DI_Key dbgi_key = {dbg_path->string, dbg_path->timestamp};
|
||||
RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi_key, max_U64);
|
||||
for(String8Node *condition_n = conditions.first; condition_n != 0; condition_n = condition_n->next)
|
||||
{
|
||||
String8 string = condition_n->string;
|
||||
EVAL_ParseCtx parse_ctx = zero_struct;
|
||||
{
|
||||
parse_ctx.arch = arch;
|
||||
parse_ctx.ip_voff = thread_rip_voff;
|
||||
parse_ctx.rdi = rdi;
|
||||
parse_ctx.type_graph = tg_graph_begin(bit_size_from_arch(arch)/8, 256);
|
||||
parse_ctx.regs_map = ctrl_string2reg_from_arch(arch);
|
||||
parse_ctx.reg_alias_map = ctrl_string2alias_from_arch(arch);
|
||||
parse_ctx.locals_map = eval_push_locals_map_from_rdi_voff(temp.arena, rdi, thread_rip_voff);
|
||||
parse_ctx.member_map = eval_push_member_map_from_rdi_voff(temp.arena, rdi, thread_rip_voff);
|
||||
}
|
||||
EVAL_TokenArray tokens = eval_token_array_from_text(temp.arena, string);
|
||||
EVAL_ParseResult parse = eval_parse_expr_from_text_tokens(temp.arena, &parse_ctx, string, &tokens);
|
||||
EVAL_ErrorList errors = parse.errors;
|
||||
B32 parse_has_expr = (parse.expr != &eval_expr_nil);
|
||||
B32 parse_is_type = (parse_has_expr && parse.expr->kind == EVAL_ExprKind_TypeIdent);
|
||||
EVAL_IRTreeAndType ir_tree_and_type = {&eval_irtree_nil};
|
||||
if(parse_has_expr && errors.count == 0)
|
||||
{
|
||||
ir_tree_and_type = eval_irtree_and_type_from_expr(temp.arena, parse_ctx.type_graph, rdi, &eval_string2expr_map_nil, parse.expr, &errors);
|
||||
}
|
||||
EVAL_OpList op_list = {0};
|
||||
if(parse_has_expr && ir_tree_and_type.tree != &eval_irtree_nil)
|
||||
{
|
||||
eval_oplist_from_irtree(scratch.arena, ir_tree_and_type.tree, &op_list);
|
||||
}
|
||||
String8 bytecode = {0};
|
||||
if(parse_has_expr && parse_is_type == 0 && op_list.encoded_size != 0)
|
||||
{
|
||||
bytecode = eval_bytecode_from_oplist(scratch.arena, &op_list);
|
||||
}
|
||||
EVAL_Result eval = {0};
|
||||
if(bytecode.size != 0)
|
||||
{
|
||||
U64 module_base = module->vaddr_range.min;
|
||||
U64 tls_base = dmn_tls_root_vaddr_from_thread(event->thread);
|
||||
EVAL_Machine machine = {0};
|
||||
machine.u = &event->process;
|
||||
machine.arch = arch;
|
||||
machine.memory_read = ctrl_eval_memory_read;
|
||||
machine.reg_size = regs_block_size_from_architecture(arch);
|
||||
machine.reg_data = push_array(scratch.arena, U8, machine.reg_size);
|
||||
machine.module_base = &module_base;
|
||||
machine.tls_base = &tls_base;
|
||||
dmn_thread_read_reg_block(event->thread, machine.reg_data);
|
||||
eval = eval_interpret(&machine, bytecode);
|
||||
}
|
||||
if(eval.code == EVAL_ResultCode_Good && eval.value.u64 == 0)
|
||||
{
|
||||
hit_user_bp = 0;
|
||||
hit_conditional_bp_but_filtered = 1;
|
||||
log_infof(">>> stepping >>> conditional breakpoint hit, but condition eval'd to 0, and so filtered\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
hit_user_bp = 1;
|
||||
hit_conditional_bp_but_filtered = 0;
|
||||
log_infof(">>> stepping >>> conditional breakpoint hit\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: gather trap net hits
|
||||
}
|
||||
|
||||
// rjf: gather trap net hits
|
||||
ProfScope("gather trap net hits")
|
||||
{
|
||||
if(!hit_user_bp && dmn_handle_match(event->process, target_process))
|
||||
{
|
||||
for(CTRL_TrapNode *node = msg->traps.first;
|
||||
@@ -4628,23 +4713,33 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log_infof(">>> stepping >>> stepping logic - BP event -> hit_user_bp: %i\n", hit_user_bp);
|
||||
log_infof(">>> stepping >>> stepping logic - BP event -> hit_entry: %i\n", hit_entry);
|
||||
temp_end(temp);
|
||||
}
|
||||
|
||||
log_infof("user_breakpoint_hit: %i\n", hit_user_bp);
|
||||
log_infof("entry_point_hit: %i\n", hit_entry);
|
||||
temp_end(temp);
|
||||
}
|
||||
|
||||
//- rjf: hit conditional user bp but filtered -> single step
|
||||
B32 cond_bp_single_step_stop = 0;
|
||||
CTRL_EventCause cond_bp_single_step_stop_cause = CTRL_EventCause_Null;
|
||||
if(hit_conditional_bp_but_filtered)
|
||||
if(hit_conditional_bp_but_filtered) LogInfoNamedBlockF("conditional_bp_hit_single_step")
|
||||
{
|
||||
DMN_RunCtrls single_step_ctrls = {0};
|
||||
single_step_ctrls.single_step_thread = event->thread;
|
||||
for(B32 single_step_done = 0; single_step_done == 0;)
|
||||
DMN_Handle thread = event->thread;
|
||||
U64 thread_pre_rip = dmn_rip_from_thread(thread);
|
||||
U64 thread_post_rip = thread_pre_rip;
|
||||
for(B32 single_step_done = 0; !single_step_done;)
|
||||
{
|
||||
DMN_RunCtrls single_step_ctrls = {0};
|
||||
single_step_ctrls.run_entities_are_unfrozen = 1;
|
||||
single_step_ctrls.run_entities = &thread;
|
||||
single_step_ctrls.run_entity_count = 1;
|
||||
if(thread_post_rip == thread_pre_rip)
|
||||
{
|
||||
single_step_ctrls.single_step_thread = thread;
|
||||
}
|
||||
DMN_Event *event = ctrl_thread__next_dmn_event(scratch.arena, ctrl_ctx, msg, &single_step_ctrls, 0);
|
||||
thread_post_rip = dmn_rip_from_thread(thread);
|
||||
switch(event->kind)
|
||||
{
|
||||
default:{}break;
|
||||
@@ -4660,7 +4755,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
}break;
|
||||
case DMN_EventKind_SingleStep:
|
||||
{
|
||||
single_step_done = 1;
|
||||
single_step_done = dmn_handle_match(event->thread, thread);
|
||||
cond_bp_single_step_stop_cause = ctrl_event_cause_from_dmn_event_kind(event->kind);
|
||||
}break;
|
||||
}
|
||||
@@ -4717,13 +4812,22 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
CTRL_EventCause single_step_stop_cause = CTRL_EventCause_Null;
|
||||
if(!hard_stop && use_trap_net_logic)
|
||||
{
|
||||
if(hit_trap_flags & CTRL_TrapFlag_SingleStepAfterHit)
|
||||
if(hit_trap_flags & CTRL_TrapFlag_SingleStepAfterHit) LogInfoNamedBlockF("trap_net__single_step_after_hit")
|
||||
{
|
||||
DMN_RunCtrls single_step_ctrls = {0};
|
||||
single_step_ctrls.single_step_thread = target_thread;
|
||||
U64 thread_pre_rip = dmn_rip_from_thread(target_thread);
|
||||
U64 thread_post_rip = thread_pre_rip;
|
||||
for(B32 single_step_done = 0; single_step_done == 0;)
|
||||
{
|
||||
DMN_RunCtrls single_step_ctrls = {0};
|
||||
single_step_ctrls.run_entities_are_unfrozen = 1;
|
||||
single_step_ctrls.run_entities = &target_thread;
|
||||
single_step_ctrls.run_entity_count = 1;
|
||||
if(thread_post_rip == thread_pre_rip)
|
||||
{
|
||||
single_step_ctrls.single_step_thread = target_thread;
|
||||
}
|
||||
DMN_Event *event = ctrl_thread__next_dmn_event(scratch.arena, ctrl_ctx, msg, &single_step_ctrls, 0);
|
||||
thread_post_rip = dmn_rip_from_thread(target_thread);
|
||||
switch(event->kind)
|
||||
{
|
||||
default:{}break;
|
||||
@@ -4740,7 +4844,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
}break;
|
||||
case DMN_EventKind_SingleStep:
|
||||
{
|
||||
single_step_done = 1;
|
||||
single_step_done = dmn_handle_match(event->thread, target_thread);;
|
||||
single_step_stop_cause = ctrl_event_cause_from_dmn_event_kind(event->kind);
|
||||
}break;
|
||||
}
|
||||
@@ -4752,7 +4856,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
B32 begin_spoof_mode = 0;
|
||||
if(!hard_stop && use_trap_net_logic)
|
||||
{
|
||||
if(hit_trap_flags & CTRL_TrapFlag_BeginSpoofMode)
|
||||
if(hit_trap_flags & CTRL_TrapFlag_BeginSpoofMode) LogInfoNamedBlockF("trap_net__begin_spoof_mode")
|
||||
{
|
||||
// rjf: setup spoof mode
|
||||
begin_spoof_mode = 1;
|
||||
@@ -4762,6 +4866,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
spoof.thread = target_thread;
|
||||
spoof.vaddr = spoof_sp;
|
||||
spoof.new_ip_value = spoof_ip_vaddr;
|
||||
log_infof("spoof:{process:[0x%I64x], thread:[0x%I64x], vaddr:0x%I64x, new_ip_value:0x%I64x}\n", spoof.process.u64[0], spoof.thread.u64[0], spoof.vaddr, spoof.new_ip_value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4771,10 +4876,11 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
{
|
||||
if(hit_trap_flags & CTRL_TrapFlag_SaveStackPointer)
|
||||
{
|
||||
if(stack_pointer_matches)
|
||||
if(stack_pointer_matches) LogInfoNamedBlockF("trap_net__save_sp")
|
||||
{
|
||||
save_stack_pointer = 1;
|
||||
sp_check_value = dmn_rsp_from_thread(target_thread);
|
||||
log_infof("sp_check_value = 0x%I64x\n", sp_check_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4783,7 +4889,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
B32 trap_net_stop = 0;
|
||||
if(!hard_stop && use_trap_net_logic)
|
||||
{
|
||||
if(hit_trap_flags & CTRL_TrapFlag_EndStepping)
|
||||
if(hit_trap_flags & CTRL_TrapFlag_EndStepping) LogInfoNamedBlockF("trap_net__end_step")
|
||||
{
|
||||
if((hit_trap_flags & CTRL_TrapFlag_IgnoreStackPointerCheck) ||
|
||||
stack_pointer_matches)
|
||||
@@ -4802,13 +4908,23 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
//- rjf: handle step past trap net
|
||||
B32 step_past_trap_net_stop = 0;
|
||||
CTRL_EventCause step_past_trap_net_stop_cause = CTRL_EventCause_Null;
|
||||
if(step_past_trap_net)
|
||||
if(step_past_trap_net) LogInfoNamedBlockF("trap_net__single_step_past_trap_net")
|
||||
{
|
||||
DMN_RunCtrls single_step_ctrls = {0};
|
||||
single_step_ctrls.single_step_thread = event->thread;
|
||||
DMN_Handle thread = event->thread;
|
||||
U64 thread_pre_rip = dmn_rip_from_thread(thread);
|
||||
U64 thread_post_rip = thread_pre_rip;
|
||||
for(B32 single_step_done = 0; single_step_done == 0;)
|
||||
{
|
||||
DMN_RunCtrls single_step_ctrls = {0};
|
||||
single_step_ctrls.run_entities_are_unfrozen = 1;
|
||||
single_step_ctrls.run_entities = &thread;
|
||||
single_step_ctrls.run_entity_count = 1;
|
||||
if(thread_post_rip == thread_pre_rip)
|
||||
{
|
||||
single_step_ctrls.single_step_thread = thread;
|
||||
}
|
||||
DMN_Event *event = ctrl_thread__next_dmn_event(scratch.arena, ctrl_ctx, msg, &single_step_ctrls, 0);
|
||||
thread_post_rip = dmn_rip_from_thread(thread);
|
||||
switch(event->kind)
|
||||
{
|
||||
default:{}break;
|
||||
@@ -4823,7 +4939,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
}break;
|
||||
case DMN_EventKind_SingleStep:
|
||||
{
|
||||
single_step_done = 1;
|
||||
single_step_done = dmn_handle_match(event->thread, thread);
|
||||
step_past_trap_net_stop_cause = ctrl_event_cause_from_dmn_event_kind(event->kind);
|
||||
}break;
|
||||
}
|
||||
@@ -4864,7 +4980,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
{
|
||||
stage_stop_cause = CTRL_EventCause_Finished;
|
||||
}
|
||||
log_infof(">>> stepping >>> stage stop cause -> %i\n", stage_stop_cause);
|
||||
log_infof("stop_cause: %i\n", stage_stop_cause);
|
||||
if(stage_stop_cause != CTRL_EventCause_Null)
|
||||
{
|
||||
stop_event = event;
|
||||
@@ -4892,6 +5008,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
ctrl_c2u_push_events(&evts);
|
||||
}
|
||||
|
||||
log_infof("}\n\n");
|
||||
di_scope_close(di_scope);
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
@@ -4915,11 +5032,21 @@ ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
DMN_Event *stop_event = 0;
|
||||
CTRL_EventCause stop_cause = CTRL_EventCause_Null;
|
||||
{
|
||||
DMN_RunCtrls run_ctrls = {0};
|
||||
run_ctrls.single_step_thread = msg->entity;
|
||||
DMN_Handle thread = msg->entity;
|
||||
U64 thread_pre_rip = dmn_rip_from_thread(thread);
|
||||
U64 thread_post_rip = thread_pre_rip;
|
||||
for(B32 done = 0; done == 0;)
|
||||
{
|
||||
DMN_RunCtrls run_ctrls = {0};
|
||||
run_ctrls.run_entities_are_unfrozen = 1;
|
||||
run_ctrls.run_entities = &thread;
|
||||
run_ctrls.run_entity_count = 1;
|
||||
if(thread_post_rip == thread_pre_rip)
|
||||
{
|
||||
run_ctrls.single_step_thread = msg->entity;
|
||||
}
|
||||
DMN_Event *event = ctrl_thread__next_dmn_event(scratch.arena, ctrl_ctx, msg, &run_ctrls, 0);
|
||||
thread_post_rip = dmn_rip_from_thread(msg->entity);
|
||||
switch(event->kind)
|
||||
{
|
||||
default:{}break;
|
||||
@@ -4927,8 +5054,8 @@ ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
case DMN_EventKind_Exception: {stop_cause = CTRL_EventCause_InterruptedByException;}goto end_single_step;
|
||||
case DMN_EventKind_Halt: {stop_cause = CTRL_EventCause_InterruptedByHalt;}goto end_single_step;
|
||||
case DMN_EventKind_Trap: {stop_cause = CTRL_EventCause_InterruptedByTrap;}goto end_single_step;
|
||||
case DMN_EventKind_SingleStep: {stop_cause = CTRL_EventCause_Finished;}goto end_single_step;
|
||||
case DMN_EventKind_Breakpoint: {stop_cause = CTRL_EventCause_UserBreakpoint;}goto end_single_step;
|
||||
case DMN_EventKind_SingleStep: {stop_cause = CTRL_EventCause_Finished;}goto end_single_step;
|
||||
end_single_step:
|
||||
{
|
||||
stop_event = event;
|
||||
|
||||
@@ -637,6 +637,7 @@ read_only global CTRL_Entity ctrl_entity_nil =
|
||||
internal U64 ctrl_hash_from_string(String8 string);
|
||||
internal U64 ctrl_hash_from_machine_id_handle(CTRL_MachineID machine_id, DMN_Handle handle);
|
||||
internal CTRL_EventCause ctrl_event_cause_from_dmn_event_kind(DMN_EventKind event_kind);
|
||||
internal String8 ctrl_string_from_event_kind(CTRL_EventKind kind);
|
||||
internal String8 ctrl_string_from_msg_kind(CTRL_MsgKind kind);
|
||||
|
||||
////////////////////////////////
|
||||
@@ -743,6 +744,7 @@ internal B32 ctrl_process_write(CTRL_MachineID machine_id, DMN_Handle process, R
|
||||
internal void *ctrl_query_cached_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle thread);
|
||||
internal U64 ctrl_query_cached_tls_root_vaddr_from_thread(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle thread);
|
||||
internal U64 ctrl_query_cached_rip_from_thread(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle thread);
|
||||
internal U64 ctrl_query_cached_rsp_from_thread(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle thread);
|
||||
|
||||
//- rjf: thread register writing
|
||||
internal B32 ctrl_thread_write_reg_block(CTRL_MachineID machine_id, DMN_Handle thread, void *block);
|
||||
@@ -809,7 +811,7 @@ internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, C
|
||||
|
||||
//- rjf: module lifetime open/close work
|
||||
internal void ctrl_thread__module_open(CTRL_MachineID machine_id, DMN_Handle process, DMN_Handle module, Rng1U64 vaddr_range, String8 path);
|
||||
internal void ctrl_thread__module_close(CTRL_MachineID machine_id, DMN_Handle module, String8 path);
|
||||
internal void ctrl_thread__module_close(CTRL_MachineID machine_id, DMN_Handle module);
|
||||
|
||||
//- rjf: attached process running/event gathering
|
||||
internal DMN_Event *ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, DMN_RunCtrls *run_ctrls, CTRL_Spoof *spoof);
|
||||
|
||||
@@ -240,14 +240,16 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params)
|
||||
}
|
||||
if(node == 0)
|
||||
{
|
||||
log_infof("[dasm] cache miss, creating node...\n");
|
||||
log_infof(" hash: [0x%I64x 0x%I64x]\n", hash.u64[0], hash.u64[1]);
|
||||
log_infof(" vaddr: 0x%I64x\n", params->vaddr);
|
||||
log_infof(" arch: %S\n", string_from_architecture(params->arch));
|
||||
log_infof(" style_flags: 0x%x\n", params->style_flags);
|
||||
log_infof(" syntax: %i\n", params->syntax);
|
||||
log_infof(" base_vaddr: 0x%I64x\n", params->base_vaddr);
|
||||
log_infof(" dbgi_key: [%S 0x%I64x]\n", params->dbgi_key.path, params->dbgi_key.min_timestamp);
|
||||
LogInfoNamedBlockF("dasm_new_node")
|
||||
{
|
||||
log_infof("hash: [0x%I64x 0x%I64x]\n", hash.u64[0], hash.u64[1]);
|
||||
log_infof("vaddr: 0x%I64x\n", params->vaddr);
|
||||
log_infof("arch: %S\n", string_from_architecture(params->arch));
|
||||
log_infof("style_flags: 0x%x\n", params->style_flags);
|
||||
log_infof("syntax: %i\n", params->syntax);
|
||||
log_infof("base_vaddr: 0x%I64x\n", params->base_vaddr);
|
||||
log_infof("dbgi_key: [%S 0x%I64x]\n", params->dbgi_key.path, params->dbgi_key.min_timestamp);
|
||||
}
|
||||
node = stripe->free_node;
|
||||
if(node)
|
||||
{
|
||||
@@ -537,7 +539,7 @@ dasm_parse_thread__entry_point(void *p)
|
||||
String8 addr_part = {0};
|
||||
if(params.style_flags & DASM_StyleFlag_Addresses)
|
||||
{
|
||||
addr_part = push_str8f(scratch.arena, "%s%016I64X ", rdi != &di_rdi_parsed_nil ? " " : "", params.vaddr+off);
|
||||
addr_part = push_str8f(scratch.arena, "%s0x%016I64x ", rdi != &di_rdi_parsed_nil ? " " : "", params.vaddr+off);
|
||||
}
|
||||
String8 code_bytes_part = {0};
|
||||
if(params.style_flags & DASM_StyleFlag_CodeBytes)
|
||||
|
||||
+2
-2
@@ -294,7 +294,7 @@ di_open(DI_Key *key)
|
||||
U64 stripe_idx = slot_idx%di_shared->stripes_count;
|
||||
DI_Slot *slot = &di_shared->slots[slot_idx];
|
||||
DI_Stripe *stripe = &di_shared->stripes[stripe_idx];
|
||||
log_infof("opening debug info: %S [0x%I64x]\n", key_normalized.path, key_normalized.min_timestamp);
|
||||
log_infof("open_debug_info: {\"%S\", 0x%I64x}\n", key_normalized.path, key_normalized.min_timestamp);
|
||||
OS_MutexScopeW(stripe->rw_mutex)
|
||||
{
|
||||
//- rjf: find existing node
|
||||
@@ -350,7 +350,7 @@ di_close(DI_Key *key)
|
||||
U64 stripe_idx = slot_idx%di_shared->stripes_count;
|
||||
DI_Slot *slot = &di_shared->slots[slot_idx];
|
||||
DI_Stripe *stripe = &di_shared->stripes[stripe_idx];
|
||||
log_infof("closing debug info: %S [0x%I64x]\n", key_normalized.path, key_normalized.min_timestamp);
|
||||
log_infof("close_debug_info: {\"%S\", 0x%I64x}\n", key_normalized.path, key_normalized.min_timestamp);
|
||||
OS_MutexScopeW(stripe->rw_mutex)
|
||||
{
|
||||
//- rjf: find existing node
|
||||
|
||||
@@ -217,6 +217,11 @@ internal void dmn_access_close(void);
|
||||
#define DMN_AccessScope DeferLoopChecked(dmn_access_open(), dmn_access_close())
|
||||
|
||||
//- rjf: processes
|
||||
internal U64 dmn_process_memory_reserve(DMN_Handle process, U64 vaddr, U64 size);
|
||||
internal void dmn_process_memory_commit(DMN_Handle process, U64 vaddr, U64 size);
|
||||
internal void dmn_process_memory_decommit(DMN_Handle process, U64 vaddr, U64 size);
|
||||
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, OS_AccessFlags flags);
|
||||
internal U64 dmn_process_read(DMN_Handle process, Rng1U64 range, void *dst);
|
||||
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)
|
||||
|
||||
@@ -580,6 +580,7 @@ internal B32
|
||||
dmn_w32_thread_read_reg_block(Architecture arch, HANDLE thread, void *reg_block)
|
||||
{
|
||||
B32 result = 0;
|
||||
ProfBeginFunction();
|
||||
switch(arch)
|
||||
{
|
||||
////////////////////////////
|
||||
@@ -817,6 +818,7 @@ dmn_w32_thread_read_reg_block(Architecture arch, HANDLE thread, void *reg_block)
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
}
|
||||
ProfEnd();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -824,6 +826,7 @@ internal B32
|
||||
dmn_w32_thread_write_reg_block(Architecture arch, HANDLE thread, void *reg_block)
|
||||
{
|
||||
B32 result = 0;
|
||||
ProfBeginFunction();
|
||||
switch(arch)
|
||||
{
|
||||
////////////////////////////
|
||||
@@ -1050,6 +1053,7 @@ dmn_w32_thread_write_reg_block(Architecture arch, HANDLE thread, void *reg_block
|
||||
}break;
|
||||
}
|
||||
ins_atomic_u64_inc_eval(&dmn_w32_shared->reg_gen);
|
||||
ProfEnd();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1342,7 +1346,9 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
||||
B32 any_processes_live = dmn_w32_shared->new_process_pending;
|
||||
if(!any_processes_live)
|
||||
{
|
||||
for(DMN_W32_Entity *process = dmn_w32_shared->entities_base->first; process != &dmn_w32_entity_nil; process = process->next)
|
||||
for(DMN_W32_Entity *process = dmn_w32_shared->entities_base->first;
|
||||
process != &dmn_w32_entity_nil;
|
||||
process = process->next)
|
||||
{
|
||||
if(process->kind == DMN_W32_EntityKind_Process)
|
||||
{
|
||||
@@ -1379,10 +1385,38 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
|
||||
//////////////////////////
|
||||
//- rjf: get single step thread's context (x64 single-step-set fast path)
|
||||
//
|
||||
CONTEXT *single_step_thread_ctx = 0;
|
||||
if(!dmn_handle_match(ctrls->single_step_thread, dmn_handle_zero()))
|
||||
{
|
||||
DMN_W32_Entity *thread = dmn_w32_entity_from_handle(ctrls->single_step_thread);
|
||||
Architecture arch = thread->arch;
|
||||
switch(arch)
|
||||
{
|
||||
default:{}break;
|
||||
case Architecture_x64:
|
||||
{
|
||||
U32 ctx_flags = DMN_W32_CTX_X64|DMN_W32_CTX_INTEL_CONTROL;
|
||||
DWORD size = 0;
|
||||
InitializeContext(0, ctx_flags, 0, &size);
|
||||
if(GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
void *ctx_memory = push_array(scratch.arena, U8, size);
|
||||
if(!InitializeContext(ctx_memory, ctx_flags, &single_step_thread_ctx, &size))
|
||||
{
|
||||
single_step_thread_ctx = 0;
|
||||
}
|
||||
}
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
//- rjf: set single step bit
|
||||
//
|
||||
if(!dmn_handle_match(ctrls->single_step_thread, dmn_handle_zero()))
|
||||
if(!dmn_handle_match(ctrls->single_step_thread, dmn_handle_zero())) ProfScope("set single step bit")
|
||||
{
|
||||
DMN_W32_Entity *thread = dmn_w32_entity_from_handle(ctrls->single_step_thread);
|
||||
Architecture arch = thread->arch;
|
||||
@@ -1396,7 +1430,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
||||
case Architecture_arm32:
|
||||
{NotImplemented;}break;
|
||||
|
||||
//- rjf: x86/64
|
||||
//- rjf: x86
|
||||
case Architecture_x86:
|
||||
{
|
||||
REGS_RegBlockX86 regs = {0};
|
||||
@@ -1404,12 +1438,22 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
||||
regs.eflags.u32 |= 0x100;
|
||||
dmn_thread_write_reg_block(ctrls->single_step_thread, ®s);
|
||||
}break;
|
||||
|
||||
//- rjf: x64
|
||||
case Architecture_x64:
|
||||
{
|
||||
REGS_RegBlockX64 regs = {0};
|
||||
dmn_thread_read_reg_block(ctrls->single_step_thread, ®s);
|
||||
regs.rflags.u64 |= 0x100;
|
||||
dmn_thread_write_reg_block(ctrls->single_step_thread, ®s);
|
||||
if(!GetThreadContext(thread->handle, single_step_thread_ctx))
|
||||
{
|
||||
single_step_thread_ctx = 0;
|
||||
}
|
||||
if(single_step_thread_ctx != 0)
|
||||
{
|
||||
U64 rflags = single_step_thread_ctx->EFlags|0x2;
|
||||
U64 new_rflags = rflags | 0x100;
|
||||
single_step_thread_ctx->EFlags = new_rflags;
|
||||
SetThreadContext(thread->handle, single_step_thread_ctx);
|
||||
ins_atomic_u64_inc_eval(&dmn_w32_shared->reg_gen);
|
||||
}
|
||||
}break;
|
||||
}
|
||||
}
|
||||
@@ -1473,10 +1517,9 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
||||
B32 is_frozen = 0;
|
||||
{
|
||||
// rjf: single-step? freeze if not the single-step thread.
|
||||
if(!dmn_handle_match(dmn_handle_zero(), ctrls->single_step_thread) &&
|
||||
!dmn_handle_match(dmn_w32_handle_from_entity(thread), ctrls->single_step_thread))
|
||||
if(!dmn_handle_match(dmn_handle_zero(), ctrls->single_step_thread))
|
||||
{
|
||||
is_frozen = 1;
|
||||
is_frozen = !dmn_handle_match(dmn_w32_handle_from_entity(thread), ctrls->single_step_thread);
|
||||
}
|
||||
|
||||
// rjf: not single-stepping? determine based on run controls freezing info
|
||||
@@ -1566,9 +1609,14 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
||||
{
|
||||
if(dmn_w32_shared->exception_not_handled && !ctrls->ignore_previous_exception)
|
||||
{
|
||||
dmn_w32_shared->exception_not_handled = 0;
|
||||
log_infof("using DBG_EXCEPTION_NOT_HANDLED\n");
|
||||
resume_code = DBG_EXCEPTION_NOT_HANDLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_infof("using DBG_CONTINUE\n");
|
||||
}
|
||||
dmn_w32_shared->exception_not_handled = 0;
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
@@ -1981,19 +2029,53 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
||||
B32 should_do_rollback = (hit_user_trap || (is_trap && !hit_explicit_trap));
|
||||
|
||||
//- rjf: roll back thread's instruction pointer
|
||||
U64 post_trap_rip = 0;
|
||||
if(should_do_rollback)
|
||||
if(should_do_rollback) ProfScope("roll back thread's instruction pointer")
|
||||
{
|
||||
Temp temp = temp_begin(scratch.arena);
|
||||
U64 regs_block_size = regs_block_size_from_architecture(thread->arch);
|
||||
void *regs_block = push_array(scratch.arena, U8, regs_block_size);
|
||||
if(dmn_w32_thread_read_reg_block(thread->arch, thread->handle, regs_block))
|
||||
switch(thread->arch)
|
||||
{
|
||||
post_trap_rip = regs_rip_from_arch_block(thread->arch, regs_block);
|
||||
regs_arch_block_write_rip(thread->arch, regs_block, instruction_pointer);
|
||||
dmn_w32_thread_write_reg_block(thread->arch, thread->handle, regs_block);
|
||||
//- rjf: default, general path
|
||||
default:
|
||||
{
|
||||
Temp temp = temp_begin(scratch.arena);
|
||||
U64 regs_block_size = regs_block_size_from_architecture(thread->arch);
|
||||
void *regs_block = push_array(scratch.arena, U8, regs_block_size);
|
||||
if(dmn_w32_thread_read_reg_block(thread->arch, thread->handle, regs_block))
|
||||
{
|
||||
regs_arch_block_write_rip(thread->arch, regs_block, instruction_pointer);
|
||||
dmn_w32_thread_write_reg_block(thread->arch, thread->handle, regs_block);
|
||||
}
|
||||
temp_end(temp);
|
||||
}break;
|
||||
|
||||
//- rjf: x64 (fastpath)
|
||||
case Architecture_x64:
|
||||
{
|
||||
CONTEXT *ctx = 0;
|
||||
U32 ctx_flags = DMN_W32_CTX_X64|DMN_W32_CTX_INTEL_CONTROL;
|
||||
DWORD size = 0;
|
||||
InitializeContext(0, ctx_flags, 0, &size);
|
||||
if(GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
void *ctx_memory = push_array(scratch.arena, U8, size);
|
||||
if(!InitializeContext(ctx_memory, ctx_flags, &ctx, &size))
|
||||
{
|
||||
ctx = 0;
|
||||
}
|
||||
}
|
||||
if(!GetThreadContext(thread->handle, ctx))
|
||||
{
|
||||
ctx = 0;
|
||||
}
|
||||
if(ctx != 0)
|
||||
{
|
||||
U64 rip = ctx->Rip;
|
||||
U64 new_rip = instruction_pointer;
|
||||
ctx->Rip = new_rip;
|
||||
SetThreadContext(thread->handle, ctx);
|
||||
ins_atomic_u64_inc_eval(&dmn_w32_shared->reg_gen);
|
||||
}
|
||||
}break;
|
||||
}
|
||||
temp_end(temp);
|
||||
}
|
||||
|
||||
//- rjf: not a user trap, not an explicit trap, then it's a trap that
|
||||
@@ -2345,10 +2427,18 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
|
||||
}break;
|
||||
case Architecture_x64:
|
||||
{
|
||||
REGS_RegBlockX64 regs = {0};
|
||||
dmn_thread_read_reg_block(ctrls->single_step_thread, ®s);
|
||||
regs.rflags.u64 &= ~0x100;
|
||||
dmn_thread_write_reg_block(ctrls->single_step_thread, ®s);
|
||||
if(!GetThreadContext(thread->handle, single_step_thread_ctx))
|
||||
{
|
||||
single_step_thread_ctx = 0;
|
||||
}
|
||||
if(ctx != 0)
|
||||
{
|
||||
U64 rflags = single_step_thread_ctx->EFlags|0x2;
|
||||
U64 new_rflags = rflags & ~0x100;
|
||||
single_step_thread_ctx->EFlags = new_rflags;
|
||||
SetThreadContext(thread->handle, single_step_thread_ctx);
|
||||
ins_atomic_u64_inc_eval(&dmn_w32_shared->reg_gen);
|
||||
}
|
||||
}break;
|
||||
}
|
||||
}
|
||||
@@ -2496,6 +2586,73 @@ dmn_access_close(void)
|
||||
|
||||
//- rjf: processes
|
||||
|
||||
internal U64
|
||||
dmn_process_memory_reserve(DMN_Handle process, U64 vaddr, U64 size)
|
||||
{
|
||||
U64 result = 0;
|
||||
DMN_AccessScope
|
||||
{
|
||||
DMN_W32_Entity *process_entity = dmn_w32_entity_from_handle(process);
|
||||
result = (U64)VirtualAllocEx(process_entity->handle, (void *)vaddr, size, MEM_RESERVE, PAGE_READWRITE);
|
||||
if(result == 0)
|
||||
{
|
||||
result = (U64)VirtualAllocEx(process_entity->handle, 0, size, MEM_RESERVE, PAGE_READWRITE);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
dmn_process_memory_commit(DMN_Handle process, U64 vaddr, U64 size)
|
||||
{
|
||||
DMN_AccessScope
|
||||
{
|
||||
DMN_W32_Entity *process_entity = dmn_w32_entity_from_handle(process);
|
||||
(U64)VirtualAllocEx(process_entity->handle, (void *)vaddr, size, MEM_COMMIT, PAGE_READWRITE);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
dmn_process_memory_decommit(DMN_Handle process, U64 vaddr, U64 size)
|
||||
{
|
||||
DMN_AccessScope
|
||||
{
|
||||
DMN_W32_Entity *process_entity = dmn_w32_entity_from_handle(process);
|
||||
VirtualFreeEx(process_entity->handle, (void *)vaddr, size, MEM_DECOMMIT);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
dmn_process_memory_release(DMN_Handle process, U64 vaddr, U64 size)
|
||||
{
|
||||
DMN_AccessScope
|
||||
{
|
||||
DMN_W32_Entity *process_entity = dmn_w32_entity_from_handle(process);
|
||||
VirtualFreeEx(process_entity->handle, (void *)vaddr, 0, MEM_RELEASE);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
dmn_process_memory_protect(DMN_Handle process, U64 vaddr, U64 size, OS_AccessFlags flags)
|
||||
{
|
||||
DMN_AccessScope
|
||||
{
|
||||
DMN_W32_Entity *process_entity = dmn_w32_entity_from_handle(process);
|
||||
DWORD old_flags = 0;
|
||||
DWORD new_flags = PAGE_NOACCESS;
|
||||
switch(flags)
|
||||
{
|
||||
default:{}break;
|
||||
case OS_AccessFlag_Execute:{new_flags = PAGE_EXECUTE;}break;
|
||||
case OS_AccessFlag_Execute|OS_AccessFlag_Read:{new_flags = PAGE_EXECUTE_READ;}break;
|
||||
case OS_AccessFlag_Execute|OS_AccessFlag_Read|OS_AccessFlag_Write:{new_flags = PAGE_EXECUTE_READWRITE;}break;
|
||||
case OS_AccessFlag_Read:{new_flags = PAGE_READONLY;}break;
|
||||
case OS_AccessFlag_Read|OS_AccessFlag_Write:{new_flags = PAGE_READWRITE;}break;
|
||||
}
|
||||
VirtualProtectEx(process_entity->handle, (void *)vaddr, size, new_flags, &old_flags);
|
||||
}
|
||||
}
|
||||
|
||||
internal U64
|
||||
dmn_process_read(DMN_Handle process, Rng1U64 range, void *dst)
|
||||
{
|
||||
|
||||
@@ -54,6 +54,8 @@
|
||||
#define DMN_W32_EXCEPTION_NO_MEMORY 0xC0000017u
|
||||
#define DMN_W32_EXCEPTION_THROW 0xE06D7363u
|
||||
#define DMN_W32_EXCEPTION_SET_THREAD_NAME 0x406d1388u
|
||||
#define DMN_w32_EXCEPTION_CLRDBG_NOTIFICATION 0x04242420u
|
||||
#define DMN_w32_EXCEPTION_CLR 0xE0434352u
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Win32 Register Codes
|
||||
@@ -61,11 +63,11 @@
|
||||
#define DMN_W32_CTX_X86 0x00010000
|
||||
#define DMN_W32_CTX_X64 0x00100000
|
||||
|
||||
#define DMN_W32_CTX_INTEL_CONTROL 0x0001
|
||||
#define DMN_W32_CTX_INTEL_INTEGER 0x0002
|
||||
#define DMN_W32_CTX_INTEL_SEGMENTS 0x0004
|
||||
#define DMN_W32_CTX_INTEL_FLOATS 0x0008
|
||||
#define DMN_W32_CTX_INTEL_DEBUG 0x0010
|
||||
#define DMN_W32_CTX_INTEL_CONTROL 0x0001 // segss, rsp, segcs, rip, and rflags
|
||||
#define DMN_W32_CTX_INTEL_INTEGER 0x0002 // rax, rcx, rdx, rbx, rbp, rsi, rdi, and r8-r15
|
||||
#define DMN_W32_CTX_INTEL_SEGMENTS 0x0004 // segds, seges, segfs, and seggs
|
||||
#define DMN_W32_CTX_INTEL_FLOATS 0x0008 // xmm0-xmm15
|
||||
#define DMN_W32_CTX_INTEL_DEBUG 0x0010 // dr0-dr3 and dr6-dr7
|
||||
#define DMN_W32_CTX_INTEL_EXTENDED 0x0020
|
||||
#define DMN_W32_CTX_INTEL_XSTATE 0x0040
|
||||
|
||||
|
||||
+80
-21
@@ -879,7 +879,7 @@ df_ctrl_flow_info_from_vaddr_code__x64(Arena *arena, DF_InstFlags exit_points_ma
|
||||
point.jump_dest_vaddr = (U64)(point.vaddr + (S64)((S32)inst.rel_voff));
|
||||
}
|
||||
DF_CtrlFlowPointNode *node = push_array(arena, DF_CtrlFlowPointNode, 1);
|
||||
node->point = point;
|
||||
node->v = point;
|
||||
SLLQueuePush(info.exit_points.first, info.exit_points.last, node);
|
||||
info.exit_points.count += 1;
|
||||
}
|
||||
@@ -1814,7 +1814,11 @@ df_entity_alloc(DF_StateDeltaHistory *hist, DF_Entity *parent, DF_EntityKind kin
|
||||
df_entity_notify_mutation(entity);
|
||||
|
||||
// rjf: log
|
||||
log_infof("new entity: %S $%I64d\n", df_g_entity_kind_display_string_table[kind], entity->id);
|
||||
LogInfoNamedBlockF("new_entity")
|
||||
{
|
||||
log_infof("kind: \"%S\"\n", df_g_entity_kind_display_string_table[kind]);
|
||||
log_infof("id: $0x%I64x\n", entity->id);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
@@ -1859,7 +1863,13 @@ df_entity_release(DF_StateDeltaHistory *hist, DF_Entity *entity)
|
||||
t->e = child;
|
||||
SLLQueuePush(first_task, last_task, t);
|
||||
}
|
||||
log_infof("end entity: %S $%I64d\n", df_g_entity_kind_display_string_table[task->e->kind], task->e->id);
|
||||
LogInfoNamedBlockF("end_entity")
|
||||
{
|
||||
String8 name = df_display_string_from_entity(scratch.arena, task->e);
|
||||
log_infof("kind: \"%S\"\n", df_g_entity_kind_display_string_table[task->e->kind]);
|
||||
log_infof("id: $0x%I64x\n", task->e->id);
|
||||
log_infof("display_string: \"%S\"\n", name);
|
||||
}
|
||||
df_state_delta_history_push_struct_delta(hist, &task->e->first);
|
||||
df_state_delta_history_push_struct_delta(hist, &task->e->last);
|
||||
df_state_delta_history_push_struct_delta(hist, &task->e->next);
|
||||
@@ -2322,6 +2332,7 @@ df_possible_overrides_from_entity(Arena *arena, DF_Entity *entity)
|
||||
|
||||
// rjf: descend tree if needed, by the chain names, find override
|
||||
DF_Entity *override = link_overridden_sibling;
|
||||
if(!df_entity_is_nil(override))
|
||||
{
|
||||
DF_Entity *parent = override;
|
||||
for(String8Node *path_part_n = p_chain_names_to_entity.first;
|
||||
@@ -2850,6 +2861,7 @@ internal CTRL_TrapList
|
||||
df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
log_infof("step_over_line:\n{\n");
|
||||
CTRL_TrapList result = {0};
|
||||
|
||||
// rjf: thread => info
|
||||
@@ -2858,6 +2870,8 @@ df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
Architecture arch = df_architecture_from_entity(thread);
|
||||
U64 ip_vaddr = ctrl_query_cached_rip_from_thread(df_state->ctrl_entity_store, thread->ctrl_machine_id, thread->ctrl_handle);
|
||||
log_infof("ip_vaddr: 0x%I64x\n", ip_vaddr);
|
||||
log_infof("dbgi_key: {%S, 0x%I64x}\n", dbgi_key.path, dbgi_key.min_timestamp);
|
||||
|
||||
// rjf: ip => line vaddr range
|
||||
Rng1U64 line_vaddr_rng = {0};
|
||||
@@ -2869,6 +2883,8 @@ df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
|
||||
{
|
||||
line_vaddr_rng = df_vaddr_range_from_voff_range(module, line_voff_rng);
|
||||
}
|
||||
log_infof("line: {%S:%I64i}\n", line_info.file->name, line_info.pt.line);
|
||||
log_infof("voff_range: {0x%I64x, 0x%I64x}\n", line_info.voff_range.min, line_info.voff_range.max);
|
||||
}
|
||||
|
||||
// rjf: opl line_vaddr_rng -> 0xf00f00 or 0xfeefee? => include in line vaddr range
|
||||
@@ -2893,6 +2909,22 @@ df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
|
||||
{
|
||||
CTRL_ProcessMemorySlice machine_code_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->ctrl_machine_id, process->ctrl_handle, line_vaddr_rng, os_now_microseconds()+50000);
|
||||
machine_code = machine_code_slice.data;
|
||||
LogInfoNamedBlockF("machine_code_slice")
|
||||
{
|
||||
log_infof("stale: %i\n", machine_code_slice.stale);
|
||||
log_infof("any_byte_bad: %i\n", machine_code_slice.any_byte_bad);
|
||||
log_infof("any_byte_changed: %i\n", machine_code_slice.any_byte_changed);
|
||||
log_infof("bytes:\n[\n");
|
||||
for(U64 idx = 0; idx < machine_code_slice.data.size; idx += 1)
|
||||
{
|
||||
log_infof("0x%x,", machine_code_slice.data.str[idx]);
|
||||
if(idx%16 == 15 || idx+1 == machine_code_slice.data.size)
|
||||
{
|
||||
log_infof("\n");
|
||||
}
|
||||
}
|
||||
log_infof("]\n");
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: machine code => ctrl flow analysis
|
||||
@@ -2908,12 +2940,20 @@ df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
|
||||
arch,
|
||||
line_vaddr_rng.min,
|
||||
machine_code);
|
||||
LogInfoNamedBlockF("ctrl_flow_info")
|
||||
{
|
||||
log_infof("flags: %x\n", ctrl_flow_info.flags);
|
||||
LogInfoNamedBlockF("exit_points") for(DF_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next)
|
||||
{
|
||||
log_infof("{vaddr:0x%I64x, jump_dest_vaddr:0x%I64x, expected_sp_delta:0x%I64x, inst_flags:%x}\n", n->v.vaddr, n->v.jump_dest_vaddr, n->v.expected_sp_delta, n->v.inst_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: push traps for all exit points
|
||||
if(good_line_info) for(DF_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next)
|
||||
{
|
||||
DF_CtrlFlowPoint *point = &n->point;
|
||||
DF_CtrlFlowPoint *point = &n->v;
|
||||
CTRL_TrapFlags flags = 0;
|
||||
B32 add = 1;
|
||||
U64 trap_addr = point->vaddr;
|
||||
@@ -2967,7 +3007,14 @@ df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
|
||||
ctrl_trap_list_push(arena, &result, &trap);
|
||||
}
|
||||
|
||||
// rjf: log
|
||||
LogInfoNamedBlockF("traps") for(CTRL_TrapNode *n = result.first; n != 0; n = n->next)
|
||||
{
|
||||
log_infof("{flags:0x%x, vaddr:0x%I64x}\n", n->v.flags, n->v.vaddr);
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
log_infof("}\n\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3038,7 +3085,7 @@ df_trap_net_from_thread__step_into_line(Arena *arena, DF_Entity *thread)
|
||||
// rjf: push traps for all exit points
|
||||
if(good_line_info) for(DF_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next)
|
||||
{
|
||||
DF_CtrlFlowPoint *point = &n->point;
|
||||
DF_CtrlFlowPoint *point = &n->v;
|
||||
CTRL_TrapFlags flags = 0;
|
||||
B32 add = 1;
|
||||
U64 trap_addr = point->vaddr;
|
||||
@@ -6557,8 +6604,9 @@ df_push_cmd__root(DF_CmdParams *params, DF_CmdSpec *spec)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DF_Entity *entity = df_entity_from_handle(params->entity);
|
||||
log_infof("debug frontend command pushed: \"%S\"\n", spec->info.string);
|
||||
#define HandleParamPrint(mem_name) if(!df_handle_match(df_handle_zero(), params->mem_name)) { log_infof("| %s: [0x%I64x, 0x%I64x]\n", #mem_name, params->mem_name.u64[0], params->mem_name.u64[1]); }
|
||||
log_infof("df_cmd:\n{\n", spec->info.string);
|
||||
log_infof("spec: \"%S\"\n", spec->info.string);
|
||||
#define HandleParamPrint(mem_name) if(!df_handle_match(df_handle_zero(), params->mem_name)) { log_infof("%s: [0x%I64x, 0x%I64x]\n", #mem_name, params->mem_name.u64[0], params->mem_name.u64[1]); }
|
||||
HandleParamPrint(window);
|
||||
HandleParamPrint(panel);
|
||||
HandleParamPrint(dest_panel);
|
||||
@@ -6567,7 +6615,7 @@ df_push_cmd__root(DF_CmdParams *params, DF_CmdSpec *spec)
|
||||
if(!df_entity_is_nil(entity))
|
||||
{
|
||||
String8 entity_name = df_display_string_from_entity(scratch.arena, entity);
|
||||
log_infof("| entity: \"%S\"\n", entity_name);
|
||||
log_infof("entity: \"%S\"\n", entity_name);
|
||||
}
|
||||
U64 idx = 0;
|
||||
for(DF_HandleNode *n = params->entity_list.first; n != 0; n = n->next, idx += 1)
|
||||
@@ -6576,22 +6624,22 @@ df_push_cmd__root(DF_CmdParams *params, DF_CmdSpec *spec)
|
||||
if(!df_entity_is_nil(entity))
|
||||
{
|
||||
String8 entity_name = df_display_string_from_entity(scratch.arena, entity);
|
||||
log_infof("| entity_list[%I64u]: \"%S\"\n", idx, entity_name);
|
||||
log_infof("entity_list[%I64u]: \"%S\"\n", idx, entity_name);
|
||||
}
|
||||
}
|
||||
if(!df_cmd_spec_is_nil(params->cmd_spec))
|
||||
{
|
||||
log_infof("| cmd_spec: \"%S\"\n", params->cmd_spec->info.string);
|
||||
log_infof("cmd_spec: \"%S\"\n", params->cmd_spec->info.string);
|
||||
}
|
||||
if(params->string.size != 0) { log_infof("| string: \"%S\"\n", params->string); }
|
||||
if(params->file_path.size != 0) { log_infof("| file_path: \"%S\"\n", params->file_path); }
|
||||
if(params->text_point.line != 0) { log_infof("| text_point: [line:%I64d, col:%I64d]\n", params->text_point.line, params->text_point.column); }
|
||||
if(params->vaddr != 0) { log_infof("| vaddr: 0x%I64x\n", params->vaddr); }
|
||||
if(params->voff != 0) { log_infof("| voff: 0x%I64x\n", params->voff); }
|
||||
if(params->index != 0) { log_infof("| index: 0x%I64x\n", params->index); }
|
||||
if(params->base_unwind_index != 0) { log_infof("| base_unwind_index: 0x%I64x\n", params->base_unwind_index); }
|
||||
if(params->inline_unwind_index != 0){ log_infof("| inline_unwind_index: 0x%I64x\n", params->inline_unwind_index); }
|
||||
if(params->id != 0) { log_infof("| id: 0x%I64x\n", params->id); }
|
||||
if(params->string.size != 0) { log_infof("string: \"%S\"\n", params->string); }
|
||||
if(params->file_path.size != 0) { log_infof("file_path: \"%S\"\n", params->file_path); }
|
||||
if(params->text_point.line != 0) { log_infof("text_point: [line:%I64d, col:%I64d]\n", params->text_point.line, params->text_point.column); }
|
||||
if(params->vaddr != 0) { log_infof("vaddr: 0x%I64x\n", params->vaddr); }
|
||||
if(params->voff != 0) { log_infof("voff: 0x%I64x\n", params->voff); }
|
||||
if(params->index != 0) { log_infof("index: 0x%I64x\n", params->index); }
|
||||
if(params->base_unwind_index != 0) { log_infof("base_unwind_index: 0x%I64x\n", params->base_unwind_index); }
|
||||
if(params->inline_unwind_index != 0){ log_infof("inline_unwind_index: 0x%I64x\n", params->inline_unwind_index); }
|
||||
if(params->id != 0) { log_infof("id: 0x%I64x\n", params->id); }
|
||||
if(params->os_event != 0)
|
||||
{
|
||||
String8 kind_string = str8_lit("<unknown>");
|
||||
@@ -6608,10 +6656,10 @@ df_push_cmd__root(DF_CmdParams *params, DF_CmdSpec *spec)
|
||||
case OS_EventKind_FileDrop: {kind_string = str8_lit("filedrop");}break;
|
||||
case OS_EventKind_Wakeup: {kind_string = str8_lit("wakeup");}break;
|
||||
}
|
||||
log_infof("| os_event->kind: %S\n", kind_string);
|
||||
log_infof("os_event->kind: %S\n", kind_string);
|
||||
}
|
||||
#undef HandleParamPrint
|
||||
log_infof("--------------------------------\n");
|
||||
log_infof("}\n\n");
|
||||
scratch_end(scratch);
|
||||
}
|
||||
df_cmd_list_push(df_state->root_cmd_arena, &df_state->root_cmds, params, spec);
|
||||
@@ -6803,6 +6851,9 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
|
||||
for(CTRL_EventNode *event_n = events.first; event_n != 0; event_n = event_n->next)
|
||||
{
|
||||
CTRL_Event *event = &event_n->v;
|
||||
log_infof("ctrl_event:\n{\n");
|
||||
log_infof("kind: \"%S\"\n", ctrl_string_from_event_kind(event->kind));
|
||||
log_infof("entity_id: %u\n", event->entity_id);
|
||||
switch(event->kind)
|
||||
{
|
||||
default:{}break;
|
||||
@@ -6838,6 +6889,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
|
||||
// rjf: select & snap to thread causing stop
|
||||
if(should_snap && stop_thread->kind == DF_EntityKind_Thread)
|
||||
{
|
||||
log_infof("stop_thread: \"%S\"\n", df_display_string_from_entity(scratch.arena, stop_thread));
|
||||
DF_CmdParams params = df_cmd_params_zero();
|
||||
params.entity = df_handle_from_entity(stop_thread);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Entity);
|
||||
@@ -7160,6 +7212,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
|
||||
case CTRL_EventKind_MemDecommit:{}break;
|
||||
case CTRL_EventKind_MemRelease:{}break;
|
||||
}
|
||||
log_infof("}\n\n");
|
||||
}
|
||||
|
||||
//- rjf: clear tls base cache
|
||||
@@ -8947,6 +9000,12 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
|
||||
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Error));
|
||||
#endif
|
||||
}break;
|
||||
|
||||
//- rjf: developer commands
|
||||
case DF_CoreCmdKind_LogMarker:
|
||||
{
|
||||
log_infof("\"#MARKER\"");
|
||||
}break;
|
||||
}
|
||||
}
|
||||
scratch_end(scratch);
|
||||
|
||||
@@ -223,7 +223,7 @@ typedef struct DF_CtrlFlowPointNode DF_CtrlFlowPointNode;
|
||||
struct DF_CtrlFlowPointNode
|
||||
{
|
||||
DF_CtrlFlowPointNode *next;
|
||||
DF_CtrlFlowPoint point;
|
||||
DF_CtrlFlowPoint v;
|
||||
};
|
||||
|
||||
typedef struct DF_CtrlFlowPointList DF_CtrlFlowPointList;
|
||||
|
||||
@@ -412,6 +412,7 @@ DF_CoreCmdTable:// | | |
|
||||
|
||||
//- rjf: developer commands
|
||||
{ToggleDevMenu 0 Null Nil 0 0 0 0 0 0 Null "toggle_dev_menu" "Toggle Developer Menu" "Opens and closes the developer menu." "" }
|
||||
{LogMarker 0 Null Nil 0 0 0 0 0 0 Null "log_marker" "Log Marker" "Logs a marker in the application log, to denote specific points in time within the log." "" }
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
@@ -214,7 +214,7 @@ DF_CoreCmdKind_Null,
|
||||
DF_CoreCmdKind_Null,
|
||||
};
|
||||
|
||||
DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[221] =
|
||||
DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[222] =
|
||||
{
|
||||
{ str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
|
||||
{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp("Exit"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_X},
|
||||
@@ -437,6 +437,7 @@ DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[221] =
|
||||
{ str8_lit_comp("complete_query"), str8_lit_comp("Completes a query."), str8_lit_comp(""), str8_lit_comp("Complete Query"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
|
||||
{ str8_lit_comp("cancel_query"), str8_lit_comp("Cancels a query."), str8_lit_comp(""), str8_lit_comp("Cancel Query"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
|
||||
{ str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp("Toggle Developer Menu"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
|
||||
{ str8_lit_comp("log_marker"), str8_lit_comp("Logs a marker in the application log, to denote specific points in time within the log."), str8_lit_comp(""), str8_lit_comp("Log Marker"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
|
||||
};
|
||||
|
||||
DF_CoreViewRuleSpecInfo df_g_core_view_rule_spec_info_table[19] =
|
||||
|
||||
@@ -269,6 +269,7 @@ DF_CoreCmdKind_PickFileOrFolder,
|
||||
DF_CoreCmdKind_CompleteQuery,
|
||||
DF_CoreCmdKind_CancelQuery,
|
||||
DF_CoreCmdKind_ToggleDevMenu,
|
||||
DF_CoreCmdKind_LogMarker,
|
||||
DF_CoreCmdKind_COUNT,
|
||||
} DF_CoreCmdKind;
|
||||
|
||||
|
||||
@@ -13290,6 +13290,8 @@ df_gfx_begin_frame(Arena *arena, DF_CmdList *cmds)
|
||||
arena_clear(df_gfx_state->rich_hover_info_current_arena);
|
||||
MemoryCopyStruct(&df_gfx_state->rich_hover_info_current, &df_gfx_state->rich_hover_info_next);
|
||||
df_gfx_state->rich_hover_info_current.dbgi_key = di_key_copy(df_gfx_state->rich_hover_info_current_arena, &df_gfx_state->rich_hover_info_current.dbgi_key);
|
||||
arena_clear(df_gfx_state->rich_hover_info_next_arena);
|
||||
MemoryZeroStruct(&df_gfx_state->rich_hover_info_next);
|
||||
|
||||
//- rjf: animate confirmation
|
||||
{
|
||||
|
||||
@@ -171,6 +171,9 @@ DF_DefaultBindingTable:
|
||||
|
||||
//- rjf: command lister
|
||||
{ "run_command" F1 0 0 0 }
|
||||
|
||||
//- rjf: developer commands
|
||||
{ "log_marker" M ctrl shift alt }
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
@@ -267,10 +270,10 @@ DF_GfxViewRuleTable:
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Theme Color Codes
|
||||
//~ rjf: Theme Tables
|
||||
|
||||
@table(name display_name name_lower)
|
||||
DF_ThemeTable:
|
||||
DF_ThemeColorTable:
|
||||
{
|
||||
{Null "Null" null }
|
||||
{PlainText "Plain Text" plain_text }
|
||||
@@ -426,7 +429,7 @@ DF_ThemePresetColorTable:
|
||||
|
||||
@enum DF_ThemeColor:
|
||||
{
|
||||
@expand(DF_ThemeTable a) `$(a.name)`,
|
||||
@expand(DF_ThemeColorTable a) `$(a.name)`,
|
||||
COUNT,
|
||||
}
|
||||
|
||||
@@ -592,12 +595,12 @@ DF_ThemePresetColorTable:
|
||||
|
||||
@data(String8) df_g_theme_color_display_string_table:
|
||||
{
|
||||
@expand(DF_ThemeTable a) `str8_lit_comp("$(a.display_name)")`
|
||||
@expand(DF_ThemeColorTable a) `str8_lit_comp("$(a.display_name)")`
|
||||
}
|
||||
|
||||
@data(String8) df_g_theme_color_cfg_string_table:
|
||||
{
|
||||
@expand(DF_ThemeTable a) `str8_lit_comp("$(a.name_lower)")`
|
||||
@expand(DF_ThemeColorTable a) `str8_lit_comp("$(a.name_lower)")`
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
+10
-7
@@ -6254,8 +6254,8 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FocusPanel));
|
||||
}
|
||||
|
||||
//- rjf: dragging? -> contain cursor
|
||||
if(ui_dragging(sig.base) && sig.base.event_flags == 0)
|
||||
//- rjf: dragging & outside region? -> contain cursor
|
||||
if(ui_dragging(sig.base) && !contains_2f32(sig.base.box->rect, ui_mouse()) && sig.base.event_flags == 0)
|
||||
{
|
||||
tv->contain_cursor = 1;
|
||||
}
|
||||
@@ -7191,8 +7191,8 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FocusPanel));
|
||||
}
|
||||
|
||||
//- rjf: dragging? -> contain cursor
|
||||
if(ui_dragging(sig.base) && sig.base.event_flags == 0)
|
||||
//- rjf: dragging & outside region? -> contain cursor
|
||||
if(ui_dragging(sig.base) && !contains_2f32(sig.base.box->rect, ui_mouse()) && sig.base.event_flags == 0)
|
||||
{
|
||||
dv->contain_cursor = 1;
|
||||
}
|
||||
@@ -8077,8 +8077,8 @@ DF_VIEW_UI_FUNCTION_DEF(Output)
|
||||
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FocusPanel));
|
||||
}
|
||||
|
||||
//- rjf: dragging? -> contain cursor
|
||||
if(ui_dragging(sig.base))
|
||||
//- rjf: dragging & outside region? -> contain cursor
|
||||
if(ui_dragging(sig.base) && !contains_2f32(sig.base.box->rect, ui_mouse()) && sig.base.event_flags == 0)
|
||||
{
|
||||
tv->contain_cursor = 1;
|
||||
}
|
||||
@@ -8849,7 +8849,10 @@ DF_VIEW_UI_FUNCTION_DEF(Memory)
|
||||
// rjf: click & drag -> select
|
||||
if(ui_dragging(sig) && mouse_hover_byte_num != 0)
|
||||
{
|
||||
mv->contain_cursor = 1;
|
||||
if(!contains_2f32(sig.box->rect, ui_mouse()))
|
||||
{
|
||||
mv->contain_cursor = 1;
|
||||
}
|
||||
mv->cursor = mouse_hover_byte_num-1;
|
||||
if(ui_pressed(sig))
|
||||
{
|
||||
|
||||
@@ -598,7 +598,7 @@ str8_lit_comp("goto_name"),
|
||||
str8_lit_comp("function_breakpoint"),
|
||||
};
|
||||
|
||||
DF_StringBindingPair df_g_default_binding_table[104] =
|
||||
DF_StringBindingPair df_g_default_binding_table[105] =
|
||||
{
|
||||
{str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_EventFlag_Shift }},
|
||||
{str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_EventFlag_Alt}},
|
||||
@@ -704,6 +704,7 @@ DF_StringBindingPair df_g_default_binding_table[104] =
|
||||
{str8_lit_comp("attach"), {OS_Key_F6, 0 |OS_EventFlag_Shift }},
|
||||
{str8_lit_comp("filter"), {OS_Key_Slash, 0 |OS_EventFlag_Ctrl }},
|
||||
{str8_lit_comp("run_command"), {OS_Key_F1, 0 }},
|
||||
{str8_lit_comp("log_marker"), {OS_Key_M, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}},
|
||||
};
|
||||
|
||||
String8 df_g_binding_version_remap_old_name_table[5] =
|
||||
|
||||
@@ -296,7 +296,7 @@ extern Vec4F32* df_g_theme_preset_colors_table[9];
|
||||
extern DF_CmdParamSlot df_g_cmd_param_slot_2_view_spec_src_map[7];
|
||||
extern String8 df_g_cmd_param_slot_2_view_spec_dst_map[7];
|
||||
extern String8 df_g_cmd_param_slot_2_view_spec_cmd_map[7];
|
||||
extern DF_StringBindingPair df_g_default_binding_table[104];
|
||||
extern DF_StringBindingPair df_g_default_binding_table[105];
|
||||
extern String8 df_g_binding_version_remap_old_name_table[5];
|
||||
extern String8 df_g_binding_version_remap_new_name_table[5];
|
||||
extern DF_ViewSpecInfo df_g_gfx_view_kind_spec_info_table[31];
|
||||
|
||||
@@ -52,7 +52,7 @@ typedef int64_t RDI_S64;
|
||||
|
||||
// \"raddbg\0\0\"
|
||||
#define RDI_MAGIC_CONSTANT 0x0000676264646172
|
||||
#define RDI_ENCODING_VERSION 6
|
||||
#define RDI_ENCODING_VERSION 7
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//~ Format Types & Functions
|
||||
|
||||
@@ -302,6 +302,14 @@ rdi_line_info_idx_from_voff(RDI_ParsedLineTable *line_info, RDI_U64 voff)
|
||||
{
|
||||
RDI_U64 count = 0;
|
||||
RDI_U64 result = rdi_line_info_idx_range_from_voff(line_info, voff, &count);
|
||||
for(RDI_U64 idx = 0; idx < count && result+idx < line_info->count; idx += 1)
|
||||
{
|
||||
if(line_info->lines[result+idx].file_idx != 0)
|
||||
{
|
||||
result += idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -2861,7 +2861,7 @@ rdim_bake_line_tables(RDIM_Arena *arena, RDIM_LineTableChunkList *src)
|
||||
RDIM_LineTableBakeResult result = {0};
|
||||
{
|
||||
result.line_tables = dst_line_tables;
|
||||
result.line_tables_count = src->total_count;
|
||||
result.line_tables_count = src->total_count+1;
|
||||
result.line_table_voffs = dst_line_voffs;
|
||||
result.line_table_voffs_count = (src->total_line_count + src->total_seq_count);
|
||||
result.line_table_lines = dst_lines;
|
||||
|
||||
+1
-2
@@ -42,8 +42,7 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Hot, High Priority Tasks (Complete Unusability, Crashes, Fire-Worthy)
|
||||
//
|
||||
// [ ] investigate heavy outputdebugstring usage causing major issues
|
||||
// (both in debugger and in target application, apparently)
|
||||
// [ ] asan stepping breakage
|
||||
// [ ] "Browse..." buttons should adopt a more relevant starting search path,
|
||||
// if possible
|
||||
// [ ] PDB files distributed with the build are not found by DbgHelp!!!
|
||||
|
||||
@@ -338,7 +338,7 @@ entry_point(CmdLine *cmd_line)
|
||||
}
|
||||
if(msg.size != 0)
|
||||
{
|
||||
log_infof("IPC message received: \"%S\"", msg);
|
||||
log_infof("ipc_msg: \"%S\"", msg);
|
||||
DF_Window *dst_window = df_gfx_state->first_window;
|
||||
for(DF_Window *window = dst_window; window != 0; window = window->next)
|
||||
{
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
"";
|
||||
"// \"raddbg\0\0\"";
|
||||
"#define RDI_MAGIC_CONSTANT 0x0000676264646172";
|
||||
"#define RDI_ENCODING_VERSION 6";
|
||||
"#define RDI_ENCODING_VERSION 7";
|
||||
"";
|
||||
"////////////////////////////////////////////////////////////////";
|
||||
"//~ Format Types & Functions";
|
||||
|
||||
@@ -387,7 +387,7 @@ static String8Array
|
||||
elf_section_name_array_from_elf(ELF_Parsed *elf){
|
||||
String8Array result = {0};
|
||||
if (elf != 0){
|
||||
result.strings = elf->section_names;
|
||||
result.v = elf->section_names;
|
||||
result.count = elf->section_count;
|
||||
}
|
||||
return(result);
|
||||
|
||||
@@ -1,26 +1,40 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Build Options
|
||||
|
||||
#define BUILD_VERSION_MAJOR 0
|
||||
#define BUILD_VERSION_MINOR 9
|
||||
#define BUILD_VERSION_PATCH 10
|
||||
#define BUILD_RELEASE_PHASE_STRING_LITERAL "ALPHA"
|
||||
#define BUILD_TITLE "rdi_from_dwarf"
|
||||
#define BUILD_CONSOLE_INTERFACE 1
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Includes
|
||||
|
||||
//- rjf: [lib]
|
||||
#include "lib_rdi_format/rdi_format.h"
|
||||
#include "lib_rdi_format/rdi_format.c"
|
||||
#include "third_party/rad_lzb_simple/rad_lzb_simple.h"
|
||||
#include "third_party/rad_lzb_simple/rad_lzb_simple.c"
|
||||
|
||||
//- rjf: [h]
|
||||
#include "base/base_inc.h"
|
||||
#include "os/os_inc.h"
|
||||
#include "rdi_make_local/rdi_make_local.h"
|
||||
|
||||
#include "rdi_make/rdi_make_local.h"
|
||||
#include "rdi_elf.h"
|
||||
#include "rdi_dwarf.h"
|
||||
|
||||
#include "rdi_dwarf_stringize.h"
|
||||
|
||||
#include "rdi_from_dwarf.h"
|
||||
|
||||
#include "lib_rdi_format/rdi_format.c"
|
||||
//- rjf: [c]
|
||||
#include "base/base_inc.c"
|
||||
#include "os/os_inc.c"
|
||||
#include "rdi_make_local/rdi_make_local.c"
|
||||
|
||||
#include "rdi_make/rdi_make_local.c"
|
||||
#include "rdi_elf.c"
|
||||
#include "rdi_dwarf.c"
|
||||
|
||||
#include "rdi_dwarf_stringize.c"
|
||||
|
||||
// TODO(allen):
|
||||
@@ -583,7 +597,7 @@ fprintf(stdout, "error(parsing): " fmt "\n", __VA_ARGS__); \
|
||||
"SECTIONS:\n"));
|
||||
|
||||
ELF_Shdr64 *sec = section_array.sections;
|
||||
String8 *sec_name = section_name_array.strings;
|
||||
String8 *sec_name = section_name_array.v;
|
||||
U64 count = section_array.count;
|
||||
for (U64 i = 0 ; i < count; i += 1, sec += 1, sec_name += 1){
|
||||
String8 type_string = elf_string_from_section_type(sec->sh_type);
|
||||
|
||||
@@ -2696,7 +2696,7 @@ internal TS_TASK_FUNCTION_DEF(p2r_symbol_stream_convert_task__entry_point)
|
||||
|
||||
// rjf: find current procedure's frameproc
|
||||
CV_SymFrameproc *frameproc = 0;
|
||||
if(procedure_num != 0 && procedure_frameprocs[procedure_num-1] != 0 && procedure_num < procedure_frameprocs_count)
|
||||
if(procedure_num != 0 && procedure_num <= procedure_frameprocs_count && procedure_frameprocs[procedure_num-1] != 0)
|
||||
{
|
||||
frameproc = procedure_frameprocs[procedure_num-1];
|
||||
}
|
||||
@@ -2774,7 +2774,7 @@ internal TS_TASK_FUNCTION_DEF(p2r_symbol_stream_convert_task__entry_point)
|
||||
|
||||
// rjf: find current procedure's frameproc
|
||||
CV_SymFrameproc *frameproc = 0;
|
||||
if(procedure_num != 0 && procedure_frameprocs[procedure_num-1] != 0 && procedure_num < procedure_frameprocs_count)
|
||||
if(procedure_num != 0 && procedure_num <= procedure_frameprocs_count && procedure_frameprocs[procedure_num-1] != 0)
|
||||
{
|
||||
frameproc = procedure_frameprocs[procedure_num-1];
|
||||
}
|
||||
|
||||
@@ -168,6 +168,7 @@ r_init(CmdLine *cmdln)
|
||||
r_d3d11_state->device_rw_mutex = os_rw_mutex_alloc();
|
||||
|
||||
//- rjf: create base device
|
||||
ProfBegin("create base device");
|
||||
UINT creation_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
|
||||
#if BUILD_DEBUG
|
||||
if(cmd_line_has_flag(cmdln, str8_lit("d3d11_debug")))
|
||||
@@ -199,7 +200,6 @@ r_init(CmdLine *cmdln)
|
||||
D3D11_SDK_VERSION,
|
||||
&r_d3d11_state->base_device, 0, &r_d3d11_state->base_device_ctx);
|
||||
}
|
||||
|
||||
if(FAILED(error))
|
||||
{
|
||||
char buffer[256] = {0};
|
||||
@@ -207,10 +207,11 @@ r_init(CmdLine *cmdln)
|
||||
os_graphical_message(1, str8_lit("Fatal Error"), str8_cstring(buffer));
|
||||
os_exit_process(1);
|
||||
}
|
||||
ProfEnd();
|
||||
|
||||
//- rjf: enable break-on-error
|
||||
#if BUILD_DEBUG
|
||||
if(cmd_line_has_flag(cmdln, str8_lit("d3d11_debug")))
|
||||
if(cmd_line_has_flag(cmdln, str8_lit("d3d11_debug"))) ProfScope("enable break-on-error")
|
||||
{
|
||||
ID3D11InfoQueue *info = 0;
|
||||
error = r_d3d11_state->base_device->lpVtbl->QueryInterface(r_d3d11_state->base_device, &IID_ID3D11InfoQueue, (void **)(&info));
|
||||
@@ -224,15 +225,20 @@ r_init(CmdLine *cmdln)
|
||||
#endif
|
||||
|
||||
//- rjf: get main device
|
||||
ProfBegin("get main device");
|
||||
error = r_d3d11_state->base_device->lpVtbl->QueryInterface(r_d3d11_state->base_device, &IID_ID3D11Device1, (void **)(&r_d3d11_state->device));
|
||||
error = r_d3d11_state->base_device_ctx->lpVtbl->QueryInterface(r_d3d11_state->base_device_ctx, &IID_ID3D11DeviceContext1, (void **)(&r_d3d11_state->device_ctx));
|
||||
ProfEnd();
|
||||
|
||||
//- rjf: get dxgi device/adapter/factory
|
||||
ProfBegin("get dxgi device/adapter/factory");
|
||||
error = r_d3d11_state->device->lpVtbl->QueryInterface(r_d3d11_state->device, &IID_IDXGIDevice1, (void **)(&r_d3d11_state->dxgi_device));
|
||||
error = r_d3d11_state->dxgi_device->lpVtbl->GetAdapter(r_d3d11_state->dxgi_device, &r_d3d11_state->dxgi_adapter);
|
||||
error = r_d3d11_state->dxgi_adapter->lpVtbl->GetParent(r_d3d11_state->dxgi_adapter, &IID_IDXGIFactory2, (void **)(&r_d3d11_state->dxgi_factory));
|
||||
ProfEnd();
|
||||
|
||||
//- rjf: create main rasterizer
|
||||
ProfScope("create main rasterizer")
|
||||
{
|
||||
D3D11_RASTERIZER_DESC1 desc = {D3D11_FILL_SOLID};
|
||||
{
|
||||
@@ -244,6 +250,7 @@ r_init(CmdLine *cmdln)
|
||||
}
|
||||
|
||||
//- rjf: create main blend state
|
||||
ProfScope("create main blend state")
|
||||
{
|
||||
D3D11_BLEND_DESC desc = {0};
|
||||
{
|
||||
@@ -259,6 +266,8 @@ r_init(CmdLine *cmdln)
|
||||
error = r_d3d11_state->device->lpVtbl->CreateBlendState(r_d3d11_state->device, &desc, &r_d3d11_state->main_blend_state);
|
||||
}
|
||||
|
||||
//- rjf: create empty blend state
|
||||
ProfScope("create empty blend state")
|
||||
{
|
||||
D3D11_BLEND_DESC desc = {0};
|
||||
{
|
||||
@@ -269,6 +278,7 @@ r_init(CmdLine *cmdln)
|
||||
}
|
||||
|
||||
//- rjf: create nearest-neighbor sampler
|
||||
ProfScope("create nearest-neighbor sampler")
|
||||
{
|
||||
D3D11_SAMPLER_DESC desc = zero_struct;
|
||||
{
|
||||
@@ -282,6 +292,7 @@ r_init(CmdLine *cmdln)
|
||||
}
|
||||
|
||||
//- rjf: create bilinear sampler
|
||||
ProfScope("create bilinear sampler")
|
||||
{
|
||||
D3D11_SAMPLER_DESC desc = zero_struct;
|
||||
{
|
||||
@@ -295,6 +306,7 @@ r_init(CmdLine *cmdln)
|
||||
}
|
||||
|
||||
//- rjf: create noop depth/stencil state
|
||||
ProfScope("create noop depth/stencil state")
|
||||
{
|
||||
D3D11_DEPTH_STENCIL_DESC desc = {0};
|
||||
{
|
||||
@@ -306,6 +318,7 @@ r_init(CmdLine *cmdln)
|
||||
}
|
||||
|
||||
//- rjf: create plain depth/stencil state
|
||||
ProfScope("create plain depth/stencil state")
|
||||
{
|
||||
D3D11_DEPTH_STENCIL_DESC desc = {0};
|
||||
{
|
||||
@@ -317,6 +330,7 @@ r_init(CmdLine *cmdln)
|
||||
}
|
||||
|
||||
//- rjf: create buffers
|
||||
ProfScope("create buffers")
|
||||
{
|
||||
D3D11_BUFFER_DESC desc = {0};
|
||||
{
|
||||
@@ -329,9 +343,10 @@ r_init(CmdLine *cmdln)
|
||||
}
|
||||
|
||||
//- rjf: build vertex shaders & input layouts
|
||||
for(R_D3D11_VShadKind kind = (R_D3D11_VShadKind)0;
|
||||
kind < R_D3D11_VShadKind_COUNT;
|
||||
kind = (R_D3D11_VShadKind)(kind+1))
|
||||
ProfScope("build vertex shaders & input layouts")
|
||||
for(R_D3D11_VShadKind kind = (R_D3D11_VShadKind)0;
|
||||
kind < R_D3D11_VShadKind_COUNT;
|
||||
kind = (R_D3D11_VShadKind)(kind+1))
|
||||
{
|
||||
String8 source = *r_d3d11_g_vshad_kind_source_table[kind];
|
||||
String8 source_name = r_d3d11_g_vshad_kind_source_name_table[kind];
|
||||
@@ -342,6 +357,7 @@ r_init(CmdLine *cmdln)
|
||||
ID3DBlob *vshad_source_blob = 0;
|
||||
ID3DBlob *vshad_source_errors = 0;
|
||||
ID3D11VertexShader *vshad = 0;
|
||||
ProfScope("compile vertex shader")
|
||||
{
|
||||
error = D3DCompile(source.str,
|
||||
source.size,
|
||||
@@ -396,6 +412,7 @@ r_init(CmdLine *cmdln)
|
||||
ID3DBlob *pshad_source_blob = 0;
|
||||
ID3DBlob *pshad_source_errors = 0;
|
||||
ID3D11PixelShader *pshad = 0;
|
||||
ProfScope("compile pixel shader")
|
||||
{
|
||||
error = D3DCompile(source.str,
|
||||
source.size,
|
||||
@@ -428,9 +445,10 @@ r_init(CmdLine *cmdln)
|
||||
}
|
||||
|
||||
//- rjf: build uniform type buffers
|
||||
for(R_D3D11_UniformTypeKind kind = (R_D3D11_UniformTypeKind)0;
|
||||
kind < R_D3D11_UniformTypeKind_COUNT;
|
||||
kind = (R_D3D11_UniformTypeKind)(kind+1))
|
||||
ProfScope("build uniform type buffers")
|
||||
for(R_D3D11_UniformTypeKind kind = (R_D3D11_UniformTypeKind)0;
|
||||
kind < R_D3D11_UniformTypeKind_COUNT;
|
||||
kind = (R_D3D11_UniformTypeKind)(kind+1))
|
||||
{
|
||||
ID3D11Buffer *buffer = 0;
|
||||
{
|
||||
@@ -449,6 +467,7 @@ r_init(CmdLine *cmdln)
|
||||
}
|
||||
|
||||
//- rjf: create backup texture
|
||||
ProfScope("create backup texture")
|
||||
{
|
||||
U32 backup_texture_data[] =
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user