mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-13 07:32:23 -07:00
Merge tag 'v0.9.10-alpha' into odin
This commit is contained in:
@@ -20,26 +20,20 @@ You can download pre-built binaries for the debugger
|
||||
[here](https://github.com/EpicGames/raddebugger/releases).
|
||||
|
||||
The RAD Debugger project aims to simplify the debugger by simplifying and
|
||||
unifying the underlying debug info format. In that pursuit we've built
|
||||
the RADDBGI debug info format, which is what the debugger parses and uses. To
|
||||
work with existing toolchains, we convert PDB (and eventually PE/ELF files
|
||||
with embedded DWARF) into the RADDBGI format on-demand. This conversion process
|
||||
is currently an unoptimized reference version. Nevertheless it's still quite
|
||||
fast for smaller PDB files (in many cases faster than many other programs
|
||||
simply deserialize the PDBs). It is much slower for much larger projects at the
|
||||
moment, but we expect this will vastly improve overtime.
|
||||
unifying the underlying debug info format. In that pursuit we've built the RAD
|
||||
Debug Info (RDI) format, which is what the debugger parses and uses. To work
|
||||
with existing toolchains, we convert PDB (and eventually PE/ELF files with
|
||||
embedded DWARF) into the RDI format on-demand.
|
||||
|
||||
The RADDBGI format is currently specified in code, in the files within the
|
||||
`src/lib_raddbgi_format` folder. The other relevant folders for working with
|
||||
the format are:
|
||||
The RDI format is currently specified in code, in the files within the
|
||||
`src/lib_rdi_format` folder. The other relevant folders for working with the
|
||||
format are:
|
||||
|
||||
- `lib_raddbgi_make`: The "RAD Debug Info Make" library, for making RADDBGI
|
||||
debug info.
|
||||
- `raddbgi_from_pdb`: Our PDB-to-RADDBGI converter. Can be used as a helper
|
||||
codebase layer, or built as an executable with a command line interface
|
||||
frontend.
|
||||
- `raddbgi_from_dwarf`: Our in-progress DWARF-to-RADDBGI converter.
|
||||
- `raddbgi_dump`: Our RADDBGI textual dumping utility.
|
||||
- `lib_rdi_make`: The "RAD Debug Info Make" library, for making RDI debug info.
|
||||
- `rdi_from_pdb`: Our PDB-to-RDI converter. Can be used as a helper codebase
|
||||
layer, or built as an executable with a command line interface frontend.
|
||||
- `rdi_from_dwarf`: Our in-progress DWARF-to-RDI converter.
|
||||
- `rdi_dump`: Our RDI textual dumping utility.
|
||||
|
||||
## Development Setup Instructions
|
||||
|
||||
@@ -126,18 +120,6 @@ there are still cases where the debugger has not been tested, and so there are
|
||||
still issues. So, we feel that the top priority is eliminating these issues,
|
||||
such that the debugging experience is rock solid.
|
||||
|
||||
Additionally, the debug info conversion process is not fast (nor wide) enough
|
||||
to support extremely large projects. This is for two reasons: (a) the
|
||||
PDB-to-RADDBGI converter is an unoptimized reference implementation, and (b)
|
||||
the debugger learns of new modules (and thus which PDBs to load) in a
|
||||
serially-dependent way (this is necessarily the case for correct debugging
|
||||
results). We expect that the conversion process' performance can be massively
|
||||
improved, and also that some heuristics can be used to begin converting PDBs
|
||||
to RADDBGIs before the debugger knows those PDBs are needed, thus ensuring the
|
||||
associated RADDBGI files are ready instantaneously when the associated modules
|
||||
are finally loaded by the debugger. Improving this situation is a major part of
|
||||
this phase, as it will make the debugger much more usable for large projects.
|
||||
|
||||
### Local x64 Linux Debugging Phase
|
||||
|
||||
The next priority for the project is to take the rock solid x64 Windows
|
||||
@@ -152,11 +134,10 @@ The major parts of this phase are:
|
||||
|
||||
- Porting the `src/demon` layer to implement the Demon local process control
|
||||
abstraction API.
|
||||
- Porting the `src/unwind` layer to support x64 ELF unwinding (currently, there
|
||||
is only an x64 PE unwinding implementation).
|
||||
- Creating a DWARF-to-RADDBGI converter (in the same way that we've built a
|
||||
PDB-to-RADDBGI converter). A partial implementation of this is in
|
||||
`src/raddbgi_from_dwarf`.
|
||||
- Implementing an x64 ELF Linux unwinder in the `src/ctrl` layer.
|
||||
- Creating a DWARF-to-RDI converter (in the same way that we've built a
|
||||
PDB-to-RDI converter). A partial implementation of this is in
|
||||
`src/rdi_from_dwarf`.
|
||||
- Porting the `src/render` layer to implement all of the rendering features the
|
||||
frontend needs on a Linux-compatible API (the backend used on Windows is D3D11).
|
||||
- Porting the `src/font_provider` layer to a Linux-compatible font
|
||||
@@ -218,7 +199,7 @@ so in other words, layers are arranged into a directed acyclic graph.
|
||||
A few layers are built to be used completely independently from the rest of the
|
||||
codebase, as libraries in other codebases and projects. As such, these layers do
|
||||
not depend on any other layers in the codebase. The folders which contain these
|
||||
layers are prefixed with `lib_`, like `lib_raddbgi_format`.
|
||||
layers are prefixed with `lib_`, like `lib_rdi_format`.
|
||||
|
||||
A list of the layers in the codebase and their associated namespaces is below:
|
||||
- `base` (no namespace): Universal, codebase-wide constructs. Strings, math,
|
||||
@@ -235,11 +216,11 @@ A list of the layers in the codebase and their associated namespaces is below:
|
||||
- `dasm` (`DASM_`): An asynchronous disassembly decoder and cache. Users ask for
|
||||
disassembly for a particular virtual address range in a process, and threads
|
||||
implemented in this layer decode and cache the disassembly for that range.
|
||||
- `dbgi` (`DBGI_`): An asynchronous debug info loader and cache. Loads debug
|
||||
info stored in the RADDBGI format. Users ask for debug info for a particular
|
||||
executable, and on separate threads, this layer loads the associated debug
|
||||
info file. If necessary, it will launch a separate conversion process to
|
||||
convert original debug info into the RADDBGI format.
|
||||
- `dbgi` (`DI_`): An asynchronous debug info loader and cache. Loads debug info
|
||||
stored in the RDI format. Users ask for debug info for a particular path, and
|
||||
on separate threads, this layer loads the associated debug info file. If
|
||||
necessary, it will launch a separate conversion process to convert original
|
||||
debug info into the RDI format.
|
||||
- `demon` (`DEMON_`): An abstraction layer for local-machine, low-level process
|
||||
control. The abstraction is used to provide a common interface for process
|
||||
control on target platforms. Used to implement part of `ctrl`.
|
||||
@@ -274,13 +255,13 @@ A list of the layers in the codebase and their associated namespaces is below:
|
||||
- `lib_raddbg_markup` (`RADDBG_`): Standalone library for marking up user
|
||||
programs to work with various features in the `raddbg` debugger. Does not
|
||||
depend on `base`, and can be independently relocated to other codebases.
|
||||
- `lib_raddbgi_make` (`RDIM_`): Standalone library for constructing RADDBGI
|
||||
debug info data. Does not depend on `base`, and can be independently relocated
|
||||
- `lib_rdi_make` (`RDIM_`): Standalone library for constructing RDI debug info
|
||||
data. Does not depend on `base`, and can be independently relocated
|
||||
to other codebases.
|
||||
- `lib_raddbgi_format` (`RDI_`): Standalone library which defines the core
|
||||
RADDBGI types and helper functions for reading and writing the RADDBGI debug
|
||||
info file format. Does not depend on `base`, and can be independently
|
||||
relocated to other codebases.
|
||||
- `lib_rdi_format` (`RDI_`): Standalone library which defines the core RDI types
|
||||
and helper functions for reading and writing the RDI debug info file format.
|
||||
Does not depend on `base`, and can be independently relocated to other
|
||||
codebases.
|
||||
- `metagen` (`MG_`): A metaprogram which is used to generate primarily code and
|
||||
data tables. Consumes Metadesk files, stored with the extension `.mdesk`, and
|
||||
generates C code which is then included by hand-written C code. Currently, it
|
||||
@@ -315,11 +296,11 @@ A list of the layers in the codebase and their associated namespaces is below:
|
||||
- `raddbg` (no namespace): The layer which ties everything together for the main
|
||||
graphical debugger. Not much "meat", just drives `df`, implements command line
|
||||
options, and so on.
|
||||
- `raddbgi_from_pdb` (`P2R_`): Our implementation of PDB-to-RADDBGI conversion.
|
||||
- `raddbgi_from_dwarf` (`D2R_`): Our in-progress implementation of
|
||||
DWARF-to-RADDBGI conversion.
|
||||
- `raddbgi_dump` (`RADDBGIDUMP_`): A dumper utility program for dumping
|
||||
textualizations of RADDBGI debug info files.
|
||||
- `rdi_from_pdb` (`P2R_`): Our implementation of PDB-to-RDI conversion.
|
||||
- `rdi_from_dwarf` (`D2R_`): Our in-progress implementation of DWARF-to-RDI
|
||||
conversion.
|
||||
- `rdi_dump` (no namespace): A dumper utility program for dumping
|
||||
textualizations of RDI debug info files.
|
||||
- `regs` (`REGS_`): Types, helper functions, and metadata for registers on
|
||||
supported architectures. Used in reading/writing registers in `demon`, or in
|
||||
looking up register metadata.
|
||||
@@ -338,11 +319,9 @@ A list of the layers in the codebase and their associated namespaces is below:
|
||||
Used by the debugger to visualize source code files. Users ask for text lines,
|
||||
tokens, and metadata, and it is prepared on background threads.
|
||||
- `type_graph` (`TG_`): Code for analyzing and navigating type structures from
|
||||
RADDBGI debug info files, with the additional capability of constructing
|
||||
RDI debug info files, with the additional capability of constructing
|
||||
synthetic types *not* found in debug info. Used in `eval` and for various
|
||||
visualization features.
|
||||
- `ui` (`UI_`): Machinery for building graphical user interfaces. Provides a
|
||||
core immediate mode hierarchical user interface data structure building
|
||||
API, and has helper layers for building some higher-level widgets.
|
||||
- `unwind` (`UNW_`): Code for generating unwind information from threads, for
|
||||
supported operating systems and architectures.
|
||||
|
||||
@@ -15,7 +15,7 @@ cd /D "%~dp0"
|
||||
:: `build raddbg clang`
|
||||
:: `build raddbg release`
|
||||
:: `build raddbg asan telemetry`
|
||||
:: `build raddbgi_from_pdb`
|
||||
:: `build rdi_from_pdb`
|
||||
::
|
||||
:: For a full list of possible build targets and their build command lines,
|
||||
:: search for @build_targets in this file.
|
||||
@@ -54,12 +54,14 @@ set clang_out= -o
|
||||
|
||||
:: --- Per-Build Settings -----------------------------------------------------
|
||||
set link_dll=-DLL
|
||||
if "%msvc%"=="1" set only_compile=/c
|
||||
if "%clang%"=="1" set only_compile=-c
|
||||
if "%msvc%"=="1" set EHsc=/EHsc
|
||||
if "%clang%"=="1" set EHsc=
|
||||
if "%msvc%"=="1" set rc=rc.exe
|
||||
if "%clang%"=="1" set rc=llvm-rc.exe
|
||||
if "%msvc%"=="1" set only_compile=/c
|
||||
if "%clang%"=="1" set only_compile=-c
|
||||
if "%msvc%"=="1" set EHsc=/EHsc
|
||||
if "%clang%"=="1" set EHsc=
|
||||
if "%msvc%"=="1" set no_aslr=/DYNAMICBASE:NO
|
||||
if "%clang%"=="1" set no_aslr=
|
||||
if "%msvc%"=="1" set rc=rc.exe
|
||||
if "%clang%"=="1" set rc=llvm-rc.exe
|
||||
|
||||
:: --- Choose Compile/Link Lines ----------------------------------------------
|
||||
if "%msvc%"=="1" set compile_debug=%cl_debug%
|
||||
@@ -97,16 +99,23 @@ if not "%no_meta%"=="1" (
|
||||
:: --- Build Everything (@build_targets) --------------------------------------
|
||||
pushd build
|
||||
if "%raddbg%"=="1" %compile% %gfx% ..\src\raddbg\raddbg_main.cpp %compile_link% %out%raddbg.exe || exit /b 1
|
||||
if "%raddbgi_from_pdb%"=="1" %compile% ..\src\raddbgi_from_pdb\raddbgi_from_pdb_main.c %compile_link% %out%raddbgi_from_pdb.exe || exit /b 1
|
||||
if "%raddbgi_from_dwarf%"=="1" %compile% ..\src\raddbgi_from_dwarf\raddbgi_from_dwarf.c %compile_link% %out%raddbgi_from_dwarf.exe || exit /b 1
|
||||
if "%raddbgi_dump%"=="1" %compile% ..\src\raddbgi_dump\raddbgi_dump_main.c %compile_link% %out%raddbgi_dump.exe || exit /b 1
|
||||
if "%raddbgi_breakpad_from_pdb%"=="1" %compile% ..\src\raddbgi_breakpad_from_pdb\raddbgi_breakpad_from_pdb_main.c %compile_link% %out%raddbgi_breakpad_from_pdb.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% %out%mule_main.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 "%mule_peb_trample%"=="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
|
||||
%compile% ..\src\mule\mule_peb_trample.c %compile_link% %out%mule_peb_trample_new.exe || exit /b 1
|
||||
move mule_peb_trample_new.exe mule_peb_trample.exe
|
||||
)
|
||||
popd
|
||||
|
||||
:: --- Unset ------------------------------------------------------------------
|
||||
|
||||
+7
-7
@@ -56,7 +56,7 @@ commands =
|
||||
},
|
||||
.rjf_f2 =
|
||||
{
|
||||
.win = "build raddbgi_from_pdb telemetry release",
|
||||
.win = "build mule_peb_trample",
|
||||
.linux = "",
|
||||
.out = "*compilation*",
|
||||
.footer_panel = true,
|
||||
@@ -74,7 +74,7 @@ commands =
|
||||
},
|
||||
.rjf_f4 =
|
||||
{
|
||||
.win = "build raddbgi_from_pdb release telemetry && pushd build && raddbgi_from_pdb.exe --exe:UnrealEditorFortnite.exe --pdb:UnrealEditorFortnite.pdb --out:UnrealEditorFortnite.raddbgi --capture && popd",
|
||||
.win = "build rdi_from_pdb release telemetry && pushd build && rdi_from_pdb.exe --exe:UnrealEditorFortnite.exe --pdb:UnrealEditorFortnite.pdb --out:UnrealEditorFortnite.rdi --capture && popd",
|
||||
.linux = "",
|
||||
.out = "*compilation*",
|
||||
.footer_panel = true,
|
||||
@@ -83,7 +83,7 @@ commands =
|
||||
},
|
||||
.rjf_f5 =
|
||||
{
|
||||
.win = "pushd build && raddbgi_from_pdb.exe --exe:raddbg.exe --pdb:raddbg.pdb --out:raddbg.raddbg --capture && popd",
|
||||
.win = "pushd build && rdi_from_pdb.exe --exe:raddbg.exe --pdb:raddbg.pdb --out:raddbg.rdi --capture && popd",
|
||||
.linux = "",
|
||||
.out = "*compilation*",
|
||||
.footer_panel = true,
|
||||
@@ -108,18 +108,18 @@ commands =
|
||||
.save_dirty_files = true,
|
||||
.cursor_at_end = false,
|
||||
},
|
||||
.build_raddbgi_from_pdb =
|
||||
.build_rdi_from_pdb =
|
||||
{
|
||||
.win = "build raddbgi_from_pdb",
|
||||
.win = "build rdi_from_pdb",
|
||||
.linux = "",
|
||||
.out = "*compilation*",
|
||||
.footer_panel = true,
|
||||
.save_dirty_files = true,
|
||||
.cursor_at_end = false,
|
||||
},
|
||||
.build_raddbgi_dump =
|
||||
.build_rdi_dump =
|
||||
{
|
||||
.win = "build raddbgi_dump",
|
||||
.win = "build rdi_dump",
|
||||
.linux = "",
|
||||
.out = "*compilation*",
|
||||
.footer_panel = true,
|
||||
|
||||
@@ -92,6 +92,7 @@ cmd_line_from_string_list(Arena *arena, String8List command_line)
|
||||
|
||||
// NOTE(rjf): Parse command line.
|
||||
B32 after_passthrough_option = 0;
|
||||
B32 first_passthrough = 1;
|
||||
for(String8Node *node = command_line.first->next, *next = 0; node != 0; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
@@ -175,10 +176,11 @@ cmd_line_from_string_list(Arena *arena, String8List command_line)
|
||||
|
||||
// NOTE(rjf): Default path, treat as a passthrough config option to be
|
||||
// handled by tool-specific code.
|
||||
else if(!str8_match(node->string, str8_lit("--"), 0))
|
||||
else if(!str8_match(node->string, str8_lit("--"), 0) || !first_passthrough)
|
||||
{
|
||||
str8_list_push(arena, &parsed.inputs, node->string);
|
||||
after_passthrough_option = 1;
|
||||
first_passthrough = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+22
-19
@@ -18,59 +18,62 @@ main_thread_base_entry_point(void (*entry_point)(CmdLine *cmdline), char **argum
|
||||
{
|
||||
ProfBeginCapture(arguments[0]);
|
||||
}
|
||||
#if defined(OS_CORE_H)
|
||||
#if defined(OS_CORE_H) && !defined(OS_INIT_MANUAL)
|
||||
os_init();
|
||||
#endif
|
||||
#if defined(TASK_SYSTEM_H)
|
||||
#if defined(TASK_SYSTEM_H) && !defined(TS_INIT_MANUAL)
|
||||
ts_init();
|
||||
#endif
|
||||
#if defined(HASH_STORE_H)
|
||||
#if defined(HASH_STORE_H) && !defined(HS_INIT_MANUAL)
|
||||
hs_init();
|
||||
#endif
|
||||
#if defined(FILE_STREAM_H)
|
||||
#if defined(FILE_STREAM_H) && !defined(FS_INIT_MANUAL)
|
||||
fs_init();
|
||||
#endif
|
||||
#if defined(TEXT_CACHE_H)
|
||||
#if defined(TEXT_CACHE_H) && !defined(TXT_INIT_MANUAL)
|
||||
txt_init();
|
||||
#endif
|
||||
#if defined(DASM_CACHE_H)
|
||||
#if defined(DASM_CACHE_H) && !defined(DASM_INIT_MANUAL)
|
||||
dasm_init();
|
||||
#endif
|
||||
#if defined(DBGI_H)
|
||||
dbgi_init();
|
||||
#if defined(DI_H) && !defined(DI_INIT_MANUAL)
|
||||
di_init();
|
||||
#endif
|
||||
#if defined(TXTI_H)
|
||||
#if defined(FUZZY_SEARCH_H) && !defined(FZY_INIT_MANUAL)
|
||||
fzy_init();
|
||||
#endif
|
||||
#if defined(TXTI_H) && !defined(TXTI_INIT_MANUAL)
|
||||
txti_init();
|
||||
#endif
|
||||
#if defined(DEMON_CORE_H)
|
||||
#if defined(DEMON_CORE_H) && !defined(DMN_INIT_MANUAL)
|
||||
dmn_init();
|
||||
#endif
|
||||
#if defined(CTRL_CORE_H)
|
||||
#if defined(CTRL_CORE_H) && !defined(CTRL_INIT_MANUAL)
|
||||
ctrl_init();
|
||||
#endif
|
||||
#if defined(OS_GRAPHICAL_H)
|
||||
#if defined(OS_GRAPHICAL_H) && !defined(OS_GFX_INIT_MANUAL)
|
||||
os_graphical_init();
|
||||
#endif
|
||||
#if defined(FONT_PROVIDER_H)
|
||||
#if defined(FONT_PROVIDER_H) && !defined(FP_INIT_MANUAL)
|
||||
fp_init();
|
||||
#endif
|
||||
#if defined(RENDER_CORE_H)
|
||||
#if defined(RENDER_CORE_H) && !defined(R_INIT_MANUAL)
|
||||
r_init(&cmdline);
|
||||
#endif
|
||||
#if defined(TEXTURE_CACHE_H)
|
||||
#if defined(TEXTURE_CACHE_H) && !defined(TEX_INIT_MANUAL)
|
||||
tex_init();
|
||||
#endif
|
||||
#if defined(GEO_CACHE_H)
|
||||
#if defined(GEO_CACHE_H) && !defined(GEO_INIT_MANUAL)
|
||||
geo_init();
|
||||
#endif
|
||||
#if defined(FONT_CACHE_H)
|
||||
#if defined(FONT_CACHE_H) && !defined(F_INIT_MANUAL)
|
||||
f_init();
|
||||
#endif
|
||||
#if defined(DF_CORE_H)
|
||||
#if defined(DF_CORE_H) && !defined(DF_INIT_MANUAL)
|
||||
DF_StateDeltaHistory *hist = df_state_delta_history_alloc();
|
||||
df_core_init(&cmdline, hist);
|
||||
#endif
|
||||
#if defined(DF_GFX_H)
|
||||
#if defined(DF_GFX_H) && !defined(DF_GFX_INIT_MANUAL)
|
||||
df_gfx_init(update_and_render, df_state_delta_history());
|
||||
#endif
|
||||
entry_point(&cmdline);
|
||||
|
||||
+1549
-134
File diff suppressed because it is too large
Load Diff
+107
-7
@@ -49,6 +49,7 @@ typedef enum CTRL_EntityKind
|
||||
CTRL_EntityKind_Thread,
|
||||
CTRL_EntityKind_Module,
|
||||
CTRL_EntityKind_EntryPoint,
|
||||
CTRL_EntityKind_DebugInfoPath,
|
||||
CTRL_EntityKind_COUNT
|
||||
}
|
||||
CTRL_EntityKind;
|
||||
@@ -67,6 +68,7 @@ struct CTRL_Entity
|
||||
DMN_Handle handle;
|
||||
U64 id;
|
||||
Rng1U64 vaddr_range;
|
||||
U64 timestamp;
|
||||
String8 string;
|
||||
};
|
||||
|
||||
@@ -107,22 +109,45 @@ struct CTRL_EntityStore
|
||||
////////////////////////////////
|
||||
//~ rjf: Unwind Types
|
||||
|
||||
typedef U32 CTRL_UnwindFlags;
|
||||
enum
|
||||
{
|
||||
CTRL_UnwindFlag_Error = (1<<0),
|
||||
CTRL_UnwindFlag_Stale = (1<<1),
|
||||
};
|
||||
|
||||
typedef struct CTRL_UnwindStepResult CTRL_UnwindStepResult;
|
||||
struct CTRL_UnwindStepResult
|
||||
{
|
||||
CTRL_UnwindFlags flags;
|
||||
};
|
||||
|
||||
typedef struct CTRL_UnwindFrame CTRL_UnwindFrame;
|
||||
struct CTRL_UnwindFrame
|
||||
{
|
||||
CTRL_UnwindFrame *next;
|
||||
CTRL_UnwindFrame *prev;
|
||||
U64 rip;
|
||||
void *regs;
|
||||
};
|
||||
|
||||
typedef struct CTRL_UnwindFrameNode CTRL_UnwindFrameNode;
|
||||
struct CTRL_UnwindFrameNode
|
||||
{
|
||||
CTRL_UnwindFrameNode *next;
|
||||
CTRL_UnwindFrameNode *prev;
|
||||
CTRL_UnwindFrame v;
|
||||
};
|
||||
|
||||
typedef struct CTRL_UnwindFrameArray CTRL_UnwindFrameArray;
|
||||
struct CTRL_UnwindFrameArray
|
||||
{
|
||||
CTRL_UnwindFrame *v;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct CTRL_Unwind CTRL_Unwind;
|
||||
struct CTRL_Unwind
|
||||
{
|
||||
CTRL_UnwindFrame *first;
|
||||
CTRL_UnwindFrame *last;
|
||||
U64 count;
|
||||
B32 error;
|
||||
CTRL_UnwindFrameArray frames;
|
||||
CTRL_UnwindFlags flags;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -224,6 +249,7 @@ typedef enum CTRL_MsgKind
|
||||
CTRL_MsgKind_Run,
|
||||
CTRL_MsgKind_SingleStep,
|
||||
CTRL_MsgKind_SetUserEntryPoints,
|
||||
CTRL_MsgKind_SetModuleDebugInfoPath,
|
||||
CTRL_MsgKind_COUNT,
|
||||
}
|
||||
CTRL_MsgKind;
|
||||
@@ -292,6 +318,9 @@ typedef enum CTRL_EventKind
|
||||
CTRL_EventKind_EndThread,
|
||||
CTRL_EventKind_EndModule,
|
||||
|
||||
//- rjf: debug info changes
|
||||
CTRL_EventKind_ModuleDebugInfoPathChange,
|
||||
|
||||
//- rjf: debug strings
|
||||
CTRL_EventKind_DebugString,
|
||||
CTRL_EventKind_ThreadName,
|
||||
@@ -348,6 +377,7 @@ struct CTRL_Event
|
||||
U64 rip_vaddr;
|
||||
U64 stack_base;
|
||||
U64 tls_root;
|
||||
U64 timestamp;
|
||||
U32 exception_code;
|
||||
String8 string;
|
||||
};
|
||||
@@ -474,6 +504,47 @@ struct CTRL_ThreadRegCache
|
||||
CTRL_ThreadRegCacheStripe *stripes;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Module Image Info Cache Types
|
||||
|
||||
typedef struct CTRL_ModuleImageInfoCacheNode CTRL_ModuleImageInfoCacheNode;
|
||||
struct CTRL_ModuleImageInfoCacheNode
|
||||
{
|
||||
CTRL_ModuleImageInfoCacheNode *next;
|
||||
CTRL_ModuleImageInfoCacheNode *prev;
|
||||
CTRL_MachineID machine_id;
|
||||
DMN_Handle module;
|
||||
Arena *arena;
|
||||
PE_IntelPdata *pdatas;
|
||||
U64 pdatas_count;
|
||||
U64 entry_point_voff;
|
||||
Rng1U64 tls_vaddr_range;
|
||||
String8 initial_debug_info_path;
|
||||
};
|
||||
|
||||
typedef struct CTRL_ModuleImageInfoCacheSlot CTRL_ModuleImageInfoCacheSlot;
|
||||
struct CTRL_ModuleImageInfoCacheSlot
|
||||
{
|
||||
CTRL_ModuleImageInfoCacheNode *first;
|
||||
CTRL_ModuleImageInfoCacheNode *last;
|
||||
};
|
||||
|
||||
typedef struct CTRL_ModuleImageInfoCacheStripe CTRL_ModuleImageInfoCacheStripe;
|
||||
struct CTRL_ModuleImageInfoCacheStripe
|
||||
{
|
||||
Arena *arena;
|
||||
OS_Handle rw_mutex;
|
||||
};
|
||||
|
||||
typedef struct CTRL_ModuleImageInfoCache CTRL_ModuleImageInfoCache;
|
||||
struct CTRL_ModuleImageInfoCache
|
||||
{
|
||||
U64 slots_count;
|
||||
CTRL_ModuleImageInfoCacheSlot *slots;
|
||||
U64 stripes_count;
|
||||
CTRL_ModuleImageInfoCacheStripe *stripes;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Wakeup Hook Function Types
|
||||
|
||||
@@ -496,6 +567,7 @@ struct CTRL_State
|
||||
// rjf: caches
|
||||
CTRL_ProcessMemoryCache process_memory_cache;
|
||||
CTRL_ThreadRegCache thread_reg_cache;
|
||||
CTRL_ModuleImageInfoCache module_image_info_cache;
|
||||
|
||||
// rjf: user -> ctrl msg ring buffer
|
||||
U64 u2c_ring_size;
|
||||
@@ -615,6 +687,7 @@ internal CTRL_EntityStore *ctrl_entity_store_alloc(void);
|
||||
internal void ctrl_entity_store_release(CTRL_EntityStore *store);
|
||||
|
||||
//- rjf: string allocation/deletion
|
||||
internal U64 ctrl_name_bucket_idx_from_string_size(U64 size);
|
||||
internal String8 ctrl_entity_string_alloc(CTRL_EntityStore *store, String8 string);
|
||||
internal void ctrl_entity_string_release(CTRL_EntityStore *store, String8 string);
|
||||
|
||||
@@ -627,6 +700,7 @@ internal void ctrl_entity_equip_string(CTRL_EntityStore *store, CTRL_Entity *ent
|
||||
|
||||
//- rjf: entity store lookups
|
||||
internal CTRL_Entity *ctrl_entity_from_machine_id_handle(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle handle);
|
||||
internal CTRL_Entity *ctrl_entity_child_from_kind(CTRL_Entity *parent, CTRL_EntityKind kind);
|
||||
|
||||
//- rjf: applying events to entity caches
|
||||
internal void ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list);
|
||||
@@ -654,6 +728,8 @@ internal U128 ctrl_hash_store_key_from_process_vaddr_range(CTRL_MachineID machin
|
||||
//- rjf: process memory cache reading helpers
|
||||
internal CTRL_ProcessMemorySlice ctrl_query_cached_data_from_process_vaddr_range(Arena *arena, CTRL_MachineID machine_id, DMN_Handle process, Rng1U64 range, U64 endt_us);
|
||||
internal CTRL_ProcessMemorySlice ctrl_query_cached_zero_terminated_data_from_process_vaddr_limit(Arena *arena, CTRL_MachineID machine_id, DMN_Handle process, U64 vaddr, U64 limit, U64 element_size, U64 endt_us);
|
||||
internal B32 ctrl_read_cached_process_memory(CTRL_MachineID machine_id, DMN_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 endt_us);
|
||||
#define ctrl_read_cached_process_memory_struct(machine_id, process, vaddr, is_stale_out, ptr, endt_us) ctrl_read_cached_process_memory((machine_id), (process), r1u64((vaddr), (vaddr)+(sizeof(*(ptr)))), (is_stale_out), (ptr), (endt_us))
|
||||
|
||||
//- rjf: process memory writing
|
||||
internal B32 ctrl_process_write(CTRL_MachineID machine_id, DMN_Handle process, Rng1U64 range, void *src);
|
||||
@@ -669,9 +745,29 @@ internal U64 ctrl_query_cached_rip_from_thread(CTRL_EntityStore *store, CTRL_Mac
|
||||
//- rjf: thread register writing
|
||||
internal B32 ctrl_thread_write_reg_block(CTRL_MachineID machine_id, DMN_Handle thread, void *block);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Module Image Info Functions
|
||||
|
||||
//- rjf: cache lookups
|
||||
internal PE_IntelPdata *ctrl_intel_pdata_from_module_voff(Arena *arena, CTRL_MachineID machine_id, DMN_Handle module_handle, U64 voff);
|
||||
internal U64 ctrl_entry_point_voff_from_module(CTRL_MachineID machine_id, DMN_Handle module_handle);
|
||||
internal Rng1U64 ctrl_tls_vaddr_range_from_module(CTRL_MachineID machine_id, DMN_Handle module_handle);
|
||||
internal String8 ctrl_initial_debug_info_path_from_module(Arena *arena, CTRL_MachineID machine_id, DMN_Handle module_handle);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Unwinding Functions
|
||||
|
||||
//- rjf: unwind deep copier
|
||||
internal CTRL_Unwind ctrl_unwind_deep_copy(Arena *arena, Architecture arch, CTRL_Unwind *src);
|
||||
|
||||
//- rjf: [x64]
|
||||
internal REGS_Reg64 *ctrl_unwind_reg_from_pe_gpr_reg__pe_x64(REGS_RegBlockX64 *regs, PE_UnwindGprRegX64 gpr_reg);
|
||||
internal CTRL_UnwindStepResult ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle process_handle, DMN_Handle module, REGS_RegBlockX64 *regs, U64 endt_us);
|
||||
|
||||
//- rjf: abstracted unwind step
|
||||
internal CTRL_UnwindStepResult ctrl_unwind_step(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle process_handle, DMN_Handle module, Architecture arch, void *reg_block, U64 endt_us);
|
||||
|
||||
//- rjf: abstracted full unwind
|
||||
internal CTRL_Unwind ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle thread, U64 endt_us);
|
||||
|
||||
////////////////////////////////
|
||||
@@ -709,6 +805,10 @@ internal void ctrl_thread__entry_point(void *p);
|
||||
internal void ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_MachineID machine_id, DMN_Handle process, DMN_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out);
|
||||
internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_MachineID machine_id, DMN_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out);
|
||||
|
||||
//- 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, U64 exe_timestamp);
|
||||
internal void ctrl_thread__module_close(CTRL_MachineID machine_id, DMN_Handle module, String8 path);
|
||||
|
||||
//- 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);
|
||||
|
||||
|
||||
+30
-21
@@ -24,7 +24,7 @@ dasm_params_match(DASM_Params *a, DASM_Params *b)
|
||||
a->style_flags == b->style_flags &&
|
||||
a->syntax == b->syntax &&
|
||||
a->base_vaddr == b->base_vaddr &&
|
||||
str8_match(a->exe_path, b->exe_path, 0));
|
||||
di_key_match(&a->dbgi_key, &b->dbgi_key));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ dasm_scope_touch_node__stripe_r_guarded(DASM_Scope *scope, DASM_Node *node)
|
||||
ins_atomic_u64_eval_assign(&node->last_user_clock_idx_touched, dasm_user_clock_idx());
|
||||
touch->hash = node->hash;
|
||||
MemoryCopyStruct(&touch->params, &node->params);
|
||||
touch->params.exe_path = push_str8_copy(dasm_tctx->arena, touch->params.exe_path);
|
||||
touch->params.dbgi_key = di_key_copy(dasm_tctx->arena, &touch->params.dbgi_key);
|
||||
SLLStackPush(scope->top_touch, touch);
|
||||
}
|
||||
|
||||
@@ -236,6 +236,14 @@ 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);
|
||||
node = stripe->free_node;
|
||||
if(node)
|
||||
{
|
||||
@@ -250,7 +258,7 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params)
|
||||
node->hash = hash;
|
||||
MemoryCopyStruct(&node->params, params);
|
||||
// TODO(rjf): need to make this releasable - currently all exe_paths just leak
|
||||
node->params.exe_path = push_str8_copy(stripe->arena, node->params.exe_path);
|
||||
node->params.dbgi_key = di_key_copy(stripe->arena, &node->params.dbgi_key);
|
||||
node_is_new = 1;
|
||||
}
|
||||
}
|
||||
@@ -294,7 +302,7 @@ dasm_u2p_enqueue_req(U128 hash, DASM_Params *params, U64 endt_us)
|
||||
{
|
||||
U64 unconsumed_size = dasm_shared->u2p_ring_write_pos - dasm_shared->u2p_ring_read_pos;
|
||||
U64 available_size = dasm_shared->u2p_ring_size - unconsumed_size;
|
||||
if(available_size >= sizeof(hash)+sizeof(U64)+sizeof(Architecture)+sizeof(DASM_StyleFlags)+sizeof(DASM_Syntax)+sizeof(U64)+sizeof(U64)+params->exe_path.size)
|
||||
if(available_size >= sizeof(hash)+sizeof(U64)+sizeof(Architecture)+sizeof(DASM_StyleFlags)+sizeof(DASM_Syntax)+sizeof(U64)+sizeof(U64)+params->dbgi_key.path.size+sizeof(U64))
|
||||
{
|
||||
good = 1;
|
||||
dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, &hash);
|
||||
@@ -303,8 +311,9 @@ dasm_u2p_enqueue_req(U128 hash, DASM_Params *params, U64 endt_us)
|
||||
dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, ¶ms->style_flags);
|
||||
dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, ¶ms->syntax);
|
||||
dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, ¶ms->base_vaddr);
|
||||
dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, ¶ms->exe_path.size);
|
||||
dasm_shared->u2p_ring_write_pos += ring_write(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, params->exe_path.str, params->exe_path.size);
|
||||
dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, ¶ms->dbgi_key.path.size);
|
||||
dasm_shared->u2p_ring_write_pos += ring_write(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, params->dbgi_key.path.str, params->dbgi_key.path.size);
|
||||
dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, ¶ms->dbgi_key.min_timestamp);
|
||||
dasm_shared->u2p_ring_write_pos += 7;
|
||||
dasm_shared->u2p_ring_write_pos -= dasm_shared->u2p_ring_write_pos%8;
|
||||
break;
|
||||
@@ -328,7 +337,7 @@ dasm_u2p_dequeue_req(Arena *arena, U128 *hash_out, DASM_Params *params_out)
|
||||
OS_MutexScope(dasm_shared->u2p_ring_mutex) for(;;)
|
||||
{
|
||||
U64 unconsumed_size = dasm_shared->u2p_ring_write_pos - dasm_shared->u2p_ring_read_pos;
|
||||
if(unconsumed_size >= sizeof(*hash_out)+sizeof(U64)+sizeof(Architecture)+sizeof(DASM_StyleFlags)+sizeof(DASM_Syntax)+sizeof(U64)+sizeof(U64))
|
||||
if(unconsumed_size >= sizeof(*hash_out)+sizeof(U64)+sizeof(Architecture)+sizeof(DASM_StyleFlags)+sizeof(DASM_Syntax)+sizeof(U64)+sizeof(U64)+sizeof(U64))
|
||||
{
|
||||
dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, hash_out);
|
||||
dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, ¶ms_out->vaddr);
|
||||
@@ -336,9 +345,10 @@ dasm_u2p_dequeue_req(Arena *arena, U128 *hash_out, DASM_Params *params_out)
|
||||
dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, ¶ms_out->style_flags);
|
||||
dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, ¶ms_out->syntax);
|
||||
dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, ¶ms_out->base_vaddr);
|
||||
dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, ¶ms_out->exe_path.size);
|
||||
params_out->exe_path.str = push_array(arena, U8, params_out->exe_path.size);
|
||||
dasm_shared->u2p_ring_read_pos += ring_read(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, params_out->exe_path.str, params_out->exe_path.size);
|
||||
dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, ¶ms_out->dbgi_key.path.size);
|
||||
params_out->dbgi_key.path.str = push_array(arena, U8, params_out->dbgi_key.path.size);
|
||||
dasm_shared->u2p_ring_read_pos += ring_read(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, params_out->dbgi_key.path.str, params_out->dbgi_key.path.size);
|
||||
dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, ¶ms_out->dbgi_key.min_timestamp);
|
||||
dasm_shared->u2p_ring_read_pos += 7;
|
||||
dasm_shared->u2p_ring_read_pos -= dasm_shared->u2p_ring_read_pos%8;
|
||||
break;
|
||||
@@ -362,7 +372,7 @@ dasm_parse_thread__entry_point(void *p)
|
||||
dasm_u2p_dequeue_req(scratch.arena, &hash, ¶ms);
|
||||
U64 change_gen = fs_change_gen();
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
DBGI_Scope *dbgi_scope = dbgi_scope_open();
|
||||
DI_Scope *di_scope = di_scope_open();
|
||||
TXT_Scope *txt_scope = txt_scope_open();
|
||||
|
||||
//- rjf: unpack hash
|
||||
@@ -386,12 +396,11 @@ dasm_parse_thread__entry_point(void *p)
|
||||
}
|
||||
|
||||
//- rjf: get dbg info
|
||||
DBGI_Parse *dbgi = &dbgi_parse_nil;
|
||||
if(got_task && params.exe_path.size != 0)
|
||||
RDI_Parsed *rdi = &di_rdi_parsed_nil;
|
||||
if(got_task && params.dbgi_key.path.size != 0)
|
||||
{
|
||||
dbgi = dbgi_parse_from_exe_path(dbgi_scope, params.exe_path, max_U64);
|
||||
rdi = di_rdi_from_key(di_scope, ¶ms.dbgi_key, max_U64);
|
||||
}
|
||||
RDI_Parsed *rdi = &dbgi->rdi;
|
||||
|
||||
//- rjf: hash -> data
|
||||
String8 data = {0};
|
||||
@@ -442,7 +451,7 @@ dasm_parse_thread__entry_point(void *p)
|
||||
// rjf: push strings derived from voff -> line info
|
||||
if(params.style_flags & (DASM_StyleFlag_SourceFilesNames|DASM_StyleFlag_SourceLines))
|
||||
{
|
||||
if(dbgi != &dbgi_parse_nil)
|
||||
if(rdi != &di_rdi_parsed_nil)
|
||||
{
|
||||
U64 voff = (params.vaddr+off) - params.base_vaddr;
|
||||
U32 unit_idx = rdi_vmap_idx_from_voff(rdi->unit_vmap, rdi->unit_vmap_count, voff);
|
||||
@@ -517,7 +526,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 ", dbgi != &dbgi_parse_nil ? " " : "", params.vaddr+off);
|
||||
addr_part = push_str8f(scratch.arena, "%s%016I64X ", rdi != &di_rdi_parsed_nil ? " " : "", params.vaddr+off);
|
||||
}
|
||||
String8 code_bytes_part = {0};
|
||||
if(params.style_flags & DASM_StyleFlag_CodeBytes)
|
||||
@@ -539,7 +548,7 @@ dasm_parse_thread__entry_point(void *p)
|
||||
code_bytes_part = str8_list_join(scratch.arena, &code_bytes_strings, 0);
|
||||
}
|
||||
String8 symbol_part = {0};
|
||||
if(jump_dst_vaddr != 0 && dbgi != &dbgi_parse_nil && params.style_flags & DASM_StyleFlag_SymbolNames)
|
||||
if(jump_dst_vaddr != 0 && rdi != &di_rdi_parsed_nil && params.style_flags & DASM_StyleFlag_SymbolNames)
|
||||
{
|
||||
RDI_U32 scope_idx = rdi_vmap_idx_from_voff(rdi->scope_vmap, rdi->scope_vmap_count, jump_dst_vaddr-params.base_vaddr);
|
||||
if(scope_idx != 0)
|
||||
@@ -590,7 +599,7 @@ dasm_parse_thread__entry_point(void *p)
|
||||
(U64)params.arch,
|
||||
(U64)params.style_flags,
|
||||
(U64)params.syntax,
|
||||
(U64)dbgi,
|
||||
(U64)rdi,
|
||||
0x4d534144,
|
||||
};
|
||||
text_key = hs_hash_from_data(str8((U8 *)hash_data, sizeof(hash_data)));
|
||||
@@ -614,7 +623,7 @@ dasm_parse_thread__entry_point(void *p)
|
||||
{
|
||||
n->info_arena = info_arena;
|
||||
MemoryCopyStruct(&n->info, &info);
|
||||
if(dbgi != &dbgi_parse_nil && params.style_flags & (DASM_StyleFlag_SourceLines|DASM_StyleFlag_SourceFilesNames))
|
||||
if(rdi != &di_rdi_parsed_nil && params.style_flags & (DASM_StyleFlag_SourceLines|DASM_StyleFlag_SourceFilesNames))
|
||||
{
|
||||
n->change_gen = change_gen;
|
||||
}
|
||||
@@ -630,7 +639,7 @@ dasm_parse_thread__entry_point(void *p)
|
||||
}
|
||||
|
||||
txt_scope_close(txt_scope);
|
||||
dbgi_scope_close(dbgi_scope);
|
||||
di_scope_close(di_scope);
|
||||
hs_scope_close(hs_scope);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ struct DASM_Params
|
||||
DASM_StyleFlags style_flags;
|
||||
DASM_Syntax syntax;
|
||||
U64 base_vaddr;
|
||||
String8 exe_path;
|
||||
DI_Key dbgi_key;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
+590
-1078
File diff suppressed because it is too large
Load Diff
+194
-337
@@ -1,294 +1,170 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef DBGI_H
|
||||
#define DBGI_H
|
||||
#ifndef DI_H
|
||||
#define DI_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Info Bundle Types
|
||||
//~ rjf: Cache Key Type
|
||||
|
||||
typedef struct DBGI_Parse DBGI_Parse;
|
||||
struct DBGI_Parse
|
||||
typedef struct DI_Key DI_Key;
|
||||
struct DI_Key
|
||||
{
|
||||
U64 gen;
|
||||
Arena *arena;
|
||||
void *exe_base;
|
||||
FileProperties exe_props;
|
||||
String8 dbg_path;
|
||||
void *dbg_base;
|
||||
FileProperties dbg_props;
|
||||
PE_BinInfo pe;
|
||||
RDI_Parsed rdi;
|
||||
String8 path;
|
||||
U64 min_timestamp;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Exe -> Debug Forced Override Cache Types
|
||||
|
||||
typedef struct DBGI_ForceNode DBGI_ForceNode;
|
||||
struct DBGI_ForceNode
|
||||
typedef struct DI_KeyNode DI_KeyNode;
|
||||
struct DI_KeyNode
|
||||
{
|
||||
DBGI_ForceNode *next;
|
||||
String8 exe_path;
|
||||
U64 dbg_path_cap;
|
||||
U64 dbg_path_size;
|
||||
U8 *dbg_path_base;
|
||||
DI_KeyNode *next;
|
||||
DI_Key v;
|
||||
};
|
||||
|
||||
typedef struct DBGI_ForceSlot DBGI_ForceSlot;
|
||||
struct DBGI_ForceSlot
|
||||
typedef struct DI_KeyList DI_KeyList;
|
||||
struct DI_KeyList
|
||||
{
|
||||
DBGI_ForceNode *first;
|
||||
DBGI_ForceNode *last;
|
||||
};
|
||||
|
||||
typedef struct DBGI_ForceStripe DBGI_ForceStripe;
|
||||
struct DBGI_ForceStripe
|
||||
{
|
||||
Arena *arena;
|
||||
OS_Handle rw_mutex;
|
||||
OS_Handle cv;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Binary Cache State Types
|
||||
|
||||
typedef U32 DBGI_BinaryFlags;
|
||||
enum
|
||||
{
|
||||
DBGI_BinaryFlag_ParseInFlight = (1<<0),
|
||||
};
|
||||
|
||||
typedef struct DBGI_Binary DBGI_Binary;
|
||||
struct DBGI_Binary
|
||||
{
|
||||
// rjf: links & metadata
|
||||
DBGI_Binary *next;
|
||||
String8 exe_path;
|
||||
U64 refcount;
|
||||
U64 scope_touch_count;
|
||||
U64 last_time_enqueued_for_parse_us;
|
||||
DBGI_BinaryFlags flags;
|
||||
U64 gen;
|
||||
|
||||
// rjf: exe handles
|
||||
OS_Handle exe_file;
|
||||
OS_Handle exe_file_map;
|
||||
|
||||
// rjf: debug handles
|
||||
OS_Handle dbg_file;
|
||||
OS_Handle dbg_file_map;
|
||||
|
||||
// rjf: analysis results
|
||||
DBGI_Parse parse;
|
||||
};
|
||||
|
||||
typedef struct DBGI_BinarySlot DBGI_BinarySlot;
|
||||
struct DBGI_BinarySlot
|
||||
{
|
||||
DBGI_Binary *first;
|
||||
DBGI_Binary *last;
|
||||
};
|
||||
|
||||
typedef struct DBGI_BinaryStripe DBGI_BinaryStripe;
|
||||
struct DBGI_BinaryStripe
|
||||
{
|
||||
Arena *arena;
|
||||
OS_Handle rw_mutex;
|
||||
OS_Handle cv;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Fuzzy Search Cache Types
|
||||
|
||||
typedef enum DBGI_FuzzySearchTarget
|
||||
{
|
||||
DBGI_FuzzySearchTarget_Procedures,
|
||||
DBGI_FuzzySearchTarget_GlobalVariables,
|
||||
DBGI_FuzzySearchTarget_ThreadVariables,
|
||||
DBGI_FuzzySearchTarget_UDTs,
|
||||
DBGI_FuzzySearchTarget_COUNT
|
||||
}
|
||||
DBGI_FuzzySearchTarget;
|
||||
|
||||
typedef struct DBGI_FuzzySearchItem DBGI_FuzzySearchItem;
|
||||
struct DBGI_FuzzySearchItem
|
||||
{
|
||||
U64 idx;
|
||||
U64 missed_size;
|
||||
FuzzyMatchRangeList match_ranges;
|
||||
};
|
||||
|
||||
typedef struct DBGI_FuzzySearchItemChunk DBGI_FuzzySearchItemChunk;
|
||||
struct DBGI_FuzzySearchItemChunk
|
||||
{
|
||||
DBGI_FuzzySearchItemChunk *next;
|
||||
DBGI_FuzzySearchItem *v;
|
||||
U64 count;
|
||||
U64 cap;
|
||||
};
|
||||
|
||||
typedef struct DBGI_FuzzySearchItemChunkList DBGI_FuzzySearchItemChunkList;
|
||||
struct DBGI_FuzzySearchItemChunkList
|
||||
{
|
||||
DBGI_FuzzySearchItemChunk *first;
|
||||
DBGI_FuzzySearchItemChunk *last;
|
||||
U64 chunk_count;
|
||||
U64 total_count;
|
||||
};
|
||||
|
||||
typedef struct DBGI_FuzzySearchItemArray DBGI_FuzzySearchItemArray;
|
||||
struct DBGI_FuzzySearchItemArray
|
||||
{
|
||||
DBGI_FuzzySearchItem *v;
|
||||
DI_KeyNode *first;
|
||||
DI_KeyNode *last;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct DBGI_FuzzySearchBucket DBGI_FuzzySearchBucket;
|
||||
struct DBGI_FuzzySearchBucket
|
||||
typedef struct DI_KeyArray DI_KeyArray;
|
||||
struct DI_KeyArray
|
||||
{
|
||||
Arena *arena;
|
||||
String8 exe_path;
|
||||
String8 query;
|
||||
DBGI_FuzzySearchTarget target;
|
||||
};
|
||||
|
||||
typedef struct DBGI_FuzzySearchNode DBGI_FuzzySearchNode;
|
||||
struct DBGI_FuzzySearchNode
|
||||
{
|
||||
DBGI_FuzzySearchNode *next;
|
||||
U128 key;
|
||||
U64 scope_touch_count;
|
||||
U64 last_time_submitted_us;
|
||||
DBGI_FuzzySearchBucket buckets[3];
|
||||
U64 gen;
|
||||
U64 submit_gen;
|
||||
DBGI_FuzzySearchItemArray gen_items;
|
||||
};
|
||||
|
||||
typedef struct DBGI_FuzzySearchSlot DBGI_FuzzySearchSlot;
|
||||
struct DBGI_FuzzySearchSlot
|
||||
{
|
||||
DBGI_FuzzySearchNode *first;
|
||||
DBGI_FuzzySearchNode *last;
|
||||
};
|
||||
|
||||
typedef struct DBGI_FuzzySearchStripe DBGI_FuzzySearchStripe;
|
||||
struct DBGI_FuzzySearchStripe
|
||||
{
|
||||
Arena *arena;
|
||||
OS_Handle rw_mutex;
|
||||
OS_Handle cv;
|
||||
};
|
||||
|
||||
typedef struct DBGI_FuzzySearchThread DBGI_FuzzySearchThread;
|
||||
struct DBGI_FuzzySearchThread
|
||||
{
|
||||
OS_Handle thread;
|
||||
OS_Handle u2f_ring_mutex;
|
||||
OS_Handle u2f_ring_cv;
|
||||
U64 u2f_ring_size;
|
||||
U8 *u2f_ring_base;
|
||||
U64 u2f_ring_write_pos;
|
||||
U64 u2f_ring_read_pos;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Weak Access Scope Types
|
||||
|
||||
typedef struct DBGI_TouchedBinary DBGI_TouchedBinary;
|
||||
struct DBGI_TouchedBinary
|
||||
{
|
||||
DBGI_TouchedBinary *next;
|
||||
DBGI_Binary *binary;
|
||||
};
|
||||
|
||||
typedef struct DBGI_TouchedFuzzySearch DBGI_TouchedFuzzySearch;
|
||||
struct DBGI_TouchedFuzzySearch
|
||||
{
|
||||
DBGI_TouchedFuzzySearch *next;
|
||||
DBGI_FuzzySearchNode *node;
|
||||
};
|
||||
|
||||
typedef struct DBGI_Scope DBGI_Scope;
|
||||
struct DBGI_Scope
|
||||
{
|
||||
DBGI_Scope *next;
|
||||
DBGI_TouchedBinary *first_tb;
|
||||
DBGI_TouchedBinary *last_tb;
|
||||
DBGI_TouchedFuzzySearch *first_tfs;
|
||||
DBGI_TouchedFuzzySearch *last_tfs;
|
||||
};
|
||||
|
||||
typedef struct DBGI_ThreadCtx DBGI_ThreadCtx;
|
||||
struct DBGI_ThreadCtx
|
||||
{
|
||||
Arena *arena;
|
||||
DBGI_Scope *free_scope;
|
||||
DBGI_TouchedBinary *free_tb;
|
||||
DBGI_TouchedFuzzySearch *free_tfs;
|
||||
DI_Key *v;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Event Types
|
||||
|
||||
typedef enum DBGI_EventKind
|
||||
typedef enum DI_EventKind
|
||||
{
|
||||
DBGI_EventKind_Null,
|
||||
DBGI_EventKind_ConversionStarted,
|
||||
DBGI_EventKind_ConversionEnded,
|
||||
DBGI_EventKind_ConversionFailureUnsupportedFormat,
|
||||
DBGI_EventKind_COUNT
|
||||
DI_EventKind_Null,
|
||||
DI_EventKind_ConversionStarted,
|
||||
DI_EventKind_ConversionEnded,
|
||||
DI_EventKind_ConversionFailureUnsupportedFormat,
|
||||
DI_EventKind_COUNT
|
||||
}
|
||||
DBGI_EventKind;
|
||||
DI_EventKind;
|
||||
|
||||
typedef struct DBGI_Event DBGI_Event;
|
||||
struct DBGI_Event
|
||||
typedef struct DI_Event DI_Event;
|
||||
struct DI_Event
|
||||
{
|
||||
DBGI_EventKind kind;
|
||||
DI_EventKind kind;
|
||||
String8 string;
|
||||
};
|
||||
|
||||
typedef struct DBGI_EventNode DBGI_EventNode;
|
||||
struct DBGI_EventNode
|
||||
typedef struct DI_EventNode DI_EventNode;
|
||||
struct DI_EventNode
|
||||
{
|
||||
DBGI_EventNode *next;
|
||||
DBGI_Event v;
|
||||
DI_EventNode *next;
|
||||
DI_Event v;
|
||||
};
|
||||
|
||||
typedef struct DBGI_EventList DBGI_EventList;
|
||||
struct DBGI_EventList
|
||||
typedef struct DI_EventList DI_EventList;
|
||||
struct DI_EventList
|
||||
{
|
||||
DBGI_EventNode *first;
|
||||
DBGI_EventNode *last;
|
||||
DI_EventNode *first;
|
||||
DI_EventNode *last;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cross-Thread Shared State
|
||||
//~ rjf: Cache Types
|
||||
|
||||
typedef struct DBGI_Shared DBGI_Shared;
|
||||
struct DBGI_Shared
|
||||
typedef struct DI_StringChunkNode DI_StringChunkNode;
|
||||
struct DI_StringChunkNode
|
||||
{
|
||||
DI_StringChunkNode *next;
|
||||
U64 size;
|
||||
};
|
||||
|
||||
typedef struct DI_Node DI_Node;
|
||||
struct DI_Node
|
||||
{
|
||||
// rjf: links
|
||||
DI_Node *next;
|
||||
DI_Node *prev;
|
||||
|
||||
// rjf: metadata
|
||||
U64 ref_count;
|
||||
U64 touch_count;
|
||||
U64 is_working;
|
||||
U64 last_time_requested_us;
|
||||
|
||||
// rjf: key
|
||||
DI_Key key;
|
||||
|
||||
// rjf: file handles
|
||||
OS_Handle file;
|
||||
OS_Handle file_map;
|
||||
void *file_base;
|
||||
FileProperties file_props;
|
||||
|
||||
// rjf: parse artifacts
|
||||
Arena *arena;
|
||||
RDI_Parsed rdi;
|
||||
B32 parse_done;
|
||||
};
|
||||
|
||||
typedef struct DI_Slot DI_Slot;
|
||||
struct DI_Slot
|
||||
{
|
||||
DI_Node *first;
|
||||
DI_Node *last;
|
||||
};
|
||||
|
||||
typedef struct DI_Stripe DI_Stripe;
|
||||
struct DI_Stripe
|
||||
{
|
||||
Arena *arena;
|
||||
DI_Node *free_node;
|
||||
DI_StringChunkNode *free_string_chunks[8];
|
||||
OS_Handle rw_mutex;
|
||||
OS_Handle cv;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Scoped Access Types
|
||||
|
||||
typedef struct DI_Touch DI_Touch;
|
||||
struct DI_Touch
|
||||
{
|
||||
DI_Touch *next;
|
||||
DI_Node *node;
|
||||
};
|
||||
|
||||
typedef struct DI_Scope DI_Scope;
|
||||
struct DI_Scope
|
||||
{
|
||||
DI_Scope *next;
|
||||
DI_Touch *first_touch;
|
||||
DI_Touch *last_touch;
|
||||
};
|
||||
|
||||
typedef struct DI_TCTX DI_TCTX;
|
||||
struct DI_TCTX
|
||||
{
|
||||
Arena *arena;
|
||||
DI_Scope *free_scope;
|
||||
DI_Touch *free_touch;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Shared State Types
|
||||
|
||||
typedef struct DI_Shared DI_Shared;
|
||||
struct DI_Shared
|
||||
{
|
||||
// rjf: arena
|
||||
Arena *arena;
|
||||
|
||||
// rjf: forced override table
|
||||
U64 force_slots_count;
|
||||
U64 force_stripes_count;
|
||||
DBGI_ForceSlot *force_slots;
|
||||
DBGI_ForceStripe *force_stripes;
|
||||
|
||||
// rjf: binary table
|
||||
U64 binary_slots_count;
|
||||
U64 binary_stripes_count;
|
||||
DBGI_BinarySlot *binary_slots;
|
||||
DBGI_BinaryStripe *binary_stripes;
|
||||
|
||||
// rjf: fuzzy search cache table
|
||||
U64 fuzzy_search_slots_count;
|
||||
U64 fuzzy_search_stripes_count;
|
||||
DBGI_FuzzySearchSlot *fuzzy_search_slots;
|
||||
DBGI_FuzzySearchStripe *fuzzy_search_stripes;
|
||||
// rjf: node cache
|
||||
U64 slots_count;
|
||||
DI_Slot *slots;
|
||||
U64 stripes_count;
|
||||
DI_Stripe *stripes;
|
||||
|
||||
// rjf: user -> parse ring
|
||||
OS_Handle u2p_ring_mutex;
|
||||
@@ -309,123 +185,104 @@ struct DBGI_Shared
|
||||
// rjf: threads
|
||||
U64 parse_thread_count;
|
||||
OS_Handle *parse_threads;
|
||||
U64 fuzzy_thread_count;
|
||||
DBGI_FuzzySearchThread *fuzzy_threads;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
global DBGI_Shared *dbgi_shared = 0;
|
||||
thread_static DBGI_ThreadCtx *dbgi_tctx = 0;
|
||||
global DBGI_Parse dbgi_parse_nil =
|
||||
global DI_Shared *di_shared = 0;
|
||||
thread_static DI_TCTX *di_tctx = 0;
|
||||
global RDI_Parsed di_rdi_parsed_nil =
|
||||
{
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{0},
|
||||
{0},
|
||||
0,
|
||||
{0},
|
||||
{0},
|
||||
{
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{0},
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&rdi_binary_section_nil, 1,
|
||||
&rdi_file_path_node_nil, 1,
|
||||
&rdi_source_file_nil, 1,
|
||||
&rdi_unit_nil, 1,
|
||||
&rdi_vmap_entry_nil, 1,
|
||||
&rdi_type_node_nil, 1,
|
||||
&rdi_udt_nil, 1,
|
||||
&rdi_member_nil, 1,
|
||||
&rdi_enum_member_nil, 1,
|
||||
&rdi_global_variable_nil, 1,
|
||||
&rdi_vmap_entry_nil, 1,
|
||||
&rdi_thread_variable_nil, 1,
|
||||
&rdi_procedure_nil, 1,
|
||||
&rdi_scope_nil, 1,
|
||||
&rdi_voff_nil, 1,
|
||||
&rdi_vmap_entry_nil, 1,
|
||||
&rdi_local_nil, 1,
|
||||
&rdi_location_block_nil, 1,
|
||||
0, 0,
|
||||
0, 0,
|
||||
},
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&rdi_top_level_info_nil,
|
||||
&rdi_binary_section_nil, 1,
|
||||
&rdi_file_path_node_nil, 1,
|
||||
&rdi_source_file_nil, 1,
|
||||
&rdi_unit_nil, 1,
|
||||
&rdi_vmap_entry_nil, 1,
|
||||
&rdi_type_node_nil, 1,
|
||||
&rdi_udt_nil, 1,
|
||||
&rdi_member_nil, 1,
|
||||
&rdi_enum_member_nil, 1,
|
||||
&rdi_global_variable_nil, 1,
|
||||
&rdi_vmap_entry_nil, 1,
|
||||
&rdi_thread_variable_nil, 1,
|
||||
&rdi_procedure_nil, 1,
|
||||
&rdi_scope_nil, 1,
|
||||
&rdi_voff_nil, 1,
|
||||
&rdi_vmap_entry_nil, 1,
|
||||
&rdi_local_nil, 1,
|
||||
&rdi_location_block_nil, 1,
|
||||
0, 0,
|
||||
0, 0,
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Helpers
|
||||
|
||||
internal U64 di_hash_from_string(String8 string, StringMatchFlags match_flags);
|
||||
internal U64 di_hash_from_key(DI_Key *k);
|
||||
internal B32 di_key_match(DI_Key *a, DI_Key *b);
|
||||
internal DI_Key di_key_copy(Arena *arena, DI_Key *src);
|
||||
internal DI_Key di_normalized_key_from_key(Arena *arena, DI_Key *src);
|
||||
internal void di_key_list_push(Arena *arena, DI_KeyList *list, DI_Key *key);
|
||||
internal DI_KeyArray di_key_array_from_list(Arena *arena, DI_KeyList *list);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Main Layer Initialization
|
||||
|
||||
internal void dbgi_init(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Thread-Context Idempotent Initialization
|
||||
|
||||
internal void dbgi_ensure_tctx_inited(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Helpers
|
||||
|
||||
internal U64 dbgi_hash_from_string(String8 string, StringMatchFlags match_flags);
|
||||
internal U64 dbgi_fuzzy_item_num_from_array_element_idx__linear_search(DBGI_FuzzySearchItemArray *array, U64 element_idx);
|
||||
internal String8 dbgi_fuzzy_item_string_from_rdi_target_element_idx(RDI_Parsed *rdi, DBGI_FuzzySearchTarget target, U64 element_idx);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Forced Override Cache Functions
|
||||
|
||||
internal void dbgi_force_exe_path_dbg_path(String8 exe_path, String8 dbg_path);
|
||||
internal String8 dbgi_forced_dbg_path_from_exe_path(Arena *arena, String8 exe_path);
|
||||
internal void di_init(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Scope Functions
|
||||
|
||||
internal DBGI_Scope *dbgi_scope_open(void);
|
||||
internal void dbgi_scope_close(DBGI_Scope *scope);
|
||||
internal void dbgi_scope_touch_binary__stripe_mutex_r_guarded(DBGI_Scope *scope, DBGI_Binary *binary);
|
||||
internal void dbgi_scope_touch_fuzzy_search__stripe_mutex_r_guarded(DBGI_Scope *scope, DBGI_FuzzySearchNode *node);
|
||||
internal DI_Scope *di_scope_open(void);
|
||||
internal void di_scope_close(DI_Scope *scope);
|
||||
internal void di_scope_touch_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_Node *node);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Binary Cache Functions
|
||||
//~ rjf: Per-Slot Functions
|
||||
|
||||
internal void dbgi_binary_open(String8 exe_path);
|
||||
internal void dbgi_binary_close(String8 exe_path);
|
||||
internal DBGI_Parse *dbgi_parse_from_exe_path(DBGI_Scope *scope, String8 exe_path, U64 endt_us);
|
||||
internal DI_Node *di_node_from_key_slot__stripe_mutex_r_guarded(DI_Slot *slot, DI_Key *key);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Fuzzy Search Cache Functions
|
||||
//~ rjf: Per-Stripe Functions
|
||||
|
||||
internal DBGI_FuzzySearchItemArray dbgi_fuzzy_search_items_from_key_exe_query(DBGI_Scope *scope, U128 key, String8 exe_path, String8 query, DBGI_FuzzySearchTarget target, U64 endt_us, B32 *stale_out);
|
||||
internal U64 di_string_bucket_idx_from_string_size(U64 size);
|
||||
internal String8 di_string_alloc__stripe_mutex_w_guarded(DI_Stripe *stripe, String8 string);
|
||||
internal void di_string_release__stripe_mutex_w_guarded(DI_Stripe *stripe, String8 string);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Key Opening/Closing
|
||||
|
||||
internal void di_open(DI_Key *key);
|
||||
internal void di_close(DI_Key *key);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Lookups
|
||||
|
||||
internal RDI_Parsed *di_rdi_from_key(DI_Scope *scope, DI_Key *key, U64 endt_us);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Parse Threads
|
||||
|
||||
internal B32 dbgi_u2p_enqueue_exe_path(String8 exe_path, U64 endt_us);
|
||||
internal String8 dbgi_u2p_dequeue_exe_path(Arena *arena);
|
||||
internal B32 di_u2p_enqueue_key(DI_Key *key, U64 endt_us);
|
||||
internal void di_u2p_dequeue_key(Arena *arena, DI_Key *out_key);
|
||||
|
||||
internal void dbgi_p2u_push_event(DBGI_Event *event);
|
||||
internal DBGI_EventList dbgi_p2u_pop_events(Arena *arena, U64 endt_us);
|
||||
internal void di_p2u_push_event(DI_Event *event);
|
||||
internal DI_EventList di_p2u_pop_events(Arena *arena, U64 endt_us);
|
||||
|
||||
internal void dbgi_parse_thread_entry_point(void *p);
|
||||
internal void di_parse_thread__entry_point(void *p);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Fuzzy Searching Threads
|
||||
|
||||
internal B32 dbgi_u2f_enqueue_req(U128 key, U64 endt_us);
|
||||
internal void dbgi_u2f_dequeue_req(Arena *arena, DBGI_FuzzySearchThread *thread, U128 *key_out);
|
||||
|
||||
internal int dbgi_qsort_compare_fuzzy_search_items(DBGI_FuzzySearchItem *a, DBGI_FuzzySearchItem *b);
|
||||
|
||||
internal void dbgi_fuzzy_thread__entry_point(void *p);
|
||||
|
||||
#endif //DBGI_H
|
||||
#endif // DI_H
|
||||
|
||||
+238
-296
File diff suppressed because it is too large
Load Diff
+47
-52
@@ -265,10 +265,10 @@ struct DF_Eval
|
||||
////////////////////////////////
|
||||
//~ rjf: View Rule Hook Types
|
||||
|
||||
#define DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_SIG(name) DF_Eval name(Arena *arena, DBGI_Scope *dbgi_scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_Eval eval, struct DF_CfgVal *val)
|
||||
#define DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_SIG(name) DF_Eval name(Arena *arena, DI_Scope *di_scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_Eval eval, struct DF_CfgVal *val)
|
||||
#define DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(name) df_core_view_rule_eval_resolution__##name
|
||||
#define DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(name) internal DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_SIG(DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(name))
|
||||
#define DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_SIG(name) void name(Arena *arena, DBGI_Scope *dbgi_scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, struct DF_EvalView *eval_view, DF_Eval eval, String8 string, struct DF_CfgTable *cfg_table, DF_ExpandKey parent_key, DF_ExpandKey key, S32 depth, struct DF_CfgNode *cfg, struct DF_EvalVizBlockList *out)
|
||||
#define DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_SIG(name) void name(Arena *arena, DI_Scope *di_scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, struct DF_EvalView *eval_view, DF_Eval eval, String8 string, struct DF_CfgTable *cfg_table, DF_ExpandKey parent_key, DF_ExpandKey key, S32 depth, struct DF_CfgNode *cfg, struct DF_EvalVizBlockList *out)
|
||||
#define DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(name) df_core_view_rule_viz_block_prod__##name
|
||||
#define DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(name) internal DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_SIG(DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(name))
|
||||
typedef DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_SIG(DF_CoreViewRuleEvalResolutionHookFunctionType);
|
||||
@@ -521,7 +521,7 @@ struct DF_TextLineSrc2DasmInfo
|
||||
{
|
||||
Rng1U64 voff_range;
|
||||
S64 remap_line;
|
||||
DF_Entity *binary;
|
||||
DI_Key dbgi_key;
|
||||
};
|
||||
|
||||
typedef struct DF_TextLineSrc2DasmInfoNode DF_TextLineSrc2DasmInfoNode;
|
||||
@@ -543,7 +543,7 @@ typedef struct DF_TextLineSrc2DasmInfoListArray DF_TextLineSrc2DasmInfoListArray
|
||||
struct DF_TextLineSrc2DasmInfoListArray
|
||||
{
|
||||
DF_TextLineSrc2DasmInfoList *v;
|
||||
DF_EntityList binaries;
|
||||
DI_KeyList dbgi_keys;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
@@ -552,7 +552,7 @@ struct DF_TextLineSrc2DasmInfoListArray
|
||||
typedef struct DF_TextLineDasm2SrcInfo DF_TextLineDasm2SrcInfo;
|
||||
struct DF_TextLineDasm2SrcInfo
|
||||
{
|
||||
DF_Entity *binary;
|
||||
DI_Key dbgi_key;
|
||||
DF_Entity *file;
|
||||
TxtPt pt;
|
||||
Rng1U64 voff_range;
|
||||
@@ -708,8 +708,8 @@ struct DF_EvalVizBlock
|
||||
// rjf: info about ranges that this block spans
|
||||
Rng1U64 visual_idx_range;
|
||||
Rng1U64 semantic_idx_range;
|
||||
DBGI_FuzzySearchTarget dbgi_target;
|
||||
DBGI_FuzzySearchItemArray backing_search_items;
|
||||
FZY_Target fzy_target;
|
||||
FZY_ItemArray fzy_backing_items;
|
||||
|
||||
// rjf: visualization config extensions
|
||||
DF_CfgTable cfg_table;
|
||||
@@ -946,29 +946,33 @@ struct DF_AutoViewRuleMapCache
|
||||
DF_AutoViewRuleSlot *slots;
|
||||
};
|
||||
|
||||
//- rjf: per-run unwind cache
|
||||
//- rjf: per-thread unwind cache
|
||||
|
||||
typedef struct DF_RunUnwindCacheNode DF_RunUnwindCacheNode;
|
||||
struct DF_RunUnwindCacheNode
|
||||
typedef struct DF_UnwindCacheNode DF_UnwindCacheNode;
|
||||
struct DF_UnwindCacheNode
|
||||
{
|
||||
DF_RunUnwindCacheNode *hash_next;
|
||||
DF_UnwindCacheNode *next;
|
||||
DF_UnwindCacheNode *prev;
|
||||
U64 reggen;
|
||||
U64 memgen;
|
||||
Arena *arena;
|
||||
DF_Handle thread;
|
||||
CTRL_Unwind unwind;
|
||||
};
|
||||
|
||||
typedef struct DF_RunUnwindCacheSlot DF_RunUnwindCacheSlot;
|
||||
struct DF_RunUnwindCacheSlot
|
||||
typedef struct DF_UnwindCacheSlot DF_UnwindCacheSlot;
|
||||
struct DF_UnwindCacheSlot
|
||||
{
|
||||
DF_RunUnwindCacheNode *first;
|
||||
DF_RunUnwindCacheNode *last;
|
||||
DF_UnwindCacheNode *first;
|
||||
DF_UnwindCacheNode *last;
|
||||
};
|
||||
|
||||
typedef struct DF_RunUnwindCache DF_RunUnwindCache;
|
||||
struct DF_RunUnwindCache
|
||||
typedef struct DF_UnwindCache DF_UnwindCache;
|
||||
struct DF_UnwindCache
|
||||
{
|
||||
Arena *arena;
|
||||
U64 slots_count;
|
||||
DF_RunUnwindCacheSlot *slots;
|
||||
DF_UnwindCacheSlot *slots;
|
||||
DF_UnwindCacheNode *free_node;
|
||||
};
|
||||
|
||||
//- rjf: per-run tls-base-vaddr cache
|
||||
@@ -1004,7 +1008,7 @@ typedef struct DF_RunLocalsCacheNode DF_RunLocalsCacheNode;
|
||||
struct DF_RunLocalsCacheNode
|
||||
{
|
||||
DF_RunLocalsCacheNode *hash_next;
|
||||
DF_Handle binary;
|
||||
DI_Key dbgi_key;
|
||||
U64 voff;
|
||||
EVAL_String2NumMap *locals_map;
|
||||
};
|
||||
@@ -1146,10 +1150,7 @@ struct DF_State
|
||||
DF_AutoViewRuleMapCache auto_view_rule_cache;
|
||||
|
||||
// rjf: per-run caches
|
||||
U64 unwind_cache_reggen_idx;
|
||||
U64 unwind_cache_memgen_idx;
|
||||
DF_RunUnwindCache unwind_caches[2];
|
||||
U64 unwind_cache_gen;
|
||||
DF_UnwindCache unwind_cache;
|
||||
U64 tls_base_cache_reggen_idx;
|
||||
U64 tls_base_cache_memgen_idx;
|
||||
DF_RunTLSBaseCache tls_base_caches[2];
|
||||
@@ -1459,6 +1460,7 @@ internal void df_entity_equip_color_rgba(DF_Entity *entity, Vec4F32 rgba);
|
||||
internal void df_entity_equip_color_hsva(DF_Entity *entity, Vec4F32 hsva);
|
||||
internal void df_entity_equip_death_timer(DF_Entity *entity, F32 seconds_til_death);
|
||||
internal void df_entity_equip_cfg_src(DF_Entity *entity, DF_CfgSrc cfg_src);
|
||||
internal void df_entity_equip_timestamp(DF_Entity *entity, U64 timestamp);
|
||||
|
||||
//- rjf: control layer correllation equipment
|
||||
internal void df_entity_equip_ctrl_machine_id(DF_Entity *entity, CTRL_MachineID machine_id);
|
||||
@@ -1507,11 +1509,6 @@ internal DF_CmdSpecList df_push_cmd_spec_list(Arena *arena);
|
||||
internal void df_register_core_view_rule_specs(DF_CoreViewRuleSpecInfoArray specs);
|
||||
internal DF_CoreViewRuleSpec *df_core_view_rule_spec_from_string(String8 string);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Debug Info Mapping
|
||||
|
||||
internal String8 df_debug_info_path_from_module(Arena *arena, DF_Entity *module);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Stepping "Trap Net" Builders
|
||||
|
||||
@@ -1522,9 +1519,9 @@ internal CTRL_TrapList df_trap_net_from_thread__step_into_line(Arena *arena, DF_
|
||||
////////////////////////////////
|
||||
//~ rjf: Modules & Debug Info Mappings
|
||||
|
||||
//- rjf: module <=> binary file
|
||||
internal DF_Entity *df_binary_file_from_module(DF_Entity *module);
|
||||
internal DF_EntityList df_modules_from_binary_file(Arena *arena, DF_Entity *binary_info);
|
||||
//- rjf: module <=> debug info keys
|
||||
internal DI_Key df_dbgi_key_from_module(DF_Entity *module);
|
||||
internal DF_EntityList df_modules_from_dbgi_key(Arena *arena, DI_Key *dbgi_key);
|
||||
|
||||
//- rjf: voff <=> vaddr
|
||||
internal U64 df_base_vaddr_from_module(DF_Entity *module);
|
||||
@@ -1536,33 +1533,29 @@ internal Rng1U64 df_vaddr_range_from_voff_range(DF_Entity *module, Rng1U64 voff_
|
||||
////////////////////////////////
|
||||
//~ rjf: Debug Info Lookups
|
||||
|
||||
//- rjf: binary file -> dbgi parse
|
||||
internal DBGI_Parse *df_dbgi_parse_from_binary_file(DBGI_Scope *scope, DF_Entity *binary);
|
||||
|
||||
//- rjf: voff|vaddr -> symbol lookups
|
||||
internal String8 df_symbol_name_from_binary_voff(Arena *arena, DF_Entity *binary, U64 voff);
|
||||
internal String8 df_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff);
|
||||
internal String8 df_symbol_name_from_process_vaddr(Arena *arena, DF_Entity *process, U64 vaddr);
|
||||
|
||||
//- rjf: src -> voff lookups
|
||||
internal DF_TextLineSrc2DasmInfoListArray df_text_line_src2dasm_info_list_array_from_src_line_range(Arena *arena, DF_Entity *file, Rng1S64 line_num_range);
|
||||
|
||||
//- rjf: voff -> src lookups
|
||||
internal DF_TextLineDasm2SrcInfo df_text_line_dasm2src_info_from_binary_voff(DF_Entity *binary, U64 voff);
|
||||
internal DF_TextLineDasm2SrcInfo df_text_line_dasm2src_info_from_dbgi_key_voff(DI_Key *dbgi_key, U64 voff);
|
||||
|
||||
//- rjf: symbol -> voff lookups
|
||||
internal U64 df_voff_from_binary_symbol_name(DF_Entity *binary, String8 symbol_name);
|
||||
internal U64 df_type_num_from_binary_name(DF_Entity *binary, String8 name);
|
||||
internal U64 df_voff_from_dbgi_key_symbol_name(DI_Key *dbgi_key, String8 symbol_name);
|
||||
internal U64 df_type_num_from_dbgi_key_name(DI_Key *dbgi_key, String8 name);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Process/Thread Info Lookups
|
||||
//~ rjf: Process/Thread/Module Info Lookups
|
||||
|
||||
//- rjf: thread info extraction helpers
|
||||
internal DF_Entity *df_module_from_process_vaddr(DF_Entity *process, U64 vaddr);
|
||||
internal DF_Entity *df_module_from_thread(DF_Entity *thread);
|
||||
internal U64 df_tls_base_vaddr_from_process_root_rip(DF_Entity *process, U64 root_vaddr, U64 rip_vaddr);
|
||||
internal Architecture df_architecture_from_entity(DF_Entity *entity);
|
||||
internal EVAL_String2NumMap *df_push_locals_map_from_binary_voff(Arena *arena, DBGI_Scope *scope, DF_Entity *binary, U64 voff);
|
||||
internal EVAL_String2NumMap *df_push_member_map_from_binary_voff(Arena *arena, DBGI_Scope *scope, DF_Entity *binary, U64 voff);
|
||||
internal EVAL_String2NumMap *df_push_locals_map_from_dbgi_key_voff(Arena *arena, DI_Scope *scope, DI_Key *dbgi_key, U64 voff);
|
||||
internal EVAL_String2NumMap *df_push_member_map_from_dbgi_key_voff(Arena *arena, DI_Scope *scope, DI_Key *dbgi_key, U64 voff);
|
||||
internal B32 df_set_thread_rip(DF_Entity *thread, U64 vaddr);
|
||||
internal DF_Entity *df_module_from_thread_candidates(DF_Entity *thread, DF_EntityList *candidates);
|
||||
|
||||
@@ -1587,12 +1580,12 @@ internal CTRL_Event df_ctrl_last_stop_event(void);
|
||||
//~ rjf: Evaluation
|
||||
|
||||
internal B32 df_eval_memory_read(void *u, void *out, U64 addr, U64 size);
|
||||
internal EVAL_ParseCtx df_eval_parse_ctx_from_process_vaddr(DBGI_Scope *scope, DF_Entity *process, U64 vaddr);
|
||||
internal EVAL_ParseCtx df_eval_parse_ctx_from_src_loc(DBGI_Scope *scope, DF_Entity *file, TxtPt pt);
|
||||
internal DF_Eval df_eval_from_string(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, String8 string);
|
||||
internal EVAL_ParseCtx df_eval_parse_ctx_from_process_vaddr(DI_Scope *scope, DF_Entity *process, U64 vaddr);
|
||||
internal EVAL_ParseCtx df_eval_parse_ctx_from_src_loc(DI_Scope *scope, DF_Entity *file, TxtPt pt);
|
||||
internal DF_Eval df_eval_from_string(Arena *arena, DI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, String8 string);
|
||||
internal DF_Eval df_value_mode_eval_from_eval(TG_Graph *graph, RDI_Parsed *rdi, DF_CtrlCtx *ctrl_ctx, DF_Eval eval);
|
||||
internal DF_Eval df_dynamically_typed_eval_from_eval(TG_Graph *graph, RDI_Parsed *rdi, DF_CtrlCtx *ctrl_ctx, DF_Eval eval);
|
||||
internal DF_Eval df_eval_from_eval_cfg_table(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_Eval eval, DF_CfgTable *cfg);
|
||||
internal DF_Eval df_eval_from_eval_cfg_table(Arena *arena, DI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_Eval eval, DF_CfgTable *cfg);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Evaluation Views
|
||||
@@ -1630,8 +1623,8 @@ internal DF_EvalLinkBaseArray df_eval_link_base_array_from_chunk_list(Arena *are
|
||||
internal DF_EvalVizBlock *df_eval_viz_block_begin(Arena *arena, DF_EvalVizBlockKind kind, DF_ExpandKey parent_key, DF_ExpandKey key, S32 depth);
|
||||
internal DF_EvalVizBlock *df_eval_viz_block_split_and_continue(Arena *arena, DF_EvalVizBlockList *list, DF_EvalVizBlock *split_block, U64 split_idx);
|
||||
internal void df_eval_viz_block_end(DF_EvalVizBlockList *list, DF_EvalVizBlock *block);
|
||||
internal void df_append_viz_blocks_for_parent__rec(Arena *arena, DBGI_Scope *scope, DF_EvalView *view, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_ExpandKey parent_key, DF_ExpandKey key, String8 string, DF_Eval eval, TG_Member *opt_member, DF_CfgTable *cfg_table, S32 depth, DF_EvalVizBlockList *list_out);
|
||||
internal DF_EvalVizBlockList df_eval_viz_block_list_from_eval_view_expr_keys(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_EvalView *eval_view, String8 expr, DF_ExpandKey parent_key, DF_ExpandKey key);
|
||||
internal void df_append_viz_blocks_for_parent__rec(Arena *arena, DI_Scope *scope, DF_EvalView *view, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_ExpandKey parent_key, DF_ExpandKey key, String8 string, DF_Eval eval, TG_Member *opt_member, DF_CfgTable *cfg_table, S32 depth, DF_EvalVizBlockList *list_out);
|
||||
internal DF_EvalVizBlockList df_eval_viz_block_list_from_eval_view_expr_keys(Arena *arena, DI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_EvalView *eval_view, String8 expr, DF_ExpandKey parent_key, DF_ExpandKey key);
|
||||
internal void df_eval_viz_block_list_concat__in_place(DF_EvalVizBlockList *dst, DF_EvalVizBlockList *to_push);
|
||||
|
||||
//- rjf: viz block list <-> table coordinates
|
||||
@@ -1684,7 +1677,9 @@ internal String8 df_info_summary_from_string(Architecture arch, String8 string);
|
||||
|
||||
//- rjf: entity kind cache
|
||||
internal DF_EntityList df_query_cached_entity_list_with_kind(DF_EntityKind kind);
|
||||
internal DF_EntityList df_push_active_binary_list(Arena *arena);
|
||||
|
||||
//- rjf: active entity based queries
|
||||
internal DI_KeyList df_push_active_dbgi_key_list(Arena *arena);
|
||||
internal DF_EntityList df_push_active_target_list(Arena *arena);
|
||||
|
||||
//- rjf: per-run caches
|
||||
@@ -1692,8 +1687,8 @@ internal CTRL_Unwind df_query_cached_unwind_from_thread(DF_Entity *thread);
|
||||
internal U64 df_query_cached_rip_from_thread(DF_Entity *thread);
|
||||
internal U64 df_query_cached_rip_from_thread_unwind(DF_Entity *thread, U64 unwind_count);
|
||||
internal U64 df_query_cached_tls_base_vaddr_from_process_root_rip(DF_Entity *process, U64 root_vaddr, U64 rip_vaddr);
|
||||
internal EVAL_String2NumMap *df_query_cached_locals_map_from_binary_voff(DF_Entity *binary, U64 voff);
|
||||
internal EVAL_String2NumMap *df_query_cached_member_map_from_binary_voff(DF_Entity *binary, U64 voff);
|
||||
internal EVAL_String2NumMap *df_query_cached_locals_map_from_dbgi_key_voff(DI_Key *dbgi_key, U64 voff);
|
||||
internal EVAL_String2NumMap *df_query_cached_member_map_from_dbgi_key_voff(DI_Key *dbgi_key, U64 voff);
|
||||
|
||||
//- rjf: top-level command dispatch
|
||||
internal void df_push_cmd__root(DF_CmdParams *params, DF_CmdSpec *spec);
|
||||
|
||||
@@ -26,14 +26,10 @@ DF_EntityKindTable:
|
||||
//- rjf: filesystem modeling
|
||||
{File file 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "Label" FileOutline "File" }
|
||||
{OverrideFileLink override_file_link 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 "Label" FileOutline "Override File Link" }
|
||||
{PendingFileChange pending_file_change 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "Label" FileOutline "Pending File Change" }
|
||||
|
||||
//- rjf: auto view rules
|
||||
{AutoViewRule auto_view_rule 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 "Label" Binoculars "Auto View Rule" }
|
||||
|
||||
//- rjf: diagnostics log
|
||||
{DiagLog diag_log 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "Label" FileOutline "Diagnostics Log" }
|
||||
|
||||
//- rjf: text attachments
|
||||
{FlashMarker flash_marker 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "Label" Null "Flash Marker" }
|
||||
|
||||
@@ -59,8 +55,8 @@ DF_EntityKindTable:
|
||||
{Process process 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 "Label" Threads "Process" }
|
||||
{Thread thread 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 "Label" Thread "Thread" }
|
||||
{Module module 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "Label" Module "Module" }
|
||||
{DebugInfoOverride debug_info_override 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 "Label" Null "Debug Info Override" }
|
||||
{PendingThreadName pending_thread_name 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "Label" Threads "Pending Thread Name" }
|
||||
{DebugInfoPath debug_info_path 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "Label" Module "Debug Info Path" }
|
||||
|
||||
//- rjf: parser task entities
|
||||
{ConversionTask conversion_task 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 "Label" Null "Conversion Task" }
|
||||
@@ -337,7 +333,7 @@ DF_CoreCmdTable:// | | |
|
||||
{DuplicateEntity 1 Null Nil 0 0 0 0 0 0 Null "duplicate_entity" "Duplicate Entity" "Duplicates an entity." "" }
|
||||
|
||||
//- rjf: breakpoints
|
||||
{TextBreakpoint 1 Null Nil 0 0 0 0 0 0 CircleFilled "text_breakpoint" "Text Breakpoint" "Places or removes a breakpoint on the specified line of source code." "" }
|
||||
{TextBreakpoint 1 FilePath Nil 0 0 0 0 0 0 CircleFilled "text_breakpoint" "Text Breakpoint" "Places or removes a breakpoint on the specified line of source code." "" }
|
||||
{AddressBreakpoint 0 VirtualAddr Nil 0 0 0 0 1 1 CircleFilled "address_breakpoint" "Address Breakpoint" "Places or removes a breakpoint on the specified address." "" }
|
||||
{FunctionBreakpoint 0 String Nil 0 0 0 0 1 1 CircleFilled "function_breakpoint" "Function Breakpoint" "Places or removes a breakpoint on the first address(es) of the specified function." "" }
|
||||
{ToggleBreakpointAtCursor 0 Null Nil 0 0 0 0 0 0 CircleFilled "toggle_breakpoint_cursor" "Toggle Breakpoint At Cursor" "Places or removes a breakpoint on the line on which the active cursor sits." "" }
|
||||
|
||||
@@ -29,16 +29,14 @@ Rng1U64 df_g_cmd_param_slot_range_table[21] =
|
||||
{OffsetOf(DF_CmdParams, dir2), OffsetOf(DF_CmdParams, dir2) + sizeof(Dir2)},
|
||||
};
|
||||
|
||||
DF_IconKind df_g_entity_kind_icon_kind_table[27] =
|
||||
DF_IconKind df_g_entity_kind_icon_kind_table[25] =
|
||||
{
|
||||
DF_IconKind_Null,
|
||||
DF_IconKind_Null,
|
||||
DF_IconKind_Machine,
|
||||
DF_IconKind_FileOutline,
|
||||
DF_IconKind_FileOutline,
|
||||
DF_IconKind_FileOutline,
|
||||
DF_IconKind_Binoculars,
|
||||
DF_IconKind_FileOutline,
|
||||
DF_IconKind_Null,
|
||||
DF_IconKind_Pin,
|
||||
DF_IconKind_CircleFilled,
|
||||
@@ -53,23 +51,21 @@ DF_IconKind_Null,
|
||||
DF_IconKind_Threads,
|
||||
DF_IconKind_Thread,
|
||||
DF_IconKind_Module,
|
||||
DF_IconKind_Null,
|
||||
DF_IconKind_Threads,
|
||||
DF_IconKind_Module,
|
||||
DF_IconKind_Null,
|
||||
DF_IconKind_Null,
|
||||
DF_IconKind_Null,
|
||||
};
|
||||
|
||||
String8 df_g_entity_kind_display_string_table[27] =
|
||||
String8 df_g_entity_kind_display_string_table[25] =
|
||||
{
|
||||
str8_lit_comp("Nil"),
|
||||
str8_lit_comp("Root"),
|
||||
str8_lit_comp("Machine"),
|
||||
str8_lit_comp("File"),
|
||||
str8_lit_comp("Override File Link"),
|
||||
str8_lit_comp("Pending File Change"),
|
||||
str8_lit_comp("Auto View Rule"),
|
||||
str8_lit_comp("Diagnostics Log"),
|
||||
str8_lit_comp("Flash Marker"),
|
||||
str8_lit_comp("Watch Pin"),
|
||||
str8_lit_comp("Breakpoint"),
|
||||
@@ -84,14 +80,14 @@ str8_lit_comp("Destination"),
|
||||
str8_lit_comp("Process"),
|
||||
str8_lit_comp("Thread"),
|
||||
str8_lit_comp("Module"),
|
||||
str8_lit_comp("Debug Info Override"),
|
||||
str8_lit_comp("Pending Thread Name"),
|
||||
str8_lit_comp("Debug Info Path"),
|
||||
str8_lit_comp("Conversion Task"),
|
||||
str8_lit_comp("Conversion Failure"),
|
||||
str8_lit_comp("EndedProcess"),
|
||||
};
|
||||
|
||||
String8 df_g_entity_kind_name_label_table[27] =
|
||||
String8 df_g_entity_kind_name_label_table[25] =
|
||||
{
|
||||
str8_lit_comp("Label"),
|
||||
str8_lit_comp("Label"),
|
||||
@@ -100,8 +96,6 @@ str8_lit_comp("Label"),
|
||||
str8_lit_comp("Label"),
|
||||
str8_lit_comp("Label"),
|
||||
str8_lit_comp("Label"),
|
||||
str8_lit_comp("Label"),
|
||||
str8_lit_comp("Label"),
|
||||
str8_lit_comp("Expression"),
|
||||
str8_lit_comp("Label"),
|
||||
str8_lit_comp("Expression"),
|
||||
@@ -122,17 +116,15 @@ str8_lit_comp("Label"),
|
||||
str8_lit_comp("Label"),
|
||||
};
|
||||
|
||||
DF_EntityKindFlags df_g_entity_kind_flags_table[27] =
|
||||
DF_EntityKindFlags df_g_entity_kind_flags_table[25] =
|
||||
{
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(1*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 1*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProfileConfig | 1*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProfileConfig | 1*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 1*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 1*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
@@ -146,14 +138,14 @@ DF_EntityKindFlags df_g_entity_kind_flags_table[27] =
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 1*DF_EntityKindFlag_LeafMutationSoftHalt | 1*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 1*DF_EntityKindFlag_TreeMutationSoftHalt | 1*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
|
||||
};
|
||||
|
||||
DF_EntityOpFlags df_g_entity_kind_op_flags_table[27] =
|
||||
DF_EntityOpFlags df_g_entity_kind_op_flags_table[25] =
|
||||
{
|
||||
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
|
||||
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
|
||||
@@ -162,8 +154,6 @@ DF_EntityOpFlags df_g_entity_kind_op_flags_table[27] =
|
||||
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
|
||||
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
|
||||
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
|
||||
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
|
||||
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
|
||||
(1*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (1*DF_EntityOpFlag_Duplicate),
|
||||
(1*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (1*DF_EntityOpFlag_Enable) | (1*DF_EntityOpFlag_Condition) | (1*DF_EntityOpFlag_Duplicate),
|
||||
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
|
||||
@@ -377,7 +367,7 @@ DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[214] =
|
||||
{ str8_lit_comp("name_entity"), str8_lit_comp("Equips an entity with a name."), str8_lit_comp(""), str8_lit_comp("Name Entity"), (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("edit_entity"), str8_lit_comp("Opens the editor for an entity."), str8_lit_comp(""), str8_lit_comp("Edit Entity"), (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("duplicate_entity"), str8_lit_comp("Duplicates an entity."), str8_lit_comp(""), str8_lit_comp("Duplicate Entity"), (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("text_breakpoint"), str8_lit_comp("Places or removes a breakpoint on the specified line of source code."), str8_lit_comp(""), str8_lit_comp("Text Breakpoint"), (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_CircleFilled},
|
||||
{ str8_lit_comp("text_breakpoint"), str8_lit_comp("Places or removes a breakpoint on the specified line of source code."), str8_lit_comp(""), str8_lit_comp("Text Breakpoint"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_FilePath, 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_CircleFilled},
|
||||
{ str8_lit_comp("address_breakpoint"), str8_lit_comp("Places or removes a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("Address Breakpoint"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_VirtualAddr, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_CircleFilled},
|
||||
{ str8_lit_comp("function_breakpoint"), str8_lit_comp("Places or removes a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("Function Breakpoint"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_String, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_CircleFilled},
|
||||
{ str8_lit_comp("toggle_breakpoint_cursor"), str8_lit_comp("Places or removes a breakpoint on the line on which the active cursor sits."), str8_lit_comp(""), str8_lit_comp("Toggle Breakpoint At Cursor"), (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_CircleFilled},
|
||||
|
||||
@@ -22,9 +22,7 @@ DF_EntityKind_Root,
|
||||
DF_EntityKind_Machine,
|
||||
DF_EntityKind_File,
|
||||
DF_EntityKind_OverrideFileLink,
|
||||
DF_EntityKind_PendingFileChange,
|
||||
DF_EntityKind_AutoViewRule,
|
||||
DF_EntityKind_DiagLog,
|
||||
DF_EntityKind_FlashMarker,
|
||||
DF_EntityKind_WatchPin,
|
||||
DF_EntityKind_Breakpoint,
|
||||
@@ -39,8 +37,8 @@ DF_EntityKind_Dest,
|
||||
DF_EntityKind_Process,
|
||||
DF_EntityKind_Thread,
|
||||
DF_EntityKind_Module,
|
||||
DF_EntityKind_DebugInfoOverride,
|
||||
DF_EntityKind_PendingThreadName,
|
||||
DF_EntityKind_DebugInfoPath,
|
||||
DF_EntityKind_ConversionTask,
|
||||
DF_EntityKind_ConversionFail,
|
||||
DF_EntityKind_EndedProcess,
|
||||
@@ -1535,11 +1533,11 @@ struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] =
|
||||
};
|
||||
C_LINKAGE_BEGIN
|
||||
extern Rng1U64 df_g_cmd_param_slot_range_table[22];
|
||||
extern DF_IconKind df_g_entity_kind_icon_kind_table[27];
|
||||
extern String8 df_g_entity_kind_display_string_table[27];
|
||||
extern String8 df_g_entity_kind_name_label_table[27];
|
||||
extern DF_EntityKindFlags df_g_entity_kind_flags_table[27];
|
||||
extern DF_EntityOpFlags df_g_entity_kind_op_flags_table[27];
|
||||
extern DF_IconKind df_g_entity_kind_icon_kind_table[25];
|
||||
extern String8 df_g_entity_kind_display_string_table[25];
|
||||
extern String8 df_g_entity_kind_name_label_table[25];
|
||||
extern DF_EntityKindFlags df_g_entity_kind_flags_table[25];
|
||||
extern DF_EntityOpFlags df_g_entity_kind_op_flags_table[25];
|
||||
extern String8 df_g_cfg_src_string_table[4];
|
||||
extern DF_CoreCmdKind df_g_cfg_src_load_cmd_kind_table[4];
|
||||
extern DF_CoreCmdKind df_g_cfg_src_write_cmd_kind_table[4];
|
||||
|
||||
+115
-97
@@ -583,17 +583,18 @@ df_queue_drag_drop(void)
|
||||
}
|
||||
|
||||
internal void
|
||||
df_set_hovered_line_info(DF_Entity *binary, U64 voff)
|
||||
df_set_hovered_line_info(DI_Key *dbgi_key, U64 voff)
|
||||
{
|
||||
df_gfx_state->hover_line_binary = df_handle_from_entity(binary);
|
||||
arena_clear(df_gfx_state->hover_line_arena);
|
||||
df_gfx_state->hover_line_dbgi_key = di_key_copy(df_gfx_state->hover_line_arena, dbgi_key);
|
||||
df_gfx_state->hover_line_voff = voff;
|
||||
df_gfx_state->hover_line_set_this_frame = 1;
|
||||
}
|
||||
|
||||
internal DF_Entity *
|
||||
df_get_hovered_line_info_binary(void)
|
||||
internal DI_Key
|
||||
df_get_hovered_line_info_dbgi_key(void)
|
||||
{
|
||||
return df_entity_from_handle(df_gfx_state->hover_line_binary);
|
||||
return df_gfx_state->hover_line_dbgi_key;
|
||||
}
|
||||
|
||||
internal U64
|
||||
@@ -1038,7 +1039,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
//////////////////////////////
|
||||
//- rjf: unpack context
|
||||
//
|
||||
B32 window_is_focused = os_window_is_focused(ws->os);
|
||||
B32 window_is_focused = os_window_is_focused(ws->os) || ws->window_temporarily_focused_ipc;
|
||||
B32 confirm_open = df_gfx_state->confirm_active;
|
||||
B32 query_is_open = !df_view_is_nil(ws->query_view_stack_top);
|
||||
B32 hover_eval_is_open = (!confirm_open &&
|
||||
@@ -1049,6 +1050,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
{
|
||||
ws->menu_bar_key_held = 0;
|
||||
}
|
||||
ws->window_temporarily_focused_ipc = 0;
|
||||
ui_select_state(ws->ui);
|
||||
|
||||
//////////////////////////////
|
||||
@@ -2488,7 +2490,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
//- rjf: thread finding
|
||||
case DF_CoreCmdKind_FindThread:
|
||||
{
|
||||
DBGI_Scope *scope = dbgi_scope_open();
|
||||
DI_Scope *scope = di_scope_open();
|
||||
DF_Entity *thread = df_entity_from_handle(params.entity);
|
||||
U64 unwind_count = params.index;
|
||||
if(thread->kind == DF_EntityKind_Thread)
|
||||
@@ -2499,19 +2501,19 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
// rjf: extract thread/rip info
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
|
||||
DF_Entity *binary = df_binary_file_from_module(module);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
RDI_Parsed *rdi = di_rdi_from_key(scope, &dbgi_key, 0);
|
||||
U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr);
|
||||
DBGI_Parse *dbgi = df_dbgi_parse_from_binary_file(scope, binary);
|
||||
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_binary_voff(binary, rip_voff);
|
||||
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, rip_voff);
|
||||
|
||||
// rjf: snap to resolved line
|
||||
B32 missing_rip = (rip_vaddr == 0);
|
||||
B32 binary_missing = (binary->flags & DF_EntityFlag_IsMissing);
|
||||
B32 dbg_info_pending = !binary_missing && dbgi == &dbgi_parse_nil;
|
||||
B32 dbgi_missing = (dbgi_key.min_timestamp == 0 || dbgi_key.path.size == 0);
|
||||
B32 dbgi_pending = !dbgi_missing && rdi == &di_rdi_parsed_nil;
|
||||
B32 has_line_info = (line_info.voff_range.max != line_info.voff_range.min);
|
||||
B32 has_module = !df_entity_is_nil(module);
|
||||
B32 has_dbg_info = has_module && !binary_missing;
|
||||
if(!dbg_info_pending && (has_line_info || has_module))
|
||||
B32 has_dbg_info = has_module && !dbgi_missing;
|
||||
if(!dbgi_pending && (has_line_info || has_module))
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_window(ws);
|
||||
if(has_line_info)
|
||||
@@ -2527,17 +2529,33 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
params.index = unwind_count;
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Entity);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_VirtualOff);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_VirtualAddr);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Index);
|
||||
df_cmd_list_push(arena, cmds, ¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FindCodeLocation));
|
||||
}
|
||||
|
||||
// rjf: snap to resolved address w/o line info
|
||||
if(!missing_rip && !dbgi_pending && !has_line_info && !has_module)
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_window(ws);
|
||||
params.entity = df_handle_from_entity(thread);
|
||||
params.voff = rip_voff;
|
||||
params.vaddr = rip_vaddr;
|
||||
params.index = unwind_count;
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Entity);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_VirtualOff);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_VirtualAddr);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Index);
|
||||
df_cmd_list_push(arena, cmds, ¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FindCodeLocation));
|
||||
}
|
||||
|
||||
// rjf: retry on stopped, pending debug info
|
||||
if(!df_ctrl_targets_running() && (dbg_info_pending || missing_rip))
|
||||
if(!df_ctrl_targets_running() && (dbgi_pending || missing_rip))
|
||||
{
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FindThread));
|
||||
}
|
||||
}
|
||||
dbgi_scope_close(scope);
|
||||
di_scope_close(scope);
|
||||
}break;
|
||||
case DF_CoreCmdKind_FindSelectedThread:
|
||||
{
|
||||
@@ -2561,17 +2579,17 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
|
||||
// rjf: try to resolve name as a symbol
|
||||
U64 voff = 0;
|
||||
DF_Entity *voff_binary = &df_g_nil_entity;
|
||||
DI_Key voff_dbgi_key = {0};
|
||||
if(name_resolved == 0)
|
||||
{
|
||||
DF_EntityList binaries = df_push_active_binary_list(scratch.arena);
|
||||
for(DF_EntityNode *n = binaries.first; n != 0; n = n->next)
|
||||
DI_KeyList keys = df_push_active_dbgi_key_list(scratch.arena);
|
||||
for(DI_KeyNode *n = keys.first; n != 0; n = n->next)
|
||||
{
|
||||
U64 binary_voff = df_voff_from_binary_symbol_name(n->entity, name);
|
||||
U64 binary_voff = df_voff_from_dbgi_key_symbol_name(&n->v, name);
|
||||
if(binary_voff != 0)
|
||||
{
|
||||
voff = binary_voff;
|
||||
voff_binary = n->entity;
|
||||
voff_dbgi_key = n->v;
|
||||
name_resolved = 1;
|
||||
break;
|
||||
}
|
||||
@@ -2680,19 +2698,25 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
// rjf: name resolved to voff * dbg info
|
||||
if(name_resolved != 0 && voff != 0)
|
||||
{
|
||||
DF_TextLineDasm2SrcInfo dasm2src_info = df_text_line_dasm2src_info_from_binary_voff(voff_binary, voff);
|
||||
DF_TextLineDasm2SrcInfo dasm2src_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&voff_dbgi_key, voff);
|
||||
DF_CmdParams p = params;
|
||||
{
|
||||
p.file_path = df_full_path_from_entity(scratch.arena, dasm2src_info.file);
|
||||
p.text_point = dasm2src_info.pt;
|
||||
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_FilePath);
|
||||
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_TextPoint);
|
||||
if(!df_entity_is_nil(voff_binary))
|
||||
if(voff_dbgi_key.path.size != 0)
|
||||
{
|
||||
p.entity = df_handle_from_entity(voff_binary);
|
||||
p.voff = dasm2src_info.voff_range.min;
|
||||
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_Entity);
|
||||
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_VirtualOff);
|
||||
DF_EntityList modules = df_modules_from_dbgi_key(scratch.arena, &voff_dbgi_key);
|
||||
DF_Entity *module = df_first_entity_from_list(&modules);
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(module, DF_EntityKind_Process);
|
||||
if(!df_entity_is_nil(process))
|
||||
{
|
||||
p.entity = df_handle_from_entity(process);
|
||||
p.vaddr = module->vaddr_rng.min + dasm2src_info.voff_range.min;
|
||||
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_Entity);
|
||||
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_VirtualAddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
df_cmd_list_push(arena, cmds, &p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FindCodeLocation));
|
||||
@@ -2911,7 +2935,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
{
|
||||
for(DF_TextLineSrc2DasmInfoNode *n = src2dasm.v[src2dasm_idx].first; n != 0; n = n->next)
|
||||
{
|
||||
DF_EntityList modules = df_modules_from_binary_file(scratch.arena, n->v.binary);
|
||||
DF_EntityList modules = df_modules_from_dbgi_key(scratch.arena, &n->v.dbgi_key);
|
||||
DF_Entity *module = df_module_from_thread_candidates(thread, &modules);
|
||||
vaddr = df_vaddr_from_voff(module, n->v.voff_range.min);
|
||||
goto end_lookup;
|
||||
@@ -3299,7 +3323,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
//
|
||||
Rng2F32 window_rect = os_client_rect_from_window(ws->os);
|
||||
Vec2F32 window_rect_dim = dim_2f32(window_rect);
|
||||
Rng2F32 top_bar_rect = r2f32p(window_rect.x0, window_rect.y0, window_rect.x0+window_rect_dim.x, window_rect.y0+ui_top_pref_height().value);
|
||||
Rng2F32 top_bar_rect = r2f32p(window_rect.x0, window_rect.y0, window_rect.x0+window_rect_dim.x+1, window_rect.y0+ui_top_pref_height().value);
|
||||
Rng2F32 bottom_bar_rect = r2f32p(window_rect.x0, window_rect_dim.y - ui_top_pref_height().value, window_rect.x0+window_rect_dim.x, window_rect.y0+window_rect_dim.y);
|
||||
Rng2F32 content_rect = r2f32p(window_rect.x0, top_bar_rect.y1, window_rect.x0+window_rect_dim.x, bottom_bar_rect.y0);
|
||||
F32 window_edge_px = os_dpi_from_window(ws->os)*0.035f;
|
||||
@@ -3411,26 +3435,10 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
|
||||
case DF_EntityKind_Module:
|
||||
{
|
||||
DF_Entity *bin_file = df_binary_file_from_module(entity);
|
||||
if(ui_clicked(df_icon_buttonf(DF_IconKind_Module, 0, "Inspect Binary File Memory")))
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_panel(ws, panel);
|
||||
params.entity = df_handle_from_entity(bin_file);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Entity);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_PendingEntity));
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
if(ui_clicked(df_icon_buttonf(DF_IconKind_Module, 0, "View Binary File Disassembly")))
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_panel(ws, panel);
|
||||
params.entity = df_handle_from_entity(bin_file);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Entity);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_PendingEntity));
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
}break;
|
||||
case DF_EntityKind_Process:
|
||||
{
|
||||
#if 0
|
||||
if(ui_clicked(df_icon_buttonf(DF_IconKind_FileOutline, 0, "Open Process Log")))
|
||||
{
|
||||
DF_Entity *log = df_log_from_entity(entity);
|
||||
@@ -3440,9 +3448,11 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Code));
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
#endif
|
||||
}break;
|
||||
case DF_EntityKind_Thread:
|
||||
{
|
||||
#if 0
|
||||
if(ui_clicked(df_icon_buttonf(DF_IconKind_FileOutline, 0, "Open Thread Log")))
|
||||
{
|
||||
DF_Entity *log = df_log_from_entity(entity);
|
||||
@@ -3452,6 +3462,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Code));
|
||||
ui_ctx_menu_close();
|
||||
}
|
||||
#endif
|
||||
}break;
|
||||
}
|
||||
}
|
||||
@@ -3924,13 +3935,13 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(entity, DF_EntityKind_Process);
|
||||
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(entity);
|
||||
String8List lines = {0};
|
||||
for(CTRL_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next)
|
||||
for(U64 frame_idx = 0; frame_idx < unwind.frames.count; frame_idx += 1)
|
||||
{
|
||||
U64 rip_vaddr = frame->rip;
|
||||
U64 rip_vaddr = regs_rip_from_arch_block(entity->arch, unwind.frames.v[frame_idx].regs);
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
|
||||
DF_Entity *binary = df_binary_file_from_module(module);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr);
|
||||
String8 symbol = df_symbol_name_from_binary_voff(scratch.arena, binary, rip_voff);
|
||||
String8 symbol = df_symbol_name_from_dbgi_key_voff(scratch.arena, &dbgi_key, rip_voff);
|
||||
if(symbol.size != 0)
|
||||
{
|
||||
str8_list_pushf(scratch.arena, &lines, "0x%I64x: %S", rip_vaddr, symbol);
|
||||
@@ -4255,7 +4266,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, thread_rip_vaddr);
|
||||
U64 thread_rip_voff = df_voff_from_vaddr(module, thread_rip_vaddr);
|
||||
DF_Entity *binary = df_binary_file_from_module(module);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
|
||||
//- rjf: gather lister items
|
||||
DF_AutoCompListerItemChunkList item_list = {0};
|
||||
@@ -4263,7 +4274,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
//- rjf: gather locals
|
||||
if(ws->autocomp_lister_params.flags & DF_AutoCompListerFlag_Locals)
|
||||
{
|
||||
EVAL_String2NumMap *locals_map = df_query_cached_locals_map_from_binary_voff(binary, thread_rip_voff);
|
||||
EVAL_String2NumMap *locals_map = df_query_cached_locals_map_from_dbgi_key_voff(&dbgi_key, thread_rip_voff);
|
||||
for(EVAL_String2NumMapNode *n = locals_map->first; n != 0; n = n->order_next)
|
||||
{
|
||||
DF_AutoCompListerItem item = {0};
|
||||
@@ -5306,7 +5317,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
}
|
||||
os_window_push_custom_title_bar_client_area(ws->os, min_sig.box->rect);
|
||||
os_window_push_custom_title_bar_client_area(ws->os, max_sig.box->rect);
|
||||
os_window_push_custom_title_bar_client_area(ws->os, cls_sig.box->rect);
|
||||
os_window_push_custom_title_bar_client_area(ws->os, pad_2f32(cls_sig.box->rect, 2.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5716,7 +5727,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
UI_FontSize(df_font_size_from_slot(ws, DF_FontSlot_Main))
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
DBGI_Scope *scope = dbgi_scope_open();
|
||||
DI_Scope *scope = di_scope_open();
|
||||
DF_CtrlCtx ctrl_ctx = ws->hover_eval_ctrl_ctx;
|
||||
DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread);
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
|
||||
@@ -5983,7 +5994,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
|
||||
}
|
||||
}
|
||||
|
||||
dbgi_scope_close(scope);
|
||||
di_scope_close(scope);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
}
|
||||
@@ -8311,7 +8322,7 @@ df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags
|
||||
}
|
||||
|
||||
internal DF_EvalVizWindowedRowList
|
||||
df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_EvalView *eval_view, U32 default_radix, F_Tag font, F32 font_size, Rng1S64 visible_range, DF_EvalVizBlockList *blocks)
|
||||
df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_EvalView *eval_view, U32 default_radix, F_Tag font, F32 font_size, Rng1S64 visible_range, DF_EvalVizBlockList *blocks)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
@@ -8697,12 +8708,12 @@ df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DBGI_Scope *scop
|
||||
for(U64 idx = visible_idx_range.min; idx < visible_idx_range.max; idx += 1)
|
||||
{
|
||||
// rjf: unpack info about this row
|
||||
String8 name = dbgi_fuzzy_item_string_from_rdi_target_element_idx(parse_ctx->rdi, block->dbgi_target, block->backing_search_items.v[idx].idx);
|
||||
String8 name = fzy_item_string_from_rdi_target_element_idx(parse_ctx->rdi, block->fzy_target, block->fzy_backing_items.v[idx].idx);
|
||||
|
||||
// rjf: get keys for this row
|
||||
DF_ExpandKey parent_key = block->parent_key;
|
||||
DF_ExpandKey key = block->key;
|
||||
key.child_num = block->backing_search_items.v[idx].idx;
|
||||
key.child_num = block->fzy_backing_items.v[idx].idx;
|
||||
|
||||
// rjf: get eval for this row
|
||||
DF_Eval eval = df_eval_from_string(arena, scope, ctrl_ctx, parse_ctx, macro_map, name);
|
||||
@@ -9547,6 +9558,13 @@ df_stop_explanation_string_icon_from_ctrl_event(Arena *arena, CTRL_Event *event,
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
DF_Entity *thread = df_entity_from_ctrl_handle(event->machine_id, event->entity);
|
||||
String8 thread_display_string = df_display_string_from_entity(scratch.arena, thread);
|
||||
String8 process_thread_string = thread_display_string;
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
|
||||
if(process->kind == DF_EntityKind_Process)
|
||||
{
|
||||
String8 process_display_string = df_display_string_from_entity(scratch.arena, process);
|
||||
process_thread_string = push_str8f(scratch.arena, "%S: %S", process_display_string, thread_display_string);
|
||||
}
|
||||
switch(event->kind)
|
||||
{
|
||||
default:
|
||||
@@ -9558,7 +9576,7 @@ df_stop_explanation_string_icon_from_ctrl_event(Arena *arena, CTRL_Event *event,
|
||||
{
|
||||
if(!df_entity_is_nil(thread))
|
||||
{
|
||||
explanation = push_str8f(arena, "%S completed step", thread_display_string);
|
||||
explanation = push_str8f(arena, "%S completed step", process_thread_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -9570,7 +9588,7 @@ df_stop_explanation_string_icon_from_ctrl_event(Arena *arena, CTRL_Event *event,
|
||||
if(!df_entity_is_nil(thread))
|
||||
{
|
||||
icon = DF_IconKind_CircleFilled;
|
||||
explanation = push_str8f(arena, "%S hit a breakpoint", thread_display_string);
|
||||
explanation = push_str8f(arena, "%S hit a breakpoint", process_thread_string);
|
||||
}
|
||||
}break;
|
||||
case CTRL_EventCause_InterruptedByException:
|
||||
@@ -9583,30 +9601,30 @@ df_stop_explanation_string_icon_from_ctrl_event(Arena *arena, CTRL_Event *event,
|
||||
default:
|
||||
{
|
||||
String8 exception_code_string = df_string_from_exception_code(event->exception_code);
|
||||
explanation = push_str8f(arena, "Exception thrown by %S - 0x%x%s%S", thread_display_string, event->exception_code, exception_code_string.size > 0 ? ": " : "", exception_code_string);
|
||||
explanation = push_str8f(arena, "Exception thrown by %S - 0x%x%s%S", process_thread_string, event->exception_code, exception_code_string.size > 0 ? ": " : "", exception_code_string);
|
||||
}break;
|
||||
case CTRL_ExceptionKind_CppThrow:
|
||||
{
|
||||
explanation = push_str8f(arena, "Exception thrown by %S - 0x%x: C++ exception", thread_display_string, event->exception_code);
|
||||
explanation = push_str8f(arena, "Exception thrown by %S - 0x%x: C++ exception", process_thread_string, event->exception_code);
|
||||
}break;
|
||||
case CTRL_ExceptionKind_MemoryRead:
|
||||
{
|
||||
explanation = push_str8f(arena, "Exception thrown by %S - 0x%x: Access violation reading 0x%I64x",
|
||||
thread_display_string,
|
||||
process_thread_string,
|
||||
event->exception_code,
|
||||
event->vaddr_rng.min);
|
||||
}break;
|
||||
case CTRL_ExceptionKind_MemoryWrite:
|
||||
{
|
||||
explanation = push_str8f(arena, "Exception thrown by %S - 0x%x: Access violation writing 0x%I64x",
|
||||
thread_display_string,
|
||||
process_thread_string,
|
||||
event->exception_code,
|
||||
event->vaddr_rng.min);
|
||||
}break;
|
||||
case CTRL_ExceptionKind_MemoryExecute:
|
||||
{
|
||||
explanation = push_str8f(arena, "Exception thrown by %S - 0x%x: Access violation executing 0x%I64x",
|
||||
thread_display_string,
|
||||
process_thread_string,
|
||||
event->exception_code,
|
||||
event->vaddr_rng.min);
|
||||
}break;
|
||||
@@ -9621,7 +9639,7 @@ df_stop_explanation_string_icon_from_ctrl_event(Arena *arena, CTRL_Event *event,
|
||||
case CTRL_EventCause_InterruptedByTrap:
|
||||
{
|
||||
icon = DF_IconKind_WarningBig;
|
||||
explanation = push_str8f(arena, "%S interrupted by trap - 0x%x", thread_display_string, event->exception_code);
|
||||
explanation = push_str8f(arena, "%S interrupted by trap - 0x%x", process_thread_string, event->exception_code);
|
||||
}break;
|
||||
case CTRL_EventCause_InterruptedByHalt:
|
||||
{
|
||||
@@ -9938,13 +9956,13 @@ df_entity_tooltips(DF_Entity *entity)
|
||||
ui_spacer(ui_em(1.5f, 1.f));
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(entity, DF_EntityKind_Process);
|
||||
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(entity);
|
||||
for(CTRL_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next)
|
||||
for(U64 idx = 0; idx < unwind.frames.count; idx += 1)
|
||||
{
|
||||
U64 rip_vaddr = frame->rip;
|
||||
U64 rip_vaddr = regs_rip_from_arch_block(entity->arch, unwind.frames.v[idx].regs);
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
|
||||
DF_Entity *binary = df_binary_file_from_module(module);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr);
|
||||
String8 symbol = df_symbol_name_from_binary_voff(scratch.arena, binary, rip_voff);
|
||||
String8 symbol = df_symbol_name_from_dbgi_key_voff(scratch.arena, &dbgi_key, rip_voff);
|
||||
UI_PrefWidth(ui_children_sum(1)) UI_Row
|
||||
{
|
||||
UI_Font(df_font_from_slot(DF_FontSlot_Code)) UI_PrefWidth(ui_em(18.f, 1.f)) UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_WeakText)) ui_labelf("0x%I64x", rip_vaddr);
|
||||
@@ -10059,13 +10077,12 @@ df_entity_desc_button(DF_Window *ws, DF_Entity *entity, FuzzyMatchRangeList *nam
|
||||
ui_set_next_background_color(bg_color);
|
||||
}
|
||||
ui_set_next_hover_cursor(OS_Cursor_HandPoint);
|
||||
UI_Key key = ui_key_from_stringf(ui_top_parent()->key, "entity_ref_button_%p", entity);
|
||||
UI_Box *box = ui_build_box_from_key(UI_BoxFlag_Clickable|
|
||||
UI_BoxFlag_DrawBorder|
|
||||
UI_BoxFlag_DrawBackground|
|
||||
UI_BoxFlag_DrawHotEffects|
|
||||
UI_BoxFlag_DrawActiveEffects,
|
||||
key);
|
||||
UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable|
|
||||
UI_BoxFlag_DrawBorder|
|
||||
UI_BoxFlag_DrawBackground|
|
||||
UI_BoxFlag_DrawHotEffects|
|
||||
UI_BoxFlag_DrawActiveEffects,
|
||||
"entity_ref_button_%p", entity);
|
||||
|
||||
//- rjf: build contents
|
||||
UI_Parent(box) UI_PrefWidth(ui_text_dim(10, 0))
|
||||
@@ -10133,13 +10150,14 @@ df_entity_desc_button(DF_Window *ws, DF_Entity *entity, FuzzyMatchRangeList *nam
|
||||
U64 idx = 0;
|
||||
U64 limit = 3;
|
||||
ui_spacer(ui_em(1.f, 1.f));
|
||||
for(CTRL_UnwindFrame *f = unwind.last; f != 0 && idx < limit; f = f->prev)
|
||||
for(U64 num = unwind.frames.count; num > 0; num -= 1)
|
||||
{
|
||||
U64 rip_vaddr = f->rip;
|
||||
CTRL_UnwindFrame *f = &unwind.frames.v[num-1];
|
||||
U64 rip_vaddr = regs_rip_from_arch_block(entity->arch, f->regs);
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
|
||||
U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr);
|
||||
DF_Entity *binary = df_binary_file_from_module(module);
|
||||
String8 procedure_name = df_symbol_name_from_binary_voff(scratch.arena, binary, rip_voff);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
String8 procedure_name = df_symbol_name_from_dbgi_key_voff(scratch.arena, &dbgi_key, rip_voff);
|
||||
if(procedure_name.size != 0)
|
||||
{
|
||||
FuzzyMatchRangeList fuzzy_matches = {0};
|
||||
@@ -10582,7 +10600,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
U64 thread_rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, unwind_count);
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, thread_rip_vaddr);
|
||||
DF_Entity *binary = df_binary_file_from_module(module);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
U64 thread_rip_voff = df_voff_from_vaddr(module, thread_rip_vaddr);
|
||||
|
||||
// rjf: thread info => color
|
||||
@@ -10649,7 +10667,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
n != 0;
|
||||
n = n->next)
|
||||
{
|
||||
if(n->v.binary == binary)
|
||||
if(di_key_match(&n->v.dbgi_key, &dbgi_key))
|
||||
{
|
||||
line_info = &n->v;
|
||||
break;
|
||||
@@ -10964,7 +10982,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
//
|
||||
UI_Focus(UI_FocusKind_Off)
|
||||
{
|
||||
DBGI_Scope *scope = dbgi_scope_open();
|
||||
DI_Scope *scope = di_scope_open();
|
||||
U64 line_idx = 0;
|
||||
for(S64 line_num = params->line_num_range.min;
|
||||
line_num < params->line_num_range.max;
|
||||
@@ -11029,7 +11047,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
}
|
||||
}
|
||||
}
|
||||
dbgi_scope_close(scope);
|
||||
di_scope_close(scope);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
@@ -11257,11 +11275,11 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
if(params->line_src2dasm[line_slice_idx].first != 0 &&
|
||||
params->line_src2dasm[line_slice_idx].first->v.remap_line == mouse_pt.line)
|
||||
{
|
||||
df_set_hovered_line_info(params->line_src2dasm[line_slice_idx].first->v.binary, params->line_src2dasm[line_slice_idx].first->v.voff_range.min);
|
||||
df_set_hovered_line_info(¶ms->line_src2dasm[line_slice_idx].first->v.dbgi_key, params->line_src2dasm[line_slice_idx].first->v.voff_range.min);
|
||||
}
|
||||
if(params->line_dasm2src[line_slice_idx].first != 0)
|
||||
{
|
||||
df_set_hovered_line_info(params->line_dasm2src[line_slice_idx].first->v.binary, params->line_dasm2src[line_slice_idx].first->v.voff_range.min);
|
||||
df_set_hovered_line_info(¶ms->line_dasm2src[line_slice_idx].first->v.dbgi_key, params->line_dasm2src[line_slice_idx].first->v.voff_range.min);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11399,7 +11417,6 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
}
|
||||
if(dasm2src_info != 0)
|
||||
{
|
||||
DF_Entity *binary = dasm2src_info->binary;
|
||||
has_line_info = 1;
|
||||
line_info_line_num = dasm2src_info->pt.line;
|
||||
line_info_t = selected_thread_module->alive_t;
|
||||
@@ -11426,7 +11443,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
//
|
||||
UI_Parent(text_container_box) ProfScope("build line text") UI_Focus(UI_FocusKind_Off)
|
||||
{
|
||||
DF_Entity *hovered_line_binary = df_get_hovered_line_info_binary();
|
||||
DI_Key hovered_line_dbgi_key = df_get_hovered_line_info_dbgi_key();
|
||||
U64 hovered_line_voff = df_get_hovered_line_info_voff();
|
||||
ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f));
|
||||
UI_WidthFill
|
||||
@@ -11501,12 +11518,12 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
if(token->kind == TXT_TokenKind_Identifier || token->kind == TXT_TokenKind_Keyword)
|
||||
{
|
||||
B32 mapped_special = 0;
|
||||
for(DF_EntityNode *n = params->relevant_binaries.first; n != 0; n = n->next)
|
||||
for(DI_KeyNode *n = params->relevant_dbgi_keys.first; n != 0; n = n->next)
|
||||
{
|
||||
DF_Entity *binary = n->entity;
|
||||
DI_Key dbgi_key = n->v;
|
||||
if(!mapped_special && token->kind == TXT_TokenKind_Identifier)
|
||||
{
|
||||
U64 voff = df_voff_from_binary_symbol_name(binary, token_string);
|
||||
U64 voff = df_voff_from_dbgi_key_symbol_name(&dbgi_key, token_string);
|
||||
if(voff != 0)
|
||||
{
|
||||
mapped_special = 1;
|
||||
@@ -11516,7 +11533,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
}
|
||||
if(!mapped_special && token->kind == TXT_TokenKind_Identifier)
|
||||
{
|
||||
U64 type_num = df_type_num_from_binary_name(binary, token_string);
|
||||
U64 type_num = df_type_num_from_dbgi_key_name(&dbgi_key, token_string);
|
||||
if(type_num != 0)
|
||||
{
|
||||
mapped_special = 1;
|
||||
@@ -11708,7 +11725,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
for(DF_TextLineSrc2DasmInfoNode *n = src2dasm_list->first; n != 0; n = n->next)
|
||||
{
|
||||
if(n->v.remap_line == line_num &&
|
||||
n->v.binary == hovered_line_binary &&
|
||||
di_key_match(&n->v.dbgi_key, &hovered_line_dbgi_key) &&
|
||||
n->v.voff_range.min <= hovered_line_voff && hovered_line_voff < n->v.voff_range.max)
|
||||
{
|
||||
matches = 1;
|
||||
@@ -11721,8 +11738,8 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
|
||||
// rjf: check dasm2src
|
||||
if(dasm2src_list->first != 0)
|
||||
{
|
||||
DF_Entity *binary = dasm2src_list->first->v.binary;
|
||||
if(binary == hovered_line_binary)
|
||||
DI_Key dbgi_key = dasm2src_list->first->v.dbgi_key;
|
||||
if(di_key_match(&dbgi_key, &dasm2src_list->first->v.dbgi_key))
|
||||
{
|
||||
for(DF_TextLineDasm2SrcInfoNode *n = dasm2src_list->first; n != 0; n = n->next)
|
||||
{
|
||||
@@ -12820,6 +12837,7 @@ df_gfx_init(OS_WindowRepaintFunctionType *window_repaint_entry_point, DF_StateDe
|
||||
df_gfx_state->repaint_hook = window_repaint_entry_point;
|
||||
df_gfx_state->cfg_main_font_path_arena = arena_alloc();
|
||||
df_gfx_state->cfg_code_font_path_arena = arena_alloc();
|
||||
df_gfx_state->hover_line_arena = arena_alloc();
|
||||
df_clear_bindings();
|
||||
|
||||
// rjf: register gfx layer views
|
||||
@@ -13829,7 +13847,7 @@ df_gfx_end_frame(void)
|
||||
//- rjf: clear hover line info
|
||||
if(df_gfx_state->hover_line_set_this_frame == 0)
|
||||
{
|
||||
df_gfx_state->hover_line_binary = df_handle_zero();
|
||||
MemoryZeroStruct(&df_gfx_state->hover_line_dbgi_key);
|
||||
df_gfx_state->hover_line_voff = 0;
|
||||
}
|
||||
|
||||
|
||||
+9
-7
@@ -300,11 +300,11 @@ enum
|
||||
#define DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(name) df_gfx_view_rule_line_stringize__##name
|
||||
#define DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_DEF(name) internal DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_SIG(DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(name))
|
||||
|
||||
#define DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_SIG(name) void name(DF_ExpandKey key, DF_Eval eval, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, struct DF_CfgNode *cfg)
|
||||
#define DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_SIG(name) void name(DF_ExpandKey key, DF_Eval eval, DI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, struct DF_CfgNode *cfg)
|
||||
#define DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_NAME(name) df_gfx_view_rule_row_ui__##name
|
||||
#define DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_DEF(name) DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_SIG(DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_NAME(name))
|
||||
|
||||
#define DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_SIG(name) void name(struct DF_Window *ws, DF_ExpandKey key, DF_Eval eval, String8 string, DBGI_Scope *dbgi_scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, struct DF_CfgNode *cfg, Vec2F32 dim)
|
||||
#define DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_SIG(name) void name(struct DF_Window *ws, DF_ExpandKey key, DF_Eval eval, String8 string, DI_Scope *di_scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, struct DF_CfgNode *cfg, Vec2F32 dim)
|
||||
#define DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(name) df_gfx_view_rule_block_ui__##name
|
||||
#define DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(name) DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_SIG(DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(name))
|
||||
|
||||
@@ -405,7 +405,7 @@ struct DF_CodeSliceParams
|
||||
DF_EntityList *line_pins;
|
||||
DF_TextLineDasm2SrcInfoList *line_dasm2src;
|
||||
DF_TextLineSrc2DasmInfoList *line_src2dasm;
|
||||
DF_EntityList relevant_binaries;
|
||||
DI_KeyList relevant_dbgi_keys;
|
||||
|
||||
// rjf: visual parameters
|
||||
F_Tag font;
|
||||
@@ -513,6 +513,7 @@ struct DF_Window
|
||||
UI_State *ui;
|
||||
F32 code_font_size_delta;
|
||||
F32 main_font_size_delta;
|
||||
B32 window_temporarily_focused_ipc;
|
||||
|
||||
// rjf: view state delta history
|
||||
DF_StateDeltaHistory *view_state_hist;
|
||||
@@ -714,7 +715,8 @@ struct DF_GfxState
|
||||
DF_DragDropState drag_drop_state;
|
||||
|
||||
// rjf: hover line info correllation state
|
||||
DF_Handle hover_line_binary;
|
||||
Arena *hover_line_arena;
|
||||
DI_Key hover_line_dbgi_key;
|
||||
U64 hover_line_voff;
|
||||
B32 hover_line_set_this_frame;
|
||||
|
||||
@@ -871,8 +873,8 @@ internal B32 df_drag_drop(DF_DragDropPayload *out_payload);
|
||||
internal void df_drag_kill(void);
|
||||
internal void df_queue_drag_drop(void);
|
||||
|
||||
internal void df_set_hovered_line_info(DF_Entity *binary, U64 voff);
|
||||
internal DF_Entity *df_get_hovered_line_info_binary(void);
|
||||
internal void df_set_hovered_line_info(DI_Key *dbgi_key, U64 voff);
|
||||
internal DI_Key df_get_hovered_line_info_dbgi_key(void);
|
||||
internal U64 df_get_hovered_line_info_voff(void);
|
||||
|
||||
////////////////////////////////
|
||||
@@ -930,7 +932,7 @@ internal void df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdLis
|
||||
|
||||
internal String8 df_eval_escaped_from_raw_string(Arena *arena, String8 raw);
|
||||
internal String8List df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags flags, TG_Graph *graph, RDI_Parsed *rdi, DF_CtrlCtx *ctrl_ctx, U32 default_radix, F_Tag font, F32 font_size, F32 max_size, S32 depth, DF_Eval eval, TG_Member *opt_member, DF_CfgTable *cfg_table);
|
||||
internal DF_EvalVizWindowedRowList df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_EvalView *eval_view, U32 default_radix, F_Tag font, F32 font_size, Rng1S64 visible_range, DF_EvalVizBlockList *blocks);
|
||||
internal DF_EvalVizWindowedRowList df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_EvalView *eval_view, U32 default_radix, F_Tag font, F32 font_size, Rng1S64 visible_range, DF_EvalVizBlockList *blocks);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Hover Eval
|
||||
|
||||
+17
-18
@@ -23,7 +23,7 @@ DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(array)
|
||||
str8_list_push(scratch.arena, &array_size_expr_strs, child->string);
|
||||
}
|
||||
String8 array_size_expr = str8_list_join(scratch.arena, &array_size_expr_strs, 0);
|
||||
DF_Eval array_size_eval = df_eval_from_string(arena, dbgi_scope, ctrl_ctx, parse_ctx, macro_map, array_size_expr);
|
||||
DF_Eval array_size_eval = df_eval_from_string(arena, di_scope, ctrl_ctx, parse_ctx, macro_map, array_size_expr);
|
||||
DF_Eval array_size_eval_value = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdi, ctrl_ctx, array_size_eval);
|
||||
eval_error_list_concat_in_place(&eval.errors, &array_size_eval.errors);
|
||||
array_size = array_size_eval_value.imm_u64;
|
||||
@@ -1036,7 +1036,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(rgba)
|
||||
//~ rjf: "text"
|
||||
|
||||
internal DF_TxtTopologyInfo
|
||||
df_vr_txt_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg)
|
||||
df_vr_txt_topology_info_from_cfg(DI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DF_TxtTopologyInfo result = zero_struct;
|
||||
@@ -1094,7 +1094,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(text)
|
||||
//
|
||||
DF_Entity *thread = df_entity_from_handle(ctrl_ctx->thread);
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
|
||||
DF_TxtTopologyInfo top = df_vr_txt_topology_info_from_cfg(dbgi_scope, ctrl_ctx, parse_ctx, macro_map, cfg);
|
||||
DF_TxtTopologyInfo top = df_vr_txt_topology_info_from_cfg(di_scope, ctrl_ctx, parse_ctx, macro_map, cfg);
|
||||
DF_Eval value_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdi, ctrl_ctx, eval);
|
||||
U64 base_vaddr = value_eval.imm_u64 ? value_eval.imm_u64 : value_eval.offset;
|
||||
Rng1U64 vaddr_range = r1u64(base_vaddr, base_vaddr + (top.size_cap ? top.size_cap : 2048));
|
||||
@@ -1177,7 +1177,7 @@ DF_VIEW_UI_FUNCTION_DEF(text)
|
||||
//~ rjf: "disasm"
|
||||
|
||||
internal DF_DisasmTopologyInfo
|
||||
df_vr_disasm_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg)
|
||||
df_vr_disasm_topology_info_from_cfg(DI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DF_DisasmTopologyInfo result = zero_struct;
|
||||
@@ -1236,7 +1236,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(disasm)
|
||||
state->last_open_frame_idx = df_frame_index();
|
||||
{
|
||||
//- rjf: unpack params
|
||||
DF_DisasmTopologyInfo top = df_vr_disasm_topology_info_from_cfg(dbgi_scope, ctrl_ctx, parse_ctx, macro_map, cfg);
|
||||
DF_DisasmTopologyInfo top = df_vr_disasm_topology_info_from_cfg(di_scope, ctrl_ctx, parse_ctx, macro_map, cfg);
|
||||
|
||||
//- rjf: resolve to address value & range
|
||||
DF_Eval value_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdi, ctrl_ctx, eval);
|
||||
@@ -1259,7 +1259,6 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(disasm)
|
||||
dasm_params.style_flags = DASM_StyleFlag_Addresses;
|
||||
dasm_params.syntax = DASM_Syntax_Intel;
|
||||
dasm_params.base_vaddr = 0;
|
||||
dasm_params.exe_path = str8_zero();
|
||||
}
|
||||
DASM_Info dasm_info = dasm_info_from_key_params(dasm_scope, dasm_key, &dasm_params, &data_hash);
|
||||
String8 dasm_text_data = {0};
|
||||
@@ -1388,7 +1387,7 @@ df_bitmap_view_state__canvas_from_screen_rect(DF_BitmapViewState *bvs, Rng2F32 r
|
||||
}
|
||||
|
||||
internal DF_BitmapTopologyInfo
|
||||
df_vr_bitmap_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg)
|
||||
df_vr_bitmap_topology_info_from_cfg(DI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DF_BitmapTopologyInfo info = {0};
|
||||
@@ -1513,7 +1512,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(bitmap)
|
||||
//
|
||||
DF_Eval value_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdi, ctrl_ctx, eval);
|
||||
U64 base_vaddr = value_eval.imm_u64 ? value_eval.imm_u64 : value_eval.offset;
|
||||
DF_BitmapTopologyInfo topology_info = df_vr_bitmap_topology_info_from_cfg(dbgi_scope, ctrl_ctx, parse_ctx, macro_map, cfg);
|
||||
DF_BitmapTopologyInfo topology_info = df_vr_bitmap_topology_info_from_cfg(di_scope, ctrl_ctx, parse_ctx, macro_map, cfg);
|
||||
U64 expected_size = topology_info.width*topology_info.height*r_tex2d_format_bytes_per_pixel_table[topology_info.fmt];
|
||||
Rng1U64 vaddr_range = r1u64(base_vaddr, base_vaddr+expected_size);
|
||||
|
||||
@@ -1568,7 +1567,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(bitmap)
|
||||
DF_VIEW_SETUP_FUNCTION_DEF(bitmap)
|
||||
{
|
||||
DF_BitmapViewState *bvs = df_view_user_state(view, DF_BitmapViewState);
|
||||
DBGI_Scope *dbgi_scope = dbgi_scope_open();
|
||||
DI_Scope *di_scope = di_scope_open();
|
||||
DF_CfgNode *view_center_cfg = df_cfg_node_child_from_string(cfg_root, str8_lit("view_center"), StringMatchFlag_CaseInsensitive);
|
||||
DF_CfgNode *zoom_cfg = df_cfg_node_child_from_string(cfg_root, str8_lit("zoom"), StringMatchFlag_CaseInsensitive);
|
||||
DF_CfgNode *bitmap_cfg = df_cfg_node_child_from_string(cfg_root, str8_lit("bitmap"), StringMatchFlag_CaseInsensitive);
|
||||
@@ -1576,16 +1575,16 @@ DF_VIEW_SETUP_FUNCTION_DEF(bitmap)
|
||||
DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread);
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
|
||||
U64 thread_unwind_rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, ctrl_ctx.unwind_count);
|
||||
EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(dbgi_scope, process, thread_unwind_rip_vaddr);
|
||||
EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(di_scope, process, thread_unwind_rip_vaddr);
|
||||
bvs->view_center_pos.x = (F32)f64_from_str8(bitmap_cfg->first->string);
|
||||
bvs->view_center_pos.y = (F32)f64_from_str8(bitmap_cfg->first->next->string);
|
||||
bvs->zoom = (F32)f64_from_str8(zoom_cfg->first->string);
|
||||
bvs->top = df_vr_bitmap_topology_info_from_cfg(dbgi_scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, bitmap_cfg);
|
||||
bvs->top = df_vr_bitmap_topology_info_from_cfg(di_scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, bitmap_cfg);
|
||||
if(bvs->zoom == 0)
|
||||
{
|
||||
bvs->zoom = 1.f;
|
||||
}
|
||||
dbgi_scope_close(dbgi_scope);
|
||||
di_scope_close(di_scope);
|
||||
}
|
||||
|
||||
DF_VIEW_STRING_FROM_STATE_FUNCTION_DEF(bitmap)
|
||||
@@ -1636,7 +1635,7 @@ DF_VIEW_UI_FUNCTION_DEF(bitmap)
|
||||
{
|
||||
DF_BitmapViewState *bvs = df_view_user_state(view, DF_BitmapViewState);
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DBGI_Scope *dbgi_scope = dbgi_scope_open();
|
||||
DI_Scope *di_scope = di_scope_open();
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
TEX_Scope *tex_scope = tex_scope_open();
|
||||
|
||||
@@ -1647,13 +1646,13 @@ DF_VIEW_UI_FUNCTION_DEF(bitmap)
|
||||
DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread);
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
|
||||
U64 thread_unwind_rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, ctrl_ctx.unwind_count);
|
||||
EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(dbgi_scope, process, thread_unwind_rip_vaddr);
|
||||
EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(di_scope, process, thread_unwind_rip_vaddr);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: evaluate expression
|
||||
//
|
||||
String8 expr = str8(view->query_buffer, view->query_string_size);
|
||||
DF_Eval eval = df_eval_from_string(scratch.arena, dbgi_scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, expr);
|
||||
DF_Eval eval = df_eval_from_string(scratch.arena, di_scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, expr);
|
||||
DF_Eval value_eval = df_value_mode_eval_from_eval(parse_ctx.type_graph, parse_ctx.rdi, &ctrl_ctx, eval);
|
||||
U64 base_vaddr = value_eval.imm_u64 ? value_eval.imm_u64 : value_eval.offset;
|
||||
U64 expected_size = bvs->top.width*bvs->top.height*r_tex2d_format_bytes_per_pixel_table[bvs->top.fmt];
|
||||
@@ -1731,7 +1730,7 @@ DF_VIEW_UI_FUNCTION_DEF(bitmap)
|
||||
|
||||
hs_scope_close(hs_scope);
|
||||
tex_scope_close(tex_scope);
|
||||
dbgi_scope_close(dbgi_scope);
|
||||
di_scope_close(di_scope);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
@@ -1739,7 +1738,7 @@ DF_VIEW_UI_FUNCTION_DEF(bitmap)
|
||||
//~ rjf: "geo"
|
||||
|
||||
internal DF_GeoTopologyInfo
|
||||
df_vr_geo_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg)
|
||||
df_vr_geo_topology_info_from_cfg(DI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DF_GeoTopologyInfo result = {0};
|
||||
@@ -1860,7 +1859,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(geo)
|
||||
U64 base_vaddr = value_eval.imm_u64 ? value_eval.imm_u64 : value_eval.offset;
|
||||
|
||||
//- rjf: extract extra geo topology info from view rule
|
||||
DF_GeoTopologyInfo top = df_vr_geo_topology_info_from_cfg(dbgi_scope, ctrl_ctx, parse_ctx, macro_map, cfg);
|
||||
DF_GeoTopologyInfo top = df_vr_geo_topology_info_from_cfg(di_scope, ctrl_ctx, parse_ctx, macro_map, cfg);
|
||||
Rng1U64 index_buffer_vaddr_range = r1u64(base_vaddr, base_vaddr+top.index_count*sizeof(U32));
|
||||
Rng1U64 vertex_buffer_vaddr_range = top.vertices_vaddr_range;
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ struct DF_VR_TextState
|
||||
F32 loaded_t;
|
||||
};
|
||||
|
||||
internal DF_TxtTopologyInfo df_vr_txt_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg);
|
||||
internal DF_TxtTopologyInfo df_vr_txt_topology_info_from_cfg(DI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: "disasm"
|
||||
@@ -61,7 +61,7 @@ struct DF_VR_DisasmState
|
||||
F32 loaded_t;
|
||||
};
|
||||
|
||||
internal DF_DisasmTopologyInfo df_vr_disasm_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg);
|
||||
internal DF_DisasmTopologyInfo df_vr_disasm_topology_info_from_cfg(DI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: "bitmap"
|
||||
@@ -104,7 +104,7 @@ internal Vec2F32 df_bitmap_view_state__screen_from_canvas_pos(DF_BitmapViewState
|
||||
internal Rng2F32 df_bitmap_view_state__screen_from_canvas_rect(DF_BitmapViewState *bvs, Rng2F32 rect, Rng2F32 cvs);
|
||||
internal Vec2F32 df_bitmap_view_state__canvas_from_screen_pos(DF_BitmapViewState *bvs, Rng2F32 rect, Vec2F32 scr);
|
||||
internal Rng2F32 df_bitmap_view_state__canvas_from_screen_rect(DF_BitmapViewState *bvs, Rng2F32 rect, Rng2F32 scr);
|
||||
internal DF_BitmapTopologyInfo df_vr_bitmap_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg);
|
||||
internal DF_BitmapTopologyInfo df_vr_bitmap_topology_info_from_cfg(DI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: "geo"
|
||||
@@ -139,6 +139,6 @@ struct DF_VR_GeoBoxDrawData
|
||||
F32 loaded_t;
|
||||
};
|
||||
|
||||
internal DF_GeoTopologyInfo df_vr_geo_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg);
|
||||
internal DF_GeoTopologyInfo df_vr_geo_topology_info_from_cfg(DI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg);
|
||||
|
||||
#endif // DF_VIEW_RULES_H
|
||||
|
||||
+214
-216
@@ -543,7 +543,7 @@ df_watch_view_text_edit_state_from_pt(DF_WatchViewState *wv, DF_WatchViewPoint p
|
||||
//- rjf: windowed watch tree visualization (both single-line and multi-line)
|
||||
|
||||
internal DF_EvalVizBlockList
|
||||
df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_View *view, DF_WatchViewState *ews)
|
||||
df_eval_viz_block_list_from_watch_view_state(Arena *arena, DI_Scope *di_scope, FZY_Scope *fzy_scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_View *view, DF_WatchViewState *ews)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
@@ -551,7 +551,7 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF
|
||||
DF_EvalViewKey eval_view_key = df_eval_view_key_from_eval_watch_view(ews);
|
||||
DF_EvalView *eval_view = df_eval_view_from_key(eval_view_key);
|
||||
String8 filter = str8(view->query_buffer, view->query_string_size);
|
||||
DBGI_FuzzySearchTarget dbgi_target = DBGI_FuzzySearchTarget_UDTs;
|
||||
FZY_Target fzy_target = FZY_Target_UDTs;
|
||||
switch(ews->fill_kind)
|
||||
{
|
||||
////////////////////////////
|
||||
@@ -568,7 +568,7 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF
|
||||
{
|
||||
DF_ExpandKey parent_key = df_parent_expand_key_from_eval_root(root);
|
||||
DF_ExpandKey key = df_expand_key_from_eval_root(root);
|
||||
DF_EvalVizBlockList root_blocks = df_eval_viz_block_list_from_eval_view_expr_keys(arena, scope, ctrl_ctx, parse_ctx, macro_map, eval_view, root_expr_string, parent_key, key);
|
||||
DF_EvalVizBlockList root_blocks = df_eval_viz_block_list_from_eval_view_expr_keys(arena, di_scope, ctrl_ctx, parse_ctx, macro_map, eval_view, root_expr_string, parent_key, key);
|
||||
df_eval_viz_block_list_concat__in_place(&blocks, &root_blocks);
|
||||
}
|
||||
}
|
||||
@@ -594,7 +594,7 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF
|
||||
{
|
||||
DF_ExpandKey parent_key = df_expand_key_make(5381, 0);
|
||||
DF_ExpandKey key = df_expand_key_make(df_hash_from_expand_key(parent_key), num);
|
||||
DF_EvalVizBlockList root_blocks = df_eval_viz_block_list_from_eval_view_expr_keys(arena, scope, ctrl_ctx, parse_ctx, macro_map, eval_view, root_expr_string, parent_key, key);
|
||||
DF_EvalVizBlockList root_blocks = df_eval_viz_block_list_from_eval_view_expr_keys(arena, di_scope, ctrl_ctx, parse_ctx, macro_map, eval_view, root_expr_string, parent_key, key);
|
||||
df_eval_viz_block_list_concat__in_place(&blocks, &root_blocks);
|
||||
}
|
||||
}
|
||||
@@ -606,7 +606,7 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF
|
||||
{
|
||||
DF_ExpandKey parent_key = df_expand_key_make(5381, 0);
|
||||
DF_ExpandKey key = df_expand_key_make(df_hash_from_expand_key(parent_key), num);
|
||||
DF_EvalVizBlockList root_blocks = df_eval_viz_block_list_from_eval_view_expr_keys(arena, scope, ctrl_ctx, parse_ctx, macro_map, eval_view, root_expr_string, parent_key, key);
|
||||
DF_EvalVizBlockList root_blocks = df_eval_viz_block_list_from_eval_view_expr_keys(arena, di_scope, ctrl_ctx, parse_ctx, macro_map, eval_view, root_expr_string, parent_key, key);
|
||||
df_eval_viz_block_list_concat__in_place(&blocks, &root_blocks);
|
||||
}
|
||||
}
|
||||
@@ -626,7 +626,7 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF
|
||||
{
|
||||
DF_ExpandKey parent_key = df_expand_key_make(5381, 0);
|
||||
DF_ExpandKey key = df_expand_key_make(df_hash_from_expand_key(parent_key), num);
|
||||
DF_EvalVizBlockList root_blocks = df_eval_viz_block_list_from_eval_view_expr_keys(arena, scope, ctrl_ctx, parse_ctx, macro_map, eval_view, root_expr_string, parent_key, key);
|
||||
DF_EvalVizBlockList root_blocks = df_eval_viz_block_list_from_eval_view_expr_keys(arena, di_scope, ctrl_ctx, parse_ctx, macro_map, eval_view, root_expr_string, parent_key, key);
|
||||
df_eval_viz_block_list_concat__in_place(&blocks, &root_blocks);
|
||||
}
|
||||
}
|
||||
@@ -635,10 +635,10 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF
|
||||
////////////////////////////
|
||||
//- rjf: debug info table fill -> build split debug info table blocks
|
||||
//
|
||||
case DF_WatchViewFillKind_Globals: dbgi_target = DBGI_FuzzySearchTarget_GlobalVariables; goto dbgi_table;
|
||||
case DF_WatchViewFillKind_ThreadLocals: dbgi_target = DBGI_FuzzySearchTarget_ThreadVariables; goto dbgi_table;
|
||||
case DF_WatchViewFillKind_Types: dbgi_target = DBGI_FuzzySearchTarget_UDTs; goto dbgi_table;
|
||||
case DF_WatchViewFillKind_Procedures: dbgi_target = DBGI_FuzzySearchTarget_Procedures; goto dbgi_table;
|
||||
case DF_WatchViewFillKind_Globals: fzy_target = FZY_Target_GlobalVariables; goto dbgi_table;
|
||||
case DF_WatchViewFillKind_ThreadLocals: fzy_target = FZY_Target_ThreadVariables; goto dbgi_table;
|
||||
case DF_WatchViewFillKind_Types: fzy_target = FZY_Target_UDTs; goto dbgi_table;
|
||||
case DF_WatchViewFillKind_Procedures: fzy_target = FZY_Target_Procedures; goto dbgi_table;
|
||||
dbgi_table:;
|
||||
{
|
||||
//- rjf: unpack context
|
||||
@@ -646,10 +646,7 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
|
||||
U64 thread_rip_unwind_vaddr = df_query_cached_rip_from_thread_unwind(thread, ctrl_ctx->unwind_count);
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, thread_rip_unwind_vaddr);
|
||||
DF_Entity *binary = df_binary_file_from_module(module);
|
||||
String8 exe_path = df_full_path_from_entity(scratch.arena, binary);
|
||||
DBGI_Parse *dbgi = dbgi_parse_from_exe_path(scope, exe_path, os_now_microseconds()+100);
|
||||
RDI_Parsed *rdi = &dbgi->rdi;
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
|
||||
//- rjf: calculate top-level keys, expand root-level, grab root expansion node
|
||||
DF_ExpandKey parent_key = df_expand_key_make(5381, 0);
|
||||
@@ -660,7 +657,12 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF
|
||||
//- rjf: query all filtered items from dbgi searching system
|
||||
U128 fuzzy_search_key = {(U64)view, df_hash_from_string(str8_struct(&view))};
|
||||
B32 items_stale = 0;
|
||||
DBGI_FuzzySearchItemArray items = dbgi_fuzzy_search_items_from_key_exe_query(scope, fuzzy_search_key, exe_path, filter, dbgi_target, os_now_microseconds()+100, &items_stale);
|
||||
FZY_Params params = {fzy_target};
|
||||
{
|
||||
params.dbgi_keys.count = 1;
|
||||
params.dbgi_keys.v = &dbgi_key;
|
||||
}
|
||||
FZY_ItemArray items = fzy_items_from_key_params_query(fzy_scope, fuzzy_search_key, ¶ms, filter, os_now_microseconds()+100, &items_stale);
|
||||
if(items_stale)
|
||||
{
|
||||
df_gfx_request_frame();
|
||||
@@ -691,7 +693,7 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF
|
||||
U64 idx = 0;
|
||||
for(DF_ExpandNode *child = root_node->first; child != 0; child = child->next)
|
||||
{
|
||||
U64 item_num = dbgi_fuzzy_item_num_from_array_element_idx__linear_search(&items, child->key.child_num);
|
||||
U64 item_num = fzy_item_num_from_array_element_idx__linear_search(&items, child->key.child_num);
|
||||
if(item_num != 0)
|
||||
{
|
||||
sub_expand_keys[idx] = child->key;
|
||||
@@ -731,8 +733,8 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF
|
||||
DF_EvalVizBlock *last_vb = df_eval_viz_block_begin(arena, DF_EvalVizBlockKind_DebugInfoTable, parent_key, root_key, 0);
|
||||
{
|
||||
last_vb->visual_idx_range = last_vb->semantic_idx_range = r1u64(0, items.count);
|
||||
last_vb->dbgi_target = dbgi_target;
|
||||
last_vb->backing_search_items = items;
|
||||
last_vb->fzy_target = fzy_target;
|
||||
last_vb->fzy_backing_items = items;
|
||||
}
|
||||
for(U64 sub_expand_idx = 0; sub_expand_idx < sub_expand_keys_count; sub_expand_idx += 1)
|
||||
{
|
||||
@@ -740,7 +742,7 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF
|
||||
last_vb = df_eval_viz_block_split_and_continue(arena, &blocks, last_vb, sub_expand_item_idxs[sub_expand_idx]);
|
||||
|
||||
// rjf: grab name for the expanded row
|
||||
String8 name = dbgi_fuzzy_item_string_from_rdi_target_element_idx(&dbgi->rdi, dbgi_target, sub_expand_keys[sub_expand_idx].child_num);
|
||||
String8 name = fzy_item_string_from_rdi_target_element_idx(parse_ctx->rdi, fzy_target, sub_expand_keys[sub_expand_idx].child_num);
|
||||
|
||||
// rjf: recurse for sub-expansion
|
||||
{
|
||||
@@ -752,8 +754,8 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF
|
||||
df_cfg_table_push_unparsed_string(arena, &child_cfg, view_rule_string, DF_CfgSrc_User);
|
||||
}
|
||||
}
|
||||
DF_Eval eval = df_eval_from_string(arena, scope, ctrl_ctx, parse_ctx, macro_map, name);
|
||||
df_append_viz_blocks_for_parent__rec(arena, scope, eval_view, ctrl_ctx, parse_ctx, macro_map, parent_key, sub_expand_keys[sub_expand_idx], name, eval, 0, &child_cfg, 0, &blocks);
|
||||
DF_Eval eval = df_eval_from_string(arena, di_scope, ctrl_ctx, parse_ctx, macro_map, name);
|
||||
df_append_viz_blocks_for_parent__rec(arena, di_scope, eval_view, ctrl_ctx, parse_ctx, macro_map, parent_key, sub_expand_keys[sub_expand_idx], name, eval, 0, &child_cfg, 0, &blocks);
|
||||
}
|
||||
}
|
||||
df_eval_viz_block_end(&blocks, last_vb);
|
||||
@@ -817,7 +819,8 @@ internal void
|
||||
df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewState *ewv, B32 modifiable, U32 default_radix, Rng2F32 rect)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
DBGI_Scope *scope = dbgi_scope_open();
|
||||
DI_Scope *di_scope = di_scope_open();
|
||||
FZY_Scope *fzy_scope = fzy_scope_open();
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
|
||||
//////////////////////////////
|
||||
@@ -837,7 +840,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
|
||||
//////////////////////////////
|
||||
//- rjf: process * thread info -> parse_ctx
|
||||
//
|
||||
EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(scope, process, thread_ip_vaddr);
|
||||
EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(di_scope, process, thread_ip_vaddr);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: determine autocompletion string
|
||||
@@ -888,19 +891,12 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
|
||||
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
|
||||
Architecture arch = df_architecture_from_entity(thread);
|
||||
U64 reg_size = regs_block_size_from_architecture(arch);
|
||||
U64 thread_unwind_ip_vaddr = 0;
|
||||
void *thread_unwind_regs_block = push_array(scratch.arena, U8, reg_size);
|
||||
U64 thread_unwind_ip_vaddr = 0;
|
||||
if(unwind.frames.count != 0)
|
||||
{
|
||||
U64 idx = 0;
|
||||
for(CTRL_UnwindFrame *f = unwind.first; f != 0; f = f->next, idx += 1)
|
||||
{
|
||||
if(idx == unwind_count)
|
||||
{
|
||||
thread_unwind_ip_vaddr = f->rip;
|
||||
thread_unwind_regs_block = f->regs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
thread_unwind_regs_block = unwind.frames.v[unwind_count%unwind.frames.count].regs;
|
||||
thread_unwind_ip_vaddr = regs_rip_from_arch_block(arch, thread_unwind_regs_block);
|
||||
}
|
||||
|
||||
//- rjf: lex & parse
|
||||
@@ -919,7 +915,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
|
||||
//
|
||||
if(state_dirty)
|
||||
{
|
||||
blocks = df_eval_viz_block_list_from_watch_view_state(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, view, ewv);
|
||||
blocks = df_eval_viz_block_list_from_watch_view_state(scratch.arena, di_scope, fzy_scope, &ctrl_ctx, &parse_ctx, ¯o_map, view, ewv);
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
@@ -1057,7 +1053,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
|
||||
ewv->text_edit_state_slots_count = u64_up_to_pow2(selection_dim.y+1);
|
||||
ewv->text_edit_state_slots_count = Max(ewv->text_edit_state_slots_count, 64);
|
||||
ewv->text_edit_state_slots = push_array(ewv->text_edit_arena, DF_WatchViewTextEditState*, ewv->text_edit_state_slots_count);
|
||||
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(),
|
||||
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, di_scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(),
|
||||
r1s64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y-1),
|
||||
ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y-1)+1), &blocks);
|
||||
DF_EvalVizRow *row = rows.first;
|
||||
@@ -1089,7 +1085,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
|
||||
if(!ewv->text_editing && evt->slot == UI_EventActionSlot_Accept && selection_tbl.min.x <= 0)
|
||||
{
|
||||
taken = 1;
|
||||
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(),
|
||||
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, di_scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(),
|
||||
r1s64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y-1),
|
||||
ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y-1)+1), &blocks);
|
||||
DF_EvalVizRow *row = rows.first;
|
||||
@@ -1100,6 +1096,25 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
|
||||
B32 is_expanded = df_expand_key_is_set(&eval_view->expand_tree_table, row->key);
|
||||
df_expand_set_expansion(eval_view->arena, &eval_view->expand_tree_table, row->parent_key, row->key, !is_expanded);
|
||||
}
|
||||
if(row->flags & DF_EvalVizRowFlag_Canvas)
|
||||
{
|
||||
DF_CfgNode *cfg = df_cfg_tree_copy(scratch.arena, row->expand_ui_rule_node);
|
||||
DF_CfgNode *cfg_root = push_array(scratch.arena, DF_CfgNode, 1);
|
||||
cfg_root->first = cfg_root->last = cfg;
|
||||
cfg_root->next = cfg_root->parent = &df_g_nil_cfg_node;
|
||||
if(cfg != &df_g_nil_cfg_node)
|
||||
{
|
||||
cfg->parent = cfg_root;
|
||||
}
|
||||
DF_CmdParams p = df_cmd_params_from_view(ws, panel, view);
|
||||
p.string = row->edit_expr;
|
||||
p.view_spec = df_tab_view_spec_from_gfx_view_rule_spec(row->expand_ui_rule_spec);
|
||||
p.cfg_node = cfg_root;
|
||||
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_String);
|
||||
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_ViewSpec);
|
||||
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_CfgNode);
|
||||
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_OpenTab));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1188,13 +1203,13 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
|
||||
case DF_WatchViewColumnKind_Value:
|
||||
if(editing_complete && evt->slot != UI_EventActionSlot_Cancel)
|
||||
{
|
||||
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(),
|
||||
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, di_scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(),
|
||||
r1s64(ui_scroll_list_row_from_item(&row_blocks, y-1),
|
||||
ui_scroll_list_row_from_item(&row_blocks, y-1)+1), &blocks);
|
||||
B32 success = 0;
|
||||
if(rows.first != 0)
|
||||
{
|
||||
DF_Eval write_eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, new_string);
|
||||
DF_Eval write_eval = df_eval_from_string(scratch.arena, di_scope, &ctrl_ctx, &parse_ctx, ¯o_map, new_string);
|
||||
success = df_commit_eval_value(parse_ctx.type_graph, parse_ctx.rdi, &ctrl_ctx, rows.first->eval, write_eval);
|
||||
}
|
||||
if(!success)
|
||||
@@ -1230,7 +1245,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
|
||||
{
|
||||
taken = 1;
|
||||
String8List strs = {0};
|
||||
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(),
|
||||
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, di_scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(),
|
||||
r1s64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y-1),
|
||||
ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y-1)+1), &blocks);
|
||||
DF_EvalVizRow *row = rows.first;
|
||||
@@ -1566,7 +1581,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
|
||||
//- rjf: viz blocks -> rows
|
||||
DF_EvalVizWindowedRowList rows = {0};
|
||||
{
|
||||
rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(), r1s64(visible_row_rng.min-1, visible_row_rng.max), &blocks);
|
||||
rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, di_scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, ui_top_font_size(), r1s64(visible_row_rng.min-1, visible_row_rng.max), &blocks);
|
||||
}
|
||||
|
||||
//- rjf: build table
|
||||
@@ -1631,7 +1646,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
|
||||
{
|
||||
Vec2F32 canvas_dim = v2f32(scroll_list_params.dim_px.x - ui_top_font_size()*1.5f,
|
||||
(row->skipped_size_in_rows+row->size_in_rows+row->chopped_size_in_rows)*scroll_list_params.row_height_px);
|
||||
row->expand_ui_rule_spec->info.block_ui(ws, row->key, row->eval, row->edit_expr, scope, &ctrl_ctx, &parse_ctx, ¯o_map, row->expand_ui_rule_node, canvas_dim);
|
||||
row->expand_ui_rule_spec->info.block_ui(ws, row->key, row->eval, row->edit_expr, di_scope, &ctrl_ctx, &parse_ctx, ¯o_map, row->expand_ui_rule_node, canvas_dim);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1906,7 +1921,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
|
||||
UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###val_%I64x", row_hash);
|
||||
UI_Parent(box)
|
||||
{
|
||||
row->value_ui_rule_spec->info.row_ui(row->key, row->eval, scope, &ctrl_ctx, &parse_ctx, ¯o_map, row->value_ui_rule_node);
|
||||
row->value_ui_rule_spec->info.row_ui(row->key, row->eval, di_scope, &ctrl_ctx, &parse_ctx, ¯o_map, row->value_ui_rule_node);
|
||||
}
|
||||
sig = ui_signal_from_box(box);
|
||||
}
|
||||
@@ -2042,7 +2057,8 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
dbgi_scope_close(scope);
|
||||
fzy_scope_close(fzy_scope);
|
||||
di_scope_close(di_scope);
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
@@ -3235,17 +3251,26 @@ DF_VIEW_UI_FUNCTION_DEF(SymbolLister)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DBGI_Scope *scope = dbgi_scope_open();
|
||||
DI_Scope *di_scope = di_scope_open();
|
||||
FZY_Scope *fzy_scope = fzy_scope_open();
|
||||
F32 row_height_px = floor_f32(ui_top_font_size()*2.5f);
|
||||
DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view);
|
||||
DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread);
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
|
||||
U64 thread_unwind_rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, ctrl_ctx.unwind_count);
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, thread_unwind_rip_vaddr);
|
||||
DF_Entity *binary = df_binary_file_from_module(module);
|
||||
String8 exe_path = df_full_path_from_entity(scratch.arena, binary);
|
||||
String8 query = str8(view->query_buffer, view->query_string_size);
|
||||
TG_Graph *graph = tg_graph_begin(bit_size_from_arch(df_architecture_from_entity(thread))/8, 256);
|
||||
DI_KeyList dbgi_keys_list = df_push_active_dbgi_key_list(scratch.arena);
|
||||
DI_KeyArray dbgi_keys = di_key_array_from_list(scratch.arena, &dbgi_keys_list);
|
||||
FZY_Params params = {FZY_Target_Procedures, dbgi_keys};
|
||||
U64 endt_us = os_now_microseconds()+200;
|
||||
|
||||
//- rjf: grab rdis, make type graphs for each
|
||||
U64 rdis_count = dbgi_keys.count;
|
||||
RDI_Parsed **rdis = push_array(scratch.arena, RDI_Parsed *, rdis_count);
|
||||
TG_Graph **graphs = push_array(scratch.arena, TG_Graph *, rdis_count);
|
||||
{
|
||||
for(U64 idx = 0; idx < rdis_count; idx += 1)
|
||||
{
|
||||
rdis[idx] = di_rdi_from_key(di_scope, &dbgi_keys.v[idx], endt_us);
|
||||
graphs[idx] = tg_graph_begin(rdi_addr_size_from_arch(rdis[idx]->top_level_info->architecture), 256);
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: grab state
|
||||
typedef struct DF_SymbolListerViewState DF_SymbolListerViewState;
|
||||
@@ -3257,10 +3282,8 @@ DF_VIEW_UI_FUNCTION_DEF(SymbolLister)
|
||||
|
||||
//- rjf: query -> raddbg, filtered items
|
||||
U128 fuzzy_search_key = {(U64)view, df_hash_from_string(str8_struct(&view))};
|
||||
DBGI_Parse *dbgi = dbgi_parse_from_exe_path(scope, exe_path, os_now_microseconds()+100);
|
||||
RDI_Parsed *rdi = &dbgi->rdi;
|
||||
B32 items_stale = 0;
|
||||
DBGI_FuzzySearchItemArray items = dbgi_fuzzy_search_items_from_key_exe_query(scope, fuzzy_search_key, exe_path, query, DBGI_FuzzySearchTarget_Procedures, os_now_microseconds()+100, &items_stale);
|
||||
FZY_ItemArray items = fzy_items_from_key_params_query(fzy_scope, fuzzy_search_key, ¶ms, query, endt_us, &items_stale);
|
||||
if(items_stale)
|
||||
{
|
||||
df_gfx_request_frame();
|
||||
@@ -3269,16 +3292,27 @@ DF_VIEW_UI_FUNCTION_DEF(SymbolLister)
|
||||
//- rjf: submit best match when hitting enter w/ no selection
|
||||
if(slv->cursor.y == 0 && items.count != 0 && ui_slot_press(UI_EventActionSlot_Accept))
|
||||
{
|
||||
RDI_Procedure *procedure = rdi_element_from_idx(rdi, procedures, items.v[0].idx);
|
||||
U64 name_size = 0;
|
||||
U8 *name_base = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size);
|
||||
String8 name = str8(name_base, name_size);
|
||||
if(name.size != 0)
|
||||
FZY_Item *item = &items.v[0];
|
||||
U64 base_idx = 0;
|
||||
for(U64 rdi_idx = 0; rdi_idx < rdis_count; rdi_idx += 1)
|
||||
{
|
||||
DF_CmdParams p = df_cmd_params_from_view(ws, panel, view);
|
||||
p.string = name;
|
||||
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_String);
|
||||
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_CompleteQuery));
|
||||
RDI_Parsed *rdi = rdis[rdi_idx];
|
||||
if(base_idx <= item->idx && item->idx < base_idx + rdi->procedures_count)
|
||||
{
|
||||
RDI_Procedure *procedure = rdi_element_from_idx(rdi, procedures, item->idx-base_idx);
|
||||
U64 name_size = 0;
|
||||
U8 *name_base = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size);
|
||||
String8 name = str8(name_base, name_size);
|
||||
if(name.size != 0)
|
||||
{
|
||||
DF_CmdParams p = df_cmd_params_from_view(ws, panel, view);
|
||||
p.string = name;
|
||||
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_String);
|
||||
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_CompleteQuery));
|
||||
}
|
||||
break;
|
||||
}
|
||||
base_idx += rdi->procedures_count;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3311,13 +3345,36 @@ DF_VIEW_UI_FUNCTION_DEF(SymbolLister)
|
||||
idx += 1)
|
||||
UI_Focus((slv->cursor.y == idx+1) ? UI_FocusKind_On : UI_FocusKind_Off)
|
||||
{
|
||||
DBGI_FuzzySearchItem *item = &items.v[idx];
|
||||
RDI_Procedure *procedure = rdi_element_from_idx(rdi, procedures, item->idx);
|
||||
FZY_Item *item = &items.v[idx];
|
||||
|
||||
//- rjf: determine dbgi/rdi to which this item belongs
|
||||
DI_Key dbgi_key = {0};
|
||||
RDI_Parsed *rdi = &di_rdi_parsed_nil;
|
||||
TG_Graph *graph = 0;
|
||||
U64 base_idx = 0;
|
||||
{
|
||||
for(U64 rdi_idx = 0; rdi_idx < rdis_count; rdi_idx += 1)
|
||||
{
|
||||
if(base_idx <= item->idx && item->idx < base_idx + rdis[rdi_idx]->procedures_count)
|
||||
{
|
||||
dbgi_key = dbgi_keys.v[rdi_idx];
|
||||
rdi = rdis[rdi_idx];
|
||||
graph = graphs[rdi_idx];
|
||||
break;
|
||||
}
|
||||
base_idx += rdis[rdi_idx]->procedures_count;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: unpack this item's info
|
||||
RDI_Procedure *procedure = rdi_element_from_idx(rdi, procedures, item->idx-base_idx);
|
||||
U64 name_size = 0;
|
||||
U8 *name_base = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size);
|
||||
String8 name = str8(name_base, name_size);
|
||||
RDI_TypeNode *type_node = rdi_element_from_idx(rdi, type_nodes, procedure->type_idx);
|
||||
TG_Key type_key = tg_key_ext(tg_kind_from_rdi_type_kind(type_node->kind), procedure->type_idx);
|
||||
|
||||
//- rjf: build item button
|
||||
ui_set_next_hover_cursor(OS_Cursor_HandPoint);
|
||||
UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable|
|
||||
UI_BoxFlag_DrawBackground|
|
||||
@@ -3330,12 +3387,14 @@ DF_VIEW_UI_FUNCTION_DEF(SymbolLister)
|
||||
{
|
||||
UI_Box *box = df_code_label(1.f, 0, df_rgba_from_theme_color(DF_ThemeColor_CodeFunction), name);
|
||||
ui_box_equip_fuzzy_match_ranges(box, &item->match_ranges);
|
||||
if(!tg_key_match(tg_key_zero(), type_key))
|
||||
if(!tg_key_match(tg_key_zero(), type_key) && graph != 0)
|
||||
{
|
||||
String8 type_string = tg_string_from_key(scratch.arena, graph, rdi, type_key);
|
||||
df_code_label(0.5f, 0, df_rgba_from_theme_color(DF_ThemeColor_WeakText), type_string);
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: interact
|
||||
UI_Signal sig = ui_signal_from_box(box);
|
||||
if(ui_clicked(sig))
|
||||
{
|
||||
@@ -3346,8 +3405,8 @@ DF_VIEW_UI_FUNCTION_DEF(SymbolLister)
|
||||
}
|
||||
if(ui_hovering(sig)) UI_Tooltip
|
||||
{
|
||||
U64 binary_voff = df_voff_from_binary_symbol_name(binary, name);
|
||||
DF_TextLineDasm2SrcInfo dasm2src_info = df_text_line_dasm2src_info_from_binary_voff(binary, binary_voff);
|
||||
U64 binary_voff = df_voff_from_dbgi_key_symbol_name(&dbgi_key, name);
|
||||
DF_TextLineDasm2SrcInfo dasm2src_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, binary_voff);
|
||||
String8 file_path = df_full_path_from_entity(scratch.arena, dasm2src_info.file);
|
||||
S64 line_num = dasm2src_info.pt.line;
|
||||
df_code_label(1.f, 0, df_rgba_from_theme_color(DF_ThemeColor_CodeFunction), name);
|
||||
@@ -3367,7 +3426,8 @@ DF_VIEW_UI_FUNCTION_DEF(SymbolLister)
|
||||
}
|
||||
}
|
||||
|
||||
dbgi_scope_close(scope);
|
||||
fzy_scope_close(fzy_scope);
|
||||
di_scope_close(di_scope);
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
}
|
||||
@@ -4527,7 +4587,6 @@ DF_VIEW_UI_FUNCTION_DEF(Scheduler)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DBGI_Scope *scope = dbgi_scope_open();
|
||||
String8 query = str8(view->query_buffer, view->query_string_size);
|
||||
DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view);
|
||||
|
||||
@@ -4742,8 +4801,8 @@ DF_VIEW_UI_FUNCTION_DEF(Scheduler)
|
||||
U64 rip_vaddr = df_query_cached_rip_from_thread(entity);
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
|
||||
U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr);
|
||||
DF_Entity *binary = df_binary_file_from_module(module);
|
||||
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_binary_voff(binary, rip_voff);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, rip_voff);
|
||||
if(!df_entity_is_nil(line_info.file))
|
||||
{
|
||||
UI_PrefWidth(ui_children_sum(0)) df_entity_src_loc_button(ws, line_info.file, line_info.pt);
|
||||
@@ -4760,7 +4819,6 @@ DF_VIEW_UI_FUNCTION_DEF(Scheduler)
|
||||
sv->selected_column = cursor.x;
|
||||
sv->selected_entity = (1 <= cursor.y && cursor.y <= items.count) ? df_handle_from_entity(items.v[cursor.y-1].entity) : df_handle_zero();
|
||||
|
||||
dbgi_scope_close(scope);
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
}
|
||||
@@ -4815,8 +4873,8 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
|
||||
scroll_list_params.flags = UI_ScrollListFlag_All;
|
||||
scroll_list_params.row_height_px = floor_f32(ui_top_font_size()*2.5f);
|
||||
scroll_list_params.dim_px = dim_2f32(rect);
|
||||
scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(3, unwind.count));
|
||||
scroll_list_params.item_range = r1s64(0, unwind.count+1);
|
||||
scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(3, unwind.frames.count));
|
||||
scroll_list_params.item_range = r1s64(0, unwind.frames.count+1);
|
||||
scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1;
|
||||
}
|
||||
UI_ScrollListSignal scroll_list_sig = {0};
|
||||
@@ -4849,20 +4907,20 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
|
||||
}
|
||||
|
||||
//- rjf: frame rows
|
||||
U64 frame_idx = 0;
|
||||
for(CTRL_UnwindFrame *frame = unwind.first; frame != 0; frame = frame->next, frame_idx += 1)
|
||||
for(S64 row_num = visible_row_range.min; row_num <= visible_row_range.max && row_num <= unwind.frames.count; row_num += 1)
|
||||
{
|
||||
// rjf: out of range -> skip (TODO(rjf): this should be an array...)
|
||||
if(frame_idx+1 < visible_row_range.min || visible_row_range.max < frame_idx+1)
|
||||
if(row_num == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
U64 frame_idx = row_num-1;
|
||||
CTRL_UnwindFrame *frame = &unwind.frames.v[frame_idx];
|
||||
|
||||
// rjf: determine selection
|
||||
B32 row_selected = cs->cursor.y == ((S64)frame_idx+1);
|
||||
B32 row_selected = (cs->cursor.y == row_num);
|
||||
|
||||
// rjf: regs => rip
|
||||
U64 rip_vaddr = frame->rip;
|
||||
U64 rip_vaddr = regs_rip_from_arch_block(thread->arch, frame->regs);
|
||||
|
||||
// rjf: rip_vaddr => module
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
|
||||
@@ -5036,7 +5094,7 @@ DF_VIEW_CMD_FUNCTION_DEF(Modules)
|
||||
{
|
||||
String8 exe_path = module->name;
|
||||
String8 dbg_path = pick_string;
|
||||
dbgi_force_exe_path_dbg_path(exe_path, dbg_path);
|
||||
// TODO(rjf)
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
@@ -5048,7 +5106,7 @@ DF_VIEW_UI_FUNCTION_DEF(Modules)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DBGI_Scope *scope = dbgi_scope_open();
|
||||
DI_Scope *scope = di_scope_open();
|
||||
String8 query = str8(view->query_buffer, view->query_string_size);
|
||||
|
||||
//- rjf: get state
|
||||
@@ -5215,16 +5273,17 @@ DF_VIEW_UI_FUNCTION_DEF(Modules)
|
||||
B32 brw_is_selected = (row_is_selected && cursor.x == 3);
|
||||
|
||||
// rjf: unpack module info
|
||||
DF_Entity *binary = df_binary_file_from_module(entity);
|
||||
DBGI_Parse *dbgi = df_dbgi_parse_from_binary_file(scope, binary);
|
||||
B32 dbgi_is_valid = (dbgi->dbg_props.modified != 0);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(entity);
|
||||
String8 dbgi_path = dbgi_key.path;
|
||||
RDI_Parsed *rdi = di_rdi_from_key(scope, &dbgi_key, 0);
|
||||
B32 dbgi_is_valid = (rdi != &di_rdi_parsed_nil);
|
||||
|
||||
// rjf: begin editing
|
||||
if(txt_is_selected && edit_begin)
|
||||
{
|
||||
mv->txt_editing = 1;
|
||||
mv->txt_size = Min(sizeof(mv->txt_buffer), dbgi->dbg_path.size);
|
||||
MemoryCopy(mv->txt_buffer, dbgi->dbg_path.str, mv->txt_size);
|
||||
mv->txt_size = Min(sizeof(mv->txt_buffer), dbgi_path.size);
|
||||
MemoryCopy(mv->txt_buffer, dbgi_path.str, mv->txt_size);
|
||||
mv->txt_cursor = txt_pt(1, 1+mv->txt_size);
|
||||
mv->txt_mark = txt_pt(1, 1);
|
||||
}
|
||||
@@ -5236,7 +5295,7 @@ DF_VIEW_UI_FUNCTION_DEF(Modules)
|
||||
UI_WidthFill
|
||||
{
|
||||
UI_TextColor(!dbgi_is_valid ? df_rgba_from_theme_color(DF_ThemeColor_FailureBackground) : ui_top_text_color())
|
||||
sig = df_line_editf(DF_LineEditFlag_NoBackground, 0, 0, &mv->txt_cursor, &mv->txt_mark, mv->txt_buffer, sizeof(mv->txt_buffer), &mv->txt_size, 0, dbgi->dbg_path, "###dbg_path_%p", entity);
|
||||
sig = df_line_editf(DF_LineEditFlag_NoBackground, 0, 0, &mv->txt_cursor, &mv->txt_mark, mv->txt_buffer, sizeof(mv->txt_buffer), &mv->txt_size, 0, dbgi_path, "###dbg_path_%p", entity);
|
||||
edit_commit = (edit_commit || ui_committed(sig));
|
||||
}
|
||||
|
||||
@@ -5254,8 +5313,8 @@ DF_VIEW_UI_FUNCTION_DEF(Modules)
|
||||
{
|
||||
ui_kill_action();
|
||||
mv->txt_editing = 1;
|
||||
mv->txt_size = Min(sizeof(mv->txt_buffer), dbgi->dbg_path.size);
|
||||
MemoryCopy(mv->txt_buffer, dbgi->dbg_path.str, mv->txt_size);
|
||||
mv->txt_size = Min(sizeof(mv->txt_buffer), dbgi_path.size);
|
||||
MemoryCopy(mv->txt_buffer, dbgi_path.str, mv->txt_size);
|
||||
mv->txt_cursor = txt_pt(1, 1+mv->txt_size);
|
||||
mv->txt_mark = txt_pt(1, 1);
|
||||
}
|
||||
@@ -5294,7 +5353,7 @@ DF_VIEW_UI_FUNCTION_DEF(Modules)
|
||||
{
|
||||
String8 exe_path = commit_module->name;
|
||||
String8 dbg_path = str8(mv->txt_buffer, mv->txt_size);
|
||||
dbgi_force_exe_path_dbg_path(exe_path, dbg_path);
|
||||
// TODO(rjf)
|
||||
}
|
||||
if(edit_submit)
|
||||
{
|
||||
@@ -5312,7 +5371,7 @@ DF_VIEW_UI_FUNCTION_DEF(Modules)
|
||||
mv->selected_column = cursor.x;
|
||||
mv->selected_entity = (1 <= cursor.y && cursor.y <= items.count) ? df_handle_from_entity(items.v[cursor.y-1].entity) : df_handle_zero();
|
||||
|
||||
dbgi_scope_close(scope);
|
||||
di_scope_close(scope);
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
}
|
||||
@@ -5356,24 +5415,6 @@ DF_VIEW_CMD_FUNCTION_DEF(PendingEntity)
|
||||
{
|
||||
default:break;
|
||||
|
||||
// rjf: pick file
|
||||
case DF_CoreCmdKind_PickFile:
|
||||
{
|
||||
DF_Entity *missing_file = df_entity_from_handle(pves->pick_file_override_target);
|
||||
String8 pick_string = cmd->params.file_path;
|
||||
if(!df_entity_is_nil(missing_file) && pick_string.size != 0)
|
||||
{
|
||||
DF_Entity *replacement = df_entity_from_path(pick_string, DF_EntityFromPathFlag_OpenAsNeeded|DF_EntityFromPathFlag_OpenMissing);
|
||||
view->entity = df_handle_from_entity(replacement);
|
||||
DF_CmdParams p = df_cmd_params_from_view(ws, panel, view);
|
||||
p.entity = df_handle_from_entity(missing_file);
|
||||
p.file_path = pick_string;
|
||||
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_Entity);
|
||||
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_FilePath);
|
||||
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SetFileReplacementPath));
|
||||
}
|
||||
}break;
|
||||
|
||||
// rjf: gather deferred commands to redispatch when entity is ready
|
||||
case DF_CoreCmdKind_GoToLine:
|
||||
case DF_CoreCmdKind_GoToAddress:
|
||||
@@ -5442,52 +5483,8 @@ DF_VIEW_CMD_FUNCTION_DEF(PendingEntity)
|
||||
|
||||
DF_VIEW_UI_FUNCTION_DEF(PendingEntity)
|
||||
{
|
||||
// rjf: grab state
|
||||
DF_PendingEntityViewState *pves = df_view_user_state(view, DF_PendingEntityViewState);
|
||||
DF_Entity *entity = df_entity_from_handle(view->entity);
|
||||
|
||||
// rjf: entity is missing -> notify user
|
||||
if(entity->flags & DF_EntityFlag_IsMissing)
|
||||
{
|
||||
UI_WidthFill UI_HeightFill UI_Column UI_Padding(ui_pct(1, 0))
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String8 full_path = df_full_path_from_entity(scratch.arena, entity);
|
||||
UI_PrefWidth(ui_children_sum(1)) UI_PrefHeight(ui_em(3, 1))
|
||||
UI_Row UI_Padding(ui_pct(1, 0))
|
||||
UI_PrefWidth(ui_text_dim(10, 1))
|
||||
UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_FailureBackground))
|
||||
{
|
||||
UI_Font(ui_icon_font()) ui_label(df_g_icon_kind_text_table[DF_IconKind_WarningBig]);
|
||||
ui_labelf("Could not find \"%S\".", full_path);
|
||||
}
|
||||
UI_PrefHeight(ui_em(3, 1))
|
||||
UI_Row UI_Padding(ui_pct(1, 0))
|
||||
UI_PrefWidth(ui_text_dim(10, 1))
|
||||
UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_ActionText))
|
||||
UI_BackgroundColor(df_rgba_from_theme_color(DF_ThemeColor_ActionBackground))
|
||||
UI_BorderColor(df_rgba_from_theme_color(DF_ThemeColor_ActionBorder))
|
||||
UI_CornerRadius(ui_top_font_size()/3)
|
||||
UI_PrefWidth(ui_text_dim(10, 1))
|
||||
UI_Focus(UI_FocusKind_On)
|
||||
if(ui_clicked(ui_buttonf("Find alternative...")))
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_view(ws, panel, view);
|
||||
params.cmd_spec = df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_PickFile);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_CmdSpec);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_RunCommand));
|
||||
pves->pick_file_override_target = df_handle_from_entity(entity);
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: entity is still loading -> loading animation
|
||||
else
|
||||
{
|
||||
view->loading_t = view->loading_t_target = 1.f;
|
||||
df_gfx_request_frame();
|
||||
}
|
||||
view->loading_t = view->loading_t_target = 1.f;
|
||||
df_gfx_request_frame();
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
@@ -5608,8 +5605,8 @@ DF_VIEW_CMD_FUNCTION_DEF(Code)
|
||||
if(src2dasm_list->first != 0)
|
||||
{
|
||||
Rng1U64 voff_rng = src2dasm_list->first->v.voff_range;
|
||||
DF_Entity *binary = src2dasm_list->first->v.binary;
|
||||
DF_EntityList possible_modules = df_modules_from_binary_file(scratch.arena, binary);
|
||||
DI_Key dbgi_key = src2dasm_list->first->v.dbgi_key;
|
||||
DF_EntityList possible_modules = df_modules_from_dbgi_key(scratch.arena, &dbgi_key);
|
||||
DF_Entity *thread_dst_module = df_module_from_thread_candidates(thread, &possible_modules);
|
||||
U64 thread_dst_voff = voff_rng.min;
|
||||
if(!df_entity_is_nil(thread_dst_module) && thread_dst_voff != 0)
|
||||
@@ -5734,7 +5731,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
DBGI_Scope *dbgi_scope = dbgi_scope_open();
|
||||
DI_Scope *di_scope = di_scope_open();
|
||||
TXT_Scope *txt_scope = txt_scope_open();
|
||||
DF_CodeViewState *tv = df_view_user_state(view, DF_CodeViewState);
|
||||
|
||||
@@ -5761,7 +5758,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
U64 unwind_count = ctrl_ctx.unwind_count;
|
||||
U64 rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, unwind_count);
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
|
||||
EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(dbgi_scope, process, rip_vaddr);
|
||||
EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(di_scope, process, rip_vaddr);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: unpack file/text entity info
|
||||
@@ -5911,8 +5908,8 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
U64 last_inst_on_unwound_rip_vaddr = rip_vaddr - !!unwind_count;
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, last_inst_on_unwound_rip_vaddr);
|
||||
U64 rip_voff = df_voff_from_vaddr(module, last_inst_on_unwound_rip_vaddr);
|
||||
DF_Entity *binary = df_binary_file_from_module(module);
|
||||
DF_TextLineDasm2SrcInfo dasm2src_info = df_text_line_dasm2src_info_from_binary_voff(binary, rip_voff);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
DF_TextLineDasm2SrcInfo dasm2src_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, rip_voff);
|
||||
if(dasm2src_info.file == entity && visible_line_num_range.min <= dasm2src_info.pt.line && dasm2src_info.pt.line <= visible_line_num_range.max)
|
||||
{
|
||||
U64 slice_line_idx = dasm2src_info.pt.line-visible_line_num_range.min;
|
||||
@@ -5943,14 +5940,14 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
{
|
||||
MemoryCopy(code_slice_params.line_src2dasm, src2dasm.v, sizeof(DF_TextLineSrc2DasmInfoList)*src2dasm.count);
|
||||
}
|
||||
code_slice_params.relevant_binaries = src2dasm.binaries;
|
||||
code_slice_params.relevant_dbgi_keys = src2dasm.dbgi_keys;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: build missing & override interface
|
||||
//
|
||||
if(entity_is_missing)
|
||||
if(entity_is_missing && !text_info_is_ready)
|
||||
{
|
||||
UI_WidthFill UI_HeightFill UI_Column UI_Padding(ui_pct(1, 0))
|
||||
{
|
||||
@@ -6187,7 +6184,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
String8 expr = txt_string_from_info_data_txt_rng(&text_info, data, expr_rng);
|
||||
if(expr.size != 0)
|
||||
{
|
||||
DF_Eval eval = df_eval_from_string(scratch.arena, dbgi_scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, expr);
|
||||
DF_Eval eval = df_eval_from_string(scratch.arena, di_scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, expr);
|
||||
if(eval.mode != EVAL_EvalMode_NULL)
|
||||
{
|
||||
df_set_hover_eval(ws, sig.mouse_expr_baseline_pos, ctrl_ctx, entity, sig.mouse_pt, 0, expr);
|
||||
@@ -6259,8 +6256,8 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
if(src2dasm_list->first != 0)
|
||||
{
|
||||
Rng1U64 voff_rng = src2dasm_list->first->v.voff_range;
|
||||
DF_Entity *binary = src2dasm_list->first->v.binary;
|
||||
DF_EntityList possible_modules = df_modules_from_binary_file(scratch.arena, binary);
|
||||
DI_Key dbgi_key = src2dasm_list->first->v.dbgi_key;
|
||||
DF_EntityList possible_modules = df_modules_from_dbgi_key(scratch.arena, &dbgi_key);
|
||||
DF_Entity *thread_dst_module = df_module_from_thread_candidates(dropped_entity, &possible_modules);
|
||||
U64 thread_dst_voff = voff_rng.min;
|
||||
if(!df_entity_is_nil(thread_dst_module) && thread_dst_voff != 0)
|
||||
@@ -6316,8 +6313,8 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
if(src2dasm_list->first != 0)
|
||||
{
|
||||
Rng1U64 voff_rng = src2dasm_list->first->v.voff_range;
|
||||
DF_Entity *binary = src2dasm_list->first->v.binary;
|
||||
DF_EntityList possible_modules = df_modules_from_binary_file(scratch.arena, binary);
|
||||
DI_Key dbgi_key = src2dasm_list->first->v.dbgi_key;
|
||||
DF_EntityList possible_modules = df_modules_from_dbgi_key(scratch.arena, &dbgi_key);
|
||||
DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread);
|
||||
DF_Entity *thread_dst_module = df_module_from_thread_candidates(thread, &possible_modules);
|
||||
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
|
||||
@@ -6475,20 +6472,19 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
//- rjf: determine up-to-dateness of source file
|
||||
//
|
||||
B32 file_is_out_of_date = 0;
|
||||
String8 out_of_date_binary_name = {0};
|
||||
for(DF_EntityNode *n = code_slice_params.relevant_binaries.first; n != 0; n = n->next)
|
||||
String8 out_of_date_dbgi_name = {0};
|
||||
for(DI_KeyNode *n = code_slice_params.relevant_dbgi_keys.first; n != 0; n = n->next)
|
||||
{
|
||||
DF_Entity *binary = n->entity;
|
||||
if(!df_entity_is_nil(binary))
|
||||
DI_Key key = n->v;
|
||||
if(key.path.size != 0)
|
||||
{
|
||||
String8 full_path = df_full_path_from_entity(scratch.arena, entity);
|
||||
TXTI_Handle handle = txti_handle_from_path(full_path);
|
||||
TXTI_BufferInfo info = txti_buffer_info_from_handle(scratch.arena, handle);
|
||||
DBGI_Parse *parse = df_dbgi_parse_from_binary_file(dbgi_scope, binary);
|
||||
if(parse->exe_props.modified < info.timestamp)
|
||||
if(key.min_timestamp < info.timestamp)
|
||||
{
|
||||
file_is_out_of_date = 1;
|
||||
out_of_date_binary_name = binary->name;
|
||||
out_of_date_dbgi_name = str8_skip_last_slash(key.path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -6526,9 +6522,9 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
{
|
||||
UI_PrefWidth(ui_children_sum(1)) UI_Row UI_PrefWidth(ui_text_dim(1, 1))
|
||||
{
|
||||
ui_labelf("This file has changed since ", out_of_date_binary_name);
|
||||
UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_Highlight0)) ui_label(out_of_date_binary_name);
|
||||
ui_labelf(" was built.");
|
||||
ui_labelf("This file has changed since ", out_of_date_dbgi_name);
|
||||
UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_Highlight0)) ui_label(out_of_date_dbgi_name);
|
||||
ui_labelf(" was produced.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6536,7 +6532,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
{
|
||||
ui_label(full_path);
|
||||
ui_spacer(ui_em(1.5f, 1));
|
||||
ui_labelf("Row: %I64d, Col: %I64d", tv->cursor.line, tv->cursor.column);
|
||||
ui_labelf("Line: %I64d, Col: %I64d", tv->cursor.line, tv->cursor.column);
|
||||
ui_spacer(ui_pct(1, 0));
|
||||
ui_labelf("(read only)");
|
||||
ui_labelf("%s",
|
||||
@@ -6548,7 +6544,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
|
||||
}
|
||||
|
||||
txt_scope_close(txt_scope);
|
||||
dbgi_scope_close(dbgi_scope);
|
||||
di_scope_close(di_scope);
|
||||
hs_scope_close(hs_scope);
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
@@ -6590,8 +6586,8 @@ DF_VIEW_CMD_FUNCTION_DEF(Disassembly)
|
||||
DF_Entity *process = df_entity_from_handle(dv->process);
|
||||
Architecture arch = df_architecture_from_entity(process);
|
||||
U64 dasm_base_vaddr = AlignDownPow2(dv->base_vaddr, KB(64));
|
||||
DF_Entity *dasm_module = df_module_from_process_vaddr(process, dasm_base_vaddr);
|
||||
DF_Entity *dasm_binary = df_binary_file_from_module(dasm_module);
|
||||
DF_Entity *dasm_module = df_module_from_process_vaddr(process, dasm_base_vaddr);
|
||||
DI_Key dasm_dbgi_key = df_dbgi_key_from_module(dasm_module);
|
||||
Rng1U64 dasm_vaddr_range = r1u64(dasm_base_vaddr, dasm_base_vaddr+KB(64));
|
||||
U128 dasm_key = ctrl_hash_store_key_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, dasm_vaddr_range, 0);
|
||||
U128 dasm_data_hash = {0};
|
||||
@@ -6602,7 +6598,7 @@ DF_VIEW_CMD_FUNCTION_DEF(Disassembly)
|
||||
dasm_params.style_flags = dv->style_flags;
|
||||
dasm_params.syntax = DASM_Syntax_Intel;
|
||||
dasm_params.base_vaddr = dasm_module->vaddr_rng.min;
|
||||
dasm_params.exe_path = df_full_path_from_entity(scratch.arena, dasm_binary);
|
||||
dasm_params.dbgi_key = dasm_dbgi_key;
|
||||
}
|
||||
DASM_Info dasm_info = dasm_info_from_key_params(dasm_scope, dasm_key, &dasm_params, &dasm_data_hash);
|
||||
U128 dasm_text_hash = {0};
|
||||
@@ -6801,7 +6797,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
DASM_Scope *dasm_scope = dasm_scope_open();
|
||||
TXT_Scope *txt_scope = txt_scope_open();
|
||||
DBGI_Scope *dbgi_scope = dbgi_scope_open();
|
||||
DI_Scope *di_scope = di_scope_open();
|
||||
DF_DisasmViewState *dv = df_view_user_state(view, DF_DisasmViewState);
|
||||
|
||||
//////////////////////////////
|
||||
@@ -6826,7 +6822,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
DF_Entity *selected_process = df_entity_ancestor_from_kind(selected_thread, DF_EntityKind_Process);
|
||||
U64 unwind_count = ctrl_ctx.unwind_count;
|
||||
U64 rip_vaddr = df_query_cached_rip_from_thread_unwind(selected_thread, unwind_count);
|
||||
EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(dbgi_scope, selected_process, rip_vaddr);
|
||||
EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(di_scope, selected_process, rip_vaddr);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: no disasm process open? -> snap to selected thread
|
||||
@@ -6843,10 +6839,10 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
//
|
||||
DF_Entity *process = df_entity_from_handle(dv->process);
|
||||
Architecture arch = df_architecture_from_entity(process);
|
||||
U64 dasm_base_vaddr = AlignDownPow2(dv->base_vaddr, KB(64));
|
||||
U64 dasm_base_vaddr = AlignDownPow2(dv->base_vaddr, KB(16));
|
||||
DF_Entity *dasm_module = df_module_from_process_vaddr(process, dasm_base_vaddr);
|
||||
DF_Entity *dasm_binary = df_binary_file_from_module(dasm_module);
|
||||
Rng1U64 dasm_vaddr_range = r1u64(dasm_base_vaddr, dasm_base_vaddr+KB(64));
|
||||
DI_Key dasm_dbgi_key = df_dbgi_key_from_module(dasm_module);
|
||||
Rng1U64 dasm_vaddr_range = r1u64(dasm_base_vaddr, dasm_base_vaddr+KB(16));
|
||||
U128 dasm_key = ctrl_hash_store_key_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, dasm_vaddr_range, 0);
|
||||
U128 dasm_data_hash = {0};
|
||||
DASM_Params dasm_params = {0};
|
||||
@@ -6856,7 +6852,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
dasm_params.style_flags = dv->style_flags;
|
||||
dasm_params.syntax = DASM_Syntax_Intel;
|
||||
dasm_params.base_vaddr = dasm_module->vaddr_rng.min;
|
||||
dasm_params.exe_path = df_full_path_from_entity(scratch.arena, dasm_binary);
|
||||
dasm_params.dbgi_key = dasm_dbgi_key;
|
||||
}
|
||||
DASM_Info dasm_info = dasm_info_from_key_params(dasm_scope, dasm_key, &dasm_params, &dasm_data_hash);
|
||||
U128 dasm_text_hash = {0};
|
||||
@@ -6869,7 +6865,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
//- rjf: unpack module info for this region
|
||||
//
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, dasm_vaddr_range.min);
|
||||
DF_Entity *binary = df_binary_file_from_module(module);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: is loading -> equip view with loading information
|
||||
@@ -6958,7 +6954,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
{
|
||||
code_slice_params.margin_float_off_px = 0;
|
||||
}
|
||||
df_entity_list_push(scratch.arena, &code_slice_params.relevant_binaries, binary);
|
||||
di_key_list_push(scratch.arena, &code_slice_params.relevant_dbgi_keys, &dbgi_key);
|
||||
|
||||
// rjf: fill text info
|
||||
{
|
||||
@@ -7040,7 +7036,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
// rjf: fill dasm -> src info
|
||||
{
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, dasm_vaddr_range.min);
|
||||
DF_Entity *binary = df_binary_file_from_module(module);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
for(S64 line_num = visible_line_num_range.min; line_num < visible_line_num_range.max; line_num += 1)
|
||||
{
|
||||
U64 vaddr = dasm_vaddr_range.min + dasm_inst_array_code_off_from_idx(&dasm_info.insts, line_num-1);
|
||||
@@ -7049,7 +7045,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
DF_TextLineDasm2SrcInfoNode *dasm2src_n = push_array(scratch.arena, DF_TextLineDasm2SrcInfoNode, 1);
|
||||
SLLQueuePush(code_slice_params.line_dasm2src[slice_idx].first, code_slice_params.line_dasm2src[slice_idx].last, dasm2src_n);
|
||||
code_slice_params.line_dasm2src[slice_idx].count += 1;
|
||||
dasm2src_n->v = df_text_line_dasm2src_info_from_binary_voff(binary, voff);
|
||||
dasm2src_n->v = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, voff);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7119,7 +7115,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
String8 expr = str8_substr(code_slice_params.line_text[line_idx], r1u64(sig.mouse_expr_rng.min.column-1, sig.mouse_expr_rng.max.column-1));
|
||||
if(expr.size != 0)
|
||||
{
|
||||
DF_Eval eval = df_eval_from_string(scratch.arena, dbgi_scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, expr);
|
||||
DF_Eval eval = df_eval_from_string(scratch.arena, di_scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, expr);
|
||||
if(eval.mode != EVAL_EvalMode_NULL)
|
||||
{
|
||||
U64 off = dasm_inst_array_code_off_from_idx(&dasm_info.insts, sig.mouse_expr_rng.min.line-1);
|
||||
@@ -7219,9 +7215,9 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
{
|
||||
U64 vaddr = dasm_vaddr_range.min+dasm_inst_array_code_off_from_idx(&dasm_info.insts, sig.goto_src_line_num-1);
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, vaddr);
|
||||
DF_Entity *binary = df_binary_file_from_module(module);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
U64 voff = df_voff_from_vaddr(module, vaddr);
|
||||
DF_TextLineDasm2SrcInfo dasm2src = df_text_line_dasm2src_info_from_binary_voff(binary, voff);
|
||||
DF_TextLineDasm2SrcInfo dasm2src = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, voff);
|
||||
String8 file_path = df_full_path_from_entity(scratch.arena, dasm2src.file);
|
||||
DF_CmdParams params = df_cmd_params_from_view(ws, panel, view);
|
||||
params.text_point = dasm2src.pt;
|
||||
@@ -7388,14 +7384,14 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
U64 cursor_vaddr = (1 <= dv->cursor.line && dv->cursor.line <= dasm_info.insts.count) ? (dasm_vaddr_range.min+dasm_info.insts.v[dv->cursor.line-1].code_off) : 0;
|
||||
ui_labelf("%S", path_normalized_from_string(scratch.arena, module->name));
|
||||
ui_spacer(ui_em(1.5f, 1));
|
||||
ui_labelf("Address: 0x%I64x, Row: %I64d, Col: %I64d", cursor_vaddr, dv->cursor.line, dv->cursor.column);
|
||||
ui_labelf("Address: 0x%I64x, Line: %I64d, Col: %I64d", cursor_vaddr, dv->cursor.line, dv->cursor.column);
|
||||
ui_spacer(ui_pct(1, 0));
|
||||
ui_labelf("(read only)");
|
||||
ui_labelf("bin");
|
||||
}
|
||||
}
|
||||
|
||||
dbgi_scope_close(dbgi_scope);
|
||||
di_scope_close(di_scope);
|
||||
txt_scope_close(txt_scope);
|
||||
dasm_scope_close(dasm_scope);
|
||||
hs_scope_close(hs_scope);
|
||||
@@ -7667,7 +7663,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DBGI_Scope *scope = dbgi_scope_open();
|
||||
DI_Scope *scope = di_scope_open();
|
||||
DF_CodeViewState *tv = df_view_user_state(view, DF_CodeViewState);
|
||||
|
||||
//////////////////////////////
|
||||
@@ -8182,13 +8178,13 @@ DF_VIEW_UI_FUNCTION_DEF(Output)
|
||||
UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_WeakText))
|
||||
UI_Font(code_font)
|
||||
{
|
||||
ui_labelf("Row: %I64d, Col: %I64d", tv->cursor.line, tv->cursor.column);
|
||||
ui_labelf("Line: %I64d, Col: %I64d", tv->cursor.line, tv->cursor.column);
|
||||
ui_spacer(ui_pct(1, 0));
|
||||
ui_labelf("(read only)");
|
||||
}
|
||||
}
|
||||
|
||||
dbgi_scope_close(scope);
|
||||
di_scope_close(scope);
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
}
|
||||
@@ -8547,21 +8543,23 @@ DF_VIEW_UI_FUNCTION_DEF(Memory)
|
||||
CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread);
|
||||
|
||||
//- rjf: fill unwind frame annotations
|
||||
if(unwind.first != 0)
|
||||
if(unwind.frames.count != 0)
|
||||
{
|
||||
U64 last_stack_top = regs_rsp_from_arch_block(thread->arch, unwind.first->regs);
|
||||
for(CTRL_UnwindFrame *f = unwind.first->next; f != 0; f = f->next)
|
||||
U64 last_stack_top = regs_rsp_from_arch_block(thread->arch, unwind.frames.v[0].regs);
|
||||
for(U64 idx = 1; idx < unwind.frames.count; idx += 1)
|
||||
{
|
||||
CTRL_UnwindFrame *f = &unwind.frames.v[idx];
|
||||
U64 f_stack_top = regs_rsp_from_arch_block(thread->arch, f->regs);
|
||||
Rng1U64 frame_vaddr_range = r1u64(last_stack_top, f_stack_top);
|
||||
Rng1U64 frame_vaddr_range_in_viz = intersect_1u64(frame_vaddr_range, viz_range_bytes);
|
||||
last_stack_top = f_stack_top;
|
||||
if(dim_1u64(frame_vaddr_range_in_viz) != 0)
|
||||
{
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, f->rip);
|
||||
DF_Entity *binary = df_binary_file_from_module(module);
|
||||
U64 rip_voff = df_voff_from_vaddr(module, f->rip);
|
||||
String8 symbol_name = df_symbol_name_from_binary_voff(scratch.arena, binary, rip_voff);
|
||||
U64 f_rip = regs_rip_from_arch_block(thread->arch, f->regs);
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, f_rip);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
U64 rip_voff = df_voff_from_vaddr(module, f_rip);
|
||||
String8 symbol_name = df_symbol_name_from_dbgi_key_voff(scratch.arena, &dbgi_key, rip_voff);
|
||||
Annotation *annotation = push_array(scratch.arena, Annotation, 1);
|
||||
annotation->name_string = symbol_name.size != 0 ? symbol_name : str8_lit("[external code]");
|
||||
annotation->kind_string = str8_lit("Call Stack Frame");
|
||||
@@ -8577,10 +8575,10 @@ DF_VIEW_UI_FUNCTION_DEF(Memory)
|
||||
}
|
||||
|
||||
//- rjf: fill selected thread stack range annotation
|
||||
if(unwind.first != 0)
|
||||
if(unwind.frames.count > 0)
|
||||
{
|
||||
U64 stack_base_vaddr = thread->stack_base;
|
||||
U64 stack_top_vaddr = regs_rsp_from_arch_block(thread->arch, unwind.first->regs);
|
||||
U64 stack_top_vaddr = regs_rsp_from_arch_block(thread->arch, unwind.frames.v[0].regs);
|
||||
Rng1U64 stack_vaddr_range = r1u64(stack_base_vaddr, stack_top_vaddr);
|
||||
Rng1U64 stack_vaddr_range_in_viz = intersect_1u64(stack_vaddr_range, viz_range_bytes);
|
||||
if(dim_1u64(stack_vaddr_range_in_viz) != 0)
|
||||
@@ -8611,7 +8609,7 @@ DF_VIEW_UI_FUNCTION_DEF(Memory)
|
||||
df_rgba_from_theme_color(DF_ThemeColor_Thread6),
|
||||
df_rgba_from_theme_color(DF_ThemeColor_Thread7),
|
||||
};
|
||||
DBGI_Scope *scope = dbgi_scope_open();
|
||||
DI_Scope *scope = di_scope_open();
|
||||
U64 thread_rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, ctrl_ctx.unwind_count);
|
||||
EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(scope, process, thread_rip_vaddr);
|
||||
RDI_Parsed *rdi = parse_ctx.rdi;
|
||||
@@ -8642,7 +8640,7 @@ DF_VIEW_UI_FUNCTION_DEF(Memory)
|
||||
}
|
||||
}
|
||||
}
|
||||
dbgi_scope_close(scope);
|
||||
di_scope_close(scope);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,6 @@ struct DF_PendingEntityViewState
|
||||
{
|
||||
Arena *deferred_cmd_arena;
|
||||
DF_CmdList deferred_cmds;
|
||||
DF_Handle pick_file_override_target;
|
||||
Arena *complete_cfg_arena;
|
||||
DF_CfgNode *complete_cfg_root;
|
||||
};
|
||||
@@ -496,7 +495,7 @@ internal String8 df_string_from_eval_viz_row_column_kind(Arena *arena, DF_EvalVi
|
||||
internal DF_WatchViewTextEditState *df_watch_view_text_edit_state_from_pt(DF_WatchViewState *wv, DF_WatchViewPoint pt);
|
||||
|
||||
//- rjf: windowed watch tree visualization
|
||||
internal DF_EvalVizBlockList df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_View *view, DF_WatchViewState *ews);
|
||||
internal DF_EvalVizBlockList df_eval_viz_block_list_from_watch_view_state(Arena *arena, DI_Scope *di_scope, FZY_Scope *fzy_scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_View *view, DF_WatchViewState *ews);
|
||||
|
||||
//- rjf: eval/watch views main hooks
|
||||
internal void df_watch_view_init(DF_WatchViewState *ewv, DF_View *view, DF_WatchViewFillKind fill_kind);
|
||||
|
||||
@@ -0,0 +1,562 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Helpers
|
||||
|
||||
internal U64
|
||||
fzy_hash_from_string(U64 seed, String8 string)
|
||||
{
|
||||
U64 result = seed;
|
||||
for(U64 i = 0; i < string.size; i += 1)
|
||||
{
|
||||
result = ((result << 5) + result) + string.str[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal U64
|
||||
fzy_hash_from_params(FZY_Params *params)
|
||||
{
|
||||
U64 hash = 5381;
|
||||
hash = fzy_hash_from_string(hash, str8_struct(¶ms->target));
|
||||
for(U64 idx = 0; idx < params->dbgi_keys.count; idx += 1)
|
||||
{
|
||||
hash = fzy_hash_from_string(hash, str8_struct(¶ms->dbgi_keys.v[idx].min_timestamp));
|
||||
hash = fzy_hash_from_string(hash, params->dbgi_keys.v[idx].path);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
internal U64
|
||||
fzy_item_num_from_array_element_idx__linear_search(FZY_ItemArray *array, U64 element_idx)
|
||||
{
|
||||
U64 fuzzy_item_num = 0;
|
||||
for(U64 idx = 0; idx < array->count; idx += 1)
|
||||
{
|
||||
if(array->v[idx].idx == element_idx)
|
||||
{
|
||||
fuzzy_item_num = idx+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return fuzzy_item_num;
|
||||
}
|
||||
|
||||
internal String8
|
||||
fzy_item_string_from_rdi_target_element_idx(RDI_Parsed *rdi, FZY_Target target, U64 element_idx)
|
||||
{
|
||||
String8 result = {0};
|
||||
switch(target)
|
||||
{
|
||||
// NOTE(rjf): no default - warn if we miss a case
|
||||
case FZY_Target_Procedures:
|
||||
{
|
||||
RDI_Procedure *proc = rdi_element_from_idx(rdi, procedures, element_idx);
|
||||
U64 name_size = 0;
|
||||
U8 *name_base = rdi_string_from_idx(rdi, proc->name_string_idx, &name_size);
|
||||
result = str8(name_base, name_size);
|
||||
}break;
|
||||
case FZY_Target_GlobalVariables:
|
||||
{
|
||||
RDI_GlobalVariable *gvar = rdi_element_from_idx(rdi, global_variables, element_idx);
|
||||
U64 name_size = 0;
|
||||
U8 *name_base = rdi_string_from_idx(rdi, gvar->name_string_idx, &name_size);
|
||||
result = str8(name_base, name_size);
|
||||
}break;
|
||||
case FZY_Target_ThreadVariables:
|
||||
{
|
||||
RDI_ThreadVariable *tvar = rdi_element_from_idx(rdi, thread_variables, element_idx);
|
||||
U64 name_size = 0;
|
||||
U8 *name_base = rdi_string_from_idx(rdi, tvar->name_string_idx, &name_size);
|
||||
result = str8(name_base, name_size);
|
||||
}break;
|
||||
case FZY_Target_UDTs:
|
||||
{
|
||||
RDI_UDT *udt = rdi_element_from_idx(rdi, udts, element_idx);
|
||||
RDI_TypeNode *type_node = rdi_element_from_idx(rdi, type_nodes, udt->self_type_idx);
|
||||
U64 name_size = 0;
|
||||
U8 *name_base = rdi_string_from_idx(rdi, type_node->user_defined.name_string_idx, &name_size);
|
||||
result = str8(name_base, name_size);
|
||||
}break;
|
||||
case FZY_Target_COUNT:{}break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal FZY_Params
|
||||
fzy_params_copy(Arena *arena, FZY_Params *src)
|
||||
{
|
||||
FZY_Params dst = zero_struct;
|
||||
MemoryCopyStruct(&dst, src);
|
||||
dst.dbgi_keys.v = push_array(arena, DI_Key, dst.dbgi_keys.count);
|
||||
MemoryCopy(dst.dbgi_keys.v, src->dbgi_keys.v, sizeof(DI_Key)*src->dbgi_keys.count);
|
||||
for(U64 idx = 0; idx < dst.dbgi_keys.count; idx += 1)
|
||||
{
|
||||
dst.dbgi_keys.v[idx].path = push_str8_copy(arena, dst.dbgi_keys.v[idx].path);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Main Layer Initialization
|
||||
|
||||
internal void
|
||||
fzy_init(void)
|
||||
{
|
||||
Arena *arena = arena_alloc();
|
||||
fzy_shared = push_array(arena, FZY_Shared, 1);
|
||||
fzy_shared->arena = arena;
|
||||
fzy_shared->slots_count = 256;
|
||||
fzy_shared->stripes_count = os_logical_core_count();
|
||||
fzy_shared->slots = push_array(arena, FZY_Slot, fzy_shared->slots_count);
|
||||
fzy_shared->stripes = push_array(arena, FZY_Stripe, fzy_shared->stripes_count);
|
||||
for(U64 idx = 0; idx < fzy_shared->stripes_count; idx += 1)
|
||||
{
|
||||
fzy_shared->stripes[idx].arena = arena_alloc();
|
||||
fzy_shared->stripes[idx].rw_mutex = os_rw_mutex_alloc();
|
||||
fzy_shared->stripes[idx].cv = os_condition_variable_alloc();
|
||||
}
|
||||
fzy_shared->thread_count = Min(os_logical_core_count(), 2);
|
||||
fzy_shared->threads = push_array(arena, FZY_Thread, fzy_shared->thread_count);
|
||||
for(U64 idx = 0; idx < fzy_shared->thread_count; idx += 1)
|
||||
{
|
||||
fzy_shared->threads[idx].u2f_ring_mutex = os_mutex_alloc();
|
||||
fzy_shared->threads[idx].u2f_ring_cv = os_condition_variable_alloc();
|
||||
fzy_shared->threads[idx].u2f_ring_size = KB(64);
|
||||
fzy_shared->threads[idx].u2f_ring_base = push_array_no_zero(arena, U8, fzy_shared->threads[idx].u2f_ring_size);
|
||||
fzy_shared->threads[idx].thread = os_launch_thread(fzy_search_thread__entry_point, (void *)idx, 0);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Scope Functions
|
||||
|
||||
internal FZY_Scope *
|
||||
fzy_scope_open(void)
|
||||
{
|
||||
if(fzy_tctx == 0)
|
||||
{
|
||||
Arena *arena = arena_alloc();
|
||||
fzy_tctx = push_array(arena, FZY_TCTX, 1);
|
||||
fzy_tctx->arena = arena;
|
||||
}
|
||||
FZY_Scope *scope = fzy_tctx->free_scope;
|
||||
if(scope != 0)
|
||||
{
|
||||
SLLStackPop(fzy_tctx->free_scope);
|
||||
}
|
||||
else
|
||||
{
|
||||
scope = push_array_no_zero(fzy_tctx->arena, FZY_Scope, 1);
|
||||
}
|
||||
MemoryZeroStruct(scope);
|
||||
return scope;
|
||||
}
|
||||
|
||||
internal void
|
||||
fzy_scope_close(FZY_Scope *scope)
|
||||
{
|
||||
for(FZY_Touch *t = scope->first_touch, *next = 0; t != 0; t = next)
|
||||
{
|
||||
next = t->next;
|
||||
SLLStackPush(fzy_tctx->free_touch, t);
|
||||
if(t->node != 0)
|
||||
{
|
||||
ins_atomic_u64_dec_eval(&t->node->touch_count);
|
||||
}
|
||||
}
|
||||
SLLStackPush(fzy_tctx->free_scope, scope);
|
||||
}
|
||||
|
||||
internal void
|
||||
fzy_scope_touch_node__stripe_mutex_r_guarded(FZY_Scope *scope, FZY_Node *node)
|
||||
{
|
||||
if(node != 0)
|
||||
{
|
||||
ins_atomic_u64_inc_eval(&node->touch_count);
|
||||
}
|
||||
FZY_Touch *touch = fzy_tctx->free_touch;
|
||||
if(touch != 0)
|
||||
{
|
||||
SLLStackPop(fzy_tctx->free_touch);
|
||||
}
|
||||
else
|
||||
{
|
||||
touch = push_array_no_zero(fzy_tctx->arena, FZY_Touch, 1);
|
||||
}
|
||||
MemoryZeroStruct(touch);
|
||||
SLLQueuePush(scope->first_touch, scope->last_touch, touch);
|
||||
touch->node = node;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Lookup Functions
|
||||
|
||||
internal FZY_ItemArray
|
||||
fzy_items_from_key_params_query(FZY_Scope *scope, U128 key, FZY_Params *params, String8 query, U64 endt_us, B32 *stale_out)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
FZY_ItemArray items = {0};
|
||||
|
||||
//- rjf: hash parameters
|
||||
U64 params_hash = fzy_hash_from_params(params);
|
||||
|
||||
//- rjf: unpack key
|
||||
U64 slot_idx = key.u64[1]%fzy_shared->slots_count;
|
||||
U64 stripe_idx = slot_idx%fzy_shared->stripes_count;
|
||||
FZY_Slot *slot = &fzy_shared->slots[slot_idx];
|
||||
FZY_Stripe *stripe = &fzy_shared->stripes[stripe_idx];
|
||||
|
||||
//- rjf: query and/or request
|
||||
OS_MutexScopeR(stripe->rw_mutex) for(;;)
|
||||
{
|
||||
// rjf: map key -> node
|
||||
FZY_Node *node = 0;
|
||||
for(FZY_Node *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(n->key, key))
|
||||
{
|
||||
node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: no node? -> allocate
|
||||
if(node == 0) OS_MutexScopeRWPromote(stripe->rw_mutex)
|
||||
{
|
||||
node = push_array(stripe->arena, FZY_Node, 1);
|
||||
SLLQueuePush(slot->first, slot->last, node);
|
||||
node->key = key;
|
||||
for(U64 idx = 0; idx < ArrayCount(node->buckets); idx += 1)
|
||||
{
|
||||
node->buckets[idx].arena = arena_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: try to grab last valid results for this key/query; determine if stale
|
||||
B32 stale = 1;
|
||||
if(params_hash == node->buckets[node->gen%ArrayCount(node->buckets)].params_hash &&
|
||||
node->gen != 0)
|
||||
{
|
||||
fzy_scope_touch_node__stripe_mutex_r_guarded(scope, node);
|
||||
items = node->gen_items;
|
||||
stale = !str8_match(query, node->buckets[node->gen%ArrayCount(node->buckets)].query, 0);
|
||||
if(stale_out != 0)
|
||||
{
|
||||
*stale_out = stale;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: if stale -> request again
|
||||
if(stale) OS_MutexScopeRWPromote(stripe->rw_mutex)
|
||||
{
|
||||
if(node->gen <= node->submit_gen && node->submit_gen < node->gen + ArrayCount(node->buckets)-1)
|
||||
{
|
||||
node->submit_gen += 1;
|
||||
arena_clear(node->buckets[node->submit_gen%ArrayCount(node->buckets)].arena);
|
||||
node->buckets[node->submit_gen%ArrayCount(node->buckets)].query = push_str8_copy(node->buckets[node->submit_gen%ArrayCount(node->buckets)].arena, query);
|
||||
node->buckets[node->submit_gen%ArrayCount(node->buckets)].params = fzy_params_copy(node->buckets[node->submit_gen%ArrayCount(node->buckets)].arena, params);
|
||||
node->buckets[node->submit_gen%ArrayCount(node->buckets)].params_hash = params_hash;
|
||||
}
|
||||
if((node->submit_gen > node->gen+1 || os_now_microseconds() >= node->last_time_submitted_us+100000) &&
|
||||
fzy_u2s_enqueue_req(key, endt_us))
|
||||
{
|
||||
node->last_time_submitted_us = os_now_microseconds();
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: not stale, or timeout -> break
|
||||
if(!stale || os_now_microseconds() >= endt_us)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// rjf: no results, but have time to wait -> wait
|
||||
os_condition_variable_wait_rw_r(stripe->cv, stripe->rw_mutex, endt_us);
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
return items;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Searcher Threads
|
||||
|
||||
internal B32
|
||||
fzy_u2s_enqueue_req(U128 key, U64 endt_us)
|
||||
{
|
||||
B32 sent = 0;
|
||||
FZY_Thread *thread = &fzy_shared->threads[key.u64[1]%fzy_shared->thread_count];
|
||||
OS_MutexScope(thread->u2f_ring_mutex) for(;;)
|
||||
{
|
||||
U64 unconsumed_size = thread->u2f_ring_write_pos - thread->u2f_ring_read_pos;
|
||||
U64 available_size = thread->u2f_ring_size - unconsumed_size;
|
||||
if(available_size >= sizeof(U128))
|
||||
{
|
||||
sent = 1;
|
||||
thread->u2f_ring_write_pos += ring_write_struct(thread->u2f_ring_base, thread->u2f_ring_size, thread->u2f_ring_write_pos, &key);
|
||||
break;
|
||||
}
|
||||
os_condition_variable_wait(thread->u2f_ring_cv, thread->u2f_ring_mutex, endt_us);
|
||||
}
|
||||
if(sent)
|
||||
{
|
||||
os_condition_variable_broadcast(thread->u2f_ring_cv);
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
internal void
|
||||
fzy_u2s_dequeue_req(Arena *arena, FZY_Thread *thread, U128 *key_out)
|
||||
{
|
||||
OS_MutexScope(thread->u2f_ring_mutex) for(;;)
|
||||
{
|
||||
U64 unconsumed_size = thread->u2f_ring_write_pos - thread->u2f_ring_read_pos;
|
||||
if(unconsumed_size >= sizeof(U128))
|
||||
{
|
||||
thread->u2f_ring_read_pos += ring_read_struct(thread->u2f_ring_base, thread->u2f_ring_size, thread->u2f_ring_read_pos, key_out);
|
||||
break;
|
||||
}
|
||||
os_condition_variable_wait(thread->u2f_ring_cv, thread->u2f_ring_mutex, max_U64);
|
||||
}
|
||||
os_condition_variable_broadcast(thread->u2f_ring_cv);
|
||||
}
|
||||
|
||||
internal int
|
||||
fzy_qsort_compare_items(FZY_Item *a, FZY_Item *b)
|
||||
{
|
||||
int result = 0;
|
||||
if(a->match_ranges.count > b->match_ranges.count)
|
||||
{
|
||||
result = -1;
|
||||
}
|
||||
else if(a->match_ranges.count < b->match_ranges.count)
|
||||
{
|
||||
result = +1;
|
||||
}
|
||||
else if(a->missed_size < b->missed_size)
|
||||
{
|
||||
result = -1;
|
||||
}
|
||||
else if(a->missed_size > b->missed_size)
|
||||
{
|
||||
result = +1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
fzy_search_thread__entry_point(void *p)
|
||||
{
|
||||
ThreadNameF("[fzy] searcher #%I64u", (U64)p);
|
||||
FZY_Thread *thread = &fzy_shared->threads[(U64)p];
|
||||
for(;;)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
DI_Scope *di_scope = di_scope_open();
|
||||
|
||||
////////////////////////////
|
||||
//- rjf: dequeue next request
|
||||
//
|
||||
U128 key = {0};
|
||||
fzy_u2s_dequeue_req(scratch.arena, thread, &key);
|
||||
U64 slot_idx = key.u64[1]%fzy_shared->slots_count;
|
||||
U64 stripe_idx = slot_idx%fzy_shared->stripes_count;
|
||||
FZY_Slot *slot = &fzy_shared->slots[slot_idx];
|
||||
FZY_Stripe *stripe = &fzy_shared->stripes[stripe_idx];
|
||||
|
||||
////////////////////////////
|
||||
//- rjf: grab next exe_path/query for this key
|
||||
//
|
||||
B32 task_is_good = 0;
|
||||
Arena *task_arena = 0;
|
||||
String8 query = {0};
|
||||
FZY_Params params = {FZY_Target_Procedures};
|
||||
U64 initial_submit_gen = 0;
|
||||
OS_MutexScopeW(stripe->rw_mutex)
|
||||
{
|
||||
for(FZY_Node *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(n->key, key))
|
||||
{
|
||||
FZY_Bucket *bucket = &n->buckets[n->submit_gen%ArrayCount(n->buckets)];
|
||||
task_is_good = 1;
|
||||
initial_submit_gen = n->submit_gen;
|
||||
task_arena = bucket->arena;
|
||||
query = bucket->query;
|
||||
params = bucket->params;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
//- rjf: params -> look up all rdis
|
||||
//
|
||||
U64 rdis_count = params.dbgi_keys.count;
|
||||
RDI_Parsed **rdis = push_array(scratch.arena, RDI_Parsed *, rdis_count);
|
||||
if(task_is_good)
|
||||
{
|
||||
for(U64 idx = 0; idx < rdis_count; idx += 1)
|
||||
{
|
||||
rdis[idx] = di_rdi_from_key(di_scope, ¶ms.dbgi_keys.v[idx], max_U64);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
//- rjf: search target -> info about search space
|
||||
//
|
||||
U64 table_ptr_off = 0;
|
||||
U64 table_count_off = 0;
|
||||
U64 element_name_idx_off = 0;
|
||||
U64 element_size = 0;
|
||||
if(task_is_good)
|
||||
{
|
||||
switch(params.target)
|
||||
{
|
||||
// NOTE(rjf): no default!
|
||||
case FZY_Target_COUNT:{}break;
|
||||
case FZY_Target_Procedures:
|
||||
{
|
||||
table_ptr_off = OffsetOf(RDI_Parsed, procedures);
|
||||
table_count_off = OffsetOf(RDI_Parsed, procedures_count);
|
||||
element_name_idx_off = OffsetOf(RDI_Procedure, name_string_idx);
|
||||
element_size = sizeof(RDI_Procedure);
|
||||
}break;
|
||||
case FZY_Target_GlobalVariables:
|
||||
{
|
||||
table_ptr_off = OffsetOf(RDI_Parsed, global_variables);
|
||||
table_count_off = OffsetOf(RDI_Parsed, global_variables_count);
|
||||
element_name_idx_off = OffsetOf(RDI_GlobalVariable, name_string_idx);
|
||||
element_size = sizeof(RDI_GlobalVariable);
|
||||
}break;
|
||||
case FZY_Target_ThreadVariables:
|
||||
{
|
||||
table_ptr_off = OffsetOf(RDI_Parsed, thread_variables);
|
||||
table_count_off = OffsetOf(RDI_Parsed, thread_variables_count);
|
||||
element_name_idx_off = OffsetOf(RDI_ThreadVariable, name_string_idx);
|
||||
element_size = sizeof(RDI_ThreadVariable);
|
||||
}break;
|
||||
case FZY_Target_UDTs:
|
||||
{
|
||||
table_ptr_off = OffsetOf(RDI_Parsed, udts);
|
||||
table_count_off = OffsetOf(RDI_Parsed, udts_count);
|
||||
element_size = sizeof(RDI_UDT);
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
//- rjf: rdis * query * params -> item list
|
||||
//
|
||||
FZY_ItemChunkList items_list = {0};
|
||||
if(task_is_good)
|
||||
{
|
||||
U64 base_idx = 0;
|
||||
for(U64 rdi_idx = 0; rdi_idx < rdis_count; rdi_idx += 1)
|
||||
{
|
||||
RDI_Parsed *rdi = rdis[rdi_idx];
|
||||
void *table_base = (U8*)rdi + table_ptr_off;
|
||||
U64 element_count = *MemberFromOffset(U64 *, rdi, table_count_off);
|
||||
for(U64 idx = 1; task_is_good && idx < element_count; idx += 1)
|
||||
{
|
||||
void *element = (U8 *)(*(void **)table_base) + element_size*idx;
|
||||
U32 *name_idx_ptr = (U32 *)((U8 *)element + element_name_idx_off);
|
||||
if(params.target == FZY_Target_UDTs)
|
||||
{
|
||||
RDI_UDT *udt = (RDI_UDT *)element;
|
||||
RDI_TypeNode *type_node = rdi_element_from_idx(rdi, type_nodes, udt->self_type_idx);
|
||||
name_idx_ptr = &type_node->user_defined.name_string_idx;
|
||||
}
|
||||
U32 name_idx = *name_idx_ptr;
|
||||
U64 name_size = 0;
|
||||
U8 *name_base = rdi_string_from_idx(rdi, name_idx, &name_size);
|
||||
String8 name = str8(name_base, name_size);
|
||||
if(name.size == 0) { continue; }
|
||||
FuzzyMatchRangeList matches = fuzzy_match_find(task_arena, query, name);
|
||||
if(matches.count == matches.needle_part_count)
|
||||
{
|
||||
FZY_ItemChunk *chunk = items_list.last;
|
||||
if(chunk == 0 || chunk->count >= chunk->cap)
|
||||
{
|
||||
chunk = push_array(scratch.arena, FZY_ItemChunk, 1);
|
||||
chunk->cap = 1024;
|
||||
chunk->count = 0;
|
||||
chunk->v = push_array_no_zero(scratch.arena, FZY_Item, chunk->cap);
|
||||
SLLQueuePush(items_list.first, items_list.last, chunk);
|
||||
items_list.chunk_count += 1;
|
||||
}
|
||||
chunk->v[chunk->count].idx = base_idx + idx;
|
||||
chunk->v[chunk->count].match_ranges = matches;
|
||||
chunk->v[chunk->count].missed_size = (name_size > matches.total_dim) ? (name_size-matches.total_dim) : 0;
|
||||
chunk->count += 1;
|
||||
items_list.total_count += 1;
|
||||
}
|
||||
if(idx%100 == 99) OS_MutexScopeR(stripe->rw_mutex)
|
||||
{
|
||||
for(FZY_Node *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(n->key, key) && n->submit_gen > initial_submit_gen)
|
||||
{
|
||||
task_is_good = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
base_idx += element_count;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: item list -> item array
|
||||
FZY_ItemArray items = {0};
|
||||
if(task_is_good)
|
||||
{
|
||||
items.count = items_list.total_count;
|
||||
items.v = push_array_no_zero(task_arena, FZY_Item, items.count);
|
||||
U64 idx = 0;
|
||||
for(FZY_ItemChunk *chunk = items_list.first; chunk != 0; chunk = chunk->next)
|
||||
{
|
||||
MemoryCopy(items.v+idx, chunk->v, sizeof(FZY_Item)*chunk->count);
|
||||
idx += chunk->count;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: sort item array
|
||||
if(items.count != 0 && query.size != 0)
|
||||
{
|
||||
qsort(items.v, items.count, sizeof(FZY_Item), (int (*)(const void *, const void *))fzy_qsort_compare_items);
|
||||
}
|
||||
|
||||
//- rjf: commit to cache - busyloop on scope touches
|
||||
if(task_is_good)
|
||||
{
|
||||
for(B32 done = 0; !done;)
|
||||
{
|
||||
B32 found = 0;
|
||||
OS_MutexScopeW(stripe->rw_mutex) for(FZY_Node *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(n->key, key))
|
||||
{
|
||||
if(n->touch_count == 0)
|
||||
{
|
||||
n->gen = initial_submit_gen;
|
||||
n->gen_items = items;
|
||||
done = 1;
|
||||
}
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
di_scope_close(di_scope);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef FUZZY_SEARCH_H
|
||||
#define FUZZY_SEARCH_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Result Types
|
||||
|
||||
typedef struct FZY_Item FZY_Item;
|
||||
struct FZY_Item
|
||||
{
|
||||
U64 idx; // indexes into whole space of parameter tables. [rdis[0] element count) [rdis[1] element count) ... [rdis[n] element count)
|
||||
U64 missed_size;
|
||||
FuzzyMatchRangeList match_ranges;
|
||||
};
|
||||
|
||||
typedef struct FZY_ItemChunk FZY_ItemChunk;
|
||||
struct FZY_ItemChunk
|
||||
{
|
||||
FZY_ItemChunk *next;
|
||||
FZY_Item *v;
|
||||
U64 count;
|
||||
U64 cap;
|
||||
};
|
||||
|
||||
typedef struct FZY_ItemChunkList FZY_ItemChunkList;
|
||||
struct FZY_ItemChunkList
|
||||
{
|
||||
FZY_ItemChunk *first;
|
||||
FZY_ItemChunk *last;
|
||||
U64 chunk_count;
|
||||
U64 total_count;
|
||||
};
|
||||
|
||||
typedef struct FZY_ItemArray FZY_ItemArray;
|
||||
struct FZY_ItemArray
|
||||
{
|
||||
FZY_Item *v;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Search Parameter Types
|
||||
|
||||
typedef enum FZY_Target
|
||||
{
|
||||
FZY_Target_Procedures,
|
||||
FZY_Target_GlobalVariables,
|
||||
FZY_Target_ThreadVariables,
|
||||
FZY_Target_UDTs,
|
||||
FZY_Target_COUNT
|
||||
}
|
||||
FZY_Target;
|
||||
|
||||
typedef struct FZY_Params FZY_Params;
|
||||
struct FZY_Params
|
||||
{
|
||||
FZY_Target target;
|
||||
DI_KeyArray dbgi_keys;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Types
|
||||
|
||||
typedef struct FZY_Bucket FZY_Bucket;
|
||||
struct FZY_Bucket
|
||||
{
|
||||
Arena *arena;
|
||||
String8 query;
|
||||
FZY_Params params;
|
||||
U64 params_hash;
|
||||
};
|
||||
|
||||
typedef struct FZY_Node FZY_Node;
|
||||
struct FZY_Node
|
||||
{
|
||||
FZY_Node *next;
|
||||
U128 key;
|
||||
U64 touch_count;
|
||||
U64 last_time_submitted_us;
|
||||
FZY_Bucket buckets[3];
|
||||
U64 gen;
|
||||
U64 submit_gen;
|
||||
FZY_ItemArray gen_items;
|
||||
};
|
||||
|
||||
typedef struct FZY_Slot FZY_Slot;
|
||||
struct FZY_Slot
|
||||
{
|
||||
FZY_Node *first;
|
||||
FZY_Node *last;
|
||||
};
|
||||
|
||||
typedef struct FZY_Stripe FZY_Stripe;
|
||||
struct FZY_Stripe
|
||||
{
|
||||
Arena *arena;
|
||||
OS_Handle rw_mutex;
|
||||
OS_Handle cv;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Scoped Access Types
|
||||
|
||||
typedef struct FZY_Touch FZY_Touch;
|
||||
struct FZY_Touch
|
||||
{
|
||||
FZY_Touch *next;
|
||||
FZY_Node *node;
|
||||
};
|
||||
|
||||
typedef struct FZY_Scope FZY_Scope;
|
||||
struct FZY_Scope
|
||||
{
|
||||
FZY_Scope *next;
|
||||
FZY_Touch *first_touch;
|
||||
FZY_Touch *last_touch;
|
||||
};
|
||||
|
||||
typedef struct FZY_TCTX FZY_TCTX;
|
||||
struct FZY_TCTX
|
||||
{
|
||||
Arena *arena;
|
||||
FZY_Scope *free_scope;
|
||||
FZY_Touch *free_touch;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Shared State Types
|
||||
|
||||
typedef struct FZY_Thread FZY_Thread;
|
||||
struct FZY_Thread
|
||||
{
|
||||
OS_Handle thread;
|
||||
OS_Handle u2f_ring_mutex;
|
||||
OS_Handle u2f_ring_cv;
|
||||
U64 u2f_ring_size;
|
||||
U8 *u2f_ring_base;
|
||||
U64 u2f_ring_write_pos;
|
||||
U64 u2f_ring_read_pos;
|
||||
};
|
||||
|
||||
typedef struct FZY_Shared FZY_Shared;
|
||||
struct FZY_Shared
|
||||
{
|
||||
Arena *arena;
|
||||
|
||||
// rjf: search artifact cache table
|
||||
U64 slots_count;
|
||||
U64 stripes_count;
|
||||
FZY_Slot *slots;
|
||||
FZY_Stripe *stripes;
|
||||
|
||||
// rjf: threads
|
||||
U64 thread_count;
|
||||
FZY_Thread *threads;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
global FZY_Shared *fzy_shared = 0;
|
||||
thread_static FZY_TCTX *fzy_tctx = 0;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Helpers
|
||||
|
||||
internal U64 fzy_hash_from_string(U64 seed, String8 string);
|
||||
internal U64 fzy_hash_from_params(FZY_Params *params);
|
||||
internal U64 fzy_item_num_from_array_element_idx__linear_search(FZY_ItemArray *array, U64 element_idx);
|
||||
internal String8 fzy_item_string_from_rdi_target_element_idx(RDI_Parsed *rdi, FZY_Target target, U64 element_idx);
|
||||
internal FZY_Params fzy_params_copy(Arena *arena, FZY_Params *src);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Main Layer Initialization
|
||||
|
||||
internal void fzy_init(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Scope Functions
|
||||
|
||||
internal FZY_Scope *fzy_scope_open(void);
|
||||
internal void fzy_scope_close(FZY_Scope *scope);
|
||||
internal void fzy_scope_touch_node__stripe_mutex_r_guarded(FZY_Scope *scope, FZY_Node *node);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Lookup Functions
|
||||
|
||||
internal FZY_ItemArray fzy_items_from_key_params_query(FZY_Scope *scope, U128 key, FZY_Params *params, String8 query, U64 endt_us, B32 *stale_out);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Searcher Threads
|
||||
|
||||
internal B32 fzy_u2s_enqueue_req(U128 key, U64 endt_us);
|
||||
internal void fzy_u2s_dequeue_req(Arena *arena, FZY_Thread *thread, U128 *key_out);
|
||||
|
||||
internal int fzy_qsort_compare_items(FZY_Item *a, FZY_Item *b);
|
||||
|
||||
internal void fzy_search_thread__entry_point(void *p);
|
||||
|
||||
#endif // FUZZY_SEARCH_H
|
||||
@@ -4,11 +4,11 @@
|
||||
////////////////////////////////////////////////////////////////
|
||||
// RAD Debug Info, (R)AD(D)BG(I) Format Library
|
||||
//
|
||||
// Defines standard RADDBGI debug information format types and
|
||||
// Defines standard RDI debug information format types and
|
||||
// functions.
|
||||
|
||||
#ifndef RADDBGI_FORMAT_H
|
||||
#define RADDBGI_FORMAT_H
|
||||
#ifndef RDI_FORMAT_H
|
||||
#define RDI_FORMAT_H
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Overridable procedure decoration
|
||||
@@ -924,4 +924,4 @@ RDI_PROC RDI_EvalConversionKind rdi_eval_conversion_rule(RDI_EvalTypeGroup in, R
|
||||
RDI_PROC RDI_U8* rdi_eval_conversion_message(RDI_EvalConversionKind conversion_kind, RDI_U64 *lennout);
|
||||
RDI_PROC RDI_S32 rdi_eval_opcode_type_compatible(RDI_EvalOp op, RDI_EvalTypeGroup group);
|
||||
|
||||
#endif // RADDBGI_FORMAT_H
|
||||
#endif // RDI_FORMAT_H
|
||||
@@ -5,14 +5,14 @@
|
||||
// RAD Debug Info Make, (R)AD(D)BG(I) (M)ake Library
|
||||
//
|
||||
// Library for building loose data structures which contain
|
||||
// RADDBGI debug information, and baking that down into the
|
||||
// proper flattened RADDBGI format.
|
||||
// RDI debug information, and baking that down into the
|
||||
// proper flattened RDI format.
|
||||
//
|
||||
// Requires prior inclusion of the RAD Debug Info, (R)AD(D)BG(I)
|
||||
// Format Library, in raddbgi_format.h.
|
||||
// Format Library, in rdi_format.h.
|
||||
|
||||
#ifndef RADDBGI_MAKE_H
|
||||
#define RADDBGI_MAKE_H
|
||||
#ifndef RDI_MAKE_H
|
||||
#define RDI_MAKE_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Overrideable Memory Operations
|
||||
@@ -1252,4 +1252,4 @@ RDI_PROC RDIM_BakeSectionList rdim_bake_idx_run_section_list_from_idx_run_map(RD
|
||||
|
||||
RDI_PROC RDIM_String8List rdim_serialized_strings_from_params_bake_section_list(RDIM_Arena *arena, RDIM_BakeParams *params, RDIM_BakeSectionList *sections);
|
||||
|
||||
#endif // RADDBGI_MAKE_H
|
||||
#endif // RDI_MAKE_H
|
||||
@@ -39,4 +39,5 @@ dll_type_eval_tests(void)
|
||||
Basics basics2 = {4, 5, 6, 7};
|
||||
int x = 0;
|
||||
(void)x;
|
||||
*(int *)0 = 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
#include "mule_peb_trample_reload.c"
|
||||
|
||||
static void
|
||||
HideModuleFromWindowsReload(HMODULE ModuleToFlush)
|
||||
{
|
||||
/* NOTE(casey): Normally you cannot "reload" an executable module with the same name,
|
||||
because Windows checks a linked list of loaded modules and assumes that if
|
||||
it's already loaded, it doesn't need to reload it, even though it may have to because
|
||||
it has changed on disk.
|
||||
|
||||
This solution to that problem comes from some excellent spelunking by Martins Mozeiko,
|
||||
who figured out that you could overwrite the filenames Windows stores in your process's
|
||||
loaded module table, thus thwarting the Windows filename check against loaded modules,
|
||||
allowing you to reload an existing module that has changed without requiring it to
|
||||
have a different filename!
|
||||
*/
|
||||
|
||||
PEB *Peb = (PEB *)__readgsqword(offsetof(TEB, ProcessEnvironmentBlock));
|
||||
LIST_ENTRY *Head = &Peb->Ldr->InMemoryOrderModuleList;
|
||||
for(LIST_ENTRY *Entry = Head->Flink;
|
||||
Entry != Head;
|
||||
Entry = Entry->Flink)
|
||||
{
|
||||
LDR_DATA_TABLE_ENTRY *Mod = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
|
||||
if(Mod->DllBase == ModuleToFlush)
|
||||
{
|
||||
ZeroMemory(Mod->FullDllName.Buffer, Mod->FullDllName.Length);
|
||||
Mod->DllBase = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argument_count, char **arguments)
|
||||
{
|
||||
char *exe_name = arguments[0];
|
||||
HANDLE last_module = GetModuleHandle(0);
|
||||
int (*loop_iteration_function)(int it) = (int (*)(int))GetProcAddress(last_module, "loop_iteration");
|
||||
FILETIME last_filetime = {0};
|
||||
int should_exit = 0;
|
||||
for(int it = 0; !should_exit; it += 1)
|
||||
{
|
||||
int result = loop_iteration_function(it);
|
||||
printf("%i\n", result);
|
||||
Sleep(50);
|
||||
FILETIME current_filetime = {0};
|
||||
HANDLE current_exe_file = CreateFile(exe_name, 0, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
GetFileTime(current_exe_file, 0, 0, ¤t_filetime);
|
||||
CloseHandle(current_exe_file);
|
||||
if(it != 0 && CompareFileTime(&last_filetime, ¤t_filetime) < 0)
|
||||
{
|
||||
HideModuleFromWindowsReload(last_module);
|
||||
last_module = LoadLibrary(arguments[0]);
|
||||
loop_iteration_function = (int (*)(int))GetProcAddress(last_module, "loop_iteration");
|
||||
}
|
||||
last_filetime = current_filetime;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
__declspec(dllexport) int
|
||||
loop_iteration(int it)
|
||||
{
|
||||
return 111;
|
||||
#if 0
|
||||
int sum = 0;
|
||||
for(int i = 0; i < 1000; i += 1)
|
||||
{
|
||||
sum += it*i;
|
||||
}
|
||||
return sum;
|
||||
#endif
|
||||
}
|
||||
@@ -1607,7 +1607,7 @@ os_semaphore_close(OS_Handle semaphore)
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_semaphore_take(OS_Handle semaphore)
|
||||
os_semaphore_take(OS_Handle semaphore, U64 endt_us)
|
||||
{
|
||||
NotImplemented;
|
||||
return 0;
|
||||
|
||||
@@ -771,12 +771,6 @@ w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
result = HTCAPTION;
|
||||
}
|
||||
|
||||
// rjf: title bar client area
|
||||
if(is_over_title_bar_client_area)
|
||||
{
|
||||
result = HTCLIENT;
|
||||
}
|
||||
|
||||
// rjf: normal edges
|
||||
if(is_over_left) { result = HTLEFT; }
|
||||
if(is_over_right) { result = HTRIGHT; }
|
||||
@@ -788,6 +782,12 @@ w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
if(is_over_left && is_over_bottom) { result = HTBOTTOMLEFT; }
|
||||
if(is_over_right && is_over_top) { result = HTTOPRIGHT; }
|
||||
if(is_over_right && is_over_bottom) { result = HTBOTTOMRIGHT; }
|
||||
|
||||
// rjf: title bar client area
|
||||
if(is_over_title_bar_client_area)
|
||||
{
|
||||
result = HTCLIENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
||||
+2
-3
@@ -69,11 +69,10 @@ pe_bin_info_from_data(Arena *arena, String8 data)
|
||||
}
|
||||
|
||||
// rjf: read pe magic
|
||||
U32 coff_off = dos_header.coff_file_offset;
|
||||
U32 pe_magic = 0;
|
||||
if(valid)
|
||||
{
|
||||
str8_deserial_read_struct(data, coff_off, &pe_magic);
|
||||
str8_deserial_read_struct(data, dos_header.coff_file_offset, &pe_magic);
|
||||
}
|
||||
|
||||
// rjf: bad pe magic -> abort
|
||||
@@ -83,7 +82,7 @@ pe_bin_info_from_data(Arena *arena, String8 data)
|
||||
}
|
||||
|
||||
// rjf: read coff header
|
||||
U32 coff_header_off = coff_off + sizeof(pe_magic);
|
||||
U32 coff_header_off = dos_header.coff_file_offset + sizeof(pe_magic);
|
||||
COFF_Header coff_header = {0};
|
||||
if(valid)
|
||||
{
|
||||
|
||||
+1
-1
@@ -393,7 +393,7 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data)
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
internal CTRL_WAKEUP_FUNCTION_DEF(wakeup_hook)
|
||||
internal CTRL_WAKEUP_FUNCTION_DEF(wakeup_hook_ctrl)
|
||||
{
|
||||
os_send_wakeup_event();
|
||||
}
|
||||
|
||||
+22
-14
@@ -37,13 +37,8 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Hot, High Priority Tasks (Complete Unusability, Crashes, Fire-Worthy)
|
||||
//
|
||||
// [ ] robustify dbgi layer to renames (cache should not be based only on
|
||||
// path - must invalidate naturally when new filetime occurs)
|
||||
//
|
||||
// [ ] raddbg jai.exe my_file.jai -- foobar -> raddbg consumes `--` incorrectly
|
||||
// [ ] PDB files distributed with the build are not found by DbgHelp!!!
|
||||
// [ ] Jai compiler debugging crash
|
||||
// [ ] raddbgi file regeneration too strict
|
||||
//
|
||||
// [ ] Jump table thunks, on code w/o /INCREMENTAL:NO
|
||||
//
|
||||
@@ -52,15 +47,10 @@
|
||||
// since that's not normally how Windows fonts work.
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Demon/Cleanup Pass Tasks
|
||||
//~ rjf: Hot, Medium Priority Tasks (Low-Hanging-Fruit Features, UI Jank, Cleanup)
|
||||
//
|
||||
// [ ] TLS eval -> in-process-memory EXE info
|
||||
// [ ] unwinding -> in-process-memory EXE info
|
||||
// [ ] "root" concept in hash store, which buckets keys & allows usage code to
|
||||
// jettison a collection of keys in retained mode fashion
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Hot, Medium Priority Tasks (Low-Hanging-Fruit Features, UI Jank, Cleanup)
|
||||
//
|
||||
// [ ] Jeff Notes
|
||||
// [ ] highlighted text & ctrl+f -> auto-fill search query
|
||||
@@ -379,6 +369,13 @@
|
||||
// function was displayed in the window by default next to the thread.
|
||||
// [x] ** It would be nice if thread listings displayed the name of the
|
||||
// thread, instead of just the ID.
|
||||
// [x] TLS eval -> in-process-memory EXE info
|
||||
// [x] unwinding -> in-process-memory EXE info
|
||||
// [x] new fuzzy searching layer
|
||||
// [x] robustify dbgi layer to renames (cache should not be based only on
|
||||
// path - must invalidate naturally when new filetime occurs)
|
||||
// [x] rdi file regeneration too strict
|
||||
// [x] raddbg jai.exe my_file.jai -- foobar -> raddbg consumes `--` incorrectly
|
||||
|
||||
#ifndef RADDBG_H
|
||||
#define RADDBG_H
|
||||
@@ -404,12 +401,23 @@ struct IPCInfo
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
#define IPC_SHARED_MEMORY_BUFFER_SIZE MB(16)
|
||||
//- rjf: IPC resources
|
||||
#define IPC_SHARED_MEMORY_BUFFER_SIZE MB(4)
|
||||
StaticAssert(IPC_SHARED_MEMORY_BUFFER_SIZE > sizeof(IPCInfo), ipc_buffer_size_requirement);
|
||||
read_only global String8 ipc_shared_memory_name = str8_lit_comp("_raddbg_ipc_shared_memory_");
|
||||
read_only global String8 ipc_semaphore_name = str8_lit_comp("_raddbg_ipc_semaphore_");
|
||||
global OS_Handle ipc_signal_semaphore = {0};
|
||||
global OS_Handle ipc_lock_semaphore = {0};
|
||||
global U8 *ipc_shared_memory_base = 0;
|
||||
global U8 ipc_s2m_ring_buffer[MB(4)] = {0};
|
||||
global U64 ipc_s2m_ring_write_pos = 0;
|
||||
global U64 ipc_s2m_ring_read_pos = 0;
|
||||
global OS_Handle ipc_s2m_ring_mutex = {0};
|
||||
global OS_Handle ipc_s2m_ring_cv = {0};
|
||||
|
||||
//- rjf: frame time history
|
||||
global U64 frame_time_us_history[64] = {0};
|
||||
global U64 frame_time_us_history_idx = 0;
|
||||
|
||||
//- rjf: main thread log
|
||||
global Log *main_thread_log = 0;
|
||||
global String8 main_thread_log_path = {0};
|
||||
|
||||
|
||||
+198
-74
@@ -11,14 +11,21 @@
|
||||
#define BUILD_TITLE "The RAD Debugger"
|
||||
#define OS_FEATURE_GRAPHICAL 1
|
||||
|
||||
#define R_INIT_MANUAL 1
|
||||
#define TEX_INIT_MANUAL 1
|
||||
#define GEO_INIT_MANUAL 1
|
||||
#define F_INIT_MANUAL 1
|
||||
#define DF_INIT_MANUAL 1
|
||||
#define DF_GFX_INIT_MANUAL 1
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Includes
|
||||
|
||||
//- rjf: [lib]
|
||||
#include "lib_raddbgi_format/raddbgi_format.h"
|
||||
#include "lib_raddbgi_format/raddbgi_format.c"
|
||||
#include "lib_raddbgi_format/raddbgi_format_parse.h"
|
||||
#include "lib_raddbgi_format/raddbgi_format_parse.c"
|
||||
#include "lib_rdi_format/rdi_format.h"
|
||||
#include "lib_rdi_format/rdi_format.c"
|
||||
#include "lib_rdi_format/rdi_format_parse.h"
|
||||
#include "lib_rdi_format/rdi_format_parse.c"
|
||||
#include "third_party/rad_lzb_simple/rad_lzb_simple.h"
|
||||
#include "third_party/rad_lzb_simple/rad_lzb_simple.c"
|
||||
|
||||
@@ -27,12 +34,11 @@
|
||||
#include "os/os_inc.h"
|
||||
#include "task_system/task_system.h"
|
||||
#include "ico/ico.h"
|
||||
#include "raddbgi_make_local/raddbgi_make_local.h"
|
||||
#include "rdi_make_local/rdi_make_local.h"
|
||||
#include "mdesk/mdesk.h"
|
||||
#include "hash_store/hash_store.h"
|
||||
#include "file_stream/file_stream.h"
|
||||
#include "text_cache/text_cache.h"
|
||||
#include "dasm_cache/dasm_cache.h"
|
||||
#include "path/path.h"
|
||||
#include "txti/txti.h"
|
||||
#include "coff/coff.h"
|
||||
@@ -42,14 +48,15 @@
|
||||
#include "msf/msf.h"
|
||||
#include "pdb/pdb.h"
|
||||
#include "pdb/pdb_stringize.h"
|
||||
#include "raddbgi_from_pdb/raddbgi_from_pdb.h"
|
||||
#include "rdi_from_pdb/rdi_from_pdb.h"
|
||||
#include "regs/regs.h"
|
||||
#include "regs/raddbgi/regs_raddbgi.h"
|
||||
#include "regs/rdi/regs_rdi.h"
|
||||
#include "type_graph/type_graph.h"
|
||||
#include "dbgi/dbgi.h"
|
||||
#include "dasm_cache/dasm_cache.h"
|
||||
#include "fuzzy_search/fuzzy_search.h"
|
||||
#include "demon/demon_inc.h"
|
||||
#include "eval/eval_inc.h"
|
||||
#include "unwind/unwind.h"
|
||||
#include "ctrl/ctrl_inc.h"
|
||||
#include "font_provider/font_provider_inc.h"
|
||||
#include "render/render_inc.h"
|
||||
@@ -66,12 +73,11 @@
|
||||
#include "os/os_inc.c"
|
||||
#include "task_system/task_system.c"
|
||||
#include "ico/ico.c"
|
||||
#include "raddbgi_make_local/raddbgi_make_local.c"
|
||||
#include "rdi_make_local/rdi_make_local.c"
|
||||
#include "mdesk/mdesk.c"
|
||||
#include "hash_store/hash_store.c"
|
||||
#include "file_stream/file_stream.c"
|
||||
#include "text_cache/text_cache.c"
|
||||
#include "dasm_cache/dasm_cache.c"
|
||||
#include "path/path.c"
|
||||
#include "txti/txti.c"
|
||||
#include "coff/coff.c"
|
||||
@@ -81,14 +87,15 @@
|
||||
#include "msf/msf.c"
|
||||
#include "pdb/pdb.c"
|
||||
#include "pdb/pdb_stringize.c"
|
||||
#include "raddbgi_from_pdb/raddbgi_from_pdb.c"
|
||||
#include "rdi_from_pdb/rdi_from_pdb.c"
|
||||
#include "regs/regs.c"
|
||||
#include "regs/raddbgi/regs_raddbgi.c"
|
||||
#include "regs/rdi/regs_rdi.c"
|
||||
#include "type_graph/type_graph.c"
|
||||
#include "dbgi/dbgi.c"
|
||||
#include "dasm_cache/dasm_cache.c"
|
||||
#include "fuzzy_search/fuzzy_search.c"
|
||||
#include "demon/demon_inc.c"
|
||||
#include "eval/eval_inc.c"
|
||||
#include "unwind/unwind.c"
|
||||
#include "ctrl/ctrl_inc.c"
|
||||
#include "font_provider/font_provider_inc.c"
|
||||
#include "render/render_inc.c"
|
||||
@@ -100,6 +107,42 @@
|
||||
#include "df/df_inc.c"
|
||||
#include "raddbg.c"
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: IPC Signaler Thread
|
||||
|
||||
internal void
|
||||
ipc_signaler_thread__entry_point(void *p)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
if(os_semaphore_take(ipc_signal_semaphore, max_U64))
|
||||
{
|
||||
if(os_semaphore_take(ipc_lock_semaphore, max_U64))
|
||||
{
|
||||
IPCInfo *ipc_info = (IPCInfo *)ipc_shared_memory_base;
|
||||
String8 msg = str8((U8 *)(ipc_info+1), ipc_info->msg_size);
|
||||
msg.size = Min(msg.size, IPC_SHARED_MEMORY_BUFFER_SIZE - sizeof(IPCInfo));
|
||||
OS_MutexScope(ipc_s2m_ring_mutex) for(;;)
|
||||
{
|
||||
U64 unconsumed_size = ipc_s2m_ring_write_pos - ipc_s2m_ring_read_pos;
|
||||
U64 available_size = (sizeof(ipc_s2m_ring_buffer) - unconsumed_size);
|
||||
if(available_size >= sizeof(U64)+sizeof(msg.size))
|
||||
{
|
||||
ipc_s2m_ring_write_pos += ring_write_struct(ipc_s2m_ring_buffer, sizeof(ipc_s2m_ring_buffer), ipc_s2m_ring_write_pos, &msg.size);
|
||||
ipc_s2m_ring_write_pos += ring_write(ipc_s2m_ring_buffer, sizeof(ipc_s2m_ring_buffer), ipc_s2m_ring_write_pos, msg.str, msg.size);
|
||||
break;
|
||||
}
|
||||
os_condition_variable_wait(ipc_s2m_ring_cv, ipc_s2m_ring_mutex, max_U64);
|
||||
}
|
||||
os_condition_variable_broadcast(ipc_s2m_ring_cv);
|
||||
os_send_wakeup_event();
|
||||
ipc_info->msg_size = 0;
|
||||
os_semaphore_drop(ipc_lock_semaphore);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entry Point
|
||||
|
||||
@@ -178,7 +221,7 @@ entry_point(CmdLine *cmd_line)
|
||||
}
|
||||
|
||||
//- rjf: set up layers
|
||||
ctrl_set_wakeup_hook(wakeup_hook);
|
||||
ctrl_set_wakeup_hook(wakeup_hook_ctrl);
|
||||
|
||||
//- rjf: dispatch to top-level codepath based on execution mode
|
||||
switch(exec_mode)
|
||||
@@ -187,12 +230,16 @@ entry_point(CmdLine *cmd_line)
|
||||
default:
|
||||
case ExecMode_Normal:
|
||||
{
|
||||
//- rjf: set up shared memory for ipc
|
||||
OS_Handle ipc_shared_memory = os_shared_memory_alloc(IPC_SHARED_MEMORY_BUFFER_SIZE, ipc_shared_memory_name);
|
||||
void *ipc_shared_memory_base = os_shared_memory_view_open(ipc_shared_memory, r1u64(0, IPC_SHARED_MEMORY_BUFFER_SIZE));
|
||||
OS_Handle ipc_semaphore = os_semaphore_alloc(1, 1, ipc_semaphore_name);
|
||||
IPCInfo *ipc_info = (IPCInfo *)ipc_shared_memory_base;
|
||||
ipc_info->msg_size = 0;
|
||||
//- rjf: manual layer initialization
|
||||
{
|
||||
r_init(cmd_line);
|
||||
tex_init();
|
||||
geo_init();
|
||||
f_init();
|
||||
DF_StateDeltaHistory *hist = df_state_delta_history_alloc();
|
||||
df_core_init(cmd_line, hist);
|
||||
df_gfx_init(update_and_render, df_state_delta_history());
|
||||
}
|
||||
|
||||
//- rjf: setup initial target from command line args
|
||||
{
|
||||
@@ -247,56 +294,97 @@ entry_point(CmdLine *cmd_line)
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: set up shared resources for ipc to this instance; launch IPC signaler thread
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
U32 instance_pid = os_get_pid();
|
||||
String8 ipc_shared_memory_name = push_str8f(scratch.arena, "_raddbg_ipc_shared_memory_%i_", instance_pid);
|
||||
String8 ipc_signal_semaphore_name = push_str8f(scratch.arena, "_raddbg_ipc_signal_semaphore_%i_", instance_pid);
|
||||
String8 ipc_lock_semaphore_name = push_str8f(scratch.arena, "_raddbg_ipc_lock_semaphore_%i_", instance_pid);
|
||||
OS_Handle ipc_shared_memory = os_shared_memory_alloc(IPC_SHARED_MEMORY_BUFFER_SIZE, ipc_shared_memory_name);
|
||||
ipc_shared_memory_base = (U8 *)os_shared_memory_view_open(ipc_shared_memory, r1u64(0, IPC_SHARED_MEMORY_BUFFER_SIZE));
|
||||
ipc_signal_semaphore = os_semaphore_alloc(0, 1, ipc_signal_semaphore_name);
|
||||
ipc_lock_semaphore = os_semaphore_alloc(1, 1, ipc_lock_semaphore_name);
|
||||
ipc_s2m_ring_mutex = os_mutex_alloc();
|
||||
ipc_s2m_ring_cv = os_condition_variable_alloc();
|
||||
IPCInfo *ipc_info = (IPCInfo *)ipc_shared_memory_base;
|
||||
MemoryZeroStruct(ipc_info);
|
||||
os_launch_thread(ipc_signaler_thread__entry_point, 0, 0);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
//- rjf: main application loop
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
//- rjf: get IPC messages & dispatch ui commands from them
|
||||
//- rjf: consume IPC messages, dispatch UI commands
|
||||
{
|
||||
if(os_semaphore_take(ipc_semaphore, max_U64))
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
B32 consumed = 0;
|
||||
String8 msg = {0};
|
||||
OS_MutexScope(ipc_s2m_ring_mutex)
|
||||
{
|
||||
if(ipc_info->msg_size != 0)
|
||||
U64 unconsumed_size = ipc_s2m_ring_write_pos - ipc_s2m_ring_read_pos;
|
||||
if(unconsumed_size >= sizeof(U64))
|
||||
{
|
||||
U8 *buffer = (U8 *)(ipc_info+1);
|
||||
U64 msg_size = ipc_info->msg_size;
|
||||
String8 cmd_string = str8(buffer, msg_size);
|
||||
ipc_info->msg_size = 0;
|
||||
DF_Window *dst_window = df_gfx_state->first_window;
|
||||
for(DF_Window *window = dst_window; window != 0; window = window->next)
|
||||
consumed = 1;
|
||||
ipc_s2m_ring_read_pos += ring_read_struct(ipc_s2m_ring_buffer, sizeof(ipc_s2m_ring_buffer), ipc_s2m_ring_read_pos, &msg.size);
|
||||
msg.size = Min(msg.size, unconsumed_size);
|
||||
msg.str = push_array(scratch.arena, U8, msg.size);
|
||||
ipc_s2m_ring_read_pos += ring_read(ipc_s2m_ring_buffer, sizeof(ipc_s2m_ring_buffer), ipc_s2m_ring_read_pos, msg.str, msg.size);
|
||||
}
|
||||
}
|
||||
if(consumed)
|
||||
{
|
||||
os_condition_variable_broadcast(ipc_s2m_ring_cv);
|
||||
}
|
||||
if(msg.size != 0)
|
||||
{
|
||||
log_infof("IPC message received: \"%S\"", msg);
|
||||
DF_Window *dst_window = df_gfx_state->first_window;
|
||||
for(DF_Window *window = dst_window; window != 0; window = window->next)
|
||||
{
|
||||
if(os_window_is_focused(window->os))
|
||||
{
|
||||
if(os_window_is_focused(window->os))
|
||||
{
|
||||
dst_window = window;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(dst_window != 0)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String8 cmd_spec_string = df_cmd_name_part_from_string(cmd_string);
|
||||
DF_CmdSpec *cmd_spec = df_cmd_spec_from_string(cmd_spec_string);
|
||||
if(!df_cmd_spec_is_nil(cmd_spec))
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_gfx();
|
||||
DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_window(dst_window);
|
||||
String8 error = df_cmd_params_apply_spec_query(scratch.arena, &ctrl_ctx, ¶ms, cmd_spec, df_cmd_arg_part_from_string(cmd_string));
|
||||
if(error.size == 0)
|
||||
{
|
||||
df_push_cmd__root(¶ms, cmd_spec);
|
||||
}
|
||||
else
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_window(dst_window);
|
||||
params.string = error;
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Error));
|
||||
}
|
||||
}
|
||||
scratch_end(scratch);
|
||||
dst_window = window;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(dst_window != 0)
|
||||
{
|
||||
dst_window->window_temporarily_focused_ipc = 1;
|
||||
String8 cmd_spec_string = df_cmd_name_part_from_string(msg);
|
||||
DF_CmdSpec *cmd_spec = df_cmd_spec_from_string(cmd_spec_string);
|
||||
if(!df_cmd_spec_is_nil(cmd_spec))
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_window(dst_window);
|
||||
DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_window(dst_window);
|
||||
String8 error = df_cmd_params_apply_spec_query(scratch.arena, &ctrl_ctx, ¶ms, cmd_spec, df_cmd_arg_part_from_string(msg));
|
||||
if(error.size == 0)
|
||||
{
|
||||
df_push_cmd__root(¶ms, cmd_spec);
|
||||
df_gfx_request_frame();
|
||||
}
|
||||
else
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_window(dst_window);
|
||||
params.string = error;
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Error));
|
||||
df_gfx_request_frame();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DF_CmdParams params = df_cmd_params_from_window(dst_window);
|
||||
params.string = push_str8f(scratch.arena, "\"%S\" is not a command.", cmd_spec_string);
|
||||
df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_String);
|
||||
df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Error));
|
||||
df_gfx_request_frame();
|
||||
}
|
||||
}
|
||||
os_semaphore_drop(ipc_semaphore);
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
//- rjf: update & render frame
|
||||
@@ -344,25 +432,61 @@ entry_point(CmdLine *cmd_line)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
|
||||
//- rjf: grab ipc shared memory
|
||||
OS_Handle ipc_shared_memory = os_shared_memory_open(ipc_shared_memory_name);
|
||||
void *ipc_shared_memory_base = os_shared_memory_view_open(ipc_shared_memory, r1u64(0, MB(16)));
|
||||
if(ipc_shared_memory_base != 0)
|
||||
//- rjf: grab explicit PID argument
|
||||
U32 dst_pid = 0;
|
||||
if(cmd_line_has_argument(cmd_line, str8_lit("pid")))
|
||||
{
|
||||
OS_Handle ipc_semaphore = os_semaphore_open(ipc_semaphore_name);
|
||||
IPCInfo *ipc_info = (IPCInfo *)ipc_shared_memory_base;
|
||||
if(os_semaphore_take(ipc_semaphore, os_now_microseconds() + Million(6)))
|
||||
String8 dst_pid_string = cmd_line_string(cmd_line, str8_lit("pid"));
|
||||
U64 dst_pid_u64 = 0;
|
||||
if(dst_pid_string.size != 0 &&
|
||||
try_u64_from_str8_c_rules(dst_pid_string, &dst_pid_u64))
|
||||
{
|
||||
U8 *buffer = (U8 *)(ipc_info+1);
|
||||
U64 buffer_max = IPC_SHARED_MEMORY_BUFFER_SIZE - sizeof(IPCInfo);
|
||||
StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")};
|
||||
String8 msg = str8_list_join(scratch.arena, &cmd_line->inputs, &join);
|
||||
ipc_info->msg_size = Min(buffer_max, msg.size);
|
||||
MemoryCopy(buffer, msg.str, ipc_info->msg_size);
|
||||
os_semaphore_drop(ipc_semaphore);
|
||||
dst_pid = (U32)dst_pid_u64;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: no explicit PID? -> find PID to send message to, by looking for other raddbg instances
|
||||
if(dst_pid == 0)
|
||||
{
|
||||
U32 this_pid = os_get_pid();
|
||||
DMN_ProcessIter it = {0};
|
||||
dmn_process_iter_begin(&it);
|
||||
for(DMN_ProcessInfo info = {0}; dmn_process_iter_next(scratch.arena, &it, &info);)
|
||||
{
|
||||
if(str8_match(str8_skip_last_slash(str8_chop_last_dot(cmd_line->exe_name)), str8_skip_last_slash(str8_chop_last_dot(info.name)), StringMatchFlag_CaseInsensitive) &&
|
||||
this_pid != info.pid)
|
||||
{
|
||||
dst_pid = info.pid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dmn_process_iter_end(&it);
|
||||
}
|
||||
|
||||
//- rjf: grab destination instance's shared memory resources
|
||||
String8 ipc_shared_memory_name = push_str8f(scratch.arena, "_raddbg_ipc_shared_memory_%i_", dst_pid);
|
||||
String8 ipc_signal_semaphore_name = push_str8f(scratch.arena, "_raddbg_ipc_signal_semaphore_%i_", dst_pid);
|
||||
String8 ipc_lock_semaphore_name = push_str8f(scratch.arena, "_raddbg_ipc_lock_semaphore_%i_", dst_pid);
|
||||
OS_Handle ipc_shared_memory = os_shared_memory_alloc(IPC_SHARED_MEMORY_BUFFER_SIZE, ipc_shared_memory_name);
|
||||
ipc_shared_memory_base = (U8 *)os_shared_memory_view_open(ipc_shared_memory, r1u64(0, IPC_SHARED_MEMORY_BUFFER_SIZE));
|
||||
ipc_signal_semaphore = os_semaphore_alloc(0, 1, ipc_signal_semaphore_name);
|
||||
ipc_lock_semaphore = os_semaphore_alloc(1, 1, ipc_lock_semaphore_name);
|
||||
|
||||
//- rjf: got resources -> write message
|
||||
if(ipc_shared_memory_base != 0 &&
|
||||
os_semaphore_take(ipc_lock_semaphore, max_U64))
|
||||
{
|
||||
IPCInfo *ipc_info = (IPCInfo *)ipc_shared_memory_base;
|
||||
U8 *buffer = (U8 *)(ipc_info+1);
|
||||
U64 buffer_max = IPC_SHARED_MEMORY_BUFFER_SIZE - sizeof(IPCInfo);
|
||||
StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")};
|
||||
String8 msg = str8_list_join(scratch.arena, &cmd_line->inputs, &join);
|
||||
ipc_info->msg_size = Min(buffer_max, msg.size);
|
||||
MemoryCopy(buffer, msg.str, ipc_info->msg_size);
|
||||
os_semaphore_drop(ipc_signal_semaphore);
|
||||
os_semaphore_drop(ipc_lock_semaphore);
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
|
||||
|
||||
+10
-10
@@ -5,17 +5,17 @@
|
||||
#define BUILD_VERSION_MINOR 9
|
||||
#define BUILD_VERSION_PATCH 10
|
||||
#define BUILD_RELEASE_PHASE_STRING_LITERAL "ALPHA"
|
||||
#define BUILD_TITLE "raddbgi_breakpad_from_pdb"
|
||||
#define BUILD_TITLE "rdi_breakpad_from_pdb"
|
||||
#define BUILD_CONSOLE_INTERFACE 1
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Includes
|
||||
|
||||
//- rjf: [lib]
|
||||
#include "lib_raddbgi_format/raddbgi_format.h"
|
||||
#include "lib_raddbgi_format/raddbgi_format_parse.h"
|
||||
#include "lib_raddbgi_format/raddbgi_format.c"
|
||||
#include "lib_raddbgi_format/raddbgi_format_parse.c"
|
||||
#include "lib_rdi_format/rdi_format.h"
|
||||
#include "lib_rdi_format/rdi_format_parse.h"
|
||||
#include "lib_rdi_format/rdi_format.c"
|
||||
#include "lib_rdi_format/rdi_format_parse.c"
|
||||
#include "third_party/rad_lzb_simple/rad_lzb_simple.h"
|
||||
#include "third_party/rad_lzb_simple/rad_lzb_simple.c"
|
||||
|
||||
@@ -24,27 +24,27 @@
|
||||
#include "base/base_inc.h"
|
||||
#include "os/os_inc.h"
|
||||
#include "task_system/task_system.h"
|
||||
#include "raddbgi_make_local/raddbgi_make_local.h"
|
||||
#include "rdi_make_local/rdi_make_local.h"
|
||||
#include "coff/coff.h"
|
||||
#include "codeview/codeview.h"
|
||||
#include "codeview/codeview_stringize.h"
|
||||
#include "msf/msf.h"
|
||||
#include "pdb/pdb.h"
|
||||
#include "pdb/pdb_stringize.h"
|
||||
#include "raddbgi_from_pdb/raddbgi_from_pdb.h"
|
||||
#include "rdi_from_pdb/rdi_from_pdb.h"
|
||||
|
||||
//- rjf: [c]
|
||||
#include "base/base_inc.c"
|
||||
#include "os/os_inc.c"
|
||||
#include "task_system/task_system.c"
|
||||
#include "raddbgi_make_local/raddbgi_make_local.c"
|
||||
#include "rdi_make_local/rdi_make_local.c"
|
||||
#include "coff/coff.c"
|
||||
#include "codeview/codeview.c"
|
||||
#include "codeview/codeview_stringize.c"
|
||||
#include "msf/msf.c"
|
||||
#include "pdb/pdb.c"
|
||||
#include "pdb/pdb_stringize.c"
|
||||
#include "raddbgi_from_pdb/raddbgi_from_pdb.c"
|
||||
#include "rdi_from_pdb/rdi_from_pdb.c"
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Baking Tasks
|
||||
@@ -209,7 +209,7 @@ entry_point(CmdLine *cmdline)
|
||||
//- rjf: display help
|
||||
if(do_help || user2convert->errors.node_count != 0)
|
||||
{
|
||||
fprintf(stderr, "--- raddbgi_breakpad_from_pdb -------------------------------------------------\n\n");
|
||||
fprintf(stderr, "--- rdi_breakpad_from_pdb -----------------------------------------------------\n\n");
|
||||
|
||||
fprintf(stderr, "This utility converts debug information from PDBs into the textual Breakpad\n");
|
||||
fprintf(stderr, "symbol information format, used for various external utilities, using the RAD\n");
|
||||
@@ -2,7 +2,7 @@
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: RADDBGI Enum -> String Functions
|
||||
//~ rjf: RDI Enum -> String Functions
|
||||
|
||||
internal String8
|
||||
rdi_string_from_data_section_tag(RDI_DataSectionTag tag){
|
||||
@@ -79,7 +79,7 @@ rdi_string_from_local_kind(RDI_LocalKind local_kind){
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: RADDBGI Flags -> String Functions
|
||||
//~ rjf: RDI Flags -> String Functions
|
||||
|
||||
internal void
|
||||
rdi_stringize_binary_section_flags(Arena *arena, String8List *out,
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef RADDBGI_DUMP_H
|
||||
#define RADDBGI_DUMP_H
|
||||
#ifndef RDI_DUMP_H
|
||||
#define RDI_DUMP_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: RADDBG Stringize Helper Types
|
||||
@@ -39,7 +39,7 @@ struct RDI_ScopeBundle
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: RADDBGI Enum -> String Functions
|
||||
//~ rjf: RDI Enum -> String Functions
|
||||
|
||||
internal String8 rdi_string_from_data_section_tag(RDI_DataSectionTag tag);
|
||||
internal String8 rdi_string_from_arch(RDI_Arch arch);
|
||||
@@ -49,7 +49,7 @@ internal String8 rdi_string_from_member_kind(RDI_MemberKind member_kind);
|
||||
internal String8 rdi_string_from_local_kind(RDI_LocalKind local_kind);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: RADDBGI Flags -> String Functions
|
||||
//~ rjf: RDI Flags -> String Functions
|
||||
|
||||
internal void rdi_stringize_binary_section_flags(Arena *arena, String8List *out, RDI_BinarySectionFlags flags);
|
||||
internal void rdi_stringize_type_modifier_flags(Arena *arena, String8List *out, RDI_TypeModifierFlags flags);
|
||||
@@ -57,7 +57,7 @@ internal void rdi_stringize_user_defined_type_flags(Arena *arena, String8List *o
|
||||
internal void rdi_stringize_link_flags(Arena *arena, String8List *out, RDI_LinkFlags flags);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: RADDBG Compound Stringize Functions
|
||||
//~ rjf: RDI Compound Stringize Functions
|
||||
|
||||
internal void rdi_stringize_data_sections(Arena *arena, String8List *out, RDI_Parsed *parsed, U32 indent_level);
|
||||
internal void rdi_stringize_top_level_info(Arena *arena, String8List *out, RDI_Parsed *parsed, RDI_TopLevelInfo *tli, U32 indent_level);
|
||||
@@ -72,4 +72,4 @@ internal void rdi_stringize_thread_variable(Arena *arena, String8List *out, RDI_
|
||||
internal void rdi_stringize_procedure(Arena *arena, String8List *out, RDI_Parsed *parsed, RDI_Procedure *proc, U32 indent_level);
|
||||
internal void rdi_stringize_scope(Arena *arena, String8List *out, RDI_Parsed *parsed, RDI_ScopeBundle *bundle, RDI_Scope *scope, U32 indent_level);
|
||||
|
||||
#endif // RADDBGI_DUMP_H
|
||||
#endif // RDI_DUMP_H
|
||||
@@ -8,27 +8,33 @@
|
||||
#define BUILD_VERSION_MINOR 9
|
||||
#define BUILD_VERSION_PATCH 10
|
||||
#define BUILD_RELEASE_PHASE_STRING_LITERAL "ALPHA"
|
||||
#define BUILD_TITLE "raddbgi_dump"
|
||||
#define BUILD_TITLE "rdi_dump"
|
||||
#define BUILD_CONSOLE_INTERFACE 1
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Includes
|
||||
|
||||
//- rjf: [lib]
|
||||
#include "lib_raddbgi_format/raddbgi_format.h"
|
||||
#include "lib_raddbgi_format/raddbgi_format_parse.h"
|
||||
#include "lib_raddbgi_format/raddbgi_format.c"
|
||||
#include "lib_raddbgi_format/raddbgi_format_parse.c"
|
||||
#include "lib_rdi_format/rdi_format.h"
|
||||
#include "lib_rdi_format/rdi_format_parse.h"
|
||||
#include "lib_rdi_format/rdi_format.c"
|
||||
#include "lib_rdi_format/rdi_format_parse.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 "raddbgi_dump.h"
|
||||
#include "path/path.h"
|
||||
#include "dbgi/dbgi.h"
|
||||
#include "rdi_dump.h"
|
||||
|
||||
//- rjf: [c]
|
||||
#include "base/base_inc.c"
|
||||
#include "os/os_inc.c"
|
||||
#include "raddbgi_dump.c"
|
||||
#include "path/path.c"
|
||||
#include "dbgi/dbgi.c"
|
||||
#include "rdi_dump.c"
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entry Point
|
||||
@@ -40,6 +46,7 @@ entry_point(CmdLine *cmd_line)
|
||||
//- rjf: set up
|
||||
//
|
||||
Arena *arena = arena_alloc();
|
||||
DI_Scope *di_scope = di_scope_open();
|
||||
String8List errors = {0};
|
||||
|
||||
//////////////////////////////
|
||||
@@ -70,11 +77,8 @@ entry_point(CmdLine *cmd_line)
|
||||
String8 input_data = {0};
|
||||
DumpFlags dump_flags = (U32)0xffffffff;
|
||||
{
|
||||
// rjf: extract input file path & load data
|
||||
// rjf: extract input file path
|
||||
input_name = str8_list_first(&cmd_line->inputs);
|
||||
if(input_name.size > 0) { input_data = os_data_from_file_path(arena, input_name); }
|
||||
else {str8_list_pushf(arena, &errors, "error (input): No input RADDBGI file specified.");}
|
||||
if(input_name.size != 0 && input_data.size == 0) { str8_list_pushf(arena, &errors, "error (input): No input RADDBGI file successfully loaded; either the path or file contents are invalid."); }
|
||||
|
||||
// rjf: extract dump options
|
||||
{
|
||||
@@ -107,17 +111,22 @@ entry_point(CmdLine *cmd_line)
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: parse raddbg from input data
|
||||
//- rjf: obtain rdi parse
|
||||
//
|
||||
RDI_ParseStatus parse_status = RDI_ParseStatus_Good;
|
||||
RDI_Parsed raddbg_ = {0};
|
||||
RDI_Parsed *raddbg = &raddbg_;
|
||||
RDI_Parsed *rdi = &di_rdi_parsed_nil;
|
||||
if(input_name.size == 0)
|
||||
{
|
||||
parse_status = rdi_parse(input_data.str, input_data.size, &raddbg_);
|
||||
if(parse_status != RDI_ParseStatus_Good)
|
||||
{
|
||||
str8_list_pushf(arena, &errors, "error (parse): RADDBGI file wasn't parsed successfully. (0x%x)", parse_status);
|
||||
}
|
||||
str8_list_pushf(arena, &errors, "error (input): No input RDI file specified.");
|
||||
}
|
||||
else
|
||||
{
|
||||
DI_Key key = {input_name};
|
||||
di_open(&key);
|
||||
rdi = di_rdi_from_key(di_scope, &key, max_U64);
|
||||
}
|
||||
if(rdi == &di_rdi_parsed_nil)
|
||||
{
|
||||
str8_list_pushf(arena, &errors, "error (input): No input RDI file successfully loaded; either the path or file contents are invalid.");
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
@@ -133,13 +142,13 @@ entry_point(CmdLine *cmd_line)
|
||||
//- rjf: build dump strings
|
||||
//
|
||||
String8List dump = {0};
|
||||
if(parse_status == RDI_ParseStatus_Good)
|
||||
if(rdi != &di_rdi_parsed_nil)
|
||||
{
|
||||
//- rjf: DATA SECTIONS
|
||||
if(dump_flags & DumpFlag_DataSections)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, "# DATA SECTIONS:\n");
|
||||
rdi_stringize_data_sections(arena, &dump, raddbg, 1);
|
||||
rdi_stringize_data_sections(arena, &dump, rdi, 1);
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
}
|
||||
|
||||
@@ -147,7 +156,7 @@ entry_point(CmdLine *cmd_line)
|
||||
if(dump_flags & DumpFlag_TopLevelInfo)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, "# TOP LEVEL INFO:\n");
|
||||
rdi_stringize_top_level_info(arena, &dump, raddbg, raddbg->top_level_info, 1);
|
||||
rdi_stringize_top_level_info(arena, &dump, rdi, rdi->top_level_info, 1);
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
}
|
||||
|
||||
@@ -155,11 +164,11 @@ entry_point(CmdLine *cmd_line)
|
||||
if(dump_flags & DumpFlag_BinarySections)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, "# BINARY SECTIONS:\n");
|
||||
RDI_BinarySection *ptr = raddbg->binary_sections;
|
||||
for(U32 i = 0; i < raddbg->binary_sections_count; i += 1, ptr += 1)
|
||||
RDI_BinarySection *ptr = rdi->binary_sections;
|
||||
for(U32 i = 0; i < rdi->binary_sections_count; i += 1, ptr += 1)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, " section[%u]:\n", i);
|
||||
rdi_stringize_binary_section(arena, &dump, raddbg, ptr, 2);
|
||||
rdi_stringize_binary_section(arena, &dump, rdi, ptr, 2);
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
}
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
@@ -170,16 +179,16 @@ entry_point(CmdLine *cmd_line)
|
||||
{
|
||||
RDI_FilePathBundle file_path_bundle = {0};
|
||||
{
|
||||
file_path_bundle.file_paths = raddbg->file_paths;
|
||||
file_path_bundle.file_path_count = raddbg->file_paths_count;
|
||||
file_path_bundle.file_paths = rdi->file_paths;
|
||||
file_path_bundle.file_path_count = rdi->file_paths_count;
|
||||
}
|
||||
str8_list_pushf(arena, &dump, "# FILE PATHS\n");
|
||||
RDI_FilePathNode *ptr = raddbg->file_paths;
|
||||
for(U32 i = 0; i < raddbg->file_paths_count; i += 1, ptr += 1)
|
||||
RDI_FilePathNode *ptr = rdi->file_paths;
|
||||
for(U32 i = 0; i < rdi->file_paths_count; i += 1, ptr += 1)
|
||||
{
|
||||
if(ptr->parent_path_node == 0)
|
||||
{
|
||||
rdi_stringize_file_path(arena, &dump, raddbg, &file_path_bundle, ptr, 1);
|
||||
rdi_stringize_file_path(arena, &dump, rdi, &file_path_bundle, ptr, 1);
|
||||
}
|
||||
}
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
@@ -189,11 +198,11 @@ entry_point(CmdLine *cmd_line)
|
||||
if(dump_flags & DumpFlag_SourceFiles)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, "# SOURCE FILES\n");
|
||||
RDI_SourceFile *ptr = raddbg->source_files;
|
||||
for(U32 i = 0; i < raddbg->source_files_count; i += 1, ptr += 1)
|
||||
RDI_SourceFile *ptr = rdi->source_files;
|
||||
for(U32 i = 0; i < rdi->source_files_count; i += 1, ptr += 1)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, " source_file[%u]:\n", i);
|
||||
rdi_stringize_source_file(arena, &dump, raddbg, ptr, 2);
|
||||
rdi_stringize_source_file(arena, &dump, rdi, ptr, 2);
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
}
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
@@ -203,11 +212,11 @@ entry_point(CmdLine *cmd_line)
|
||||
if(dump_flags & DumpFlag_Units)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, "# UNITS\n");
|
||||
RDI_Unit *ptr = raddbg->units;
|
||||
for (U32 i = 0; i < raddbg->units_count; i += 1, ptr += 1)
|
||||
RDI_Unit *ptr = rdi->units;
|
||||
for (U32 i = 0; i < rdi->units_count; i += 1, ptr += 1)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, " unit[%u]:\n", i);
|
||||
rdi_stringize_unit(arena, &dump, raddbg, ptr, 2);
|
||||
rdi_stringize_unit(arena, &dump, rdi, ptr, 2);
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
}
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
@@ -217,8 +226,8 @@ entry_point(CmdLine *cmd_line)
|
||||
if(dump_flags & DumpFlag_UnitVMap)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, "# UNIT VMAP\n");
|
||||
RDI_VMapEntry *ptr = raddbg->unit_vmap;
|
||||
for(U32 i = 0; i < raddbg->unit_vmap_count; i += 1, ptr += 1)
|
||||
RDI_VMapEntry *ptr = rdi->unit_vmap;
|
||||
for(U32 i = 0; i < rdi->unit_vmap_count; i += 1, ptr += 1)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, " 0x%08x: %llu\n", ptr->voff, ptr->idx);
|
||||
}
|
||||
@@ -229,11 +238,11 @@ entry_point(CmdLine *cmd_line)
|
||||
if(dump_flags & DumpFlag_TypeNodes)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, "# TYPE NODES:\n");
|
||||
RDI_TypeNode *ptr = raddbg->type_nodes;
|
||||
for(U32 i = 0; i < raddbg->type_nodes_count; i += 1, ptr += 1)
|
||||
RDI_TypeNode *ptr = rdi->type_nodes;
|
||||
for(U32 i = 0; i < rdi->type_nodes_count; i += 1, ptr += 1)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, " type[%u]:\n", i);
|
||||
rdi_stringize_type_node(arena, &dump, raddbg, ptr, 2);
|
||||
rdi_stringize_type_node(arena, &dump, rdi, ptr, 2);
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
}
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
@@ -244,17 +253,17 @@ entry_point(CmdLine *cmd_line)
|
||||
{
|
||||
RDI_UDTMemberBundle member_bundle = {0};
|
||||
{
|
||||
member_bundle.members = raddbg->members;
|
||||
member_bundle.enum_members = raddbg->enum_members;
|
||||
member_bundle.member_count = raddbg->members_count;
|
||||
member_bundle.enum_member_count = raddbg->enum_members_count;
|
||||
member_bundle.members = rdi->members;
|
||||
member_bundle.enum_members = rdi->enum_members;
|
||||
member_bundle.member_count = rdi->members_count;
|
||||
member_bundle.enum_member_count = rdi->enum_members_count;
|
||||
}
|
||||
str8_list_pushf(arena, &dump, "# UDTS:\n");
|
||||
RDI_UDT *ptr = raddbg->udts;
|
||||
for(U32 i = 0; i < raddbg->udts_count; i += 1, ptr += 1)
|
||||
RDI_UDT *ptr = rdi->udts;
|
||||
for(U32 i = 0; i < rdi->udts_count; i += 1, ptr += 1)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, " udt[%u]:\n", i);
|
||||
rdi_stringize_udt(arena, &dump, raddbg, &member_bundle, ptr, 2);
|
||||
rdi_stringize_udt(arena, &dump, rdi, &member_bundle, ptr, 2);
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
}
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
@@ -264,11 +273,11 @@ entry_point(CmdLine *cmd_line)
|
||||
if(dump_flags & DumpFlag_GlobalVariables)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, "# GLOBAL VARIABLES:\n");
|
||||
RDI_GlobalVariable *ptr = raddbg->global_variables;
|
||||
for(U32 i = 0; i < raddbg->global_variables_count; i += 1, ptr += 1)
|
||||
RDI_GlobalVariable *ptr = rdi->global_variables;
|
||||
for(U32 i = 0; i < rdi->global_variables_count; i += 1, ptr += 1)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, " global_variable[%u]:\n", i);
|
||||
rdi_stringize_global_variable(arena, &dump, raddbg, ptr, 2);
|
||||
rdi_stringize_global_variable(arena, &dump, rdi, ptr, 2);
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
}
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
@@ -278,8 +287,8 @@ entry_point(CmdLine *cmd_line)
|
||||
if(dump_flags & DumpFlag_GlobalVMap)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, "# GLOBAL VMAP:\n");
|
||||
RDI_VMapEntry *ptr = raddbg->global_vmap;
|
||||
for(U32 i = 0; i < raddbg->global_vmap_count; i += 1, ptr += 1)
|
||||
RDI_VMapEntry *ptr = rdi->global_vmap;
|
||||
for(U32 i = 0; i < rdi->global_vmap_count; i += 1, ptr += 1)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, " 0x%08x: %llu\n", ptr->voff, ptr->idx);
|
||||
}
|
||||
@@ -290,11 +299,11 @@ entry_point(CmdLine *cmd_line)
|
||||
if(dump_flags & DumpFlag_ThreadVariables)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, "# THREAD VARIABLES:\n");
|
||||
RDI_ThreadVariable *ptr = raddbg->thread_variables;
|
||||
for(U32 i = 0; i < raddbg->thread_variables_count; i += 1, ptr += 1)
|
||||
RDI_ThreadVariable *ptr = rdi->thread_variables;
|
||||
for(U32 i = 0; i < rdi->thread_variables_count; i += 1, ptr += 1)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, " thread_variable[%u]:\n", i);
|
||||
rdi_stringize_thread_variable(arena, &dump, raddbg, ptr, 2);
|
||||
rdi_stringize_thread_variable(arena, &dump, rdi, ptr, 2);
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
}
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
@@ -304,11 +313,11 @@ entry_point(CmdLine *cmd_line)
|
||||
if(dump_flags & DumpFlag_Procedures)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, "# PROCEDURES:\n");
|
||||
RDI_Procedure *ptr = raddbg->procedures;
|
||||
for(U32 i = 0; i < raddbg->procedures_count; i += 1, ptr += 1)
|
||||
RDI_Procedure *ptr = rdi->procedures;
|
||||
for(U32 i = 0; i < rdi->procedures_count; i += 1, ptr += 1)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, " procedure[%u]:\n", i);
|
||||
rdi_stringize_procedure(arena, &dump, raddbg, ptr, 2);
|
||||
rdi_stringize_procedure(arena, &dump, rdi, ptr, 2);
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
}
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
@@ -319,24 +328,24 @@ entry_point(CmdLine *cmd_line)
|
||||
{
|
||||
RDI_ScopeBundle scope_bundle = {0};
|
||||
{
|
||||
scope_bundle.scopes = raddbg->scopes;
|
||||
scope_bundle.scope_count = raddbg->scopes_count;
|
||||
scope_bundle.scope_voffs = raddbg->scope_voffs;
|
||||
scope_bundle.scope_voff_count = raddbg->scope_voffs_count;
|
||||
scope_bundle.locals = raddbg->locals;
|
||||
scope_bundle.local_count = raddbg->locals_count;
|
||||
scope_bundle.location_blocks = raddbg->location_blocks;
|
||||
scope_bundle.location_block_count = raddbg->location_blocks_count;
|
||||
scope_bundle.location_data = raddbg->location_data;
|
||||
scope_bundle.location_data_size = raddbg->location_data_size;
|
||||
scope_bundle.scopes = rdi->scopes;
|
||||
scope_bundle.scope_count = rdi->scopes_count;
|
||||
scope_bundle.scope_voffs = rdi->scope_voffs;
|
||||
scope_bundle.scope_voff_count = rdi->scope_voffs_count;
|
||||
scope_bundle.locals = rdi->locals;
|
||||
scope_bundle.local_count = rdi->locals_count;
|
||||
scope_bundle.location_blocks = rdi->location_blocks;
|
||||
scope_bundle.location_block_count = rdi->location_blocks_count;
|
||||
scope_bundle.location_data = rdi->location_data;
|
||||
scope_bundle.location_data_size = rdi->location_data_size;
|
||||
}
|
||||
str8_list_pushf(arena, &dump, "# SCOPES:\n");
|
||||
RDI_Scope *ptr = raddbg->scopes;
|
||||
for(U32 i = 0; i < raddbg->scopes_count; i += 1, ptr += 1)
|
||||
RDI_Scope *ptr = rdi->scopes;
|
||||
for(U32 i = 0; i < rdi->scopes_count; i += 1, ptr += 1)
|
||||
{
|
||||
if(ptr->parent_scope_idx == 0)
|
||||
{
|
||||
rdi_stringize_scope(arena, &dump, raddbg, &scope_bundle, ptr, 1);
|
||||
rdi_stringize_scope(arena, &dump, rdi, &scope_bundle, ptr, 1);
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
}
|
||||
}
|
||||
@@ -347,8 +356,8 @@ entry_point(CmdLine *cmd_line)
|
||||
if(dump_flags & DumpFlag_ScopeVMap)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, "# SCOPE VMAP:\n");
|
||||
RDI_VMapEntry *ptr = raddbg->scope_vmap;
|
||||
for(U32 i = 0; i < raddbg->scope_vmap_count; i += 1, ptr += 1)
|
||||
RDI_VMapEntry *ptr = rdi->scope_vmap;
|
||||
for(U32 i = 0; i < rdi->scope_vmap_count; i += 1, ptr += 1)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, " 0x%08x: %llu\n", ptr->voff, ptr->idx);
|
||||
}
|
||||
@@ -359,11 +368,11 @@ entry_point(CmdLine *cmd_line)
|
||||
if(dump_flags & DumpFlag_NameMaps)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, "# NAME MAP:\n");
|
||||
RDI_NameMap *ptr = raddbg->name_maps;
|
||||
for(U32 i = 0; i < raddbg->name_maps_count; i += 1, ptr += 1)
|
||||
RDI_NameMap *ptr = rdi->name_maps;
|
||||
for(U32 i = 0; i < rdi->name_maps_count; i += 1, ptr += 1)
|
||||
{
|
||||
RDI_ParsedNameMap name_map = {0};
|
||||
rdi_name_map_parse(raddbg, ptr, &name_map);
|
||||
rdi_name_map_parse(rdi, ptr, &name_map);
|
||||
str8_list_pushf(arena, &dump, " name_map[%u]:\n", i);
|
||||
RDI_NameMapBucket *bucket = name_map.buckets;
|
||||
for(U32 j = 0; j < name_map.bucket_count; j += 1, bucket += 1)
|
||||
@@ -376,7 +385,7 @@ entry_point(CmdLine *cmd_line)
|
||||
for(;node < node_opl; node += 1)
|
||||
{
|
||||
String8 string = {0};
|
||||
string.str = rdi_string_from_idx(raddbg, node->string_idx, &string.size);
|
||||
string.str = rdi_string_from_idx(rdi, node->string_idx, &string.size);
|
||||
str8_list_pushf(arena, &dump, " match \"%.*s\": ", str8_varg(string));
|
||||
if(node->match_count == 1)
|
||||
{
|
||||
@@ -386,7 +395,7 @@ entry_point(CmdLine *cmd_line)
|
||||
{
|
||||
RDI_U32 idx_count = 0;
|
||||
RDI_U32 *idx_run =
|
||||
rdi_idx_run_from_first_count(raddbg, node->match_idx_or_idx_run_first,
|
||||
rdi_idx_run_from_first_count(rdi, node->match_idx_or_idx_run_first,
|
||||
node->match_count, &idx_count);
|
||||
if(idx_count > 0)
|
||||
{
|
||||
@@ -411,10 +420,10 @@ entry_point(CmdLine *cmd_line)
|
||||
if(dump_flags & DumpFlag_Strings)
|
||||
{
|
||||
str8_list_pushf(arena, &dump, "# STRINGS:\n");
|
||||
for(U64 string_idx = 0; string_idx < raddbg->string_count; string_idx += 1)
|
||||
for(U64 string_idx = 0; string_idx < rdi->string_count; string_idx += 1)
|
||||
{
|
||||
String8 string = {0};
|
||||
string.str = rdi_string_from_idx(raddbg, string_idx, &string.size);
|
||||
string.str = rdi_string_from_idx(rdi, string_idx, &string.size);
|
||||
str8_list_pushf(arena, &dump, " string[%I64u]: \"%S\"\n", string_idx, string);
|
||||
}
|
||||
str8_list_push(arena, &dump, str8_lit("\n"));
|
||||
@@ -428,4 +437,6 @@ entry_point(CmdLine *cmd_line)
|
||||
{
|
||||
fwrite(n->string.str, 1, n->string.size, stdout);
|
||||
}
|
||||
|
||||
di_scope_close(di_scope);
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef RADDBGI_DWARF_H
|
||||
#define RADDBGI_DWARF_H
|
||||
#ifndef RDI_DWARF_H
|
||||
#define RDI_DWARF_H
|
||||
|
||||
// https://dwarfstd.org/doc/DWARF4.pdf
|
||||
// https://dwarfstd.org/doc/DWARF5.pdf
|
||||
@@ -1489,5 +1489,5 @@ static String8 dwarf_string_from_line_ext_op(DWARF_LineExtOp op);
|
||||
static String8 dwarf_string_from_line_entry_format(DWARF_LineEntryFormat format);
|
||||
static String8 dwarf_string_from_section_code(DWARF_SectionCode sec_code);
|
||||
|
||||
#endif //RADDBGI_DWARF_H
|
||||
#endif //RDI_DWARF_H
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef RADDBGI_DWARF_STRINGIZE_H
|
||||
#define RADDBGI_DWARF_STRINGIZE_H
|
||||
#ifndef RDI_DWARF_STRINGIZE_H
|
||||
#define RDI_DWARF_STRINGIZE_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ DWARF Stringize Functions
|
||||
@@ -25,4 +25,4 @@ dwarf_stringize_addr(Arena *arena, String8List *out, DWARF_AddrUnit *unit, U32 i
|
||||
|
||||
|
||||
|
||||
#endif //RADDBGI_DWARF_STRINGIZE_H
|
||||
#endif //RDI_DWARF_STRINGIZE_H
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef RADDBGI_ELF_H
|
||||
#define RADDBGI_ELF_H
|
||||
#ifndef RDI_ELF_H
|
||||
#define RDI_ELF_H
|
||||
|
||||
// https://refspecs.linuxfoundation.org/elf/elf.pdf
|
||||
|
||||
@@ -514,4 +514,4 @@ static String8 elf_string_from_symbol_binding(ELF_SymbolBinding binding);
|
||||
static String8 elf_string_from_symbol_type(ELF_SymbolType type);
|
||||
static String8 elf_string_from_symbol_visibility(ELF_SymbolVisibility visibility);
|
||||
|
||||
#endif //RADDBGI_ELF_H
|
||||
#endif //RDI_ELF_H
|
||||
@@ -1,27 +1,27 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#include "lib_raddbgi_format/raddbgi_format.h"
|
||||
#include "lib_rdi_format/rdi_format.h"
|
||||
#include "base/base_inc.h"
|
||||
#include "os/os_inc.h"
|
||||
#include "raddbgi_make_local/raddbgi_make_local.h"
|
||||
#include "rdi_make_local/rdi_make_local.h"
|
||||
|
||||
#include "raddbgi_elf.h"
|
||||
#include "raddbgi_dwarf.h"
|
||||
#include "rdi_elf.h"
|
||||
#include "rdi_dwarf.h"
|
||||
|
||||
#include "raddbgi_dwarf_stringize.h"
|
||||
#include "rdi_dwarf_stringize.h"
|
||||
|
||||
#include "raddbgi_from_dwarf.h"
|
||||
#include "rdi_from_dwarf.h"
|
||||
|
||||
#include "lib_raddbgi_format/raddbgi_format.c"
|
||||
#include "lib_rdi_format/rdi_format.c"
|
||||
#include "base/base_inc.c"
|
||||
#include "os/os_inc.c"
|
||||
#include "raddbgi_make_local/raddbgi_make_local.c"
|
||||
#include "rdi_make_local/rdi_make_local.c"
|
||||
|
||||
#include "raddbgi_elf.c"
|
||||
#include "raddbgi_dwarf.c"
|
||||
#include "rdi_elf.c"
|
||||
#include "rdi_dwarf.c"
|
||||
|
||||
#include "raddbgi_dwarf_stringize.c"
|
||||
#include "rdi_dwarf_stringize.c"
|
||||
|
||||
// TODO(allen):
|
||||
// [ ] need sample data for .debug_names
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef RADDBGI_FROM_DWARF_H
|
||||
#define RADDBGI_FROM_DWARF_H
|
||||
#ifndef RDI_FROM_DWARF_H
|
||||
#define RDI_FROM_DWARF_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ Program Parameters Type
|
||||
@@ -47,4 +47,4 @@ static DWARFCONV_Params *dwarf_convert_params_from_cmd_line(Arena *arena, CmdLin
|
||||
|
||||
|
||||
|
||||
#endif //RADDBGI_FROM_DWARF_H
|
||||
#endif //RDI_FROM_DWARF_H
|
||||
@@ -147,7 +147,7 @@ Case("source_path_name_map",NormalSourcePathNameMap)\
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: COFF <-> RADDBGI Canonical Conversions
|
||||
//~ rjf: COFF <-> RDI Canonical Conversions
|
||||
|
||||
internal RDI_BinarySectionFlags
|
||||
p2r_rdi_binary_section_flags_from_coff_section_flags(COFF_SectionFlags flags)
|
||||
@@ -169,7 +169,7 @@ p2r_rdi_binary_section_flags_from_coff_section_flags(COFF_SectionFlags flags)
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: CodeView <-> RADDBGI Canonical Conversions
|
||||
//~ rjf: CodeView <-> RDI Canonical Conversions
|
||||
|
||||
internal RDI_Arch
|
||||
p2r_rdi_arch_from_cv_arch(CV_Arch cv_arch)
|
||||
@@ -2935,7 +2935,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in)
|
||||
//- rjf: types pass 2: produce per-itype itype chain
|
||||
//
|
||||
// this pass is to ensure that subsequent passes always produce types for
|
||||
// dependent itypes first - guaranteeing raddbgi's "only reference backward"
|
||||
// dependent itypes first - guaranteeing rdi's "only reference backward"
|
||||
// rule (which eliminates cycles). each itype slot gets a list of itypes,
|
||||
// starting with the deepest dependency - when types are produced per-itype,
|
||||
// this chain is walked, so that deeper dependencies are built first, and
|
||||
@@ -2974,7 +2974,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in)
|
||||
//- rjf: types pass 3: construct all types from TPI
|
||||
//
|
||||
// this doesn't gather struct/class/union/enum members, which is done by
|
||||
// subsequent passes, to build RADDBGI "UDT" information, which is distinct
|
||||
// subsequent passes, to build RDI "UDT" information, which is distinct
|
||||
// from regular type info.
|
||||
//
|
||||
RDIM_Type **itype_type_ptrs = 0;
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef RADDBGI_FROM_PDB_H
|
||||
#define RADDBGI_FROM_PDB_H
|
||||
#ifndef RDI_FROM_PDB_H
|
||||
#define RDI_FROM_PDB_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Export Artifact Flags
|
||||
@@ -514,12 +514,12 @@ internal U64 p2r_hash_from_voff(U64 voff);
|
||||
internal P2R_User2Convert *p2r_user2convert_from_cmdln(Arena *arena, CmdLine *cmdline);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: COFF => RADDBGI Canonical Conversions
|
||||
//~ rjf: COFF => RDI Canonical Conversions
|
||||
|
||||
internal RDI_BinarySectionFlags p2r_rdi_binary_section_flags_from_coff_section_flags(COFF_SectionFlags flags);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: CodeView => RADDBGI Canonical Conversions
|
||||
//~ rjf: CodeView => RDI Canonical Conversions
|
||||
|
||||
internal RDI_Arch p2r_rdi_arch_from_cv_arch(CV_Arch arch);
|
||||
internal RDI_RegisterCode p2r_rdi_reg_code_from_cv_reg_code(RDI_Arch arch, CV_Reg reg_code);
|
||||
@@ -626,4 +626,4 @@ internal P2R_Bake2Serialize *p2r_bake(Arena *arena, P2R_Convert2Bake *in);
|
||||
|
||||
internal P2R_Bake2Serialize *p2r_compress(Arena *arena, P2R_Bake2Serialize *in);
|
||||
|
||||
#endif // RADDBGI_FROM_PDB_H
|
||||
#endif // RDI_FROM_PDB_H
|
||||
@@ -8,15 +8,15 @@
|
||||
#define BUILD_VERSION_MINOR 9
|
||||
#define BUILD_VERSION_PATCH 10
|
||||
#define BUILD_RELEASE_PHASE_STRING_LITERAL "ALPHA"
|
||||
#define BUILD_TITLE "raddbgi_from_pdb"
|
||||
#define BUILD_TITLE "rdi_from_pdb"
|
||||
#define BUILD_CONSOLE_INTERFACE 1
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Includes
|
||||
|
||||
//- rjf: [lib]
|
||||
#include "lib_raddbgi_format/raddbgi_format.h"
|
||||
#include "lib_raddbgi_format/raddbgi_format.c"
|
||||
#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"
|
||||
|
||||
@@ -24,27 +24,27 @@
|
||||
#include "base/base_inc.h"
|
||||
#include "os/os_inc.h"
|
||||
#include "task_system/task_system.h"
|
||||
#include "raddbgi_make_local/raddbgi_make_local.h"
|
||||
#include "rdi_make_local/rdi_make_local.h"
|
||||
#include "coff/coff.h"
|
||||
#include "codeview/codeview.h"
|
||||
#include "codeview/codeview_stringize.h"
|
||||
#include "msf/msf.h"
|
||||
#include "pdb/pdb.h"
|
||||
#include "pdb/pdb_stringize.h"
|
||||
#include "raddbgi_from_pdb.h"
|
||||
#include "rdi_from_pdb.h"
|
||||
|
||||
//- rjf: [c]
|
||||
#include "base/base_inc.c"
|
||||
#include "os/os_inc.c"
|
||||
#include "task_system/task_system.c"
|
||||
#include "raddbgi_make_local/raddbgi_make_local.c"
|
||||
#include "rdi_make_local/rdi_make_local.c"
|
||||
#include "coff/coff.c"
|
||||
#include "codeview/codeview.c"
|
||||
#include "codeview/codeview_stringize.c"
|
||||
#include "msf/msf.c"
|
||||
#include "pdb/pdb.c"
|
||||
#include "pdb/pdb_stringize.c"
|
||||
#include "raddbgi_from_pdb.c"
|
||||
#include "rdi_from_pdb.c"
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entry Point
|
||||
@@ -62,7 +62,7 @@ entry_point(CmdLine *cmdline)
|
||||
//- rjf: display help
|
||||
if(do_help || user2convert->errors.node_count != 0)
|
||||
{
|
||||
fprintf(stderr, "--- raddbgi_from_pdb ----------------------------------------------------------\n\n");
|
||||
fprintf(stderr, "--- rdi_from_pdb --------------------------------------------------------------\n\n");
|
||||
|
||||
fprintf(stderr, "This utility converts debug information from PDBs into the RAD Debug Info.\n");
|
||||
fprintf(stderr, "format. The following arguments are accepted:\n\n");
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#include "lib_raddbgi_make/raddbgi_make.c"
|
||||
#include "lib_rdi_make/rdi_make.c"
|
||||
@@ -45,6 +45,6 @@
|
||||
#define RDIM_ProfBegin(...) ProfBeginDynamic(__VA_ARGS__)
|
||||
#define RDIM_ProfEnd(...) ProfEnd()
|
||||
|
||||
#include "lib_raddbgi_make/raddbgi_make.h"
|
||||
#include "lib_rdi_make/rdi_make.h"
|
||||
|
||||
#endif // RDI_CONS_LOCAL_H
|
||||
+3
-3
@@ -3,10 +3,10 @@
|
||||
|
||||
//- GENERATED CODE
|
||||
|
||||
#ifndef REGS_RADDBGI_META_H
|
||||
#define REGS_RADDBGI_META_H
|
||||
#ifndef REGS_RDI_META_H
|
||||
#define REGS_RDI_META_H
|
||||
|
||||
C_LINKAGE_BEGIN
|
||||
C_LINKAGE_END
|
||||
|
||||
#endif // REGS_RADDBGI_META_H
|
||||
#endif // REGS_RDI_META_H
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#include "regs/raddbgi/generated/regs_raddbgi.meta.c"
|
||||
#include "regs/rdi/generated/regs_rdi.meta.c"
|
||||
@@ -1,10 +1,10 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef REGS_RADDBGI_H
|
||||
#define REGS_RADDBGI_H
|
||||
#ifndef REGS_RDI_H
|
||||
#define REGS_RDI_H
|
||||
|
||||
internal RDI_RegisterCode regs_rdi_code_from_arch_reg_code(Architecture arch, REGS_RegCode code);
|
||||
internal REGS_RegCode regs_reg_code_from_arch_rdi_code(Architecture arch, RDI_RegisterCode reg);
|
||||
|
||||
#endif //REGS_RADDBGI_H
|
||||
#endif //REGS_RDI_H
|
||||
+4
-4
@@ -13,7 +13,7 @@ internal U64
|
||||
regs_rip_from_arch_block(Architecture arch, void *block)
|
||||
{
|
||||
U64 result = 0;
|
||||
switch(arch)
|
||||
if(block != 0) switch(arch)
|
||||
{
|
||||
default:{}break;
|
||||
case Architecture_x64:{result = ((REGS_RegBlockX64 *)block)->rip.u64;}break;
|
||||
@@ -26,7 +26,7 @@ internal U64
|
||||
regs_rsp_from_arch_block(Architecture arch, void *block)
|
||||
{
|
||||
U64 result = 0;
|
||||
switch(arch)
|
||||
if(block != 0) switch(arch)
|
||||
{
|
||||
default:{}break;
|
||||
case Architecture_x64:{result = ((REGS_RegBlockX64 *)block)->rsp.u64;}break;
|
||||
@@ -38,7 +38,7 @@ regs_rsp_from_arch_block(Architecture arch, void *block)
|
||||
internal void
|
||||
regs_arch_block_write_rip(Architecture arch, void *block, U64 rip)
|
||||
{
|
||||
switch(arch)
|
||||
if(block != 0) switch(arch)
|
||||
{
|
||||
default:{}break;
|
||||
case Architecture_x64:{((REGS_RegBlockX64 *)block)->rip.u64 = rip;}break;
|
||||
@@ -49,7 +49,7 @@ regs_arch_block_write_rip(Architecture arch, void *block, U64 rip)
|
||||
internal void
|
||||
regs_arch_block_write_rsp(Architecture arch, void *block, U64 rsp)
|
||||
{
|
||||
switch(arch)
|
||||
if(block != 0) switch(arch)
|
||||
{
|
||||
default:{}break;
|
||||
case Architecture_x64:{((REGS_RegBlockX64 *)block)->rsp.u64 = rsp;}break;
|
||||
|
||||
@@ -496,7 +496,7 @@ r_window_equip(OS_Handle handle)
|
||||
os_graphical_message(1, str8_lit("Fatal Error"), str8_cstring(buffer));
|
||||
os_exit_process(1);
|
||||
}
|
||||
|
||||
|
||||
r_d3d11_state->dxgi_factory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER);
|
||||
|
||||
//- rjf: create framebuffer & view
|
||||
@@ -841,18 +841,13 @@ r_window_begin_frame(OS_Handle window, R_Handle window_equip)
|
||||
Vec2S32 resolution = {(S32)(client_rect.x1 - client_rect.x0), (S32)(client_rect.y1 - client_rect.y0)};
|
||||
|
||||
//- rjf: resolution change
|
||||
B32 resize_done = 0;
|
||||
if(wnd->last_resolution.x != resolution.x ||
|
||||
wnd->last_resolution.y != resolution.y)
|
||||
{
|
||||
resize_done = 1;
|
||||
wnd->last_resolution = resolution;
|
||||
|
||||
// rjf: resize swapchain & main framebuffer
|
||||
wnd->framebuffer_rtv->Release();
|
||||
wnd->framebuffer->Release();
|
||||
wnd->swapchain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
|
||||
wnd->swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void **)(&wnd->framebuffer));
|
||||
r_d3d11_state->device->CreateRenderTargetView(wnd->framebuffer, 0, &wnd->framebuffer_rtv);
|
||||
|
||||
// rjf: release screen-sized render target resources, if there
|
||||
if(wnd->stage_scratch_color_srv){wnd->stage_scratch_color_srv->Release();}
|
||||
if(wnd->stage_scratch_color_rtv){wnd->stage_scratch_color_rtv->Release();}
|
||||
@@ -867,6 +862,13 @@ r_window_begin_frame(OS_Handle window, R_Handle window_equip)
|
||||
if(wnd->geo3d_depth_dsv) {wnd->geo3d_depth_dsv->Release();}
|
||||
if(wnd->geo3d_depth) {wnd->geo3d_depth->Release();}
|
||||
|
||||
// rjf: resize swapchain & main framebuffer
|
||||
wnd->framebuffer_rtv->Release();
|
||||
wnd->framebuffer->Release();
|
||||
wnd->swapchain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
|
||||
wnd->swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void **)(&wnd->framebuffer));
|
||||
r_d3d11_state->device->CreateRenderTargetView(wnd->framebuffer, 0, &wnd->framebuffer_rtv);
|
||||
|
||||
// rjf: create stage color targets
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC color_desc = {};
|
||||
@@ -946,6 +948,10 @@ r_window_begin_frame(OS_Handle window, R_Handle window_equip)
|
||||
Vec4F32 clear_color = {0, 0, 0, 0};
|
||||
d_ctx->ClearRenderTargetView(wnd->framebuffer_rtv, clear_color.v);
|
||||
d_ctx->ClearRenderTargetView(wnd->stage_color_rtv, clear_color.v);
|
||||
if(resize_done)
|
||||
{
|
||||
d_ctx->Flush();
|
||||
}
|
||||
}
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
+10
-10
@@ -15,16 +15,16 @@
|
||||
//~ rjf: Includes
|
||||
|
||||
//- rjf: [lib]
|
||||
#include "lib_raddbgi_format/raddbgi_format.h"
|
||||
#include "lib_raddbgi_format/raddbgi_format_parse.h"
|
||||
#include "lib_raddbgi_format/raddbgi_format.c"
|
||||
#include "lib_raddbgi_format/raddbgi_format_parse.c"
|
||||
#include "lib_rdi_format/rdi_format.h"
|
||||
#include "lib_rdi_format/rdi_format_parse.h"
|
||||
#include "lib_rdi_format/rdi_format.c"
|
||||
#include "lib_rdi_format/rdi_format_parse.c"
|
||||
|
||||
//- rjf: [h]
|
||||
#include "base/base_inc.h"
|
||||
#include "os/os_inc.h"
|
||||
#include "task_system/task_system.h"
|
||||
#include "raddbgi_make_local/raddbgi_make_local.h"
|
||||
#include "rdi_make_local/rdi_make_local.h"
|
||||
#include "mdesk/mdesk.h"
|
||||
#include "hash_store/hash_store.h"
|
||||
#include "file_stream/file_stream.h"
|
||||
@@ -38,9 +38,9 @@
|
||||
#include "msf/msf.h"
|
||||
#include "pdb/pdb.h"
|
||||
#include "pdb/pdb_stringize.h"
|
||||
#include "raddbgi_from_pdb/raddbgi_from_pdb.h"
|
||||
#include "rdi_from_pdb/rdi_from_pdb.h"
|
||||
#include "regs/regs.h"
|
||||
#include "regs/raddbgi/regs_raddbgi.h"
|
||||
#include "regs/rdi/regs_rdi.h"
|
||||
#include "type_graph/type_graph.h"
|
||||
#include "dbgi/dbgi.h"
|
||||
#include "demon/demon_inc.h"
|
||||
@@ -52,7 +52,7 @@
|
||||
#include "base/base_inc.c"
|
||||
#include "os/os_inc.c"
|
||||
#include "task_system/task_system.c"
|
||||
#include "raddbgi_make_local/raddbgi_make_local.c"
|
||||
#include "rdi_make_local/rdi_make_local.c"
|
||||
#include "mdesk/mdesk.c"
|
||||
#include "hash_store/hash_store.c"
|
||||
#include "file_stream/file_stream.c"
|
||||
@@ -66,9 +66,9 @@
|
||||
#include "msf/msf.c"
|
||||
#include "pdb/pdb.c"
|
||||
#include "pdb/pdb_stringize.c"
|
||||
#include "raddbgi_from_pdb/raddbgi_from_pdb.c"
|
||||
#include "rdi_from_pdb/rdi_from_pdb.c"
|
||||
#include "regs/regs.c"
|
||||
#include "regs/raddbgi/regs_raddbgi.c"
|
||||
#include "regs/rdi/regs_rdi.c"
|
||||
#include "type_graph/type_graph.c"
|
||||
#include "dbgi/dbgi.c"
|
||||
#include "demon/demon_inc.c"
|
||||
|
||||
@@ -17,6 +17,12 @@ txt_lang_kind_from_extension(String8 extension)
|
||||
str8_match(extension, str8_lit("cxx"), StringMatchFlag_CaseInsensitive) ||
|
||||
str8_match(extension, str8_lit("cc"), StringMatchFlag_CaseInsensitive) ||
|
||||
str8_match(extension, str8_lit("c++"), StringMatchFlag_CaseInsensitive) ||
|
||||
str8_match(extension, str8_lit("ixx"), StringMatchFlag_CaseInsensitive) ||
|
||||
str8_match(extension, str8_lit("cxxm"), StringMatchFlag_CaseInsensitive) ||
|
||||
str8_match(extension, str8_lit("c++m"), StringMatchFlag_CaseInsensitive) ||
|
||||
str8_match(extension, str8_lit("ccm"), StringMatchFlag_CaseInsensitive) ||
|
||||
str8_match(extension, str8_lit("cppm"), StringMatchFlag_CaseInsensitive) ||
|
||||
str8_match(extension, str8_lit("mpp"), StringMatchFlag_CaseInsensitive) ||
|
||||
str8_match(extension, str8_lit("C"), 0) ||
|
||||
str8_match(extension, str8_lit("hpp"), StringMatchFlag_CaseInsensitive) ||
|
||||
str8_match(extension, str8_lit("hxx"), StringMatchFlag_CaseInsensitive) ||
|
||||
|
||||
@@ -1,859 +0,0 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Memory View Helpers
|
||||
|
||||
internal UNW_MemView
|
||||
unw_memview_from_data(String8 data, U64 base_vaddr)
|
||||
{
|
||||
UNW_MemView result = {0};
|
||||
result.data = data.str;
|
||||
result.addr_first = base_vaddr;
|
||||
result.addr_opl = base_vaddr + data.size;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
unw_memview_read(UNW_MemView *memview, U64 addr, U64 size, void *out)
|
||||
{
|
||||
B32 result = 0;
|
||||
if(memview->addr_first <= addr && addr + size <= memview->addr_opl)
|
||||
{
|
||||
MemoryCopy(out, (U8*)memview->data + addr - memview->addr_first, size);
|
||||
result = 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: PE/X64 Unwind Implementation
|
||||
|
||||
//- rjf: helpers
|
||||
|
||||
internal UNW_Step
|
||||
unw_pe_x64__epilog(String8 bindata, PE_BinInfo *bin, U64 base_vaddr, UNW_MemView*memview, REGS_RegBlockX64 *regs)
|
||||
{
|
||||
UNW_Step result = {0};
|
||||
U64 missed_read_addr = 0;
|
||||
|
||||
//- setup parsing context
|
||||
U64 ip_voff = regs->rip.u64 - base_vaddr;
|
||||
U64 sec_number = pe_section_num_from_voff(bindata, bin, ip_voff);
|
||||
COFF_SectionHeader *sec = coff_section_header_from_num(bindata, bin->section_array_off, sec_number);
|
||||
void* inst_base = pe_ptr_from_section_num(bindata, bin, sec_number);
|
||||
U64 inst_size = sec->vsize;
|
||||
|
||||
//- setup parsing variables
|
||||
B32 keep_parsing = 1;
|
||||
U64 off = ip_voff - sec->voff;
|
||||
|
||||
|
||||
//- parsing loop
|
||||
for(;keep_parsing;)
|
||||
{
|
||||
keep_parsing = 0;
|
||||
|
||||
U8 inst_byte = 0;
|
||||
if(off + sizeof(inst_byte) <= inst_size)
|
||||
{
|
||||
void *ptr = (U8*)inst_base + off;
|
||||
MemoryCopy(&inst_byte, ptr, sizeof(inst_byte));
|
||||
}
|
||||
off += 1;
|
||||
|
||||
U8 rex = 0;
|
||||
if((inst_byte & 0xF0) == 0x40)
|
||||
{
|
||||
rex = inst_byte & 0xF; // rex prefix
|
||||
if(off + sizeof(inst_base) <= inst_size)
|
||||
{
|
||||
void *ptr = (U8*)inst_base + off;
|
||||
MemoryCopy(&inst_byte, ptr, sizeof(inst_byte));
|
||||
}
|
||||
off += 1;
|
||||
}
|
||||
|
||||
switch(inst_byte)
|
||||
{
|
||||
// pop
|
||||
case 0x58:
|
||||
case 0x59:
|
||||
case 0x5A:
|
||||
case 0x5B:
|
||||
case 0x5C:
|
||||
case 0x5D:
|
||||
case 0x5E:
|
||||
case 0x5F:
|
||||
{
|
||||
U64 sp = regs->rsp.u64;
|
||||
U64 value = 0;
|
||||
if(!unw_memview_read_struct(memview, sp, &value))
|
||||
{
|
||||
missed_read_addr = sp;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
// modify register
|
||||
PE_UnwindGprRegX64 gpr_reg = (inst_byte - 0x58) + (rex & 1)*8;
|
||||
REGS_Reg64 *reg = unw_pe_x64__gpr_reg(regs, gpr_reg);
|
||||
|
||||
// not a final instruction
|
||||
keep_parsing = 1;
|
||||
|
||||
// commit registers
|
||||
reg->u64 = value;
|
||||
regs->rsp.u64 = sp + 8;
|
||||
}break;
|
||||
|
||||
// add $nnnn,%rsp
|
||||
case 0x81:
|
||||
{
|
||||
// skip one byte (we already know what it is in this scenario)
|
||||
off += 1;
|
||||
|
||||
// read the 4-byte immediate
|
||||
S32 imm = 0;
|
||||
if(off + sizeof(imm) < inst_size)
|
||||
{
|
||||
void *ptr = (U8*)inst_base + off;
|
||||
MemoryCopy(&imm, ptr, sizeof(imm));
|
||||
}
|
||||
off += 4;
|
||||
|
||||
// not a final instruction
|
||||
keep_parsing = 1;
|
||||
|
||||
// update stack pointer
|
||||
regs->rsp.u64 = (U64)(regs->rsp.u64 + imm);
|
||||
}break;
|
||||
|
||||
// add $n,%rsp
|
||||
case 0x83:
|
||||
{
|
||||
// skip one byte (we already know what it is in this scenario)
|
||||
off += 1;
|
||||
|
||||
// read the 1-byte immediate
|
||||
S8 imm = 0;
|
||||
if(off + sizeof(imm) < inst_size)
|
||||
{
|
||||
void *ptr = (U8*)inst_base + off;
|
||||
MemoryCopy(&imm, ptr, sizeof(imm));
|
||||
}
|
||||
off += 1;
|
||||
|
||||
// update stack pointer
|
||||
regs->rsp.u64 = (U64)(regs->rsp.u64 + imm);
|
||||
keep_parsing = 1;
|
||||
}break;
|
||||
|
||||
// lea imm8/imm32,$rsp
|
||||
case 0x8D:
|
||||
{
|
||||
// read source register
|
||||
U8 modrm = 0;
|
||||
if(off + sizeof(modrm) < inst_size)
|
||||
{
|
||||
void *ptr = (U8*)inst_base + off;
|
||||
MemoryCopy(&modrm, ptr, sizeof(modrm));
|
||||
}
|
||||
PE_UnwindGprRegX64 gpr_reg = (modrm & 7) + (rex & 1)*8;
|
||||
REGS_Reg64 *reg = unw_pe_x64__gpr_reg(regs, gpr_reg);
|
||||
U64 reg_value = reg->u64;
|
||||
|
||||
// advance to the immediate
|
||||
off += 1;
|
||||
|
||||
S32 imm = 0;
|
||||
// read 1-byte immediate
|
||||
if((modrm >> 6) == 1)
|
||||
{
|
||||
S8 imm8 = 0;
|
||||
if(off + sizeof(imm8) < inst_size)
|
||||
{
|
||||
void *ptr = (U8*)inst_base + off;
|
||||
MemoryCopy(&imm8, ptr, sizeof(imm8));
|
||||
}
|
||||
imm = imm8;
|
||||
off += 1;
|
||||
}
|
||||
|
||||
// read 4-byte immediate
|
||||
else
|
||||
{
|
||||
if(off + sizeof(imm) < inst_size)
|
||||
{
|
||||
void *ptr = (U8*)inst_base + off;
|
||||
MemoryCopy(&imm, ptr, sizeof(imm));
|
||||
}
|
||||
off += 4;
|
||||
}
|
||||
|
||||
regs->rsp.u64 = (U64)(reg_value + imm);
|
||||
keep_parsing = 1;
|
||||
}break;
|
||||
|
||||
// ret $nn
|
||||
case 0xC2:
|
||||
{
|
||||
// read new ip
|
||||
U64 sp = regs->rsp.u64;
|
||||
U64 new_ip = 0;
|
||||
if(!unw_memview_read_struct(memview, sp, &new_ip))
|
||||
{
|
||||
missed_read_addr = sp;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
// read 2-byte immediate & advance stack pointer
|
||||
U16 imm = 0;
|
||||
if(off + sizeof(imm) < inst_size)
|
||||
{
|
||||
void *ptr = (U8*)inst_base + off;
|
||||
MemoryCopy(&imm, ptr, sizeof(imm));
|
||||
}
|
||||
U64 new_sp = sp + 8 + imm;
|
||||
|
||||
// commit registers
|
||||
regs->rip.u64 = new_ip;
|
||||
regs->rsp.u64 = new_sp;
|
||||
}break;
|
||||
|
||||
// ret / rep; ret
|
||||
case 0xF3:
|
||||
{
|
||||
Assert(!"Hit me!");
|
||||
}
|
||||
case 0xC3:
|
||||
{
|
||||
// read new ip
|
||||
U64 sp = regs->rsp.u64;
|
||||
U64 new_ip = 0;
|
||||
if(!unw_memview_read_struct(memview, sp, &new_ip))
|
||||
{
|
||||
missed_read_addr = sp;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
// advance stack pointer
|
||||
U64 new_sp = sp + 8;
|
||||
|
||||
// commit registers
|
||||
regs->rip.u64 = new_ip;
|
||||
regs->rsp.u64 = new_sp;
|
||||
}break;
|
||||
|
||||
// jmp nnnn
|
||||
case 0xE9:
|
||||
{
|
||||
Assert(!"Hit Me");
|
||||
// TODO(allen): general idea: read the immediate, move the ip, leave the sp, done
|
||||
// we don't have any cases to exercise this right now. no guess implementation!
|
||||
}break;
|
||||
|
||||
// jmp n
|
||||
case 0xEB:
|
||||
{
|
||||
Assert(!"Hit Me");
|
||||
// TODO(allen): general idea: read the immediate, move the ip, leave the sp, done
|
||||
// we don't have any cases to exercise this right now. no guess implementation!
|
||||
}break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
error_out:;
|
||||
|
||||
if(missed_read_addr != 0)
|
||||
{
|
||||
result.dead = 1;
|
||||
result.missed_read = 1;
|
||||
result.missed_read_addr = missed_read_addr;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal B32
|
||||
unw_pe_x64__voff_is_in_epilog(String8 bindata, PE_BinInfo *bin, U64 voff, PE_IntelPdata *final_pdata)
|
||||
{
|
||||
// NOTE(allen): There are restrictions placed on how an epilog is allowed
|
||||
// to be formed (https://docs.microsoft.com/en-us/cpp/build/prolog-and-epilog?view=msvc-160)
|
||||
// Here we interpret machine code directly according to the rules
|
||||
// given there to determine if the code we're looking at looks like an epilog.
|
||||
|
||||
// TODO(allen): Figure out how to verify this.
|
||||
|
||||
//- setup parsing context
|
||||
U64 sec_number = pe_section_num_from_voff(bindata, bin, voff);
|
||||
COFF_SectionHeader *sec = coff_section_header_from_num(bindata, bin->section_array_off, sec_number);
|
||||
void* inst_base = pe_ptr_from_section_num(bindata, bin, sec_number);
|
||||
U64 inst_size = sec->vsize;
|
||||
|
||||
//- setup parsing variables
|
||||
B32 is_epilog = 0;
|
||||
B32 keep_parsing = 1;
|
||||
U64 off = voff - sec->voff;
|
||||
|
||||
//- check first instruction
|
||||
{
|
||||
B32 inst_read_success = 0;
|
||||
U8 inst[4];
|
||||
if (off + sizeof(inst) < inst_size){
|
||||
void *ptr = (U8*)inst_base + off;
|
||||
MemoryCopy(&inst, ptr, sizeof(inst));
|
||||
inst_read_success = 1;
|
||||
}
|
||||
|
||||
if (!inst_read_success){
|
||||
keep_parsing = 0;
|
||||
}
|
||||
else{
|
||||
if ((inst[0] & 0xF8) == 0x48){
|
||||
switch (inst[1]){
|
||||
// add $nnnn,%rsp
|
||||
case 0x81:
|
||||
{
|
||||
if (inst[0] == 0x48 && inst[2] == 0xC4){
|
||||
off += 7;
|
||||
}
|
||||
else{
|
||||
keep_parsing = 0;
|
||||
}
|
||||
}break;
|
||||
|
||||
// add $n,%rsp
|
||||
case 0x83:
|
||||
{
|
||||
if (inst[0] == 0x48 && inst[2] == 0xC4){
|
||||
off += 4;
|
||||
}
|
||||
else{
|
||||
keep_parsing = 0;
|
||||
}
|
||||
}break;
|
||||
|
||||
// lea n(reg),%rsp
|
||||
case 0x8D:
|
||||
{
|
||||
if ((inst[0] & 0x06) == 0 &&
|
||||
((inst[2] >> 3) & 0x07) == 0x04 &&
|
||||
(inst[2] & 0x07) != 0x04){
|
||||
U8 imm_size = (inst[2] >> 6);
|
||||
// 1-byte immediate
|
||||
if (imm_size == 1){
|
||||
off += 4;
|
||||
}
|
||||
// 4-byte immediate
|
||||
else if (imm_size == 2){
|
||||
off += 7;
|
||||
}
|
||||
else{
|
||||
keep_parsing = 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
keep_parsing = 0;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- parsing loop
|
||||
if (keep_parsing){
|
||||
for (;;){
|
||||
// read inst
|
||||
U8 inst_byte = 0;
|
||||
if (off + sizeof(inst_byte) < inst_size){
|
||||
void *ptr = (U8*)inst_base + off;
|
||||
MemoryCopy(&inst_byte, ptr, sizeof(inst_byte));
|
||||
}
|
||||
else{
|
||||
goto loop_break;
|
||||
}
|
||||
|
||||
// when (... I don't know ...) rely on the next byte
|
||||
U64 check_off = off;
|
||||
U8 check_inst_byte = inst_byte;
|
||||
if ((inst_byte & 0xF0) == 0x40){
|
||||
check_off = off + 1;
|
||||
if (off + sizeof(check_inst_byte) < inst_size){
|
||||
void *ptr = (U8*)inst_base + off;
|
||||
MemoryCopy(&check_inst_byte, ptr, sizeof(check_inst_byte));
|
||||
}
|
||||
else{
|
||||
goto loop_break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (check_inst_byte){
|
||||
// pop
|
||||
case 0x58:case 0x59:case 0x5A:case 0x5B:
|
||||
case 0x5C:case 0x5D:case 0x5E:case 0x5F:
|
||||
{
|
||||
off = check_off + 1;
|
||||
}break;
|
||||
|
||||
// ret
|
||||
case 0xC2:case 0xC3:
|
||||
{
|
||||
is_epilog = 1;
|
||||
goto loop_break;
|
||||
}break;
|
||||
|
||||
// jmp nnnn
|
||||
case 0xE9:
|
||||
{
|
||||
U64 imm_off = check_off + 1;
|
||||
S32 imm = 0;
|
||||
if (off + sizeof(imm) < inst_size){
|
||||
void *ptr = (U8*)inst_base + off;
|
||||
MemoryCopy(&imm, ptr, sizeof(imm));
|
||||
}
|
||||
else{
|
||||
goto loop_break;
|
||||
}
|
||||
|
||||
U64 next_off = (U64)(imm_off + sizeof(imm) + imm);
|
||||
if (!(final_pdata->voff_first <= next_off && next_off < final_pdata->voff_one_past_last)){
|
||||
goto loop_break;
|
||||
}
|
||||
|
||||
off = next_off;
|
||||
// TODO(allen): why isn't this just the end of the epilog?
|
||||
}break;
|
||||
|
||||
// rep; ret (for amd64 prediction bug)
|
||||
case 0xF3:
|
||||
{
|
||||
U8 next_inst_byte = 0;
|
||||
if (off + sizeof(next_inst_byte) < inst_size){
|
||||
void *ptr = (U8*)inst_base + off;
|
||||
MemoryCopy(&next_inst_byte, ptr, sizeof(next_inst_byte));
|
||||
}
|
||||
is_epilog = (next_inst_byte == 0xC3);
|
||||
goto loop_break;
|
||||
}break;
|
||||
|
||||
default: goto loop_break;
|
||||
}
|
||||
}
|
||||
|
||||
loop_break:;
|
||||
}
|
||||
|
||||
//- fill result
|
||||
B32 result = is_epilog;
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal REGS_Reg64*
|
||||
unw_pe_x64__gpr_reg(REGS_RegBlockX64 *regs, PE_UnwindGprRegX64 unw_reg){
|
||||
static REGS_Reg64 dummy = {0};
|
||||
REGS_Reg64 *result = &dummy;
|
||||
switch (unw_reg){
|
||||
case PE_UnwindGprRegX64_RAX: result = ®s->rax; break;
|
||||
case PE_UnwindGprRegX64_RCX: result = ®s->rcx; break;
|
||||
case PE_UnwindGprRegX64_RDX: result = ®s->rdx; break;
|
||||
case PE_UnwindGprRegX64_RBX: result = ®s->rbx; break;
|
||||
case PE_UnwindGprRegX64_RSP: result = ®s->rsp; break;
|
||||
case PE_UnwindGprRegX64_RBP: result = ®s->rbp; break;
|
||||
case PE_UnwindGprRegX64_RSI: result = ®s->rsi; break;
|
||||
case PE_UnwindGprRegX64_RDI: result = ®s->rdi; break;
|
||||
case PE_UnwindGprRegX64_R8 : result = ®s->r8 ; break;
|
||||
case PE_UnwindGprRegX64_R9 : result = ®s->r9 ; break;
|
||||
case PE_UnwindGprRegX64_R10: result = ®s->r10; break;
|
||||
case PE_UnwindGprRegX64_R11: result = ®s->r11; break;
|
||||
case PE_UnwindGprRegX64_R12: result = ®s->r12; break;
|
||||
case PE_UnwindGprRegX64_R13: result = ®s->r13; break;
|
||||
case PE_UnwindGprRegX64_R14: result = ®s->r14; break;
|
||||
case PE_UnwindGprRegX64_R15: result = ®s->r15; break;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
//- rjf: unwind step
|
||||
|
||||
internal UNW_Step
|
||||
unw_unwind_pe_x64(String8 bindata, PE_BinInfo *bin, U64 base_vaddr, UNW_MemView *memview, REGS_RegBlockX64 *regs)
|
||||
{
|
||||
UNW_Step result = {0};
|
||||
U64 missed_read_addr = 0;
|
||||
|
||||
//- grab ip_voff (several places can use this)
|
||||
U64 ip_voff = regs->rip.u64 - base_vaddr;
|
||||
|
||||
//- get pdata entry from current ip
|
||||
PE_IntelPdata *initial_pdata = 0;
|
||||
{
|
||||
U64 initial_pdata_off = pe_intel_pdata_off_from_voff__binary_search(bindata, bin, ip_voff);
|
||||
if(initial_pdata_off != 0)
|
||||
{
|
||||
initial_pdata = (PE_IntelPdata*)(bindata.str + initial_pdata_off);
|
||||
}
|
||||
}
|
||||
|
||||
//- no pdata; unwind by reading stack pointer
|
||||
if(initial_pdata == 0)
|
||||
{
|
||||
// read ip from stack pointer
|
||||
U64 sp = regs->rsp.u64;
|
||||
U64 new_ip = 0;
|
||||
if(!unw_memview_read_struct(memview, sp, &new_ip))
|
||||
{
|
||||
missed_read_addr = sp;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
// advance stack pointer
|
||||
U64 new_sp = sp + 8;
|
||||
|
||||
// commit registers
|
||||
regs->rip.u64 = new_ip;
|
||||
regs->rsp.u64 = new_sp;
|
||||
}
|
||||
|
||||
//- got pdata; perform unwinding with exception handling
|
||||
else
|
||||
{
|
||||
// try epilog unwind
|
||||
B32 did_epilog_unwind = 0;
|
||||
if(unw_pe_x64__voff_is_in_epilog(bindata, bin, ip_voff, initial_pdata))
|
||||
{
|
||||
result = unw_pe_x64__epilog(bindata, bin, base_vaddr, memview, regs);
|
||||
did_epilog_unwind = 1;
|
||||
}
|
||||
|
||||
// try xdata unwind
|
||||
if(!did_epilog_unwind)
|
||||
{
|
||||
B32 did_machframe = 0;
|
||||
|
||||
// get frame reg
|
||||
REGS_Reg64 *frame_reg = 0;
|
||||
U64 frame_off = 0;
|
||||
|
||||
{
|
||||
U64 unwind_info_off = initial_pdata->voff_unwind_info;
|
||||
PE_UnwindInfo *unwind_info = (PE_UnwindInfo*)(pe_ptr_from_voff(bindata, bin, unwind_info_off));
|
||||
|
||||
U32 frame_reg_id = PE_UNWIND_INFO_REG_FROM_FRAME(unwind_info->frame);
|
||||
U64 frame_off_val = PE_UNWIND_INFO_OFF_FROM_FRAME(unwind_info->frame);
|
||||
|
||||
if (frame_reg_id != 0){
|
||||
frame_reg = unw_pe_x64__gpr_reg(regs, frame_reg_id);
|
||||
// TODO(allen): at this point if frame_reg is zero, the exe is corrupted.
|
||||
}
|
||||
frame_off = frame_off_val;
|
||||
}
|
||||
|
||||
PE_IntelPdata *last_pdata = 0;
|
||||
PE_IntelPdata *pdata = initial_pdata;
|
||||
for (;pdata != last_pdata;)
|
||||
{
|
||||
//- rjf: unpack unwind info & codes
|
||||
U64 unwind_info_off = pdata->voff_unwind_info;
|
||||
PE_UnwindInfo *unwind_info = (PE_UnwindInfo*)(pe_ptr_from_voff(bindata, bin, unwind_info_off));
|
||||
PE_UnwindCode *unwind_codes = (PE_UnwindCode*)(unwind_info + 1);
|
||||
|
||||
//- rjf: unpack frame base
|
||||
U64 frame_base = regs->rsp.u64;
|
||||
if(frame_reg != 0)
|
||||
{
|
||||
U64 raw_frame_base = frame_reg->u64;
|
||||
U64 adjusted_frame_base = raw_frame_base - frame_off*16;
|
||||
if(adjusted_frame_base < raw_frame_base)
|
||||
{
|
||||
frame_base = adjusted_frame_base;
|
||||
}
|
||||
else
|
||||
{
|
||||
frame_base = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: bad unwind info -> abort
|
||||
if(unwind_info == 0)
|
||||
{
|
||||
result.dead = 1;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
//- op code interpreter
|
||||
PE_UnwindCode *code_ptr = unwind_codes;
|
||||
PE_UnwindCode *code_opl = unwind_codes + unwind_info->codes_num;
|
||||
for(PE_UnwindCode *next_code_ptr = 0; code_ptr < code_opl; code_ptr = next_code_ptr)
|
||||
{
|
||||
// extract op code parts
|
||||
U32 op_code = PE_UNWIND_OPCODE_FROM_FLAGS(code_ptr->flags);
|
||||
U32 op_info = PE_UNWIND_INFO_FROM_FLAGS(code_ptr->flags);
|
||||
|
||||
// determine number of op code slots
|
||||
U32 slot_count = pe_slot_count_from_unwind_op_code(op_code);
|
||||
if(op_code == PE_UnwindOpCode_ALLOC_LARGE && op_info == 1)
|
||||
{
|
||||
slot_count += 1;
|
||||
}
|
||||
|
||||
// check op code slot count
|
||||
if (slot_count == 0 || code_ptr + slot_count > code_opl){
|
||||
result.dead = 1;
|
||||
goto end_xdata_unwind;
|
||||
}
|
||||
|
||||
// set next op code pointer
|
||||
next_code_ptr = code_ptr + slot_count;
|
||||
|
||||
// interpret this op code
|
||||
U64 code_voff = pdata->voff_first + code_ptr->off_in_prolog;
|
||||
if (code_voff <= ip_voff){
|
||||
switch (op_code){
|
||||
case PE_UnwindOpCode_PUSH_NONVOL:
|
||||
{
|
||||
// read value from stack pointer
|
||||
U64 sp = regs->rsp.u64;
|
||||
U64 value = 0;
|
||||
if(!unw_memview_read_struct(memview, sp, &value))
|
||||
{
|
||||
missed_read_addr = sp;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
// advance stack pointer
|
||||
U64 new_sp = sp + 8;
|
||||
|
||||
// commit registers
|
||||
REGS_Reg64 *reg = unw_pe_x64__gpr_reg(regs, op_info);
|
||||
reg->u64 = value;
|
||||
regs->rsp.u64 = new_sp;
|
||||
}break;
|
||||
|
||||
case PE_UnwindOpCode_ALLOC_LARGE:
|
||||
{
|
||||
// read alloc size
|
||||
U64 size = 0;
|
||||
if (op_info == 0){
|
||||
size = code_ptr[1].u16*8;
|
||||
}
|
||||
else if (op_info == 1){
|
||||
size = code_ptr[1].u16 + ((U32)code_ptr[2].u16 << 16);
|
||||
}
|
||||
else{
|
||||
result.dead = 1;
|
||||
goto end_xdata_unwind;
|
||||
}
|
||||
|
||||
// advance stack pointer
|
||||
U64 sp = regs->rsp.u64;
|
||||
U64 new_sp = sp + size;
|
||||
|
||||
// advance stack pointer
|
||||
regs->rsp.u64 = new_sp;
|
||||
}break;
|
||||
|
||||
case PE_UnwindOpCode_ALLOC_SMALL:
|
||||
{
|
||||
// advance stack pointer
|
||||
regs->rsp.u64 += op_info*8 + 8;
|
||||
}break;
|
||||
|
||||
case PE_UnwindOpCode_SET_FPREG:
|
||||
{
|
||||
// put stack pointer back to the frame base
|
||||
regs->rsp.u64 = frame_base;
|
||||
}break;
|
||||
|
||||
case PE_UnwindOpCode_SAVE_NONVOL:
|
||||
{
|
||||
// read value from frame base
|
||||
U64 off = code_ptr[1].u16*8;
|
||||
U64 addr = frame_base + off;
|
||||
U64 value = 0;
|
||||
if (!unw_memview_read_struct(memview, addr, &value)){
|
||||
missed_read_addr = addr;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
// commit to register
|
||||
REGS_Reg64 *reg = unw_pe_x64__gpr_reg(regs, op_info);
|
||||
reg->u64 = value;
|
||||
}break;
|
||||
|
||||
case PE_UnwindOpCode_SAVE_NONVOL_FAR:
|
||||
{
|
||||
// read value from frame base
|
||||
U64 off = code_ptr[1].u16 + ((U32)code_ptr[2].u16 << 16);
|
||||
U64 addr = frame_base + off;
|
||||
U64 value = 0;
|
||||
if (!unw_memview_read_struct(memview, addr, &value)){
|
||||
missed_read_addr = addr;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
// commit to register
|
||||
REGS_Reg64 *reg = unw_pe_x64__gpr_reg(regs, op_info);
|
||||
reg->u64 = value;
|
||||
}break;
|
||||
|
||||
case PE_UnwindOpCode_EPILOG:
|
||||
{
|
||||
result.dead = 1;
|
||||
}break;
|
||||
|
||||
case PE_UnwindOpCode_SPARE_CODE:
|
||||
{
|
||||
result.dead = 1;
|
||||
// Assert(!"Hit me!");
|
||||
// TODO(allen): ???
|
||||
}break;
|
||||
|
||||
case PE_UnwindOpCode_SAVE_XMM128:
|
||||
{
|
||||
// read new register values
|
||||
U8 buf[16];
|
||||
U64 off = code_ptr[1].u16*16;
|
||||
U64 addr = frame_base + off;
|
||||
if (!unw_memview_read(memview, addr, 16, buf)){
|
||||
missed_read_addr = addr;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
// commit to register
|
||||
void *xmm_reg = (®s->ymm0) + op_info;
|
||||
MemoryCopy(xmm_reg, buf, sizeof(buf));
|
||||
}break;
|
||||
|
||||
case PE_UnwindOpCode_SAVE_XMM128_FAR:
|
||||
{
|
||||
// read new register values
|
||||
U8 buf[16];
|
||||
U64 off = code_ptr[1].u16 + ((U32)code_ptr[2].u16 << 16);
|
||||
U64 addr = frame_base + off;
|
||||
if (!unw_memview_read(memview, addr, 16, buf)){
|
||||
missed_read_addr = addr;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
// commit to register
|
||||
void *xmm_reg = (®s->ymm0) + op_info;
|
||||
MemoryCopy(xmm_reg, buf, sizeof(buf));
|
||||
}break;
|
||||
|
||||
case PE_UnwindOpCode_PUSH_MACHFRAME:
|
||||
{
|
||||
// NOTE(rjf): this was found by stepping through kernel code after an exception was
|
||||
// thrown, encountered in the exception_stepping_tests (after the throw) in mule_main
|
||||
|
||||
if(op_info > 1)
|
||||
{
|
||||
result.dead = 1;
|
||||
goto end_xdata_unwind;
|
||||
}
|
||||
|
||||
// read values
|
||||
U64 sp_og = regs->rsp.u64;
|
||||
U64 sp_adj = sp_og;
|
||||
if(op_info == 1)
|
||||
{
|
||||
sp_adj += 8;
|
||||
}
|
||||
|
||||
U64 ip_value = 0;
|
||||
if(!unw_memview_read_struct(memview, sp_adj, &ip_value))
|
||||
{
|
||||
missed_read_addr = sp_adj;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
U64 sp_after_ip = sp_adj + 8;
|
||||
U16 ss_value = 0;
|
||||
if(!unw_memview_read_struct(memview, sp_after_ip, &ss_value))
|
||||
{
|
||||
missed_read_addr = sp_after_ip;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
U64 sp_after_ss = sp_after_ip + 8;
|
||||
U64 rflags_value = 0;
|
||||
if(!unw_memview_read_struct(memview, sp_after_ss, &rflags_value))
|
||||
{
|
||||
missed_read_addr = sp_after_ss;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
U64 sp_after_rflags = sp_after_ss + 8;
|
||||
U64 sp_value = 0;
|
||||
if(!unw_memview_read_struct(memview, sp_after_rflags, &sp_value))
|
||||
{
|
||||
missed_read_addr = sp_after_rflags;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
// commit registers
|
||||
regs->rip.u64 = ip_value;
|
||||
regs->ss.u16 = ss_value;
|
||||
regs->rflags.u64 = rflags_value;
|
||||
regs->rsp.u64 = sp_value;
|
||||
|
||||
// mark machine frame
|
||||
did_machframe = 1;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- iterate pdata chain
|
||||
U32 flags = PE_UNWIND_INFO_FLAGS_FROM_HDR(unwind_info->header);
|
||||
if (!(flags & PE_UnwindInfoFlag_CHAINED)){
|
||||
break;
|
||||
}
|
||||
|
||||
U64 code_count_rounded = AlignPow2(unwind_info->codes_num, sizeof(PE_UnwindCode));
|
||||
U64 code_size = code_count_rounded*sizeof(PE_UnwindCode);
|
||||
U64 chained_pdata_off = unwind_info_off + sizeof(PE_UnwindInfo) + code_size;
|
||||
|
||||
last_pdata = pdata;
|
||||
pdata = (PE_IntelPdata*)pe_ptr_from_voff(bindata, bin, chained_pdata_off);
|
||||
}
|
||||
|
||||
if(!did_machframe)
|
||||
{
|
||||
U64 sp = regs->rsp.u64;
|
||||
U64 new_ip = 0;
|
||||
if(!unw_memview_read_struct(memview, sp, &new_ip))
|
||||
{
|
||||
missed_read_addr = sp;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
// advance stack pointer
|
||||
U64 new_sp = sp + 8;
|
||||
|
||||
// commit registers
|
||||
regs->rip.u64 = new_ip;
|
||||
regs->rsp.u64 = new_sp;
|
||||
}
|
||||
|
||||
end_xdata_unwind:;
|
||||
}
|
||||
}
|
||||
|
||||
error_out:;
|
||||
|
||||
if(missed_read_addr != 0)
|
||||
{
|
||||
result.dead = 1;
|
||||
result.missed_read = 1;
|
||||
result.missed_read_addr = missed_read_addr;
|
||||
}
|
||||
|
||||
if(!result.dead)
|
||||
{
|
||||
result.stack_pointer = regs->rsp.u64;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef UNWIND_H
|
||||
#define UNWIND_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Memory View Types
|
||||
//
|
||||
// Memory views are used to provide a slice (or, in the future, slices) of data
|
||||
// required to do a proper unwind. This is generally a very small region in an
|
||||
// address space, generally some things on the stack. But, some formats don't
|
||||
// restrict this in an organized way, and so theoretically you might have some
|
||||
// unwind information require arbitrary reads at an unknown address. So this
|
||||
// "memory view" concept serves as kind of a "stand-in" for "provided memory
|
||||
// info from the user". This keeps the control flow of this layer simpler, so
|
||||
// we aren't calling a user-supplied hook to read memory or anything like that.
|
||||
|
||||
typedef struct UNW_MemView UNW_MemView;
|
||||
struct UNW_MemView
|
||||
{
|
||||
// Upgrade Path:
|
||||
// 1. A list of ranges like this one
|
||||
// 2. Binary-searchable list of ranges
|
||||
// 3. In-line growth strategy for missing pages (hardwired to source of new data)
|
||||
// 4. Abstracted source of new data
|
||||
void *data;
|
||||
U64 addr_first;
|
||||
U64 addr_opl;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Unwind Step Results
|
||||
|
||||
typedef struct UNW_Step UNW_Step;
|
||||
struct UNW_Step
|
||||
{
|
||||
B32 dead;
|
||||
B32 missed_read;
|
||||
U64 missed_read_addr;
|
||||
U64 stack_pointer;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Memory View Helpers
|
||||
|
||||
internal UNW_MemView unw_memview_from_data(String8 data, U64 base_vaddr);
|
||||
internal B32 unw_memview_read(UNW_MemView *memview, U64 addr, U64 size, void *out);
|
||||
#define unw_memview_read_struct(v,addr,p) unw_memview_read((v), (addr), sizeof(*(p)), (p))
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: PE/X64 Unwind Implementation
|
||||
|
||||
//- rjf: helpers
|
||||
internal UNW_Step unw_pe_x64__epilog(String8 bindata, PE_BinInfo *bin, U64 base_vaddr, UNW_MemView *memview, REGS_RegBlockX64 *regs_inout);
|
||||
internal B32 unw_pe_x64__voff_is_in_epilog(String8 bindata, PE_BinInfo *bin, U64 voff, PE_IntelPdata *final_pdata);
|
||||
internal REGS_Reg64 *unw_pe_x64__gpr_reg(REGS_RegBlockX64 *regs, PE_UnwindGprRegX64 unw_reg);
|
||||
|
||||
//- rjf: unwind step
|
||||
internal UNW_Step unw_unwind_pe_x64(String8 bindata, PE_BinInfo *bin, U64 base_vaddr, UNW_MemView *memview, REGS_RegBlockX64 *regs_inout);
|
||||
|
||||
#endif // UNWIND_H
|
||||
Reference in New Issue
Block a user