Merge remote-tracking branch 'gingerbill/master' into odin

# Conflicts:
#	src/df/core/df_core.mdesk
#	src/df/core/generated/df_core.meta.c
#	src/df/core/generated/df_core.meta.h
#	src/df/gfx/df_gfx.c
#	src/df/gfx/df_view_rule_hooks.c
#	src/font_cache/font_cache.c
#	src/txti/txti.c
#	src/txti/txti.h
This commit is contained in:
2024-03-30 13:02:37 -04:00
214 changed files with 32941 additions and 31715 deletions
+8 -6
View File
@@ -20,9 +20,11 @@ jobs:
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
call build raddbg msvc debug || exit /b 1
call build raddbg_from_pdb msvc debug || exit /b 1
call build raddbg_from_dwarf msvc debug || exit /b 1
call build raddbg clang debug || exit /b 1
call build raddbg_from_pdb clang debug || exit /b 1
call build raddbg_from_dwarf clang debug || exit /b 1
call build raddbg msvc debug || exit /b 1
call build raddbgi_from_pdb msvc debug || exit /b 1
call build raddbgi_from_dwarf msvc debug || exit /b 1
call build raddbgi_dump msvc debug || exit /b 1
call build raddbg clang debug || exit /b 1
call build raddbgi_from_pdb clang debug || exit /b 1
call build raddbgi_from_dwarf clang debug || exit /b 1
call build raddbgi_dump clang debug || exit /b 1
+51 -28
View File
@@ -1,5 +1,11 @@
# The RAD Debugger Project
_**Note:** This README does not document usage instructions and tips for the
debugger itself, and is intended as a technical overview of the project. The
debugger's README, which includes usage instructions and tips, can be found
packaged along with debugger releases, or within the `build` folder after a
local copy has been built._
The RAD Debugger is a native, user-mode, multi-process, graphical debugger. It
currently only supports local-machine Windows x64 debugging with PDBs, with
plans to expand and port in the future. In the future we'll expand to also
@@ -15,22 +21,25 @@ You can download pre-built binaries for the debugger
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 RADDBG debug info format, which is what the debugger parses and uses. To
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 RADDBG format on-demand. This conversion process
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.
The RADDBG format is currently specified in code, in the files within the
`src/raddbg_format` folder. The other relevant folders for working with the
format are:
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:
- `raddbg_cons`: The RADDBG construction layer, for constructing RADDBG files.
- `raddbg_convert`: Our implementation of PDB-to-RADDBG (and an in-progress
implementation of a DWARF-to-RADDBG) conversion.
- `raddbg_dump`: Code for textually dumping information from RADDBG files.
- `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.
## Development Setup Instructions
@@ -119,13 +128,13 @@ 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-RADDBG converter is an unoptimized reference implementation, and (b) the
debugger learns of new modules (and thus which PDBs to load) in a
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 RADDBGs before the debugger knows those PDBs are needed, thus ensuring the
associated RADDBG files are ready instantaneously when the associated modules
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.
@@ -145,9 +154,9 @@ The major parts of this phase are:
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-RADDBG converter (in the same way that we've built a PDB-
to-RADDBG converter). A partial implementation of this is in
`src/raddbg_convert/dwarf`.
- 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`.
- 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
@@ -206,10 +215,16 @@ Layers depend on other layers, but circular dependencies would break the
separability and isolation utility of layers (in effect, forming one big layer),
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`.
A list of the layers in the codebase and their associated namespaces is below:
- `base` (no namespace): Universal, codebase-wide constructs. Strings, math,
memory allocators, helper macros, command-line parsing, and so on. Depends
on no other codebase layers.
- `codeview` (`CV_`): Code for parsing and/or writing the CodeView format.
- `coff` (`COFF_`): Code for parsing and/or writing the COFF (Common Object File
Format) file format.
- `ctrl` (`CTRL_`): The debugger's "control system" layer. Implements
@@ -221,10 +236,10 @@ A list of the layers in the codebase and their associated namespaces is below:
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 RADDBG format. Users ask for debug info for a particular
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 RADDBG format.
convert original debug info into the RADDBGI 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`.
@@ -256,6 +271,16 @@ A list of the layers in the codebase and their associated namespaces is below:
for asynchronously preparing data for memory visualization in the debugger.
- `hash_store` (`HS_`): Implements a cache for general data blobs, keyed by a
128-bit hash of the data. Used as a general data store by other layers.
- `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
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.
- `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
@@ -270,6 +295,7 @@ A list of the layers in the codebase and their associated namespaces is below:
duplicate version of `base` and `os` are included in this layer. They are
updated manually, as needed. This is to ensure the stability of the
metaprogram.
- `msf` (`MSF_`): Code for parsing and/or writing the MSF file format.
- `mule` (no namespace): Test executables for battle testing debugger
functionality.
- `natvis` (no namespace): NatVis files for type visualization of the codebase's
@@ -283,20 +309,17 @@ A list of the layers in the codebase and their associated namespaces is below:
- `os/socket` (`OS_`): An abstraction layer, building on `os/core`, providing
networking operating system features under an abstract API, which is
implemented per-target-operating-system.
- `pdb` (`PDB_`): Code for parsing and/or writing the PDB file format.
- `pe` (`PE_`): Code for parsing and/or writing the PE (Portable Executable)
file format.
- `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.
- `raddbg_cons` (`CONS_`): Implements an API for constructing files of the
RADDBG debug info file format.
- `raddbg_dump` (`DUMP_`): A dumper utility program for dumping textualizations
of RADDBG debug info files.
- `raddbg_format` (`RADDBG_`): Standalone types and helper functions for the
RADDBG debug info file format. Does not depend on `base`.
- `raddbg_markup` (`RADDBG_`): Standalone header file for marking up user
programs to work with various features in the `raddbg` debugger. Does not
depend on `base`.
- `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.
- `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.
@@ -315,7 +338,7 @@ 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
RADDBG debug info files, with the additional capability of constructing
RADDBGI 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
+17 -18
View File
@@ -15,7 +15,7 @@ cd /D "%~dp0"
:: `build raddbg clang`
:: `build raddbg release`
:: `build raddbg asan telemetry`
:: `build raddbg_from_pdb`
:: `build raddbgi_from_pdb`
::
:: For a full list of possible build targets and their build command lines,
:: search for @build_targets in this file.
@@ -43,18 +43,16 @@ if "%asan%"=="1" set auto_compile_flags=%auto_compile_flags% -fsanitize=add
:: --- Compile/Link Line Definitions ------------------------------------------
set cl_common= /I..\src\ /I..\local\ /nologo /FC /Z7
set clang_common= -I..\src\ -I..\local\ -gcodeview -fdiagnostics-absolute-paths -Wall -Wno-unknown-warning-option -Wno-missing-braces -Wno-unused-function -Wno-writable-strings -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-register -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion -Xclang -flto-visibility-public-std -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf
set cl_debug= call cl /Od %cl_common% %auto_compile_flags%
set cl_release= call cl /O2 /DNDEBUG %cl_common% %auto_compile_flags%
set clang_debug= call clang -g -O0 %clang_common% %auto_compile_flags%
set clang_release= call clang -g -O2 -DNDEBUG %clang_common% %auto_compile_flags%
set cl_debug= call cl /Od /DBUILD_DEBUG=1 %cl_common% %auto_compile_flags%
set cl_release= call cl /O2 /DBUILD_DEBUG=0 %cl_common% %auto_compile_flags%
set clang_debug= call clang -g -O0 -DBUILD_DEBUG=1 %clang_common% %auto_compile_flags%
set clang_release= call clang -g -O2 -DBUILD_DEBUG=0 %clang_common% %auto_compile_flags%
set cl_link= /link /MANIFEST:EMBED /INCREMENTAL:NO /natvis:"%~dp0\src\natvis\base.natvis" logo.res
set clang_link= -fuse-ld=lld -Xlinker /MANIFEST:EMBED -Xlinker /natvis:"%~dp0\src\natvis\base.natvis" logo.res
set cl_out= /out:
set clang_out= -o
:: --- Per-Build Settings -----------------------------------------------------
set gfx=-DOS_FEATURE_GRAPHICAL=1
set net=-DOS_FEATURE_SOCKET=1
set link_dll=-DLL
if "%msvc%"=="1" set only_compile=/c
if "%clang%"=="1" set only_compile=-c
@@ -85,7 +83,7 @@ pushd build
popd
:: --- Get Current Git Commit Id ----------------------------------------------
for /f %%i in ('call git describe --always --dirty') do set compile=%compile% -DRADDBG_GIT=\"%%i\"
for /f %%i in ('call git describe --always --dirty') do set compile=%compile% -DBUILD_GIT_HASH=\"%%i\"
:: --- Build & Run Metaprogram ------------------------------------------------
if "%no_meta%"=="1" echo [skipping metagen]
@@ -98,16 +96,17 @@ 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 "%raddbg_from_pdb%"=="1" %compile% ..\src\raddbg_convert\pdb\raddbg_from_pdb_main.c %compile_link% %out%raddbg_from_pdb.exe || exit /b 1
if "%raddbg_from_dwarf%"=="1" %compile% ..\src\raddbg_convert\dwarf\raddbg_from_dwarf.c %compile_link% %out%raddbg_from_dwarf.exe || exit /b 1
if "%raddbg_dump%"=="1" %compile% ..\src\raddbg_dump\raddbg_dump.c %compile_link% %out%raddbg_dump.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_module%"=="1" %compile% ..\src\mule\mule_module.cpp %compile_link% %link_dll% %out%mule_module.dll || exit /b 1
if "%mule_hotload%"=="1" %compile% ..\src\mule\mule_hotload_main.c %compile_link% %out%mule_hotload.exe & %compile% ..\src\mule\mule_hotload_module_main.c %compile_link% %link_dll% %out%mule_hotload_module.dll || exit /b 1
if "%raddbg%"=="1" %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 "%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_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
popd
:: --- Unset ------------------------------------------------------------------
+34 -5
View File
@@ -56,7 +56,7 @@ commands =
},
.rjf_f2 =
{
.win = "build raddbg_from_pdb",
.win = "build raddbgi_from_pdb telemetry release",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
@@ -72,6 +72,24 @@ commands =
.save_dirty_files = true,
.cursor_at_end = false,
},
.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",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
.save_dirty_files = true,
.cursor_at_end = false,
},
.rjf_f5 =
{
.win = "pushd build && raddbgi_from_pdb.exe --exe:raddbg.exe --pdb:raddbg.pdb --out:raddbg.raddbg --capture && popd",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
.save_dirty_files = true,
.cursor_at_end = false,
},
.build_raddbg =
{
.win = "build raddbg",
@@ -90,18 +108,18 @@ commands =
.save_dirty_files = true,
.cursor_at_end = false,
},
.build_raddbg_from_pdb =
.build_raddbgi_from_pdb =
{
.win = "build raddbg_from_pdb",
.win = "build raddbgi_from_pdb",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
.save_dirty_files = true,
.cursor_at_end = false,
},
.build_raddbg_dump =
.build_raddbgi_dump =
{
.win = "build raddbg_dump",
.win = "build raddbgi_dump",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
@@ -117,6 +135,15 @@ commands =
.save_dirty_files = true,
.cursor_at_end = false,
},
.build_ryan_scratch =
{
.win = "build ryan_scratch",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
.save_dirty_files = true,
.cursor_at_end = false,
},
.run_raddbg =
{
.win = "pushd build && raddbg.exe && popd",
@@ -141,5 +168,7 @@ fkey_command_override =
.F1 = "rjf_f1",
.F2 = "rjf_f2",
.F3 = "rjf_f3",
.F4 = "rjf_f4",
.F5 = "rjf_f5",
},
};
-13
View File
@@ -55,9 +55,6 @@ arena_alloc__sized(U64 init_res, U64 init_cmt)
arena->cmt = cmt;
arena->res = res;
arena->align = 8;
#if ENABLE_DEV
arena->dev = 0;
#endif
arena->grow = 1;
arena->large_pages = large_pages;
}
@@ -209,10 +206,6 @@ arena_pop_to(Arena *arena, U64 big_pos_unclamped)
internal void
arena_absorb(Arena *arena, Arena *sub)
{
#if ENABLE_DEV
arena_annotate_absorb__dev(arena, sub);
#endif
// base adjustment
Arena *current = arena->current;
U64 base_adjust = current->base_pos + current->res;
@@ -233,9 +226,6 @@ internal void *
arena_push(Arena *arena, U64 size)
{
void *memory = arena_push__impl(arena, size);
#if ENABLE_DEV
arena_annotate_push__dev(arena, size, memory);
#endif
return memory;
}
@@ -246,9 +236,6 @@ arena_push_contiguous(Arena *arena, U64 size)
arena->grow = 0;
void *memory = arena_push(arena, size);
arena->grow = restore;
#if ENABLE_DEV
arena_annotate_push__dev(arena, size, memory);
#endif
return memory;
}
+1 -8
View File
@@ -36,7 +36,6 @@ struct Arena
U64 cmt;
U64 res;
U64 align;
struct ArenaDev *dev;
B8 grow;
B8 large_pages;
};
@@ -82,13 +81,7 @@ internal B32 ensure_commit(void **cmt, void *pos, U64 cmt_block_size);
////////////////////////////////
//~ NOTE(allen): Main API Macros
#if !ENABLE_DEV
# define push_array_no_zero(a,T,c) (T*)arena_push((a), sizeof(T)*(c))
#else
# define push_array_no_zero(a,T,c) (tctx_write_this_srcloc(), (T*)arena_push((a), sizeof(T)*(c)))
#endif
#define push_array_no_zero__no_annotation(a,T,c) (T*)arena_push__impl((a), sizeof(T)*(c))
#define push_array_no_zero(a,T,c) (T*)arena_push((a), sizeof(T)*(c))
#define push_array(a,T,c) (T*)MemoryZero(push_array_no_zero(a,T,c), sizeof(T)*(c))
#endif // BASE_ARENA_H
-197
View File
@@ -1,197 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
// NOTE(allen): Dev Arena
#if ENABLE_DEV
internal void
arena_annotate_push__dev(Arena *arena, U64 size, void *ptr){
ArenaDev *dev = arena->dev;
if (dev != 0 && ptr != 0){
//- read location
char *file_name = 0;
U64 line_number = 0;
tctx_read_srcloc(&file_name, &line_number);
tctx_write_srcloc(0, 0);
//- profile
ArenaProf *prof = dev->prof;
if (prof != 0){
// c string -> string
String8 file_name_str = str8_lit("(null)");
if (file_name != 0){
file_name_str = str8_cstring(file_name);
}
// record
arena_prof_inc_counters__dev(dev->arena, prof, file_name_str, line_number, size, 1);
}
}
}
internal void
arena_annotate_absorb__dev(Arena *arena, Arena *sub){
ArenaDev *dev = arena->dev;
ArenaDev *sub_dev = sub->dev;
if (dev != 0 && sub_dev != 0){
//- merge profiles
ArenaProf *prof = dev->prof;
ArenaProf *sub_prof = sub_dev->prof;
if (prof != 0 && sub_prof != 0){
for (ArenaProfNode *sub_node = sub_prof->first;
sub_node != 0;
sub_node = sub_node->next){
arena_prof_inc_counters__dev(dev->arena, prof, sub_node->file_name, sub_node->line,
sub_node->size, sub_node->count);
}
}
}
//- release the sub dev memory
if (sub_dev != 0){
arena_release(sub_dev->arena);
}
}
internal ArenaDev*
arena_equip__dev(Arena *arena){
ArenaDev *result = arena->dev;
if (result == 0){
Arena *dev_arena = arena_alloc();
ArenaDev *dev = (ArenaDev*)arena_push__impl(dev_arena, sizeof(ArenaDev));
MemoryZeroStruct(dev);
dev->arena = dev_arena;
arena->dev = dev;
result = dev;
}
return(result);
}
internal void
arena_equip_profile__dev(Arena *arena){
ArenaDev *dev = arena_equip__dev(arena);
if (dev->prof == 0){
dev->prof = (ArenaProf*)arena_push__impl(dev->arena, sizeof(ArenaProf));
MemoryZeroStruct(dev->prof);
}
}
internal void
arena_print_profile__dev(Arena *arena, Arena *out_arena, String8List *out){
Assert(arena != out_arena);
//- get dev & disable
ArenaDev *dev = arena->dev;
arena->dev = 0;
//- get prof
ArenaProf *prof = (dev != 0)?dev->prof:0;
//- not equipped with prof
if (prof == 0){
str8_list_push(out_arena, out, str8_lit("not equipped with a memory profile\n"));
}
//- print prof
if (prof != 0){
Temp scratch = temp_begin(dev->arena);
//- make flat array
U64 note_count = prof->count;
ArenaProfNode **notes = push_array_no_zero__no_annotation(scratch.arena, ArenaProfNode*, note_count);
{
ArenaProfNode **note_ptr = notes;
for (ArenaProfNode *node = prof->first;
node != 0;
node = node->next, note_ptr += 1){
*note_ptr = node;
}
}
//- file name size
U64 max_file_name_size = 0;
{
ArenaProfNode **note_ptr = notes;
for (U64 i = 0; i < note_count; i += 1, note_ptr += 1){
max_file_name_size = Max(max_file_name_size, (**note_ptr).file_name.size);
}
}
//- sort (> size, < [address])
for (U64 i = 0; i < note_count; i += 1){
ArenaProfNode **i_note = notes + i;
ArenaProfNode **min_note = i_note;
for (U64 j = i + 1; j < note_count; j += 1){
ArenaProfNode **j_note = notes + j;
if ((**j_note).size > (**min_note).size ||
((**j_note).size == (**min_note).size && *j_note < *min_note)){
min_note = j_note;
}
}
if (min_note != i_note){
ArenaProfNode *t = *i_note;
*i_note = *min_note;
*min_note = t;
}
}
//- total size
U64 total_size = 0;
{
ArenaProfNode **note_ptr = notes;
for (U64 i = 0; i < note_count; i += 1, note_ptr += 1){
ArenaProfNode *note = *note_ptr;
total_size += note->size;
}
}
//- print
{
str8_list_pushf(out_arena, out, "memory total: %llu\n", total_size);
ArenaProfNode **note_ptr = notes;
for (U64 i = 0; i < note_count; i += 1, note_ptr += 1){
ArenaProfNode *note = *note_ptr;
String8 location = push_str8f(scratch.arena, "%S:%5llu:",
note->file_name, note->line);
F32 percent = 100.f*((F32)note->size)/total_size;
str8_list_pushf(out_arena, out, "%*.*s %12llu %5.2f%% [%5llu]\n",
max_file_name_size + 7, str8_varg(location),
note->size, percent, note->count);
}
}
temp_end(scratch);
}
//- restore dev
arena->dev = dev;
}
internal void
arena_prof_inc_counters__dev(Arena *dev_arena, ArenaProf *prof, String8 file_name, U64 line,
U64 size, U64 count){
// find existing profile node
ArenaProfNode *prof_node = 0;
for (ArenaProfNode *node = prof->first;
node != 0;
node = node->next){
if (node->line == line && str8_match(file_name, node->file_name, 0)){
prof_node = node;
break;
}
}
// make new histogram node if necessary
if (prof_node == 0){
prof_node = (ArenaProfNode*)arena_push(dev_arena, sizeof(*prof_node));
SLLQueuePush(prof->first, prof->last, prof_node);
prof->count += 1;
prof_node->file_name = file_name;
prof_node->line = line;
}
// record this allocation
prof_node->size += size;
prof_node->count += count;
}
#endif
-47
View File
@@ -1,47 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_ARENA_DEV_H
#define BASE_ARENA_DEV_H
////////////////////////////////
//~ NOTE(allen): Dev Arena Types
typedef struct ArenaDev ArenaDev;
struct ArenaDev
{
Arena *arena;
struct ArenaProf *prof;
};
typedef struct ArenaProf ArenaProf;
struct ArenaProf
{
struct ArenaProfNode *first;
struct ArenaProfNode *last;
U64 count;
};
typedef struct ArenaProfNode ArenaProfNode;
struct ArenaProfNode
{
ArenaProfNode *next;
String8 file_name;
U64 line;
U64 size;
U64 count;
};
////////////////////////////////
//~ NOTE(allen): Dev Arena Functions
#if ENABLE_DEV
internal void arena_annotate_push__dev(Arena *arena, U64 size, void *ptr);
internal void arena_annotate_absorb__dev(Arena *arena, Arena *sub);
internal ArenaDev* arena_equip__dev(Arena *arena);
internal void arena_equip_profile__dev(Arena *arena);
internal void arena_print_profile__dev(Arena *arena, Arena *out_arena, String8List *out);
internal void arena_prof_inc_counters__dev(Arena *dev_arena, ArenaProf *prof, String8 file_name, U64 line, U64 size, U64 count);
#endif
#endif // BASE_ARENA_DEV_H
-103
View File
@@ -1,103 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#if COMPILER_CL || (COMPILER_CLANG && OS_WINDOWS)
internal U64
count_bits_set16(U16 val)
{
return __popcnt16(val);
}
internal U64
count_bits_set32(U32 val)
{
return __popcnt(val);
}
internal U64
count_bits_set64(U64 val)
{
return __popcnt64(val);
}
internal U64
ctz32(U32 mask)
{
unsigned long idx;
_BitScanForward(&idx, mask);
return idx;
}
internal U64
ctz64(U64 mask)
{
unsigned long idx;
_BitScanForward64(&idx, mask);
return idx;
}
internal U64
clz32(U32 mask)
{
unsigned long idx;
_BitScanReverse(&idx, mask);
return 31 - idx;
}
internal U64
clz64(U64 mask)
{
unsigned long idx;
_BitScanReverse64(&idx, mask);
return 63 - idx;
}
#elif COMPILER_CLANG || COMPILER_GCC
internal U64
count_bits_set16(U16 val)
{
NotImplemented;
return 0;
}
internal U64
count_bits_set32(U32 val)
{
NotImplemented;
return 0;
}
internal U64
count_bits_set64(U64 val)
{
NotImplemented;
return 0;
}
internal U64
ctz32(U32 val)
{
NotImplemented;
return 0;
}
internal U64
clz32(U32 val)
{
NotImplemented;
return 0;
}
internal U64
clz64(U64 val)
{
NotImplemented;
return 0;
}
#else
# error "bits not defined for this target"
#endif
-18
View File
@@ -1,18 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_BITS_H
#define BASE_BITS_H
#define ExtractBit(word, idx) (((word) >> (idx)) & 1)
internal U64 count_bits_set16(U16 val);
internal U64 count_bits_set32(U32 val);
internal U64 count_bits_set64(U64 val);
internal U64 ctz32(U32 val);
internal U64 ctz64(U64 val);
internal U64 clz32(U32 val);
internal U64 clz64(U64 val);
#endif // BASE_BITS_H
+1
View File
@@ -82,6 +82,7 @@ internal CmdLine
cmd_line_from_string_list(Arena *arena, String8List command_line)
{
CmdLine parsed = {0};
parsed.exe_name = command_line.first->string;
// NOTE(rjf): Set up config option table.
{
+1
View File
@@ -29,6 +29,7 @@ struct CmdLineOptList
typedef struct CmdLine CmdLine;
struct CmdLine
{
String8 exe_name;
CmdLineOptList options;
String8List inputs;
U64 option_table_size;
+110 -17
View File
@@ -4,6 +4,9 @@
#ifndef BASE_CONTEXT_CRACKING_H
#define BASE_CONTEXT_CRACKING_H
////////////////////////////////
//~ rjf: Clang OS/Arch Cracking
#if defined(__clang__)
# define COMPILER_CLANG 1
@@ -15,7 +18,7 @@
# elif defined(__APPLE__) && defined(__MACH__)
# define OS_MAC 1
# else
# error This compiler/platform combo is not supported yet
# error This compiler/OS combo is not supported.
# endif
# if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
@@ -27,17 +30,40 @@
# elif defined(__arm__)
# define ARCH_ARM32 1
# else
# error architecture not supported yet
# error Architecture not supported.
# endif
////////////////////////////////
//~ rjf: MSVC OS/Arch Cracking
#elif defined(_MSC_VER)
# define COMPILER_CL 1
# define COMPILER_MSVC 1
# if _MSC_VER >= 1920
# define COMPILER_MSVC_YEAR 2019
# elif _MSC_VER >= 1910
# define COMPILER_MSVC_YEAR 2017
# elif _MSC_VER >= 1900
# define COMPILER_MSVC_YEAR 2015
# elif _MSC_VER >= 1800
# define COMPILER_MSVC_YEAR 2013
# elif _MSC_VER >= 1700
# define COMPILER_MSVC_YEAR 2012
# elif _MSC_VER >= 1600
# define COMPILER_MSVC_YEAR 2010
# elif _MSC_VER >= 1500
# define COMPILER_MSVC_YEAR 2008
# elif _MSC_VER >= 1400
# define COMPILER_MSVC_YEAR 2005
# else
# define COMPILER_MSVC_YEAR 0
# endif
# if defined(_WIN32)
# define OS_WINDOWS 1
# else
# error This compiler/platform combo is not supported yet
# error This compiler/OS combo is not supported.
# endif
# if defined(_M_AMD64)
@@ -49,9 +75,12 @@
# elif defined(_M_ARM)
# define ARCH_ARM32 1
# else
# error architecture not supported yet
# error Architecture not supported.
# endif
////////////////////////////////
//~ rjf: GCC OS/Arch Cracking
#elif defined(__GNUC__) || defined(__GNUG__)
# define COMPILER_GCC 1
@@ -59,7 +88,7 @@
# if defined(__gnu_linux__) || defined(__linux__)
# define OS_LINUX 1
# else
# error This compiler/platform combo is not supported yet
# error This compiler/OS combo is not supported.
# endif
# if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
@@ -71,26 +100,96 @@
# elif defined(__arm__)
# define ARCH_ARM32 1
# else
# error architecture not supported yet
# error Architecture not supported.
# endif
#else
# error This compiler is not supported yet
# error Compiler not supported.
#endif
////////////////////////////////
//~ rjf: Arch Cracking
#if defined(ARCH_X64)
# define ARCH_64BIT 1
#elif defined(ARCH_X86)
# define ARCH_32BIT 1
#endif
#if ARCH_ARM32 || ARCH_ARM64 || ARCH_X64 || ARCH_X86
# define ARCH_LITTLE_ENDIAN 1
#else
# error Endianness of this architecture not understood by context cracker.
#endif
////////////////////////////////
//~ rjf: Language Cracking
#if defined(__cplusplus)
# define LANG_CPP 1
#else
# define LANG_C 1
#endif
// zeroify
////////////////////////////////
//~ rjf: Build Option Cracking
#if !defined(BUILD_DEBUG)
# define BUILD_DEBUG 1
#endif
#if !defined(BUILD_SUPPLEMENTARY_UNIT)
# define BUILD_SUPPLEMENTARY_UNIT 0
#endif
#if !defined(BUILD_ENTRY_DEFINING_UNIT)
# define BUILD_ENTRY_DEFINING_UNIT 1
#endif
#if !defined(BUILD_CONSOLE_INTERFACE)
# define BUILD_CONSOLE_INTERFACE 0
#endif
#if !defined(BUILD_VERSION_MAJOR)
# define BUILD_VERSION_MAJOR 0
#endif
#if !defined(BUILD_VERSION_MINOR)
# define BUILD_VERSION_MINOR 0
#endif
#if !defined(BUILD_VERSION_PATCH)
# define BUILD_VERSION_PATCH 0
#endif
#define BUILD_VERSION_STRING_LITERAL Stringify(BUILD_VERSION_MAJOR) "." Stringify(BUILD_VERSION_MINOR) "." Stringify(BUILD_VERSION_PATCH)
#if BUILD_DEBUG
# define BUILD_MODE_STRING_LITERAL_APPEND " [Debug]"
#else
# define BUILD_MODE_STRING_LITERAL_APPEND ""
#endif
#if defined(BUILD_GIT_HASH)
# define BUILD_GIT_HASH_STRING_LITERAL_APPEND " [" BUILD_GIT_HASH "]"
#else
# define BUILD_GIT_HASH_STRING_LITERAL_APPEND ""
#endif
#if !defined(BUILD_TITLE)
# define BUILD_TITLE "Untitled"
#endif
#if !defined(BUILD_RELEASE_PHASE_STRING_LITERAL)
# define BUILD_RELEASE_PHASE_STRING_LITERAL "ALPHA"
#endif
#if !defined(BUILD_ISSUES_LINK_STRING_LITERAL)
# define BUILD_ISSUES_LINK_STRING_LITERAL "https://github.com/EpicGames/raddebugger/issues"
#endif
#define BUILD_TITLE_STRING_LITERAL BUILD_TITLE " (" BUILD_VERSION_STRING_LITERAL " " BUILD_RELEASE_PHASE_STRING_LITERAL ") - " __DATE__ "" BUILD_GIT_HASH_STRING_LITERAL_APPEND BUILD_MODE_STRING_LITERAL_APPEND
////////////////////////////////
//~ rjf: Zero All Undefined Options
#if !defined(ARCH_32BIT)
# define ARCH_32BIT 0
@@ -110,8 +209,8 @@
#if !defined(ARCH_ARM32)
# define ARCH_ARM32 0
#endif
#if !defined(COMPILER_CL)
# define COMPILER_CL 0
#if !defined(COMPILER_MSVC)
# define COMPILER_MSVC 0
#endif
#if !defined(COMPILER_GCC)
# define COMPILER_GCC 0
@@ -135,10 +234,4 @@
# define LANG_C 0
#endif
#if ARCH_ARM32 || ARCH_ARM64 || ARCH_X64 || ARCH_X86
# define ARCH_LITTLE_ENDIAN 1
#else
# error Endianness of this architecture not understood by context cracker
#endif
#endif // BASE_CONTEXT_CRACKING_H
+111 -3
View File
@@ -2,7 +2,7 @@
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ Safe Casts
//~ rjf: Safe Casts
internal U16
safe_cast_u16(U32 x)
@@ -141,6 +141,106 @@ bswap_u64(U64 x)
return result;
}
#if COMPILER_MSVC || (COMPILER_CLANG && OS_WINDOWS)
internal U64
count_bits_set16(U16 val)
{
return __popcnt16(val);
}
internal U64
count_bits_set32(U32 val)
{
return __popcnt(val);
}
internal U64
count_bits_set64(U64 val)
{
return __popcnt64(val);
}
internal U64
ctz32(U32 mask)
{
unsigned long idx;
_BitScanForward(&idx, mask);
return idx;
}
internal U64
ctz64(U64 mask)
{
unsigned long idx;
_BitScanForward64(&idx, mask);
return idx;
}
internal U64
clz32(U32 mask)
{
unsigned long idx;
_BitScanReverse(&idx, mask);
return 31 - idx;
}
internal U64
clz64(U64 mask)
{
unsigned long idx;
_BitScanReverse64(&idx, mask);
return 63 - idx;
}
#elif COMPILER_CLANG || COMPILER_GCC
internal U64
count_bits_set16(U16 val)
{
NotImplemented;
return 0;
}
internal U64
count_bits_set32(U32 val)
{
NotImplemented;
return 0;
}
internal U64
count_bits_set64(U64 val)
{
NotImplemented;
return 0;
}
internal U64
ctz32(U32 val)
{
NotImplemented;
return 0;
}
internal U64
clz32(U32 val)
{
NotImplemented;
return 0;
}
internal U64
clz64(U64 val)
{
NotImplemented;
return 0;
}
#else
# error "Bit intrinsic functions not defined for this compiler."
#endif
////////////////////////////////
//~ rjf: Enum -> Sign
@@ -287,6 +387,14 @@ txt_rng_union(TxtRng a, TxtRng b)
return result;
}
internal B32
txt_rng_contains(TxtRng r, TxtPt pt)
{
B32 result = ((txt_pt_less_than(r.min, pt) || txt_pt_match(r.min, pt)) &&
txt_pt_less_than(pt, r.max));
return result;
}
////////////////////////////////
//~ rjf: Toolchain/Environment Enum Functions
@@ -344,8 +452,8 @@ architecture_from_context(void){
internal Compiler
compiler_from_context(void){
Compiler compiler = Compiler_Null;
#if COMPILER_CL
compiler = Compiler_cl;
#if COMPILER_MSVC
compiler = Compiler_msvc;
#elif COMPILER_GCC
compiler = Compiler_gcc;
#elif COMPILER_CLANG
+222 -134
View File
@@ -13,17 +13,6 @@
#include <string.h>
#include <stdint.h>
////////////////////////////////
//~ rjf: Build Configuration
#if !defined(ENABLE_DEV)
# define ENABLE_DEV 0
#endif
#if !defined(SUPPLEMENT_UNIT)
# define SUPPLEMENT_UNIT 0
#endif
////////////////////////////////
//~ rjf: Codebase Keywords
@@ -31,7 +20,7 @@
#define global static
#define local_persist static
#if COMPILER_CL || (COMPILER_CLANG && OS_WINDOWS)
#if COMPILER_MSVC || (COMPILER_CLANG && OS_WINDOWS)
# pragma section(".rdata$", read)
# define read_only __declspec(allocate(".rdata$"))
#elif (COMPILER_CLANG && OS_LINUX)
@@ -45,6 +34,80 @@
# define read_only
#endif
#if COMPILER_MSVC
# define thread_static __declspec(thread)
#elif COMPILER_CLANG || COMPILER_GCC
# define thread_static __thread
#endif
////////////////////////////////
//~ rjf: Linkage Keyword Macros
#if OS_WINDOWS
# define shared_function C_LINKAGE __declspec(dllexport)
#else
# define shared_function C_LINKAGE
#endif
#if LANG_CPP
# define C_LINKAGE_BEGIN extern "C"{
# define C_LINKAGE_END }
# define C_LINKAGE extern "C"
#else
# define C_LINKAGE_BEGIN
# define C_LINKAGE_END
# define C_LINKAGE
#endif
////////////////////////////////
//~ rjf: Units
#define KB(n) (((U64)(n)) << 10)
#define MB(n) (((U64)(n)) << 20)
#define GB(n) (((U64)(n)) << 30)
#define TB(n) (((U64)(n)) << 40)
#define Thousand(n) ((n)*1000)
#define Million(n) ((n)*1000000)
#define Billion(n) ((n)*1000000000)
////////////////////////////////
//~ rjf: Branch Predictor Hints
#if defined(__clang__)
# define Expect(expr, val) __builtin_expect((expr), (val))
#else
# define Expect(expr, val) (expr)
#endif
#define Likely(expr) Expect(expr,1)
#define Unlikely(expr) Expect(expr,0)
////////////////////////////////
//~ rjf: Clamps, Mins, Maxes
#define Min(A,B) (((A)<(B))?(A):(B))
#define Max(A,B) (((A)>(B))?(A):(B))
#define ClampTop(A,X) Min(A,X)
#define ClampBot(X,B) Max(X,B)
#define Clamp(A,X,B) (((X)<(A))?(A):((X)>(B))?(B):(X))
////////////////////////////////
//~ rjf: Member Offsets
#define Member(T,m) (((T*)0)->m)
#define OffsetOf(T,m) IntFromPtr(&Member(T,m))
#define MemberFromOffset(T,ptr,off) (T)((((U8 *)ptr)+(off)))
#define CastFromMember(T,m,ptr) (T*)(((U8*)ptr) - OffsetOf(T,m))
////////////////////////////////
//~ rjf: For-Loop Construct Macros
#define DeferLoop(begin, end) for(int _i_ = ((begin), 0); !_i_; _i_ += 1, (end))
#define DeferLoopChecked(begin, end) for(int _i_ = 2 * !(begin); (_i_ == 2 ? ((end), 0) : !_i_); _i_ += 1, (end))
#define EachEnumVal(type, it) type it = (type)0; it < type##_COUNT; it = (type)(it+1)
#define EachNonZeroEnumVal(type, it) type it = (type)1; it < type##_COUNT; it = (type)(it+1)
////////////////////////////////
//~ rjf: Memory Operation Macros
@@ -67,99 +130,178 @@
#define MemoryMatchArray(a,b) MemoryMatch((a),(b),sizeof(a))
#define MemoryRead(T,p,e) ( ((p)+sizeof(T)<=(e))?(*(T*)(p)):(0) )
#define MemoryConsume(T,p,e) \
( ((p)+sizeof(T)<=(e))?((p)+=sizeof(T),*(T*)((p)-sizeof(T))):((p)=(e),0) )
////////////////////////////////
//~ rjf: Units
#define KB(n) (((U64)(n)) << 10)
#define MB(n) (((U64)(n)) << 20)
#define GB(n) (((U64)(n)) << 30)
#define TB(n) (((U64)(n)) << 40)
#define Thousand(n) ((n)*1000)
#define Million(n) ((n)*1000000)
#define Billion(n) ((n)*1000000000)
#define MemoryConsume(T,p,e) ( ((p)+sizeof(T)<=(e))?((p)+=sizeof(T),*(T*)((p)-sizeof(T))):((p)=(e),0) )
////////////////////////////////
//~ rjf: Asserts
#if COMPILER_CL
#if COMPILER_MSVC
# define Trap() __debugbreak()
#elif COMPILER_CLANG || COMPILER_GCC
# define Trap() __builtin_trap()
# else
# error "undefined trap"
#else
# error Unknown trap intrinsic for this compiler.
#endif
#define AssertAlways(x) do{if(!(x)) {Trap();}}while(0)
#if !defined(NDEBUG)
#if BUILD_DEBUG
# define Assert(x) AssertAlways(x)
#else
# define Assert(x) (void)(x)
#endif
#define AssertImplies(a,b) Assert(!(a) || b)
#define AssertIff(a,b) Assert(!!(a) == !!(b))
#define InvalidPath Assert(!"Invalid Path!")
#define NotImplemented Assert(!"Not Implemented!")
#define StaticAssert(C,ID) global U8 Glue(ID,__LINE__)[(C)?1:-1]
#define NoOp ((void)0)
#define StaticAssert(C, ID) global U8 Glue(ID, __LINE__)[(C)?1:-1]
////////////////////////////////
//~ rjf: Branch Predictor Hints
//~ rjf: Atomic Operations
#if defined(__clang__)
# define Expect(expr, val) __builtin_expect((expr), (val))
#if OS_WINDOWS
# include <windows.h>
# include <tmmintrin.h>
# include <wmmintrin.h>
# include <intrin.h>
# if ARCH_X64
# define ins_atomic_u64_eval(x) InterlockedAdd64((volatile __int64 *)(x), 0)
# define ins_atomic_u64_inc_eval(x) InterlockedIncrement64((volatile __int64 *)(x))
# define ins_atomic_u64_dec_eval(x) InterlockedDecrement64((volatile __int64 *)(x))
# define ins_atomic_u64_eval_assign(x,c) InterlockedExchange64((volatile __int64 *)(x),(c))
# define ins_atomic_u64_add_eval(x,c) InterlockedAdd64((volatile __int64 *)(x), c)
# define ins_atomic_u32_eval(x,c) InterlockedAdd((volatile LONG *)(x), 0)
# define ins_atomic_u32_eval_assign(x,c) InterlockedExchange((volatile LONG *)(x),(c))
# define ins_atomic_u32_eval_cond_assign(x,k,c) InterlockedCompareExchange((volatile LONG *)(x),(k),(c))
# define ins_atomic_ptr_eval_assign(x,c) (void*)ins_atomic_u64_eval_assign((volatile __int64 *)(x), (__int64)(c))
# else
# error Atomic intrinsics not defined for this operating system / architecture combination.
# endif
#elif OS_LINUX
# if ARCH_X64
# define ins_atomic_u64_inc_eval(x) __sync_fetch_and_add((volatile U64 *)(x), 1)
# else
# error Atomic intrinsics not defined for this operating system / architecture combination.
# endif
#else
# define Expect(expr, val) (expr)
# error Atomic intrinsics not defined for this operating system.
#endif
#define Likely(expr) Expect(expr,1)
#define Unlikely(expr) Expect(expr,0)
////////////////////////////////
//~ rjf: Linked List Building Macros
//- rjf: linked list macro helpers
#define CheckNil(nil,p) ((p) == 0 || (p) == nil)
#define SetNil(nil,p) ((p) = nil)
//- rjf: doubly-linked-lists
#define DLLInsert_NPZ(nil,f,l,p,n,next,prev) (CheckNil(nil,f) ? \
((f) = (l) = (n), SetNil(nil,(n)->next), SetNil(nil,(n)->prev)) :\
CheckNil(nil,p) ? \
((n)->next = (f), (f)->prev = (n), (f) = (n), SetNil(nil,(n)->prev)) :\
((p)==(l)) ? \
((l)->next = (n), (n)->prev = (l), (l) = (n), SetNil(nil, (n)->next)) :\
(((!CheckNil(nil,p) && CheckNil(nil,(p)->next)) ? (0) : ((p)->next->prev = (n))), ((n)->next = (p)->next), ((p)->next = (n)), ((n)->prev = (p))))
#define DLLPushBack_NPZ(nil,f,l,n,next,prev) DLLInsert_NPZ(nil,f,l,l,n,next,prev)
#define DLLPushFront_NPZ(nil,f,l,n,next,prev) DLLInsert_NPZ(nil,l,f,f,n,prev,next)
#define DLLRemove_NPZ(nil,f,l,n,next,prev) (((n) == (f) ? (f) = (n)->next : (0)),\
((n) == (l) ? (l) = (l)->prev : (0)),\
(CheckNil(nil,(n)->prev) ? (0) :\
((n)->prev->next = (n)->next)),\
(CheckNil(nil,(n)->next) ? (0) :\
((n)->next->prev = (n)->prev)))
//- rjf: singly-linked, doubly-headed lists (queues)
#define SLLQueuePush_NZ(nil,f,l,n,next) (CheckNil(nil,f)?\
((f)=(l)=(n),SetNil(nil,(n)->next)):\
((l)->next=(n),(l)=(n),SetNil(nil,(n)->next)))
#define SLLQueuePushFront_NZ(nil,f,l,n,next) (CheckNil(nil,f)?\
((f)=(l)=(n),SetNil(nil,(n)->next)):\
((n)->next=(f),(f)=(n)))
#define SLLQueuePop_NZ(nil,f,l,next) ((f)==(l)?\
(SetNil(nil,f),SetNil(nil,l)):\
((f)=(f)->next))
//- rjf: singly-linked, singly-headed lists (stacks)
#define SLLStackPush_N(f,n,next) ((n)->next=(f), (f)=(n))
#define SLLStackPop_N(f,next) ((f)=(f)->next)
//- rjf: doubly-linked-list helpers
#define DLLInsert_NP(f,l,p,n,next,prev) DLLInsert_NPZ(0,f,l,p,n,next,prev)
#define DLLPushBack_NP(f,l,n,next,prev) DLLPushBack_NPZ(0,f,l,n,next,prev)
#define DLLPushFront_NP(f,l,n,next,prev) DLLPushFront_NPZ(0,f,l,n,next,prev)
#define DLLRemove_NP(f,l,n,next,prev) DLLRemove_NPZ(0,f,l,n,next,prev)
#define DLLInsert(f,l,p,n) DLLInsert_NPZ(0,f,l,p,n,next,prev)
#define DLLPushBack(f,l,n) DLLPushBack_NPZ(0,f,l,n,next,prev)
#define DLLPushFront(f,l,n) DLLPushFront_NPZ(0,f,l,n,next,prev)
#define DLLRemove(f,l,n) DLLRemove_NPZ(0,f,l,n,next,prev)
//- rjf: singly-linked, doubly-headed list helpers
#define SLLQueuePush_N(f,l,n,next) SLLQueuePush_NZ(0,f,l,n,next)
#define SLLQueuePushFront_N(f,l,n,next) SLLQueuePushFront_NZ(0,f,l,n,next)
#define SLLQueuePop_N(f,l,next) SLLQueuePop_NZ(0,f,l,next)
#define SLLQueuePush(f,l,n) SLLQueuePush_NZ(0,f,l,n,next)
#define SLLQueuePushFront(f,l,n) SLLQueuePushFront_NZ(0,f,l,n,next)
#define SLLQueuePop(f,l) SLLQueuePop_NZ(0,f,l,next)
//- rjf: singly-linked, singly-headed list helpers
#define SLLStackPush(f,n) SLLStackPush_N(f,n,next)
#define SLLStackPop(f) SLLStackPop_N(f,next)
////////////////////////////////
//~ rjf: Address Sanitizer Markup
#if COMPILER_MSVC
# if defined(__SANITIZE_ADDRESS__)
# define ASAN_ENABLED 1
# define NO_ASAN __declspec(no_sanitize_address)
# else
# define NO_ASAN
# endif
#elif COMPILER_CLANG
# if defined(__has_feature)
# if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
# define ASAN_ENABLED 1
# endif
# endif
# define NO_ASAN __attribute__((no_sanitize("address")))
#else
# error "NO_ASAN is not defined for this compiler."
#endif
#if ASAN_ENABLED
#pragma comment(lib, "clang_rt.asan-x86_64.lib")
C_LINKAGE void __asan_poison_memory_region(void const volatile *addr, size_t size);
C_LINKAGE void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
# define AsanPoisonMemoryRegion(addr, size) __asan_poison_memory_region((addr), (size))
# define AsanUnpoisonMemoryRegion(addr, size) __asan_unpoison_memory_region((addr), (size))
#else
# define AsanPoisonMemoryRegion(addr, size) ((void)(addr), (void)(size))
# define AsanUnpoisonMemoryRegion(addr, size) ((void)(addr), (void)(size))
#endif
////////////////////////////////
//~ rjf: Misc. Helper Macros
#define ArrayCount(a) (sizeof(a) / sizeof((a)[0]))
#define Stmnt(S) do{ S }while(0)
#define Stringify_(S) #S
#define Stringify(S) Stringify_(S)
#define Glue_(A,B) A##B
#define Glue(A,B) Glue_(A,B)
#define Min(A,B) ( ((A)<(B))?(A):(B) )
#define Max(A,B) ( ((A)>(B))?(A):(B) )
#define ClampTop(A,X) Min(A,X)
#define ClampBot(X,B) Max(X,B)
#define Clamp(A,X,B) ( ((X)<(A))?(A):((X)>(B))?(B):(X) )
#define PtrClampTop(A,X) ClampTop(A,X)
#define PtrClampBot(X,B) ClampBot(X,B)
#define PtrClamp(A,X,B) Clamp(A,X,B)
#define ArrayCount(a) (sizeof(a) / sizeof((a)[0]))
#define CeilIntegerDiv(a,b) (((a) + (b) - 1)/(b))
#define Swap(T,a,b) Stmnt( T t__ = a; a = b; b = t__; )
#define Swap(T,a,b) do{T t__ = a; a = b; b = t__;}while(0)
#if ARCH_64BIT
# define IntFromPtr(ptr) ((U64)(ptr))
#elif ARCH_32BIT
# define IntFromPtr(ptr) ((U32)(ptr))
#else
# error missing ptr cast for this architecture
# error Missing pointer-to-integer cast for this architecture.
#endif
#define PtrFromInt(i) (void*)((U8*)0 + (i))
#define Member(T,m) (((T*)0)->m)
#define OffsetOf(T,m) IntFromPtr(&Member(T,m))
#define MemberFromOffset(T,ptr,off) (T)((((U8 *)ptr)+(off)))
#define CastFromMember(T,m,ptr) (T*)(((U8*)ptr) - OffsetOf(T,m))
#define Compose64Bit(a,b) ((((U64)a) << 32) | ((U64)b));
#define AlignPow2(x,b) (((x) + (b) - 1)&(~((b) - 1)))
#define AlignDownPow2(x,b) ((x)&(~((b) - 1)))
@@ -167,8 +309,7 @@
#define IsPow2(x) ((x)!=0 && ((x)&((x)-1))==0)
#define IsPow2OrZero(x) ((((x) - 1)&(x)) == 0)
#define DeferLoop(begin, end) for(int _i_ = ((begin), 0); !_i_; _i_ += 1, (end))
#define DeferLoopChecked(begin, end) for(int _i_ = 2 * !(begin); (_i_ == 2 ? ((end), 0) : !_i_); _i_ += 1, (end))
#define ExtractBit(word, idx) (((word) >> (idx)) & 1)
#if LANG_CPP
# define zero_struct {}
@@ -182,66 +323,6 @@
# define this_function_name __func__
#endif
#if LANG_CPP
# define C_LINKAGE_BEGIN extern "C"{
# define C_LINKAGE_END }
# define C_LINKAGE extern "C"
#else
# define C_LINKAGE_BEGIN
# define C_LINKAGE_END
# define C_LINKAGE
#endif
#if COMPILER_CL
# define thread_static __declspec(thread)
#elif COMPILER_CLANG || COMPILER_GCC
# define thread_static __thread
#endif
#if OS_WINDOWS
# define shared_function C_LINKAGE __declspec(dllexport)
#else
# define shared_function C_LINKAGE
#endif
////////////////////////////////
//~ ASAN
#if COMPILER_CL
# if defined(__SANITIZE_ADDRESS__)
# define ASAN_ENABLED 1
# define NO_ASAN __declspec(no_sanitize_address)
# else
# define NO_ASAN
# endif
#elif COMPILER_CLANG
# if defined(__has_feature)
# if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
# define ASAN_ENABLED 1
# endif
# endif
# define NO_ASAN __attribute__((no_sanitize("address")))
#else
# error "NO_ASAN is not defined"
#endif
#if ASAN_ENABLED
#pragma comment(lib, "clang_rt.asan-x86_64.lib")
C_LINKAGE_BEGIN
void __asan_poison_memory_region(void const volatile *addr, size_t size);
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
C_LINKAGE_END
# define AsanPoisonMemoryRegion(addr, size) __asan_poison_memory_region((addr), (size))
# define AsanUnpoisonMemoryRegion(addr, size) __asan_unpoison_memory_region((addr), (size))
#else
# define AsanPoisonMemoryRegion(addr, size) ((void)(addr), (void)(size))
# define AsanUnpoisonMemoryRegion(addr, size) ((void)(addr), (void)(size))
#endif
////////////////////////////////
//~ rjf: Base Types
@@ -259,10 +340,7 @@ typedef S32 B32;
typedef S64 B64;
typedef float F32;
typedef double F64;
////////////////////////////////
//~ rjf: Large Base Types
typedef void VoidProc(void);
typedef struct U128 U128;
struct U128
{
@@ -272,8 +350,6 @@ struct U128
////////////////////////////////
//~ rjf: Basic Types & Spaces
typedef void VoidProc(void);
typedef enum Dimension
{
Dimension_X,
@@ -341,7 +417,7 @@ Architecture;
typedef enum Compiler
{
Compiler_Null,
Compiler_cl,
Compiler_msvc,
Compiler_gcc,
Compiler_clang,
Compiler_COUNT,
@@ -569,11 +645,13 @@ struct DateTime
U16 min; // [0,59]
U16 hour; // [0,24]
U16 day; // [0,30]
union{
union
{
WeekDay week_day;
U32 wday;
};
union{
union
{
Month month;
U32 mon;
};
@@ -601,7 +679,7 @@ struct FileProperties
};
////////////////////////////////
//~ Safe Casts
//~ rjf: Safe Casts
internal U16 safe_cast_u16(U32 x);
internal U32 safe_cast_u32(U64 x);
@@ -629,6 +707,15 @@ internal U16 bswap_u16(U16 x);
internal U32 bswap_u32(U32 x);
internal U64 bswap_u64(U64 x);
internal U64 count_bits_set16(U16 val);
internal U64 count_bits_set32(U32 val);
internal U64 count_bits_set64(U64 val);
internal U64 ctz32(U32 val);
internal U64 ctz64(U64 val);
internal U64 clz32(U32 val);
internal U64 clz64(U64 val);
////////////////////////////////
//~ rjf: Enum -> Sign
@@ -651,6 +738,7 @@ internal TxtPt txt_pt_max(TxtPt a, TxtPt b);
internal TxtRng txt_rng(TxtPt min, TxtPt max);
internal TxtRng txt_rng_intersect(TxtRng a, TxtRng b);
internal TxtRng txt_rng_union(TxtRng a, TxtRng b);
internal B32 txt_rng_contains(TxtRng r, TxtPt pt);
////////////////////////////////
//~ rjf: Toolchain/Environment Enum Functions
@@ -677,4 +765,4 @@ internal U64 ring_read(U8 *ring_base, U64 ring_size, U64 ring_pos, void *dst_dat
#define ring_write_struct(ring_base, ring_size, ring_pos, ptr) ring_write((ring_base), (ring_size), (ring_pos), (ptr), sizeof(*(ptr)))
#define ring_read_struct(ring_base, ring_size, ring_pos, ptr) ring_read((ring_base), (ring_size), (ring_pos), (ptr), sizeof(*(ptr)))
#endif // BASE_TYPES_H
#endif // BASE_CORE_H
+95
View File
@@ -0,0 +1,95 @@
internal void
main_thread_base_entry_point(void (*entry_point)(CmdLine *cmdline), char **arguments, U64 arguments_count)
{
#if PROFILE_TELEMETRY
local_persist U8 tm_data[MB(64)];
tmLoadLibrary(TM_RELEASE);
tmSetMaxThreadCount(256);
tmInitialize(sizeof(tm_data), (char *)tm_data);
#endif
TCTX tctx;
tctx_init_and_equip(&tctx);
ThreadNameF("[main thread]");
Temp scratch = scratch_begin(0, 0);
String8List command_line_argument_strings = os_string_list_from_argcv(scratch.arena, (int)arguments_count, arguments);
CmdLine cmdline = cmd_line_from_string_list(scratch.arena, command_line_argument_strings);
B32 capture = cmd_line_has_flag(&cmdline, str8_lit("capture"));
if(capture)
{
ProfBeginCapture(arguments[0]);
}
#if defined(OS_CORE_H)
os_init();
#endif
#if defined(TASK_SYSTEM_H)
ts_init();
#endif
#if defined(HASH_STORE_H)
hs_init();
#endif
#if defined(FILE_STREAM_H)
fs_init();
#endif
#if defined(TEXT_CACHE_H)
txt_init();
#endif
#if defined(DASM_CACHE_H)
dasm_init();
#endif
#if defined(DBGI_H)
dbgi_init();
#endif
#if defined(TXTI_H)
txti_init();
#endif
#if defined(DEMON_CORE_H)
dmn_init();
#endif
#if defined(CTRL_CORE_H)
ctrl_init();
#endif
#if defined(DASM_H)
dasmi_init();
#endif
#if defined(OS_GRAPHICAL_H)
os_graphical_init();
#endif
#if defined(FONT_PROVIDER_H)
fp_init();
#endif
#if defined(RENDER_CORE_H)
r_init(&cmdline);
#endif
#if defined(TEXTURE_CACHE_H)
tex_init();
#endif
#if defined(GEO_CACHE_H)
geo_init();
#endif
#if defined(FONT_CACHE_H)
f_init();
#endif
#if defined(DF_CORE_H)
DF_StateDeltaHistory *hist = df_state_delta_history_alloc();
df_core_init(&cmdline, hist);
#endif
#if defined(DF_GFX_H)
df_gfx_init(update_and_render, df_state_delta_history());
#endif
entry_point(&cmdline);
if(capture)
{
ProfEndCapture();
}
scratch_end(scratch);
tctx_release();
}
internal void
supplement_thread_base_entry_point(void (*entry_point)(void *params), void *params)
{
TCTX tctx;
tctx_init_and_equip(&tctx);
entry_point(params);
tctx_release();
}
+10
View File
@@ -0,0 +1,10 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_ENTRY_POINT_H
#define BASE_ENTRY_POINT_H
internal void main_thread_base_entry_point(void (*entry_point)(CmdLine *cmdline), char **arguments, U64 arguments_count);
internal void supplement_thread_base_entry_point(void (*entry_point)(void *params), void *params);
#endif // BASE_ENTRY_POINT_H
+5 -5
View File
@@ -7,12 +7,12 @@
#undef RADDBG_LAYER_COLOR
#define RADDBG_LAYER_COLOR 0.20f, 0.60f, 0.80f
#include "base_types.c"
#include "base_markup.c"
#include "base_core.c"
#include "base_profile.c"
#include "base_arena.c"
#include "base_math.c"
#include "base_string.c"
#include "base_strings.c"
#include "base_thread_context.c"
#include "base_command_line.c"
#include "base_arena_dev.c"
#include "base_bits.c"
#include "base_markup.c"
#include "base_entry_point.c"
+6 -7
View File
@@ -8,16 +8,15 @@
//~ rjf: Base Includes
#include "base_context_cracking.h"
#include "base_types.h"
#include "base_markup.h"
#include "base_ins.h"
#include "base_linked_lists.h"
#include "base_core.h"
#include "base_profile.h"
#include "base_arena.h"
#include "base_math.h"
#include "base_string.h"
#include "base_strings.h"
#include "base_thread_context.h"
#include "base_command_line.h"
#include "base_arena_dev.h"
#include "base_bits.h"
#include "base_markup.h"
#include "base_entry_point.h"
#endif // BASE_INC_H
-52
View File
@@ -1,52 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_INS_H
#define BASE_INS_H
////////////////////////////////
// NOTE(allen): Implementations of Intrinsics
#if OS_WINDOWS
# include <windows.h>
# include <tmmintrin.h>
# include <wmmintrin.h>
# include <intrin.h>
# if ARCH_X64
# define ins_atomic_u64_eval(x) InterlockedAdd((volatile LONG *)(x), 0)
# define ins_atomic_u64_inc_eval(x) InterlockedIncrement64((volatile __int64 *)(x))
# define ins_atomic_u64_dec_eval(x) InterlockedDecrement64((volatile __int64 *)(x))
# define ins_atomic_u64_eval_assign(x,c) InterlockedExchange64((volatile __int64 *)(x),(c))
# define ins_atomic_u64_add_eval(x,c) InterlockedAdd((volatile LONG *)(x), c)
# define ins_atomic_u32_eval_assign(x,c) InterlockedExchange((volatile LONG *)(x),(c))
# define ins_atomic_u32_eval_cond_assign(x,k,c) InterlockedCompareExchange((volatile LONG *)(x),(k),(c))
# define ins_atomic_ptr_eval_assign(x,c) (void*)ins_atomic_u64_eval_assign((volatile __int64 *)(x), (__int64)(c))
# endif
#elif OS_LINUX
# if ARCH_X64
# define ins_atomic_u64_inc_eval(x) __sync_fetch_and_add((volatile U64 *)(x), 1)
# endif
#else
// TODO(allen):
#endif
////////////////////////////////
// NOTE(allen): Intrinsic Checks
#if ARCH_X64
# if !defined(ins_atomic_u64_inc_eval)
# error missing: ins_atomic_u64_inc_eval
# endif
#else
# error the intrinsic set for this arch is not developed
#endif
#endif //BASE_INS_H
-73
View File
@@ -1,73 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_LINKED_LIST_H
#define BASE_LINKED_LIST_H
////////////////////////////////
//~ rjf: Helpers
#define CheckNil(nil,p) ((p) == 0 || (p) == nil)
#define SetNil(nil,p) ((p) = nil)
////////////////////////////////
//~ rjf: Base Macros
//- rjf: Base Doubly-Linked-List Macros
#define DLLInsert_NPZ(nil,f,l,p,n,next,prev) (CheckNil(nil,f) ? \
((f) = (l) = (n), SetNil(nil,(n)->next), SetNil(nil,(n)->prev)) :\
CheckNil(nil,p) ? \
((n)->next = (f), (f)->prev = (n), (f) = (n), SetNil(nil,(n)->prev)) :\
((p)==(l)) ? \
((l)->next = (n), (n)->prev = (l), (l) = (n), SetNil(nil, (n)->next)) :\
(((!CheckNil(nil,p) && CheckNil(nil,(p)->next)) ? (0) : ((p)->next->prev = (n))), ((n)->next = (p)->next), ((p)->next = (n)), ((n)->prev = (p))))
#define DLLPushBack_NPZ(nil,f,l,n,next,prev) DLLInsert_NPZ(nil,f,l,l,n,next,prev)
#define DLLPushFront_NPZ(nil,f,l,n,next,prev) DLLInsert_NPZ(nil,l,f,f,n,prev,next)
#define DLLRemove_NPZ(nil,f,l,n,next,prev) (((n) == (f) ? (f) = (n)->next : (0)),\
((n) == (l) ? (l) = (l)->prev : (0)),\
(CheckNil(nil,(n)->prev) ? (0) :\
((n)->prev->next = (n)->next)),\
(CheckNil(nil,(n)->next) ? (0) :\
((n)->next->prev = (n)->prev)))
//- rjf: Base Singly-Linked-List Queue Macros
#define SLLQueuePush_NZ(nil,f,l,n,next) (CheckNil(nil,f)?\
((f)=(l)=(n),SetNil(nil,(n)->next)):\
((l)->next=(n),(l)=(n),SetNil(nil,(n)->next)))
#define SLLQueuePushFront_NZ(nil,f,l,n,next) (CheckNil(nil,f)?\
((f)=(l)=(n),SetNil(nil,(n)->next)):\
((n)->next=(f),(f)=(n)))
#define SLLQueuePop_NZ(nil,f,l,next) ((f)==(l)?\
(SetNil(nil,f),SetNil(nil,l)):\
((f)=(f)->next))
//- rjf: Base Singly-Linked-List Stack Macros
#define SLLStackPush_N(f,n,next) ((n)->next=(f), (f)=(n))
#define SLLStackPop_N(f,next) ((f)=(f)->next)
////////////////////////////////
//~ rjf: Convenience Wrappers
//- rjf: Doubly-Linked-List Wrappers
#define DLLInsert_NP(f,l,p,n,next,prev) DLLInsert_NPZ(0,f,l,p,n,next,prev)
#define DLLPushBack_NP(f,l,n,next,prev) DLLPushBack_NPZ(0,f,l,n,next,prev)
#define DLLPushFront_NP(f,l,n,next,prev) DLLPushFront_NPZ(0,f,l,n,next,prev)
#define DLLRemove_NP(f,l,n,next,prev) DLLRemove_NPZ(0,f,l,n,next,prev)
#define DLLInsert(f,l,p,n) DLLInsert_NPZ(0,f,l,p,n,next,prev)
#define DLLPushBack(f,l,n) DLLPushBack_NPZ(0,f,l,n,next,prev)
#define DLLPushFront(f,l,n) DLLPushFront_NPZ(0,f,l,n,next,prev)
#define DLLRemove(f,l,n) DLLRemove_NPZ(0,f,l,n,next,prev)
//- rjf: Singly-Linked-List Queue Wrappers
#define SLLQueuePush_N(f,l,n,next) SLLQueuePush_NZ(0,f,l,n,next)
#define SLLQueuePushFront_N(f,l,n,next) SLLQueuePushFront_NZ(0,f,l,n,next)
#define SLLQueuePop_N(f,l,next) SLLQueuePop_NZ(0,f,l,next)
#define SLLQueuePush(f,l,n) SLLQueuePush_NZ(0,f,l,n,next)
#define SLLQueuePushFront(f,l,n) SLLQueuePushFront_NZ(0,f,l,n,next)
#define SLLQueuePop(f,l) SLLQueuePop_NZ(0,f,l,next)
//- rjf: Singly-Linked-List Stack Wrappers
#define SLLStackPush(f,n) SLLStackPush_N(f,n,next)
#define SLLStackPop(f) SLLStackPop_N(f,next)
#endif //BASE_LINKED_LIST_H
+19
View File
@@ -1,2 +1,21 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal void
thread_name(String8 string)
{
ProfThreadName("%.*s", str8_varg(string));
os_set_thread_name(string);
}
internal void
thread_namef(char *fmt, ...)
{
Temp scratch = scratch_begin(0, 0);
va_list args;
va_start(args, fmt);
String8 string = push_str8fv(scratch.arena, fmt, args);
thread_name(string);
va_end(args);
scratch_end(scratch);
}
+4 -71
View File
@@ -4,76 +4,9 @@
#ifndef BASE_MARKUP_H
#define BASE_MARKUP_H
////////////////////////////////
//~ rjf: Zero Settings
#if !defined(PROFILE_TELEMETRY)
# define PROFILE_TELEMETRY 0
#endif
#if !defined(MARKUP_LAYER_COLOR)
# define MARKUP_LAYER_COLOR 1.00f, 0.00f, 1.00f
#endif
////////////////////////////////
//~ rjf: Third Party Includes
#if PROFILE_TELEMETRY
# include "rad_tm.h"
# if OS_WINDOWS
# pragma comment(lib, "rad_tm_win64.lib")
# endif
#endif
////////////////////////////////
//~ rjf: Telemetry Profile Defines
#if PROFILE_TELEMETRY
# define ProfBegin(...) tmEnter(0, 0, __VA_ARGS__)
# define ProfBeginDynamic(...) (TM_API_PTR ? TM_API_PTR->_tmEnterZoneV_Core(0, 0, __FILE__, &g_telemetry_filename_id, __LINE__, __VA_ARGS__) : (void)0)
# define ProfEnd(...) (TM_API_PTR ? TM_API_PTR->_tmLeaveZone(0) : (void)0)
# define ProfTick(...) tmTick(0)
# define ProfIsCapturing(...) tmRunning()
# define ProfBeginCapture(...) tmOpen(0, __VA_ARGS__, __DATE__, "localhost", TMCT_TCP, TELEMETRY_DEFAULT_PORT, TMOF_INIT_NETWORKING|TMOF_CAPTURE_CONTEXT_SWITCHES, 100)
# define ProfEndCapture(...) tmClose(0)
# define ProfThreadName(...) (TM_API_PTR ? TM_API_PTR->_tmThreadName(0, 0, __VA_ARGS__) : (void)0)
# define ProfMsg(...) (TM_API_PTR ? TM_API_PTR->_tmMessageV_Core(0, TMMF_ICON_NOTE, __FILE__, &g_telemetry_filename_id, __LINE__, __VA_ARGS__) : (void)0)
# define ProfBeginLockWait(...) tmStartWaitForLock(0, 0, __VA_ARGS__)
# define ProfEndLockWait(...) tmEndWaitForLock(0)
# define ProfLockTake(...) tmAcquiredLock(0, 0, __VA_ARGS__)
# define ProfLockDrop(...) tmReleasedLock(0, __VA_ARGS__)
# define ProfColor(color) tmZoneColorSticky(color)
#endif
////////////////////////////////
//~ rjf: Zeroify Undefined Defines
#if !defined(ProfBegin)
# define ProfBegin(...) (0)
# define ProfBeginDynamic(...) (0)
# define ProfEnd(...) (0)
# define ProfTick(...) (0)
# define ProfIsCapturing(...) (0)
# define ProfBeginCapture(...) (0)
# define ProfEndCapture(...) (0)
# define ProfThreadName(...) (0)
# define ProfMsg(...) (0)
# define ProfBeginLockWait(...) (0)
# define ProfEndLockWait(...) (0)
# define ProfLockTake(...) (0)
# define ProfLockDrop(...) (0)
# define ProfColor(...) (0)
#endif
////////////////////////////////
//~ rjf: Helper Wrappers
#define ProfBeginFunction(...) ProfBegin(this_function_name)
#define ProfScope(...) DeferLoop(ProfBeginDynamic(__VA_ARGS__), ProfEnd())
////////////////////////////////
//~ rjf: General Markup
#define ThreadName(...) (ProfThreadName(__VA_ARGS__))
internal void thread_namef(char *fmt, ...);
internal void thread_name(String8 string);
#define ThreadNameF(...) (ProfThreadName(__VA_ARGS__), thread_namef(__VA_ARGS__))
#define ThreadName(str) (ProfThreadName("%s", str8_varg(str)), thread_name(str))
#endif // BASE_MARKUP_H
+2
View File
@@ -0,0 +1,2 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
+74
View File
@@ -0,0 +1,74 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_PROFILE_H
#define BASE_PROFILE_H
////////////////////////////////
//~ rjf: Zero Settings
#if !defined(PROFILE_TELEMETRY)
# define PROFILE_TELEMETRY 0
#endif
#if !defined(MARKUP_LAYER_COLOR)
# define MARKUP_LAYER_COLOR 1.00f, 0.00f, 1.00f
#endif
////////////////////////////////
//~ rjf: Third Party Includes
#if PROFILE_TELEMETRY
# include "rad_tm.h"
# if OS_WINDOWS
# pragma comment(lib, "rad_tm_win64.lib")
# endif
#endif
////////////////////////////////
//~ rjf: Telemetry Profile Defines
#if PROFILE_TELEMETRY
# define ProfBegin(...) tmEnter(0, 0, __VA_ARGS__)
# define ProfBeginDynamic(...) (TM_API_PTR ? TM_API_PTR->_tmEnterZoneV_Core(0, 0, __FILE__, &g_telemetry_filename_id, __LINE__, __VA_ARGS__) : (void)0)
# define ProfEnd(...) (TM_API_PTR ? TM_API_PTR->_tmLeaveZone(0) : (void)0)
# define ProfTick(...) tmTick(0)
# define ProfIsCapturing(...) tmRunning()
# define ProfBeginCapture(...) tmOpen(0, __VA_ARGS__, __DATE__, "localhost", TMCT_TCP, TELEMETRY_DEFAULT_PORT, TMOF_INIT_NETWORKING|TMOF_CAPTURE_CONTEXT_SWITCHES, 100)
# define ProfEndCapture(...) tmClose(0)
# define ProfThreadName(...) (TM_API_PTR ? TM_API_PTR->_tmThreadName(0, 0, __VA_ARGS__) : (void)0)
# define ProfMsg(...) (TM_API_PTR ? TM_API_PTR->_tmMessageV_Core(0, TMMF_ICON_NOTE, __FILE__, &g_telemetry_filename_id, __LINE__, __VA_ARGS__) : (void)0)
# define ProfBeginLockWait(...) tmStartWaitForLock(0, 0, __VA_ARGS__)
# define ProfEndLockWait(...) tmEndWaitForLock(0)
# define ProfLockTake(...) tmAcquiredLock(0, 0, __VA_ARGS__)
# define ProfLockDrop(...) tmReleasedLock(0, __VA_ARGS__)
# define ProfColor(color) tmZoneColorSticky(color)
#endif
////////////////////////////////
//~ rjf: Zeroify Undefined Defines
#if !defined(ProfBegin)
# define ProfBegin(...) (0)
# define ProfBeginDynamic(...) (0)
# define ProfEnd(...) (0)
# define ProfTick(...) (0)
# define ProfIsCapturing(...) (0)
# define ProfBeginCapture(...) (0)
# define ProfEndCapture(...) (0)
# define ProfThreadName(...) (0)
# define ProfMsg(...) (0)
# define ProfBeginLockWait(...) (0)
# define ProfEndLockWait(...) (0)
# define ProfLockTake(...) (0)
# define ProfLockDrop(...) (0)
# define ProfColor(...) (0)
#endif
////////////////////////////////
//~ rjf: Helper Wrappers
#define ProfBeginFunction(...) ProfBegin(this_function_name)
#define ProfScope(...) DeferLoop(ProfBeginDynamic(__VA_ARGS__), ProfEnd())
#endif // BASE_PROFILE_H
@@ -4,7 +4,7 @@
////////////////////////////////
//~ rjf: Third Party Includes
#if !SUPPLEMENT_UNIT
#if !BUILD_SUPPLEMENTARY_UNIT
# define STB_SPRINTF_IMPLEMENTATION
# define STB_SPRINTF_STATIC
# include "third_party/stb/stb_sprintf.h"
@@ -1306,7 +1306,7 @@ utf8_encode(U8 *str, U32 codepoint){
inc = 3;
}
else if (codepoint <= 0x10FFFF){
str[0] = (bitmask4 << 3) | ((codepoint >> 18) & bitmask3);
str[0] = (bitmask4 << 4) | ((codepoint >> 18) & bitmask3);
str[1] = bit8 | ((codepoint >> 12) & bitmask6);
str[2] = bit8 | ((codepoint >> 6) & bitmask6);
str[3] = bit8 | ( codepoint & bitmask6);
@@ -1565,6 +1565,64 @@ string_from_elapsed_time(Arena *arena, DateTime dt){
return(result);
}
////////////////////////////////
//~ rjf: Textual String Wrapping
internal String8List
wrapped_lines_from_string(Arena *arena, String8 string, U64 first_line_max_width, U64 max_width, U64 wrap_indent)
{
String8List list = {0};
Rng1U64 line_range = r1u64(0, 0);
U64 wrapped_indent_level = 0;
static char *spaces = " ";
for (U64 idx = 0; idx <= string.size; idx += 1){
U8 chr = idx < string.size ? string.str[idx] : 0;
if (chr == '\n'){
Rng1U64 candidate_line_range = line_range;
candidate_line_range.max = idx;
// NOTE(nick): when wrapping is interrupted with \n we emit a string without including \n
// because later tool_fprint_list inserts separator after each node
// except for last node, so don't strip last \n.
if (idx + 1 == string.size){
candidate_line_range.max += 1;
}
String8 substr = str8_substr(string, candidate_line_range);
str8_list_push(arena, &list, substr);
line_range = r1u64(idx+1,idx+1);
}
else
if (char_is_space(chr) || chr == 0){
Rng1U64 candidate_line_range = line_range;
candidate_line_range.max = idx;
String8 substr = str8_substr(string, candidate_line_range);
U64 width_this_line = max_width-wrapped_indent_level;
if (list.node_count == 0){
width_this_line = first_line_max_width;
}
if (substr.size > width_this_line){
String8 line = str8_substr(string, line_range);
if (wrapped_indent_level > 0){
line = push_str8f(arena, "%.*s%S", wrapped_indent_level, spaces, line);
}
str8_list_push(arena, &list, line);
line_range = r1u64(line_range.max+1, candidate_line_range.max);
wrapped_indent_level = ClampTop(64, wrap_indent);
}
else{
line_range = candidate_line_range;
}
}
}
if (line_range.min < string.size && line_range.max > line_range.min){
String8 line = str8_substr(string, line_range);
if (wrapped_indent_level > 0){
line = push_str8f(arena, "%.*s%S", wrapped_indent_level, spaces, line);
}
str8_list_push(arena, &list, line);
}
return list;
}
////////////////////////////////
//~ rjf: String <-> Color
@@ -1,8 +1,8 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_STRING_H
#define BASE_STRING_H
#ifndef BASE_STRINGS_H
#define BASE_STRINGS_H
////////////////////////////////
//~ rjf: Third Party Includes
@@ -326,6 +326,11 @@ internal String8 push_date_time_string(Arena *arena, DateTime *date_time);
internal String8 push_file_name_date_time_string(Arena *arena, DateTime *date_time);
internal String8 string_from_elapsed_time(Arena *arena, DateTime dt);
////////////////////////////////
//~ rjf: Textual String Wrapping
internal String8List wrapped_lines_from_string(Arena *arena, String8 string, U64 first_line_max_width, U64 max_width, U64 wrap_indent);
////////////////////////////////
//~ rjf: String <-> Color
@@ -368,4 +373,4 @@ internal U64 str8_deserial_read_block(String8 string, U64 off, U64 size, Stri
#define str8_deserial_read_array(string, off, ptr, count) str8_deserial_read((string), (off), (ptr), sizeof(*(ptr))*(count), sizeof(*(ptr)))
#define str8_deserial_read_struct(string, off, ptr) str8_deserial_read((string), (off), (ptr), sizeof(*(ptr)), sizeof(*(ptr)))
#endif // BASE_STRING_H
#endif // BASE_STRINGS_H
+10 -1
View File
@@ -5,7 +5,7 @@
// NOTE(allen): Thread Context Functions
C_LINKAGE thread_static TCTX* tctx_thread_local;
#if !SUPPLEMENT_UNIT
#if !BUILD_SUPPLEMENTARY_UNIT
C_LINKAGE thread_static TCTX* tctx_thread_local = 0;
#endif
@@ -19,6 +19,15 @@ tctx_init_and_equip(TCTX *tctx){
tctx_thread_local = tctx;
}
internal void
tctx_release(void)
{
for(U64 i = 0; i < ArrayCount(tctx_thread_local->arenas); i += 1)
{
arena_release(tctx_thread_local->arenas[i]);
}
}
internal TCTX*
tctx_get_equipped(void){
return(tctx_thread_local);
+1
View File
@@ -23,6 +23,7 @@ struct TCTX
// NOTE(allen): Thread Context Functions
internal void tctx_init_and_equip(TCTX *tctx);
internal void tctx_release(void);
internal TCTX* tctx_get_equipped(void);
internal Arena* tctx_get_scratch(Arena **conflicts, U64 count);
@@ -1,10 +1,15 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ Generated Code
#include "generated/codeview.meta.c"
////////////////////////////////
//~ CodeView Common Functions
static CV_NumericParsed
internal CV_NumericParsed
cv_numeric_from_data_range(U8 *first, U8 *opl){
CV_NumericParsed result = {0};
if (first + 2 <= opl){
@@ -52,7 +57,7 @@ cv_numeric_from_data_range(U8 *first, U8 *opl){
return(result);
}
static B32
internal B32
cv_numeric_fits_in_u64(CV_NumericParsed *num){
B32 result = 0;
switch (num->kind){
@@ -66,7 +71,7 @@ cv_numeric_fits_in_u64(CV_NumericParsed *num){
return(result);
}
static B32
internal B32
cv_numeric_fits_in_s64(CV_NumericParsed *num){
B32 result = 0;
switch (num->kind){
@@ -81,7 +86,7 @@ cv_numeric_fits_in_s64(CV_NumericParsed *num){
return(result);
}
static B32
internal B32
cv_numeric_fits_in_f64(CV_NumericParsed *num){
B32 result = 0;
switch (num->kind){
@@ -94,7 +99,7 @@ cv_numeric_fits_in_f64(CV_NumericParsed *num){
return(result);
}
static U64
internal U64
cv_u64_from_numeric(CV_NumericParsed *num){
U64 result = 0;
switch (num->kind){
@@ -116,7 +121,7 @@ cv_u64_from_numeric(CV_NumericParsed *num){
return(result);
}
static S64
internal S64
cv_s64_from_numeric(CV_NumericParsed *num){
S64 result = 0;
switch (num->kind){
@@ -143,7 +148,7 @@ cv_s64_from_numeric(CV_NumericParsed *num){
return(result);
}
static F64
internal F64
cv_f64_from_numeric(CV_NumericParsed *num){
F64 result = 0;
switch (num->kind){
@@ -164,54 +169,9 @@ cv_f64_from_numeric(CV_NumericParsed *num){
////////////////////////////////
//~ CodeView Sym Parser Functions
static CV_SymParsed*
cv_sym_from_data(Arena *arena, String8 sym_data, U64 sym_align){
Assert(1 <= sym_align && IsPow2OrZero(sym_align));
ProfBegin("cv_sym_from_data");
Temp scratch = scratch_begin(&arena, 1);
// gather up symbols
CV_RecRangeStream *stream = cv_rec_range_stream_from_data(scratch.arena, sym_data, sym_align);
// convert to result
CV_SymParsed *result = push_array(arena, CV_SymParsed, 1);
result->data = sym_data;
result->sym_align = sym_align;
result->sym_ranges = cv_rec_range_array_from_stream(arena, stream);
cv_sym_top_level_info_from_syms(arena, sym_data, &result->sym_ranges, &result->info);
scratch_end(scratch);
ProfEnd();
return(result);
}
//- the first pass parser
static CV_LeafParsed*
cv_leaf_from_data(Arena *arena, String8 leaf_data, CV_TypeId itype_first){
ProfBegin("cv_leaf_from_data");
Temp scratch = scratch_begin(&arena, 1);
// gather up symbols
CV_RecRangeStream *stream = cv_rec_range_stream_from_data(scratch.arena, leaf_data, 1);
// convert to result
CV_LeafParsed *result = push_array(arena, CV_LeafParsed, 1);
result->data = leaf_data;
result->itype_first = itype_first;
result->itype_opl = itype_first + stream->total_count;
result->leaf_ranges = cv_rec_range_array_from_stream(arena, stream);
scratch_end(scratch);
ProfEnd();
return(result);
}
static CV_RecRangeStream*
internal CV_RecRangeStream*
cv_rec_range_stream_from_data(Arena *arena, String8 sym_data, U64 sym_align){
Assert(1 <= sym_align && IsPow2OrZero(sym_align));
@@ -248,7 +208,33 @@ cv_rec_range_stream_from_data(Arena *arena, String8 sym_data, U64 sym_align){
return(result);
}
static void
//- sym
internal CV_SymParsed*
cv_sym_from_data(Arena *arena, String8 sym_data, U64 sym_align){
Assert(1 <= sym_align && IsPow2OrZero(sym_align));
ProfBegin("cv_sym_from_data");
Temp scratch = scratch_begin(&arena, 1);
// gather up symbols
CV_RecRangeStream *stream = cv_rec_range_stream_from_data(scratch.arena, sym_data, sym_align);
// convert to result
CV_SymParsed *result = push_array(arena, CV_SymParsed, 1);
result->data = sym_data;
result->sym_align = sym_align;
result->sym_ranges = cv_rec_range_array_from_stream(arena, stream);
cv_sym_top_level_info_from_syms(arena, sym_data, &result->sym_ranges, &result->info);
scratch_end(scratch);
ProfEnd();
return(result);
}
internal void
cv_sym_top_level_info_from_syms(Arena *arena, String8 sym_data,
CV_RecRangeArray *ranges,
CV_SymTopLevelInfo *info_out){
@@ -313,17 +299,41 @@ cv_sym_top_level_info_from_syms(Arena *arena, String8 sym_data,
}
}
//- leaf
internal CV_LeafParsed*
cv_leaf_from_data(Arena *arena, String8 leaf_data, CV_TypeId itype_first){
ProfBegin("cv_leaf_from_data");
Temp scratch = scratch_begin(&arena, 1);
// gather up symbols
CV_RecRangeStream *stream = cv_rec_range_stream_from_data(scratch.arena, leaf_data, 1);
// convert to result
CV_LeafParsed *result = push_array(arena, CV_LeafParsed, 1);
result->data = leaf_data;
result->itype_first = itype_first;
result->itype_opl = itype_first + stream->total_count;
result->leaf_ranges = cv_rec_range_array_from_stream(arena, stream);
scratch_end(scratch);
ProfEnd();
return(result);
}
//- range streams
static CV_RecRangeChunk*
internal CV_RecRangeChunk*
cv_rec_range_stream_push_chunk(Arena *arena, CV_RecRangeStream *stream){
CV_RecRangeChunk *result = push_array_no_zero(arena, CV_RecRangeChunk, 1);
SLLQueuePush(stream->first_chunk, stream->last_chunk, result);
return(result);
}
static CV_RecRangeArray
internal CV_RecRangeArray
cv_rec_range_array_from_stream(Arena *arena, CV_RecRangeStream *stream){
U64 total_count = stream->total_count;
CV_RecRange *ranges = push_array_no_zero(arena, CV_RecRange, total_count);
@@ -345,9 +355,8 @@ cv_rec_range_array_from_stream(Arena *arena, CV_RecRangeStream *stream){
////////////////////////////////
//~ CodeView C13 Parser Functions
static CV_C13Parsed*
cv_c13_from_data(Arena *arena, String8 c13_data,
PDB_Strtbl *strtbl, PDB_CoffSectionArray *sections){
internal CV_C13Parsed*
cv_c13_from_data(Arena *arena, String8 c13_data, PDB_Strtbl *strtbl, PDB_CoffSectionArray *sections){
ProfBegin("cv_c13_from_data");
// gather c13 data
@@ -399,76 +408,86 @@ cv_c13_from_data(Arena *arena, String8 c13_data,
{
// read header
if (sizeof(CV_C13_SubSecLinesHeader) <= cap){
CV_C13_SubSecLinesHeader *hdr = (CV_C13_SubSecLinesHeader*)first;
U32 read_off = 0;
U64 read_off_opl = node->size;
CV_C13_SubSecLinesHeader *hdr = (CV_C13_SubSecLinesHeader*)(first + read_off);
read_off += sizeof(*hdr);
// read file
U32 file_info_off = sizeof(*hdr);
if (file_info_off + sizeof(CV_C13_File) <= cap){
CV_C13_File *file = (CV_C13_File*)(first + file_info_off);
// extract top level info
U32 sec_idx = hdr->sec;
B32 has_cols = !!(hdr->flags & CV_C13_SubSecLinesFlag_HasColumns);
U64 secrel_off = hdr->sec_off;
U64 secrel_opl = secrel_off + hdr->len;
U64 sec_base_off = sections->sections[sec_idx - 1].voff;
// rjf: bad section index -> skip
if(sec_idx < 1 || sections->count < sec_idx)
{
continue;
}
// read files
for(;read_off+sizeof(CV_C13_File) <= read_off_opl;)
{
// rjf: grab next file header
CV_C13_File *file = (CV_C13_File*)(first + read_off);
U32 file_off = file->file_off;
U32 line_count_unclamped = file->num_lines;
U32 block_size = file->block_size;
// extract top level info
U32 sec_idx = hdr->sec;
if (1 <= sec_idx && sec_idx <= sections->count){
B32 has_cols = !!(hdr->flags & CV_C13_SubSecLinesFlag_HasColumns);
U64 secrel_off = hdr->sec_off;
U64 secrel_opl = secrel_off + hdr->len;
U64 sec_base_off = sections->sections[sec_idx - 1].voff;
U32 file_off = file->file_off;
U32 line_count_unclamped = file->num_lines;
U32 block_size = file->block_size;
// file_name from file_off
String8 file_name = {0};
if (file_off + sizeof(CV_C13_Checksum) <= file_chksms->size){
CV_C13_Checksum *checksum = (CV_C13_Checksum*)(c13_data.str + file_chksms->off + file_off);
U32 name_off = checksum->name_off;
file_name = pdb_strtbl_string_from_off(strtbl, name_off);
}
// array layouts
U32 line_item_size = sizeof(CV_C13_Line);
if (has_cols){
line_item_size += sizeof(CV_C13_Column);
}
U32 line_array_off = file_info_off + sizeof(*file);
U32 line_count_max = (cap - line_array_off)/line_item_size;
U32 line_count = ClampTop(line_count_unclamped, line_count_max);
U32 col_array_off = line_array_off + line_count*sizeof(CV_C13_Line);
// parse lines
U64 *voffs = push_array_no_zero(arena, U64, line_count + 1);
U32 *line_nums = push_array_no_zero(arena, U32, line_count);
{
CV_C13_Line *line_ptr = (CV_C13_Line*)(first + line_array_off);
CV_C13_Line *line_opl = line_ptr + line_count;
// TODO(allen): check order correctness here
U32 i = 0;
for (; line_ptr < line_opl; line_ptr += 1, i += 1){
voffs[i] = line_ptr->off + secrel_off + sec_base_off;
line_nums[i] = CV_C13_LineFlags_ExtractLineNumber(line_ptr->flags);
}
voffs[i] = secrel_opl + sec_base_off;
}
// emit parsed lines
CV_C13LinesParsed *lines_parsed = push_array(arena, CV_C13LinesParsed, 1);
lines_parsed->sec_idx = sec_idx;
lines_parsed->file_off = file_off;
lines_parsed->secrel_base_off = secrel_off;
lines_parsed->file_name = file_name;
lines_parsed->voffs = voffs;
lines_parsed->line_nums = line_nums;
lines_parsed->line_count = line_count;
node->lines = lines_parsed;
// file_name from file_off
String8 file_name = {0};
if (file_off + sizeof(CV_C13_Checksum) <= file_chksms->size){
CV_C13_Checksum *checksum = (CV_C13_Checksum*)(c13_data.str + file_chksms->off + file_off);
U32 name_off = checksum->name_off;
file_name = pdb_strtbl_string_from_off(strtbl, name_off);
}
// array layouts
U32 line_item_size = sizeof(CV_C13_Line);
if (has_cols){
line_item_size += sizeof(CV_C13_Column);
}
U32 line_array_off = read_off + sizeof(*file);
U32 line_count_max = (read_off_opl - line_array_off) / line_item_size;
U32 line_count = ClampTop(line_count_unclamped, line_count_max);
U32 col_array_off = line_array_off + line_count*sizeof(CV_C13_Line);
// parse lines
U64 *voffs = push_array_no_zero(arena, U64, line_count + 1);
U32 *line_nums = push_array_no_zero(arena, U32, line_count);
{
CV_C13_Line *line_ptr = (CV_C13_Line*)(first + line_array_off);
CV_C13_Line *line_opl = line_ptr + line_count;
// TODO(allen): check order correctness here
U32 i = 0;
for (; line_ptr < line_opl; line_ptr += 1, i += 1){
voffs[i] = line_ptr->off + secrel_off + sec_base_off;
line_nums[i] = CV_C13_LineFlags_ExtractLineNumber(line_ptr->flags);
}
voffs[i] = secrel_opl + sec_base_off;
}
// emit parsed lines
CV_C13LinesParsedNode *lines_parsed_node = push_array(arena, CV_C13LinesParsedNode, 1);
CV_C13LinesParsed *lines_parsed = &lines_parsed_node->v;
lines_parsed->sec_idx = sec_idx;
lines_parsed->file_off = file_off;
lines_parsed->secrel_base_off = secrel_off;
lines_parsed->file_name = file_name;
lines_parsed->voffs = voffs;
lines_parsed->line_nums = line_nums;
lines_parsed->line_count = line_count;
SLLQueuePush(node->lines_first, node->lines_last, lines_parsed_node);
// rjf: advance
read_off += sizeof(*file);
read_off += line_item_size*line_count;
}
}
}break;
File diff suppressed because it is too large Load Diff
+622
View File
@@ -0,0 +1,622 @@
////////////////////////////////
//~ rjf: CV Numerics
@table(name val)
CV_NumericKindTable:
{
{CHAR 0x8000}
{SHORT 0x8001}
{USHORT 0x8002}
{LONG 0x8003}
{ULONG 0x8004}
{FLOAT32 0x8005}
{FLOAT64 0x8006}
{FLOAT80 0x8007}
{FLOAT128 0x8008}
{QUADWORD 0x8009}
{UQUADWORD 0x800a}
{FLOAT48 0x800b}
{COMPLEX32 0x800c}
{COMPLEX64 0x800d}
{COMPLEX80 0x800e}
{COMPLEX128 0x800f}
{VARSTRING 0x8010}
{OCTWORD 0x8017}
{UOCTWORD 0x8018}
{DECIMAL 0x8019}
{DATE 0x801a}
{UTF8STRING 0x801b}
{FLOAT16 0x801c}
}
@enum(U16) CV_NumericKind:
{
@expand(CV_NumericKindTable a) `$(a.name) = $(a.val)`
}
@enum2string_switch(CV_NumericKind)
cv_string_from_numeric_kind:
{
@expand(CV_NumericKindTable a) `case CV_NumericKind_$(a.name):{result = str8_lit("$(a.name)");}break`;
}
////////////////////////////////
//~ rjf: CV Architectures
@table(name val)
CV_ArchTable:
{
{8080 0x00}
{8086 0x01}
{80286 0x02}
{80386 0x03}
{80486 0x04}
{PENTIUM 0x05}
{PENTIUMII 0x06}
{PENTIUMIII 0x07}
{MIPS 0x10}
{MIPS16 0x11}
{MIPS32 0x12}
{MIPS64 0x13}
{MIPSI 0x14}
{MIPSII 0x15}
{MIPSIII 0x16}
{MIPSIV 0x17}
{MIPSV 0x18}
{M68000 0x20}
{M68010 0x21}
{M68020 0x22}
{M68030 0x23}
{M68040 0x24}
{ALPHA 0x30}
{ALPHA_21164 0x31}
{ALPHA_21164A 0x32}
{ALPHA_21264 0x33}
{ALPHA_21364 0x34}
{PPC601 0x40}
{PPC603 0x41}
{PPC604 0x42}
{PPC620 0x43}
{PPCFP 0x44}
{PPCBE 0x45}
{SH3 0x50}
{SH3E 0x51}
{SH3DSP 0x52}
{SH4 0x53}
{SHMEDIA 0x54}
{ARM3 0x60}
{ARM4 0x61}
{ARM4T 0x62}
{ARM5 0x63}
{ARM5T 0x64}
{ARM6 0x65}
{ARM_XMAC 0x66}
{ARM_WMMX 0x67}
{ARM7 0x68}
{OMNI 0x70}
{IA64_1 0x80}
{IA64_2 0x81}
{CEE 0x90}
{AM33 0xA0}
{M32R 0xB0}
{TRICORE 0xC0}
{X64 0xD0}
{EBC 0xE0}
{THUMB 0xF0}
{ARMNT 0xF4}
{ARM64 0xF6}
{D3D11_SHADER 0x100}
}
@enum(U16) CV_Arch:
{
@expand(CV_ArchTable a) `$(a.name) = $(a.val)`,
`IA64 = CV_Arch_IA64_1`,
`PENTIUMPRO = CV_Arch_PENTIUMII`,
`MIPSR4000 = CV_Arch_MIPS`,
`ALPHA_21064 = CV_Arch_ALPHA`,
`AMD64 = CV_Arch_X64`,
}
@enum2string_switch(CV_Arch)
cv_string_from_arch:
{
@expand(CV_ArchTable a) `case CV_Arch_$(a.name):{result = str8_lit("$(a.name)");}break`;
}
////////////////////////////////
//~ rjf: CV Registers
@table(name val) CV_AllRegTable:
{
{ERR 30000}
{TEB 30001}
{TIMER 30002}
{EFAD1 30003}
{EFAD2 30004}
{EFAD3 30005}
{VFRAME 30006}
{HANDLE 30007}
{PARAMS 30008}
{LOCALS 30009}
{TID 30010}
{ENV 30011}
{CMDLN 30012}
}
@enum(U16) CV_AllReg:
{
@expand(CV_AllRegTable a) `$(a.name) = $(a.val)`
}
////////////////////////////////
//~ rjf: CV Sym Kinds
@table(name header_type_name val) CV_SymKindTable:
{
{COMPILE Compile 0x0001}
{REGISTER_16t - 0x0002}
{CONSTANT_16t - 0x0003}
{UDT_16t - 0x0004}
{SSEARCH StartSearch 0x0005}
{END - 0x0006}
{SKIP - 0x0007}
{CVRESERVE - 0x0008}
{OBJNAME_ST - 0x0009}
{ENDARG - 0x000a}
{COBOLUDT_16t - 0x000b}
{MANYREG_16t - 0x000c}
{RETURN Return 0x000d}
{ENTRYTHIS - 0x000e}
{BPREL16 - 0x0100}
{LDATA16 - 0x0101}
{GDATA16 - 0x0102}
{PUB16 - 0x0103}
{LPROC16 - 0x0104}
{GPROC16 - 0x0105}
{THUNK16 - 0x0106}
{BLOCK16 - 0x0107}
{WITH16 - 0x0108}
{LABEL16 - 0x0109}
{CEXMODEL16 - 0x010a}
{VFTABLE16 - 0x010b}
{REGREL16 - 0x010c}
{BPREL32_16t - 0x0200}
{LDATA32_16t - 0x0201}
{GDATA32_16t - 0x0202}
{PUB32_16t - 0x0203}
{LPROC32_16t - 0x0204}
{GPROC32_16t - 0x0205}
{THUNK32_ST - 0x0206}
{BLOCK32_ST - 0x0207}
{WITH32_ST - 0x0208}
{LABEL32_ST - 0x0209}
{CEXMODEL32 - 0x020a}
{VFTABLE32_16t - 0x020b}
{REGREL32_16t - 0x020c}
{LTHREAD32_16t - 0x020d}
{GTHREAD32_16t - 0x020e}
{SLINK32 SLink32 0x020f}
{LPROCMIPS_16t - 0x0300}
{GPROCMIPS_16t - 0x0301}
{PROCREF_ST - 0x0400}
{DATAREF_ST - 0x0401}
{ALIGN - 0x0402}
{LPROCREF_ST - 0x0403}
{OEM OEM 0x0404}
{TI16_MAX - 0x1000}
{CONSTANT_ST - 0x1002}
{UDT_ST - 0x1003}
{COBOLUDT_ST - 0x1004}
{MANYREG_ST - 0x1005}
{BPREL32_ST - 0x1006}
{LDATA32_ST - 0x1007}
{GDATA32_ST - 0x1008}
{PUB32_ST - 0x1009}
{LPROC32_ST - 0x100a}
{GPROC32_ST - 0x100b}
{VFTABLE32 VPath32 0x100c}
{REGREL32_ST - 0x100d}
{LTHREAD32_ST - 0x100e}
{GTHREAD32_ST - 0x100f}
{LPROCMIPS_ST - 0x1010}
{GPROCMIPS_ST - 0x1011}
{FRAMEPROC Frameproc 0x1012}
{COMPILE2_ST - 0x1013}
{MANYREG2_ST - 0x1014}
{LPROCIA64_ST - 0x1015}
{GPROCIA64_ST - 0x1016}
{LOCALSLOT_ST - 0x1017}
{PARAMSLOT_ST - 0x1018}
{ANNOTATION Annotation 0x1019}
{GMANPROC_ST - 0x101a}
{LMANPROC_ST - 0x101b}
{RESERVED1 - 0x101c}
{RESERVED2 - 0x101d}
{RESERVED3 - 0x101e}
{RESERVED4 - 0x101f}
{LMANDATA_ST - 0x1020}
{GMANDATA_ST - 0x1021}
{MANFRAMEREL_ST - 0x1022}
{MANREGISTER_ST - 0x1023}
{MANSLOT_ST - 0x1024}
{MANMANYREG_ST - 0x1025}
{MANREGREL_ST - 0x1026}
{MANMANYREG2_ST - 0x1027}
{MANTYPREF - 0x1028}
{UNAMESPACE_ST - 0x1029}
{ST_MAX - 0x1100}
{OBJNAME Objname 0x1101}
{THUNK32 Thunk32 0x1102}
{BLOCK32 Block32 0x1103}
{WITH32 - 0x1104}
{LABEL32 Label32 0x1105}
{REGISTER Register 0x1106}
{CONSTANT Constant 0x1107}
{UDT UDT 0x1108}
{COBOLUDT - 0x1109}
{MANYREG Manyreg 0x110a}
{BPREL32 BPRel32 0x110b}
{LDATA32 Data32 0x110c}
{GDATA32 Data32 0x110d}
{PUB32 Pub32 0x110e}
{LPROC32 Proc32 0x110f}
{GPROC32 Proc32 0x1110}
{REGREL32 Regrel32 0x1111}
{LTHREAD32 Thread32 0x1112}
{GTHREAD32 Thread32 0x1113}
{LPROCMIPS - 0x1114}
{GPROCMIPS - 0x1115}
{COMPILE2 Compile2 0x1116}
{MANYREG2 Manyreg2 0x1117}
{LPROCIA64 - 0x1118}
{GPROCIA64 - 0x1119}
{LOCALSLOT Slot 0x111a}
{PARAMSLOT - 0x111b}
{LMANDATA - 0x111c}
{GMANDATA - 0x111d}
{MANFRAMEREL AttrFrameRel 0x111e}
{MANREGISTER AttrReg 0x111f}
{MANSLOT - 0x1120}
{MANMANYREG AttrManyReg 0x1121}
{MANREGREL AttrRegRel 0x1122}
{MANMANYREG2 - 0x1123}
{UNAMESPACE UNamespace 0x1124}
{PROCREF Ref2 0x1125}
{DATAREF Ref2 0x1126}
{LPROCREF Ref2 0x1127}
{ANNOTATIONREF - 0x1128}
{TOKENREF - 0x1129}
{GMANPROC - 0x112a}
{LMANPROC - 0x112b}
{TRAMPOLINE Trampoline 0x112c}
{MANCONSTANT - 0x112d}
{ATTR_FRAMEREL AttrFrameRel 0x112e}
{ATTR_REGISTER AttrReg 0x112f}
{ATTR_REGREL AttrRegRel 0x1130}
{ATTR_MANYREG AttrManyReg 0x1131}
{SEPCODE Sepcode 0x1132}
{DEFRANGE_2005 - 0x1134}
{DEFRANGE2_2005 - 0x1135}
{SECTION Section 0x1136}
{COFFGROUP CoffGroup 0x1137}
{EXPORT Export 0x1138}
{CALLSITEINFO CallSiteInfo 0x1139}
{FRAMECOOKIE FrameCookie 0x113a}
{DISCARDED Discarded 0x113b}
{COMPILE3 Compile3 0x113c}
{ENVBLOCK EnvBlock 0x113d}
{LOCAL Local 0x113e}
{DEFRANGE - 0x113f}
{DEFRANGE_SUBFIELD DefrangeSubfield 0x1140}
{DEFRANGE_REGISTER DefrangeRegister 0x1141}
{DEFRANGE_FRAMEPOINTER_REL DefrangeFramepointerRel 0x1142}
{DEFRANGE_SUBFIELD_REGISTER DefrangeSubfieldRegister 0x1143}
{DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE DefrangeFramepointerRelFullScope 0x1144}
{DEFRANGE_REGISTER_REL DefrangeRegisterRel 0x1145}
{LPROC32_ID - 0x1146}
{GPROC32_ID - 0x1147}
{LPROCMIPS_ID - 0x1148}
{GPROCMIPS_ID - 0x1149}
{LPROCIA64_ID - 0x114a}
{GPROCIA64_ID - 0x114b}
{BUILDINFO BuildInfo 0x114c}
{INLINESITE InlineSite 0x114d}
{INLINESITE_END - 0x114e}
{PROC_ID_END - 0x114f}
{DEFRANGE_HLSL - 0x1150}
{GDATA_HLSL - 0x1151}
{LDATA_HLSL - 0x1152}
{FILESTATIC FileStatic 0x1153}
{LPROC32_DPC - 0x1155}
{LPROC32_DPC_ID - 0x1156}
{DEFRANGE_DPC_PTR_TAG - 0x1157}
{DPC_SYM_TAG_MAP - 0x1158}
{ARMSWITCHTABLE - 0x1159}
{CALLEES FunctionList 0x115a}
{CALLERS FunctionList 0x115b}
{POGODATA PogoInfo 0x115c}
{INLINESITE2 InlineSite2 0x115d}
{HEAPALLOCSITE HeapAllocSite 0x115e}
{MOD_TYPEREF ModTypeRef 0x115f}
{REF_MINIPDB RefMiniPdb 0x1160}
{PDBMAP - 0x1161}
{GDATA_HLSL32 - 0x1162}
{LDATA_HLSL32 - 0x1163}
{GDATA_HLSL32_EX - 0x1164}
{LDATA_HLSL32_EX - 0x1165}
{FASTLINK FastLink 0x1167}
{INLINEES Inlinees 0x1168}
}
@enum(U16) CV_SymKind:
{
@expand(CV_SymKindTable a) `$(a.name) = $(a.val)`
}
@enum2string_switch(CV_SymKind)
cv_string_from_sym_kind:
{
@expand(CV_SymKindTable a) `case CV_SymKind_$(a.name):{result = str8_lit("$(a.name)");}break`;
}
@gen(functions)
{
`internal U64 cv_header_struct_size_from_sym_kind(CV_SymKind v);`;
}
@gen(functions) @c_file
{
`internal U64`;
`cv_header_struct_size_from_sym_kind(CV_SymKind v)`;
`{`;
`U64 result = 0;`;
`switch(v)`;
`{`;
`default:{}break;`;
@expand(CV_SymKindTable a) `$(a.header_type_name != "-" -> "case CV_SymKind_"..a.name..":{result = sizeof(CV_Sym"..a.header_type_name..");}break;")`;
`}`;
`return result;`;
`}`;
}
////////////////////////////////
//~ rjf: CV Basic Types
@table(name val type_name)
CV_BasicTypeTable:
{
{NOTYPE 0x00 "" }
{ABS 0x01 "" }
{SEGMENT 0x02 "" }
{VOID 0x03 "void" }
{CURRENCY 0x04 "" }
{NBASICSTR 0x05 "" }
{FBASICSTR 0x06 "" }
{NOTTRANS 0x07 "" }
{HRESULT 0x08 "HRESULT" }
{CHAR 0x10 "char" }
{SHORT 0x11 "S16" }
{LONG 0x12 "S32" }
{QUAD 0x13 "S64" }
{OCT 0x14 "S128" }
{UCHAR 0x20 "UCHAR" }
{USHORT 0x21 "U16" }
{ULONG 0x22 "U32" }
{UQUAD 0x23 "U64" }
{UOCT 0x24 "U128" }
{BOOL8 0x30 "B8" }
{BOOL16 0x31 "B16" }
{BOOL32 0x32 "B32" }
{BOOL64 0x33 "B64" }
{FLOAT32 0x40 "F32" }
{FLOAT64 0x41 "F64" }
{FLOAT80 0x42 "F80" }
{FLOAT128 0x43 "F128" }
{FLOAT48 0x44 "F48" }
{FLOAT32PP 0x45 "F32PP" }
{FLOAT16 0x46 "F16" }
{COMPLEX32 0x50 "ComplexF32" }
{COMPLEX64 0x51 "ComplexF64" }
{COMPLEX80 0x52 "ComplexF80" }
{COMPLEX128 0x53 "ComplexF128" }
{BIT 0x60 "" }
{PASCHAR 0x61 "" }
{BOOL32FF 0x62 "B32FF" }
{INT8 0x68 "S8" }
{UINT8 0x69 "U8" }
{RCHAR 0x70 "char" }
{WCHAR 0x71 "WCHAR" }
{INT16 0x72 "S16" }
{UINT16 0x73 "U16" }
{INT32 0x74 "S32" }
{UINT32 0x75 "U32" }
{INT64 0x76 "S64" }
{UINT64 0x77 "U64" }
{INT128 0x78 "S128" }
{UINT128 0x79 "U128" }
{CHAR16 0x7a "CHAR16" }
{CHAR32 0x7b "CHAR32" }
{CHAR8 0x7c "char" }
{PTR 0xf0 "PTR" }
}
@enum(U8) CV_BasicType:
{
@expand(CV_BasicTypeTable a) `$(a.name) = $(a.val)`
}
@enum2string_switch(CV_BasicType) cv_string_from_basic_type:
{
@expand(CV_BasicTypeTable a) `case CV_BasicType_$(a.name):{result = str8_lit("$(a.name)");}break`
}
@enum2string_switch(CV_BasicType) cv_type_name_from_basic_type:
{
@expand(CV_BasicTypeTable a) `case CV_BasicType_$(a.name):{result = str8_lit("$(a.type_name)");}break`
}
////////////////////////////////
//~ rjf: CV Leaf Kinds
@table(name header_type_name val)
CV_LeafKindTable:
{
{MODIFIER_16t - 0x0001}
{POINTER_16t - 0x0002}
{ARRAY_16t - 0x0003}
{CLASS_16t - 0x0004}
{STRUCTURE_16t - 0x0005}
{UNION_16t - 0x0006}
{ENUM_16t - 0x0007}
{PROCEDURE_16t - 0x0008}
{MFUNCTION_16t - 0x0009}
{VTSHAPE VTShape 0x000a}
{COBOL0_16t - 0x000b}
{COBOL1 - 0x000c}
{BARRAY_16t - 0x000d}
{LABEL Label 0x000e}
{NULL - 0x000f}
{NOTTRAN - 0x0010}
{DIMARRAY_16t - 0x0011}
{VFTPATH_16t - 0x0012}
{PRECOMP_16t - 0x0013}
{ENDPRECOMP - 0x0014}
{OEM_16t - 0x0015}
{TYPESERVER_ST - 0x0016}
{SKIP_16t - 0x0200}
{ARGLIST_16t - 0x0201}
{DEFARG_16t - 0x0202}
{LIST - 0x0203}
{FIELDLIST_16t - 0x0204}
{DERIVED_16t - 0x0205}
{BITFIELD_16t - 0x0206}
{METHODLIST_16t - 0x0207}
{DIMCONU_16t - 0x0208}
{DIMCONLU_16t - 0x0209}
{DIMVARU_16t - 0x020a}
{DIMVARLU_16t - 0x020b}
{REFSYM - 0x020c}
{BCLASS_16t - 0x0400}
{VBCLASS_16t - 0x0401}
{IVBCLASS_16t - 0x0402}
{ENUMERATE_ST - 0x0403}
{FRIENDFCN_16t - 0x0404}
{INDEX_16t - 0x0405}
{MEMBER_16t - 0x0406}
{STMEMBER_16t - 0x0407}
{METHOD_16t - 0x0408}
{NESTTYPE_16t - 0x0409}
{VFUNCTAB_16t - 0x040a}
{FRIENDCLS_16t - 0x040b}
{ONEMETHOD_16t - 0x040c}
{VFUNCOFF_16t - 0x040d}
{TI16_MAX - 0x1000}
{MODIFIER Modifier 0x1001}
{POINTER Pointer 0x1002}
{ARRAY_ST - 0x1003}
{CLASS_ST - 0x1004}
{STRUCTURE_ST - 0x1005}
{UNION_ST - 0x1006}
{ENUM_ST - 0x1007}
{PROCEDURE Procedure 0x1008}
{MFUNCTION MFunction 0x1009}
{COBOL0 - 0x100a}
{BARRAY - 0x100b}
{DIMARRAY_ST - 0x100c}
{VFTPATH VFPath 0x100d}
{PRECOMP_ST - 0x100e}
{OEM - 0x100f}
{ALIAS_ST - 0x1010}
{OEM2 - 0x1011}
{SKIP Skip 0x1200}
{ARGLIST ArgList 0x1201}
{DEFARG_ST - 0x1202}
{FIELDLIST - 0x1203}
{DERIVED - 0x1204}
{BITFIELD BitField 0x1205}
{METHODLIST MethodListMember 0x1206}
{DIMCONU - 0x1207}
{DIMCONLU - 0x1208}
{DIMVARU - 0x1209}
{DIMVARLU - 0x120a}
{BCLASS BClass 0x1400}
{VBCLASS VBClass 0x1401}
{IVBCLASS - 0x1402}
{FRIENDFCN_ST - 0x1403}
{INDEX Index 0x1404}
{MEMBER_ST - 0x1405}
{STMEMBER_ST - 0x1406}
{METHOD_ST - 0x1407}
{NESTTYPE_ST - 0x1408}
{VFUNCTAB VFuncTab 0x1409}
{FRIENDCLS - 0x140a}
{ONEMETHOD_ST - 0x140b}
{VFUNCOFF VFuncOff 0x140c}
{NESTTYPEEX_ST - 0x140d}
{MEMBERMODIFY_ST - 0x140e}
{MANAGED_ST - 0x140f}
{ST_MAX - 0x1500}
{TYPESERVER TypeServer 0x1501}
{ENUMERATE Enumerate 0x1502}
{ARRAY Array 0x1503}
{CLASS Struct 0x1504}
{STRUCTURE Struct 0x1505}
{UNION Union 0x1506}
{ENUM Enum 0x1507}
{DIMARRAY - 0x1508}
{PRECOMP PreComp 0x1509}
{ALIAS Alias 0x150a}
{DEFARG - 0x150b}
{FRIENDFCN - 0x150c}
{MEMBER Member 0x150d}
{STMEMBER StMember 0x150e}
{METHOD Method 0x150f}
{NESTTYPE NestType 0x1510}
{ONEMETHOD OneMethod 0x1511}
{NESTTYPEEX NestTypeEx 0x1512}
{MEMBERMODIFY - 0x1513}
{MANAGED - 0x1514}
{TYPESERVER2 TypeServer2 0x1515}
{STRIDED_ARRAY - 0x1516}
{HLSL - 0x1517}
{MODIFIER_EX - 0x1518}
{INTERFACE Struct 0x1519}
{BINTERFACE - 0x151a}
{VECTOR - 0x151b}
{MATRIX - 0x151c}
{VFTABLE - 0x151d}
{CLASS2 Struct2 0x1608}
{STRUCT2 Struct2 0x1609}
}
@enum(U16) CV_LeafKind:
{
@expand(CV_LeafKindTable a) `$(a.name) = $(a.val)`;
}
@enum2string_switch(CV_LeafKind)
cv_string_from_leaf_kind:
{
@expand(CV_LeafKindTable a) `case CV_LeafKind_$(a.name):{result = str8_lit("$(a.name)");}break`;
}
@gen(functions)
{
`internal U64 cv_header_struct_size_from_leaf_kind(CV_LeafKind v);`;
}
@gen(functions) @c_file
{
`internal U64`;
`cv_header_struct_size_from_leaf_kind(CV_LeafKind v)`;
`{`;
`U64 result = 0;`;
`switch(v)`;
`{`;
`default:{}break;`;
@expand(CV_LeafKindTable a) `$(a.header_type_name != "-" -> "case CV_LeafKind_"..a.name..":{result = sizeof(CV_Leaf"..a.header_type_name..");}break;")`;
`}`;
`return result;`;
`}`;
}
@@ -4,7 +4,7 @@
////////////////////////////////
//~ CodeView Common Stringize Functions
static void
internal void
cv_stringize_numeric(Arena *arena, String8List *out, CV_NumericParsed *num){
String8 numeric_kind_str = cv_string_from_numeric_kind(num->kind);
str8_list_pushf(arena, out, "(%.*s)", str8_varg(numeric_kind_str));
@@ -23,17 +23,17 @@ cv_stringize_numeric(Arena *arena, String8List *out, CV_NumericParsed *num){
}
}
static void
internal void
cv_stringize_lvar_addr_range(Arena *arena, String8List *out, CV_LvarAddrRange *range){
str8_list_pushf(arena, out, "{off=%x, sec=%u, len=%u}", range->off, range->sec, range->len);
}
static void
internal void
cv_stringize_lvar_addr_gap(Arena *arena, String8List *out, CV_LvarAddrGap *gap){
str8_list_pushf(arena, out, "{off=%x, len=%u}", gap->off, gap->len);
}
static void
internal void
cv_stringize_lvar_addr_gap_list(Arena *arena, String8List *out, void *first, void *opl){
U64 gap_count = ((U8*)first - (U8*)opl)/sizeof(CV_LvarAddrGap);
if (gap_count > 0){
@@ -48,56 +48,7 @@ cv_stringize_lvar_addr_gap_list(Arena *arena, String8List *out, void *first, voi
}
}
static String8
cv_string_from_sym_kind(CV_SymKind kind){
String8 result = str8_lit("UNRECOGNIZED_SYM_KIND");
switch (kind){
#define X(N,c) case CV_SymKind_##N: result = str8_lit(#N); break;
CV_SymKindXList(X)
#undef X
}
return(result);
}
static String8
cv_string_from_basic_type(CV_BasicType basic_type){
String8 result = str8_lit("UNRECOGNIZED_BASIC_TYPE");
switch (basic_type){
#define X(N,c) case CV_BasicType_##N: result = str8_lit(#N); break;
CV_BasicTypeXList(X)
#undef X
}
return(result);
}
static String8
cv_string_from_leaf_kind(CV_LeafKind kind){
String8 result = str8_lit("UNRECOGNIZED_LEAF_KIND");
switch (kind){
#define X(N,c) case CV_LeafKind_##N: result = str8_lit(#N); break;
CV_LeafKindXList(X)
#undef X
#define X(N,c) case CV_LeafIDKind_##N: result = str8_lit(#N); break;
CV_LeafIDKindXList(X)
#undef X
}
return(result);
}
static String8
cv_string_from_numeric_kind(CV_NumericKind kind){
String8 result = str8_lit("UNRECOGNIZED_NUMERIC_KIND");
switch (kind){
case 0: str8_lit("PARSE_ERROR"); break;
#define X(N,c) case CV_NumericKind_##N: result = str8_lit(#N); break;
CV_NumericKindXList(X)
#undef X
}
return(result);
}
static String8
internal String8
cv_string_from_c13_sub_section_kind(CV_C13_SubSectionKind kind){
String8 result = str8_lit("UNRECOGNIZED_C13_SUB_SECTION_KIND");
switch (kind){
@@ -109,18 +60,7 @@ cv_string_from_c13_sub_section_kind(CV_C13_SubSectionKind kind){
return(result);
}
static String8
cv_string_from_machine(CV_Arch arch){
String8 result = {0};
switch (arch){
#define X(N,c) case CV_Arch_##N: result = str8_lit(#N); break;
CV_ArchXList(X)
#undef X
}
return(result);
}
static String8
internal String8
cv_string_from_reg(CV_Arch arch, CV_Reg reg){
String8 result = {0};
switch (arch){
@@ -147,7 +87,7 @@ cv_string_from_reg(CV_Arch arch, CV_Reg reg){
return(result);
}
static String8
internal String8
cv_string_from_pointer_kind(CV_PointerKind ptr_kind){
String8 result = {0};
switch (ptr_kind){
@@ -169,7 +109,7 @@ cv_string_from_pointer_kind(CV_PointerKind ptr_kind){
return(result);
}
static String8
internal String8
cv_string_from_pointer_mode(CV_PointerMode ptr_mode){
String8 result = {0};
switch (ptr_mode){
@@ -183,7 +123,7 @@ cv_string_from_pointer_mode(CV_PointerMode ptr_mode){
return(result);
}
static String8
internal String8
cv_string_from_hfa_kind(CV_HFAKind hfa_kind){
String8 result = {0};
switch (hfa_kind){
@@ -196,7 +136,7 @@ cv_string_from_hfa_kind(CV_HFAKind hfa_kind){
return(result);
}
static String8
internal String8
cv_string_from_mo_com_udt_kind(CV_MoComUDTKind mo_com_udt_kind){
String8 result = {0};
switch (mo_com_udt_kind){
@@ -212,11 +152,11 @@ cv_string_from_mo_com_udt_kind(CV_MoComUDTKind mo_com_udt_kind){
////////////////////////////////
//~ CodeView Flags Stringize Functions
static char cv_stringize_spaces[] = " ";
global char cv_stringize_spaces[] = " ";
#define SPACES cv_stringize_spaces
static void
internal void
cv_stringize_modifier_flags(Arena *arena, String8List *out,
U32 indent, CV_ModifierFlags flags){
if (flags & CV_ModifierFlag_Const){
@@ -230,7 +170,7 @@ cv_stringize_modifier_flags(Arena *arena, String8List *out,
}
}
static void
internal void
cv_stringize_type_props(Arena *arena, String8List *out,
U32 indent, CV_TypeProps props){
if (props & CV_TypeProp_Packed){
@@ -285,7 +225,7 @@ cv_stringize_type_props(Arena *arena, String8List *out,
}
}
static void
internal void
cv_stringize_pointer_attribs(Arena *arena, String8List *out,
U32 indent, CV_PointerAttribs attribs){
if (attribs & CV_PointerAttrib_IsFlat){
@@ -332,7 +272,7 @@ cv_stringize_pointer_attribs(Arena *arena, String8List *out,
indent, SPACES, size);
}
static void
internal void
cv_stringize_local_flags(Arena *arena, String8List *out,
U32 indent, CV_LocalFlags flags){
if (flags & CV_LocalFlag_Param){
@@ -376,7 +316,7 @@ cv_stringize_local_flags(Arena *arena, String8List *out,
////////////////////////////////
//~ CodeView Sym Stringize Functions
static void
internal void
cv_stringize_sym_parsed(Arena *arena, String8List *out, CV_SymParsed *sym){
CV_StringizeSymParams params = {0};
params.arch = sym->info.arch;
@@ -384,7 +324,7 @@ cv_stringize_sym_parsed(Arena *arena, String8List *out, CV_SymParsed *sym){
cv_stringize_sym_array(arena, out, &sym->sym_ranges, sym->data, &params);
}
static void
internal void
cv_stringize_sym_range(Arena *arena, String8List *out,
CV_RecRange *range, String8 data,
CV_StringizeSymParams *p){
@@ -417,7 +357,7 @@ cv_stringize_sym_range(Arena *arena, String8List *out,
CV_SymCompile *compile = (CV_SymCompile*)first;
// machine
String8 machine = cv_string_from_machine(compile->machine);
String8 machine = cv_string_from_arch(compile->machine);
str8_list_pushf(arena, out, " machine=%.*s\n",
str8_varg(machine));
@@ -742,7 +682,7 @@ cv_stringize_sym_range(Arena *arena, String8List *out,
str8_list_pushf(arena, out, " flags=%x\n", compile2->flags);
// machine
String8 machine = cv_string_from_machine(compile2->machine);
String8 machine = cv_string_from_arch(compile2->machine);
str8_list_pushf(arena, out, " machine=%.*s\n",
str8_varg(machine));
@@ -906,7 +846,7 @@ cv_stringize_sym_range(Arena *arena, String8List *out,
str8_list_pushf(arena, out, " flags=%x\n", compile3->flags);
// machine
String8 machine = cv_string_from_machine(compile3->machine);
String8 machine = cv_string_from_arch(compile3->machine);
str8_list_pushf(arena, out, " machine=%.*s\n",
str8_varg(machine));
@@ -1381,7 +1321,7 @@ cv_stringize_sym_range(Arena *arena, String8List *out,
}
}
static void
internal void
cv_stringize_sym_array(Arena *arena, String8List *out,
CV_RecRangeArray *ranges, String8 data,
CV_StringizeSymParams *p){
@@ -1396,7 +1336,7 @@ cv_stringize_sym_array(Arena *arena, String8List *out,
////////////////////////////////
//~ CodeView Leaf Stringize Functions
static void
internal void
cv_stringize_leaf_parsed(Arena *arena, String8List *out, CV_LeafParsed *leaf){
CV_StringizeLeafParams params = {0};
@@ -1404,7 +1344,7 @@ cv_stringize_leaf_parsed(Arena *arena, String8List *out, CV_LeafParsed *leaf){
leaf->data, &params);
}
static void
internal void
cv_stringize_leaf_range(Arena *arena, String8List *out,
CV_RecRange *range, CV_TypeId itype, String8 data,
CV_StringizeLeafParams *p){
@@ -2312,7 +2252,7 @@ cv_stringize_leaf_range(Arena *arena, String8List *out,
}
}
static void
internal void
cv_stringize_leaf_array(Arena *arena, String8List *out,
CV_RecRangeArray *ranges, CV_TypeId itype_first, String8 data,
CV_StringizeLeafParams *p){
@@ -2328,23 +2268,28 @@ cv_stringize_leaf_array(Arena *arena, String8List *out,
////////////////////////////////
//~ CodeView C13 Stringize Functions
static void
internal void
cv_stringize_c13_parsed(Arena *arena, String8List *out, CV_C13Parsed *c13){
for (CV_C13SubSectionNode *node = c13->first_sub_section;
node != 0;
node = node->next){
for(CV_C13SubSectionNode *node = c13->first_sub_section;
node != 0;
node = node->next)
{
String8 kind_str = cv_string_from_c13_sub_section_kind(node->kind);
str8_list_pushf(arena, out, "C13 Sub Section [%llx] (%.*s):\n",
node->off, str8_varg(kind_str));
switch (node->kind){
switch(node->kind)
{
case CV_C13_SubSectionKind_Lines:
{
CV_C13LinesParsed *lines = node->lines;
if (lines == 0){
if (node->lines_first == 0)
{
str8_list_push(arena, out, str8_lit(" failed to extract info\n"));
}
else{
else for(CV_C13LinesParsedNode *n = node->lines_first; n != 0; n = n->next)
{
CV_C13LinesParsed *lines = &n->v;
str8_list_pushf(arena, out, " section: %u\n", lines->sec_idx);
str8_list_pushf(arena, out, " file off: %u\n", lines->file_off);
str8_list_pushf(arena, out, " file name: %.*s\n", str8_varg(lines->file_name));
+82
View File
@@ -0,0 +1,82 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef CODEVIEW_STRINGIZE_H
#define CODEVIEW_STRINGIZE_H
////////////////////////////////
//~ CodeView Stringize Helper Types
typedef struct CV_StringizeSymParams{
CV_Arch arch;
} CV_StringizeSymParams;
typedef struct CV_StringizeLeafParams{
U32 dummy;
} CV_StringizeLeafParams;
////////////////////////////////
//~ CodeView Common Stringize Functions
internal void cv_stringize_numeric(Arena *arena, String8List *out, CV_NumericParsed *num);
internal void cv_stringize_lvar_addr_range(Arena *arena, String8List *out,
CV_LvarAddrRange *range);
internal void cv_stringize_lvar_addr_gap(Arena *arena, String8List *out, CV_LvarAddrGap *gap);
internal void cv_stringize_lvar_addr_gap_list(Arena *arena, String8List *out,
void *first, void *opl);
internal String8 cv_string_from_basic_type(CV_BasicType basic_type);
internal String8 cv_string_from_c13_sub_section_kind(CV_C13_SubSectionKind kind);
internal String8 cv_string_from_reg(CV_Arch arch, CV_Reg reg);
internal String8 cv_string_from_pointer_kind(CV_PointerKind ptr_kind);
internal String8 cv_string_from_pointer_mode(CV_PointerMode ptr_mode);
internal String8 cv_string_from_hfa_kind(CV_HFAKind hfa_kind);
internal String8 cv_string_from_mo_com_udt_kind(CV_MoComUDTKind mo_com_udt_kind);
////////////////////////////////
//~ CodeView Flags Stringize Functions
internal void cv_stringize_modifier_flags(Arena *arena, String8List *out,
U32 indent, CV_ModifierFlags flags);
internal void cv_stringize_type_props(Arena *arena, String8List *out,
U32 indent, CV_TypeProps props);
internal void cv_stringize_pointer_attribs(Arena *arena, String8List *out,
U32 indent, CV_PointerAttribs attribs);
internal void cv_stringize_local_flags(Arena *arena, String8List *out,
U32 indent, CV_LocalFlags flags);
////////////////////////////////
//~ CodeView Sym Stringize Functions
internal void cv_stringize_sym_parsed(Arena *arena, String8List *out, CV_SymParsed *sym);
internal void cv_stringize_sym_range(Arena *arena, String8List *out,
CV_RecRange *range, String8 data,
CV_StringizeSymParams *p);
internal void cv_stringize_sym_array(Arena *arena, String8List *out,
CV_RecRangeArray *ranges, String8 data,
CV_StringizeSymParams *p);
////////////////////////////////
//~ CodeView Leaf Stringize Functions
internal void cv_stringize_leaf_parsed(Arena *arena, String8List *out, CV_LeafParsed *leaf);
internal void cv_stringize_leaf_range(Arena *arena, String8List *out,
CV_RecRange *range, CV_TypeId itype, String8 data,
CV_StringizeLeafParams *p);
internal void cv_stringize_leaf_array(Arena *arena, String8List *out,
CV_RecRangeArray *ranges, CV_TypeId itype_first,
String8 data,
CV_StringizeLeafParams *p);
////////////////////////////////
//~ CodeView C13 Stringize Functions
internal void cv_stringize_c13_parsed(Arena *arena, String8List *out, CV_C13Parsed *c13);
#endif // CODEVIEW_STRINGIZE_H
+706
View File
@@ -0,0 +1,706 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
//- GENERATED CODE
internal String8
cv_string_from_numeric_kind(CV_NumericKind v)
{
String8 result = str8_lit("<Unknown CV_NumericKind>");
switch(v)
{
default:{}break;
case CV_NumericKind_CHAR:{result = str8_lit("CHAR");}break;
case CV_NumericKind_SHORT:{result = str8_lit("SHORT");}break;
case CV_NumericKind_USHORT:{result = str8_lit("USHORT");}break;
case CV_NumericKind_LONG:{result = str8_lit("LONG");}break;
case CV_NumericKind_ULONG:{result = str8_lit("ULONG");}break;
case CV_NumericKind_FLOAT32:{result = str8_lit("FLOAT32");}break;
case CV_NumericKind_FLOAT64:{result = str8_lit("FLOAT64");}break;
case CV_NumericKind_FLOAT80:{result = str8_lit("FLOAT80");}break;
case CV_NumericKind_FLOAT128:{result = str8_lit("FLOAT128");}break;
case CV_NumericKind_QUADWORD:{result = str8_lit("QUADWORD");}break;
case CV_NumericKind_UQUADWORD:{result = str8_lit("UQUADWORD");}break;
case CV_NumericKind_FLOAT48:{result = str8_lit("FLOAT48");}break;
case CV_NumericKind_COMPLEX32:{result = str8_lit("COMPLEX32");}break;
case CV_NumericKind_COMPLEX64:{result = str8_lit("COMPLEX64");}break;
case CV_NumericKind_COMPLEX80:{result = str8_lit("COMPLEX80");}break;
case CV_NumericKind_COMPLEX128:{result = str8_lit("COMPLEX128");}break;
case CV_NumericKind_VARSTRING:{result = str8_lit("VARSTRING");}break;
case CV_NumericKind_OCTWORD:{result = str8_lit("OCTWORD");}break;
case CV_NumericKind_UOCTWORD:{result = str8_lit("UOCTWORD");}break;
case CV_NumericKind_DECIMAL:{result = str8_lit("DECIMAL");}break;
case CV_NumericKind_DATE:{result = str8_lit("DATE");}break;
case CV_NumericKind_UTF8STRING:{result = str8_lit("UTF8STRING");}break;
case CV_NumericKind_FLOAT16:{result = str8_lit("FLOAT16");}break;
}
return result;
}
internal String8
cv_string_from_arch(CV_Arch v)
{
String8 result = str8_lit("<Unknown CV_Arch>");
switch(v)
{
default:{}break;
case CV_Arch_8080:{result = str8_lit("8080");}break;
case CV_Arch_8086:{result = str8_lit("8086");}break;
case CV_Arch_80286:{result = str8_lit("80286");}break;
case CV_Arch_80386:{result = str8_lit("80386");}break;
case CV_Arch_80486:{result = str8_lit("80486");}break;
case CV_Arch_PENTIUM:{result = str8_lit("PENTIUM");}break;
case CV_Arch_PENTIUMII:{result = str8_lit("PENTIUMII");}break;
case CV_Arch_PENTIUMIII:{result = str8_lit("PENTIUMIII");}break;
case CV_Arch_MIPS:{result = str8_lit("MIPS");}break;
case CV_Arch_MIPS16:{result = str8_lit("MIPS16");}break;
case CV_Arch_MIPS32:{result = str8_lit("MIPS32");}break;
case CV_Arch_MIPS64:{result = str8_lit("MIPS64");}break;
case CV_Arch_MIPSI:{result = str8_lit("MIPSI");}break;
case CV_Arch_MIPSII:{result = str8_lit("MIPSII");}break;
case CV_Arch_MIPSIII:{result = str8_lit("MIPSIII");}break;
case CV_Arch_MIPSIV:{result = str8_lit("MIPSIV");}break;
case CV_Arch_MIPSV:{result = str8_lit("MIPSV");}break;
case CV_Arch_M68000:{result = str8_lit("M68000");}break;
case CV_Arch_M68010:{result = str8_lit("M68010");}break;
case CV_Arch_M68020:{result = str8_lit("M68020");}break;
case CV_Arch_M68030:{result = str8_lit("M68030");}break;
case CV_Arch_M68040:{result = str8_lit("M68040");}break;
case CV_Arch_ALPHA:{result = str8_lit("ALPHA");}break;
case CV_Arch_ALPHA_21164:{result = str8_lit("ALPHA_21164");}break;
case CV_Arch_ALPHA_21164A:{result = str8_lit("ALPHA_21164A");}break;
case CV_Arch_ALPHA_21264:{result = str8_lit("ALPHA_21264");}break;
case CV_Arch_ALPHA_21364:{result = str8_lit("ALPHA_21364");}break;
case CV_Arch_PPC601:{result = str8_lit("PPC601");}break;
case CV_Arch_PPC603:{result = str8_lit("PPC603");}break;
case CV_Arch_PPC604:{result = str8_lit("PPC604");}break;
case CV_Arch_PPC620:{result = str8_lit("PPC620");}break;
case CV_Arch_PPCFP:{result = str8_lit("PPCFP");}break;
case CV_Arch_PPCBE:{result = str8_lit("PPCBE");}break;
case CV_Arch_SH3:{result = str8_lit("SH3");}break;
case CV_Arch_SH3E:{result = str8_lit("SH3E");}break;
case CV_Arch_SH3DSP:{result = str8_lit("SH3DSP");}break;
case CV_Arch_SH4:{result = str8_lit("SH4");}break;
case CV_Arch_SHMEDIA:{result = str8_lit("SHMEDIA");}break;
case CV_Arch_ARM3:{result = str8_lit("ARM3");}break;
case CV_Arch_ARM4:{result = str8_lit("ARM4");}break;
case CV_Arch_ARM4T:{result = str8_lit("ARM4T");}break;
case CV_Arch_ARM5:{result = str8_lit("ARM5");}break;
case CV_Arch_ARM5T:{result = str8_lit("ARM5T");}break;
case CV_Arch_ARM6:{result = str8_lit("ARM6");}break;
case CV_Arch_ARM_XMAC:{result = str8_lit("ARM_XMAC");}break;
case CV_Arch_ARM_WMMX:{result = str8_lit("ARM_WMMX");}break;
case CV_Arch_ARM7:{result = str8_lit("ARM7");}break;
case CV_Arch_OMNI:{result = str8_lit("OMNI");}break;
case CV_Arch_IA64_1:{result = str8_lit("IA64_1");}break;
case CV_Arch_IA64_2:{result = str8_lit("IA64_2");}break;
case CV_Arch_CEE:{result = str8_lit("CEE");}break;
case CV_Arch_AM33:{result = str8_lit("AM33");}break;
case CV_Arch_M32R:{result = str8_lit("M32R");}break;
case CV_Arch_TRICORE:{result = str8_lit("TRICORE");}break;
case CV_Arch_X64:{result = str8_lit("X64");}break;
case CV_Arch_EBC:{result = str8_lit("EBC");}break;
case CV_Arch_THUMB:{result = str8_lit("THUMB");}break;
case CV_Arch_ARMNT:{result = str8_lit("ARMNT");}break;
case CV_Arch_ARM64:{result = str8_lit("ARM64");}break;
case CV_Arch_D3D11_SHADER:{result = str8_lit("D3D11_SHADER");}break;
}
return result;
}
internal String8
cv_string_from_sym_kind(CV_SymKind v)
{
String8 result = str8_lit("<Unknown CV_SymKind>");
switch(v)
{
default:{}break;
case CV_SymKind_COMPILE:{result = str8_lit("COMPILE");}break;
case CV_SymKind_REGISTER_16t:{result = str8_lit("REGISTER_16t");}break;
case CV_SymKind_CONSTANT_16t:{result = str8_lit("CONSTANT_16t");}break;
case CV_SymKind_UDT_16t:{result = str8_lit("UDT_16t");}break;
case CV_SymKind_SSEARCH:{result = str8_lit("SSEARCH");}break;
case CV_SymKind_END:{result = str8_lit("END");}break;
case CV_SymKind_SKIP:{result = str8_lit("SKIP");}break;
case CV_SymKind_CVRESERVE:{result = str8_lit("CVRESERVE");}break;
case CV_SymKind_OBJNAME_ST:{result = str8_lit("OBJNAME_ST");}break;
case CV_SymKind_ENDARG:{result = str8_lit("ENDARG");}break;
case CV_SymKind_COBOLUDT_16t:{result = str8_lit("COBOLUDT_16t");}break;
case CV_SymKind_MANYREG_16t:{result = str8_lit("MANYREG_16t");}break;
case CV_SymKind_RETURN:{result = str8_lit("RETURN");}break;
case CV_SymKind_ENTRYTHIS:{result = str8_lit("ENTRYTHIS");}break;
case CV_SymKind_BPREL16:{result = str8_lit("BPREL16");}break;
case CV_SymKind_LDATA16:{result = str8_lit("LDATA16");}break;
case CV_SymKind_GDATA16:{result = str8_lit("GDATA16");}break;
case CV_SymKind_PUB16:{result = str8_lit("PUB16");}break;
case CV_SymKind_LPROC16:{result = str8_lit("LPROC16");}break;
case CV_SymKind_GPROC16:{result = str8_lit("GPROC16");}break;
case CV_SymKind_THUNK16:{result = str8_lit("THUNK16");}break;
case CV_SymKind_BLOCK16:{result = str8_lit("BLOCK16");}break;
case CV_SymKind_WITH16:{result = str8_lit("WITH16");}break;
case CV_SymKind_LABEL16:{result = str8_lit("LABEL16");}break;
case CV_SymKind_CEXMODEL16:{result = str8_lit("CEXMODEL16");}break;
case CV_SymKind_VFTABLE16:{result = str8_lit("VFTABLE16");}break;
case CV_SymKind_REGREL16:{result = str8_lit("REGREL16");}break;
case CV_SymKind_BPREL32_16t:{result = str8_lit("BPREL32_16t");}break;
case CV_SymKind_LDATA32_16t:{result = str8_lit("LDATA32_16t");}break;
case CV_SymKind_GDATA32_16t:{result = str8_lit("GDATA32_16t");}break;
case CV_SymKind_PUB32_16t:{result = str8_lit("PUB32_16t");}break;
case CV_SymKind_LPROC32_16t:{result = str8_lit("LPROC32_16t");}break;
case CV_SymKind_GPROC32_16t:{result = str8_lit("GPROC32_16t");}break;
case CV_SymKind_THUNK32_ST:{result = str8_lit("THUNK32_ST");}break;
case CV_SymKind_BLOCK32_ST:{result = str8_lit("BLOCK32_ST");}break;
case CV_SymKind_WITH32_ST:{result = str8_lit("WITH32_ST");}break;
case CV_SymKind_LABEL32_ST:{result = str8_lit("LABEL32_ST");}break;
case CV_SymKind_CEXMODEL32:{result = str8_lit("CEXMODEL32");}break;
case CV_SymKind_VFTABLE32_16t:{result = str8_lit("VFTABLE32_16t");}break;
case CV_SymKind_REGREL32_16t:{result = str8_lit("REGREL32_16t");}break;
case CV_SymKind_LTHREAD32_16t:{result = str8_lit("LTHREAD32_16t");}break;
case CV_SymKind_GTHREAD32_16t:{result = str8_lit("GTHREAD32_16t");}break;
case CV_SymKind_SLINK32:{result = str8_lit("SLINK32");}break;
case CV_SymKind_LPROCMIPS_16t:{result = str8_lit("LPROCMIPS_16t");}break;
case CV_SymKind_GPROCMIPS_16t:{result = str8_lit("GPROCMIPS_16t");}break;
case CV_SymKind_PROCREF_ST:{result = str8_lit("PROCREF_ST");}break;
case CV_SymKind_DATAREF_ST:{result = str8_lit("DATAREF_ST");}break;
case CV_SymKind_ALIGN:{result = str8_lit("ALIGN");}break;
case CV_SymKind_LPROCREF_ST:{result = str8_lit("LPROCREF_ST");}break;
case CV_SymKind_OEM:{result = str8_lit("OEM");}break;
case CV_SymKind_TI16_MAX:{result = str8_lit("TI16_MAX");}break;
case CV_SymKind_CONSTANT_ST:{result = str8_lit("CONSTANT_ST");}break;
case CV_SymKind_UDT_ST:{result = str8_lit("UDT_ST");}break;
case CV_SymKind_COBOLUDT_ST:{result = str8_lit("COBOLUDT_ST");}break;
case CV_SymKind_MANYREG_ST:{result = str8_lit("MANYREG_ST");}break;
case CV_SymKind_BPREL32_ST:{result = str8_lit("BPREL32_ST");}break;
case CV_SymKind_LDATA32_ST:{result = str8_lit("LDATA32_ST");}break;
case CV_SymKind_GDATA32_ST:{result = str8_lit("GDATA32_ST");}break;
case CV_SymKind_PUB32_ST:{result = str8_lit("PUB32_ST");}break;
case CV_SymKind_LPROC32_ST:{result = str8_lit("LPROC32_ST");}break;
case CV_SymKind_GPROC32_ST:{result = str8_lit("GPROC32_ST");}break;
case CV_SymKind_VFTABLE32:{result = str8_lit("VFTABLE32");}break;
case CV_SymKind_REGREL32_ST:{result = str8_lit("REGREL32_ST");}break;
case CV_SymKind_LTHREAD32_ST:{result = str8_lit("LTHREAD32_ST");}break;
case CV_SymKind_GTHREAD32_ST:{result = str8_lit("GTHREAD32_ST");}break;
case CV_SymKind_LPROCMIPS_ST:{result = str8_lit("LPROCMIPS_ST");}break;
case CV_SymKind_GPROCMIPS_ST:{result = str8_lit("GPROCMIPS_ST");}break;
case CV_SymKind_FRAMEPROC:{result = str8_lit("FRAMEPROC");}break;
case CV_SymKind_COMPILE2_ST:{result = str8_lit("COMPILE2_ST");}break;
case CV_SymKind_MANYREG2_ST:{result = str8_lit("MANYREG2_ST");}break;
case CV_SymKind_LPROCIA64_ST:{result = str8_lit("LPROCIA64_ST");}break;
case CV_SymKind_GPROCIA64_ST:{result = str8_lit("GPROCIA64_ST");}break;
case CV_SymKind_LOCALSLOT_ST:{result = str8_lit("LOCALSLOT_ST");}break;
case CV_SymKind_PARAMSLOT_ST:{result = str8_lit("PARAMSLOT_ST");}break;
case CV_SymKind_ANNOTATION:{result = str8_lit("ANNOTATION");}break;
case CV_SymKind_GMANPROC_ST:{result = str8_lit("GMANPROC_ST");}break;
case CV_SymKind_LMANPROC_ST:{result = str8_lit("LMANPROC_ST");}break;
case CV_SymKind_RESERVED1:{result = str8_lit("RESERVED1");}break;
case CV_SymKind_RESERVED2:{result = str8_lit("RESERVED2");}break;
case CV_SymKind_RESERVED3:{result = str8_lit("RESERVED3");}break;
case CV_SymKind_RESERVED4:{result = str8_lit("RESERVED4");}break;
case CV_SymKind_LMANDATA_ST:{result = str8_lit("LMANDATA_ST");}break;
case CV_SymKind_GMANDATA_ST:{result = str8_lit("GMANDATA_ST");}break;
case CV_SymKind_MANFRAMEREL_ST:{result = str8_lit("MANFRAMEREL_ST");}break;
case CV_SymKind_MANREGISTER_ST:{result = str8_lit("MANREGISTER_ST");}break;
case CV_SymKind_MANSLOT_ST:{result = str8_lit("MANSLOT_ST");}break;
case CV_SymKind_MANMANYREG_ST:{result = str8_lit("MANMANYREG_ST");}break;
case CV_SymKind_MANREGREL_ST:{result = str8_lit("MANREGREL_ST");}break;
case CV_SymKind_MANMANYREG2_ST:{result = str8_lit("MANMANYREG2_ST");}break;
case CV_SymKind_MANTYPREF:{result = str8_lit("MANTYPREF");}break;
case CV_SymKind_UNAMESPACE_ST:{result = str8_lit("UNAMESPACE_ST");}break;
case CV_SymKind_ST_MAX:{result = str8_lit("ST_MAX");}break;
case CV_SymKind_OBJNAME:{result = str8_lit("OBJNAME");}break;
case CV_SymKind_THUNK32:{result = str8_lit("THUNK32");}break;
case CV_SymKind_BLOCK32:{result = str8_lit("BLOCK32");}break;
case CV_SymKind_WITH32:{result = str8_lit("WITH32");}break;
case CV_SymKind_LABEL32:{result = str8_lit("LABEL32");}break;
case CV_SymKind_REGISTER:{result = str8_lit("REGISTER");}break;
case CV_SymKind_CONSTANT:{result = str8_lit("CONSTANT");}break;
case CV_SymKind_UDT:{result = str8_lit("UDT");}break;
case CV_SymKind_COBOLUDT:{result = str8_lit("COBOLUDT");}break;
case CV_SymKind_MANYREG:{result = str8_lit("MANYREG");}break;
case CV_SymKind_BPREL32:{result = str8_lit("BPREL32");}break;
case CV_SymKind_LDATA32:{result = str8_lit("LDATA32");}break;
case CV_SymKind_GDATA32:{result = str8_lit("GDATA32");}break;
case CV_SymKind_PUB32:{result = str8_lit("PUB32");}break;
case CV_SymKind_LPROC32:{result = str8_lit("LPROC32");}break;
case CV_SymKind_GPROC32:{result = str8_lit("GPROC32");}break;
case CV_SymKind_REGREL32:{result = str8_lit("REGREL32");}break;
case CV_SymKind_LTHREAD32:{result = str8_lit("LTHREAD32");}break;
case CV_SymKind_GTHREAD32:{result = str8_lit("GTHREAD32");}break;
case CV_SymKind_LPROCMIPS:{result = str8_lit("LPROCMIPS");}break;
case CV_SymKind_GPROCMIPS:{result = str8_lit("GPROCMIPS");}break;
case CV_SymKind_COMPILE2:{result = str8_lit("COMPILE2");}break;
case CV_SymKind_MANYREG2:{result = str8_lit("MANYREG2");}break;
case CV_SymKind_LPROCIA64:{result = str8_lit("LPROCIA64");}break;
case CV_SymKind_GPROCIA64:{result = str8_lit("GPROCIA64");}break;
case CV_SymKind_LOCALSLOT:{result = str8_lit("LOCALSLOT");}break;
case CV_SymKind_PARAMSLOT:{result = str8_lit("PARAMSLOT");}break;
case CV_SymKind_LMANDATA:{result = str8_lit("LMANDATA");}break;
case CV_SymKind_GMANDATA:{result = str8_lit("GMANDATA");}break;
case CV_SymKind_MANFRAMEREL:{result = str8_lit("MANFRAMEREL");}break;
case CV_SymKind_MANREGISTER:{result = str8_lit("MANREGISTER");}break;
case CV_SymKind_MANSLOT:{result = str8_lit("MANSLOT");}break;
case CV_SymKind_MANMANYREG:{result = str8_lit("MANMANYREG");}break;
case CV_SymKind_MANREGREL:{result = str8_lit("MANREGREL");}break;
case CV_SymKind_MANMANYREG2:{result = str8_lit("MANMANYREG2");}break;
case CV_SymKind_UNAMESPACE:{result = str8_lit("UNAMESPACE");}break;
case CV_SymKind_PROCREF:{result = str8_lit("PROCREF");}break;
case CV_SymKind_DATAREF:{result = str8_lit("DATAREF");}break;
case CV_SymKind_LPROCREF:{result = str8_lit("LPROCREF");}break;
case CV_SymKind_ANNOTATIONREF:{result = str8_lit("ANNOTATIONREF");}break;
case CV_SymKind_TOKENREF:{result = str8_lit("TOKENREF");}break;
case CV_SymKind_GMANPROC:{result = str8_lit("GMANPROC");}break;
case CV_SymKind_LMANPROC:{result = str8_lit("LMANPROC");}break;
case CV_SymKind_TRAMPOLINE:{result = str8_lit("TRAMPOLINE");}break;
case CV_SymKind_MANCONSTANT:{result = str8_lit("MANCONSTANT");}break;
case CV_SymKind_ATTR_FRAMEREL:{result = str8_lit("ATTR_FRAMEREL");}break;
case CV_SymKind_ATTR_REGISTER:{result = str8_lit("ATTR_REGISTER");}break;
case CV_SymKind_ATTR_REGREL:{result = str8_lit("ATTR_REGREL");}break;
case CV_SymKind_ATTR_MANYREG:{result = str8_lit("ATTR_MANYREG");}break;
case CV_SymKind_SEPCODE:{result = str8_lit("SEPCODE");}break;
case CV_SymKind_DEFRANGE_2005:{result = str8_lit("DEFRANGE_2005");}break;
case CV_SymKind_DEFRANGE2_2005:{result = str8_lit("DEFRANGE2_2005");}break;
case CV_SymKind_SECTION:{result = str8_lit("SECTION");}break;
case CV_SymKind_COFFGROUP:{result = str8_lit("COFFGROUP");}break;
case CV_SymKind_EXPORT:{result = str8_lit("EXPORT");}break;
case CV_SymKind_CALLSITEINFO:{result = str8_lit("CALLSITEINFO");}break;
case CV_SymKind_FRAMECOOKIE:{result = str8_lit("FRAMECOOKIE");}break;
case CV_SymKind_DISCARDED:{result = str8_lit("DISCARDED");}break;
case CV_SymKind_COMPILE3:{result = str8_lit("COMPILE3");}break;
case CV_SymKind_ENVBLOCK:{result = str8_lit("ENVBLOCK");}break;
case CV_SymKind_LOCAL:{result = str8_lit("LOCAL");}break;
case CV_SymKind_DEFRANGE:{result = str8_lit("DEFRANGE");}break;
case CV_SymKind_DEFRANGE_SUBFIELD:{result = str8_lit("DEFRANGE_SUBFIELD");}break;
case CV_SymKind_DEFRANGE_REGISTER:{result = str8_lit("DEFRANGE_REGISTER");}break;
case CV_SymKind_DEFRANGE_FRAMEPOINTER_REL:{result = str8_lit("DEFRANGE_FRAMEPOINTER_REL");}break;
case CV_SymKind_DEFRANGE_SUBFIELD_REGISTER:{result = str8_lit("DEFRANGE_SUBFIELD_REGISTER");}break;
case CV_SymKind_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:{result = str8_lit("DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE");}break;
case CV_SymKind_DEFRANGE_REGISTER_REL:{result = str8_lit("DEFRANGE_REGISTER_REL");}break;
case CV_SymKind_LPROC32_ID:{result = str8_lit("LPROC32_ID");}break;
case CV_SymKind_GPROC32_ID:{result = str8_lit("GPROC32_ID");}break;
case CV_SymKind_LPROCMIPS_ID:{result = str8_lit("LPROCMIPS_ID");}break;
case CV_SymKind_GPROCMIPS_ID:{result = str8_lit("GPROCMIPS_ID");}break;
case CV_SymKind_LPROCIA64_ID:{result = str8_lit("LPROCIA64_ID");}break;
case CV_SymKind_GPROCIA64_ID:{result = str8_lit("GPROCIA64_ID");}break;
case CV_SymKind_BUILDINFO:{result = str8_lit("BUILDINFO");}break;
case CV_SymKind_INLINESITE:{result = str8_lit("INLINESITE");}break;
case CV_SymKind_INLINESITE_END:{result = str8_lit("INLINESITE_END");}break;
case CV_SymKind_PROC_ID_END:{result = str8_lit("PROC_ID_END");}break;
case CV_SymKind_DEFRANGE_HLSL:{result = str8_lit("DEFRANGE_HLSL");}break;
case CV_SymKind_GDATA_HLSL:{result = str8_lit("GDATA_HLSL");}break;
case CV_SymKind_LDATA_HLSL:{result = str8_lit("LDATA_HLSL");}break;
case CV_SymKind_FILESTATIC:{result = str8_lit("FILESTATIC");}break;
case CV_SymKind_LPROC32_DPC:{result = str8_lit("LPROC32_DPC");}break;
case CV_SymKind_LPROC32_DPC_ID:{result = str8_lit("LPROC32_DPC_ID");}break;
case CV_SymKind_DEFRANGE_DPC_PTR_TAG:{result = str8_lit("DEFRANGE_DPC_PTR_TAG");}break;
case CV_SymKind_DPC_SYM_TAG_MAP:{result = str8_lit("DPC_SYM_TAG_MAP");}break;
case CV_SymKind_ARMSWITCHTABLE:{result = str8_lit("ARMSWITCHTABLE");}break;
case CV_SymKind_CALLEES:{result = str8_lit("CALLEES");}break;
case CV_SymKind_CALLERS:{result = str8_lit("CALLERS");}break;
case CV_SymKind_POGODATA:{result = str8_lit("POGODATA");}break;
case CV_SymKind_INLINESITE2:{result = str8_lit("INLINESITE2");}break;
case CV_SymKind_HEAPALLOCSITE:{result = str8_lit("HEAPALLOCSITE");}break;
case CV_SymKind_MOD_TYPEREF:{result = str8_lit("MOD_TYPEREF");}break;
case CV_SymKind_REF_MINIPDB:{result = str8_lit("REF_MINIPDB");}break;
case CV_SymKind_PDBMAP:{result = str8_lit("PDBMAP");}break;
case CV_SymKind_GDATA_HLSL32:{result = str8_lit("GDATA_HLSL32");}break;
case CV_SymKind_LDATA_HLSL32:{result = str8_lit("LDATA_HLSL32");}break;
case CV_SymKind_GDATA_HLSL32_EX:{result = str8_lit("GDATA_HLSL32_EX");}break;
case CV_SymKind_LDATA_HLSL32_EX:{result = str8_lit("LDATA_HLSL32_EX");}break;
case CV_SymKind_FASTLINK:{result = str8_lit("FASTLINK");}break;
case CV_SymKind_INLINEES:{result = str8_lit("INLINEES");}break;
}
return result;
}
internal String8
cv_string_from_basic_type(CV_BasicType v)
{
String8 result = str8_lit("<Unknown CV_BasicType>");
switch(v)
{
default:{}break;
case CV_BasicType_NOTYPE:{result = str8_lit("NOTYPE");}break;
case CV_BasicType_ABS:{result = str8_lit("ABS");}break;
case CV_BasicType_SEGMENT:{result = str8_lit("SEGMENT");}break;
case CV_BasicType_VOID:{result = str8_lit("VOID");}break;
case CV_BasicType_CURRENCY:{result = str8_lit("CURRENCY");}break;
case CV_BasicType_NBASICSTR:{result = str8_lit("NBASICSTR");}break;
case CV_BasicType_FBASICSTR:{result = str8_lit("FBASICSTR");}break;
case CV_BasicType_NOTTRANS:{result = str8_lit("NOTTRANS");}break;
case CV_BasicType_HRESULT:{result = str8_lit("HRESULT");}break;
case CV_BasicType_CHAR:{result = str8_lit("CHAR");}break;
case CV_BasicType_SHORT:{result = str8_lit("SHORT");}break;
case CV_BasicType_LONG:{result = str8_lit("LONG");}break;
case CV_BasicType_QUAD:{result = str8_lit("QUAD");}break;
case CV_BasicType_OCT:{result = str8_lit("OCT");}break;
case CV_BasicType_UCHAR:{result = str8_lit("UCHAR");}break;
case CV_BasicType_USHORT:{result = str8_lit("USHORT");}break;
case CV_BasicType_ULONG:{result = str8_lit("ULONG");}break;
case CV_BasicType_UQUAD:{result = str8_lit("UQUAD");}break;
case CV_BasicType_UOCT:{result = str8_lit("UOCT");}break;
case CV_BasicType_BOOL8:{result = str8_lit("BOOL8");}break;
case CV_BasicType_BOOL16:{result = str8_lit("BOOL16");}break;
case CV_BasicType_BOOL32:{result = str8_lit("BOOL32");}break;
case CV_BasicType_BOOL64:{result = str8_lit("BOOL64");}break;
case CV_BasicType_FLOAT32:{result = str8_lit("FLOAT32");}break;
case CV_BasicType_FLOAT64:{result = str8_lit("FLOAT64");}break;
case CV_BasicType_FLOAT80:{result = str8_lit("FLOAT80");}break;
case CV_BasicType_FLOAT128:{result = str8_lit("FLOAT128");}break;
case CV_BasicType_FLOAT48:{result = str8_lit("FLOAT48");}break;
case CV_BasicType_FLOAT32PP:{result = str8_lit("FLOAT32PP");}break;
case CV_BasicType_FLOAT16:{result = str8_lit("FLOAT16");}break;
case CV_BasicType_COMPLEX32:{result = str8_lit("COMPLEX32");}break;
case CV_BasicType_COMPLEX64:{result = str8_lit("COMPLEX64");}break;
case CV_BasicType_COMPLEX80:{result = str8_lit("COMPLEX80");}break;
case CV_BasicType_COMPLEX128:{result = str8_lit("COMPLEX128");}break;
case CV_BasicType_BIT:{result = str8_lit("BIT");}break;
case CV_BasicType_PASCHAR:{result = str8_lit("PASCHAR");}break;
case CV_BasicType_BOOL32FF:{result = str8_lit("BOOL32FF");}break;
case CV_BasicType_INT8:{result = str8_lit("INT8");}break;
case CV_BasicType_UINT8:{result = str8_lit("UINT8");}break;
case CV_BasicType_RCHAR:{result = str8_lit("RCHAR");}break;
case CV_BasicType_WCHAR:{result = str8_lit("WCHAR");}break;
case CV_BasicType_INT16:{result = str8_lit("INT16");}break;
case CV_BasicType_UINT16:{result = str8_lit("UINT16");}break;
case CV_BasicType_INT32:{result = str8_lit("INT32");}break;
case CV_BasicType_UINT32:{result = str8_lit("UINT32");}break;
case CV_BasicType_INT64:{result = str8_lit("INT64");}break;
case CV_BasicType_UINT64:{result = str8_lit("UINT64");}break;
case CV_BasicType_INT128:{result = str8_lit("INT128");}break;
case CV_BasicType_UINT128:{result = str8_lit("UINT128");}break;
case CV_BasicType_CHAR16:{result = str8_lit("CHAR16");}break;
case CV_BasicType_CHAR32:{result = str8_lit("CHAR32");}break;
case CV_BasicType_CHAR8:{result = str8_lit("CHAR8");}break;
case CV_BasicType_PTR:{result = str8_lit("PTR");}break;
}
return result;
}
internal String8
cv_type_name_from_basic_type(CV_BasicType v)
{
String8 result = str8_lit("<Unknown CV_BasicType>");
switch(v)
{
default:{}break;
case CV_BasicType_NOTYPE:{result = str8_lit("");}break;
case CV_BasicType_ABS:{result = str8_lit("");}break;
case CV_BasicType_SEGMENT:{result = str8_lit("");}break;
case CV_BasicType_VOID:{result = str8_lit("void");}break;
case CV_BasicType_CURRENCY:{result = str8_lit("");}break;
case CV_BasicType_NBASICSTR:{result = str8_lit("");}break;
case CV_BasicType_FBASICSTR:{result = str8_lit("");}break;
case CV_BasicType_NOTTRANS:{result = str8_lit("");}break;
case CV_BasicType_HRESULT:{result = str8_lit("HRESULT");}break;
case CV_BasicType_CHAR:{result = str8_lit("char");}break;
case CV_BasicType_SHORT:{result = str8_lit("S16");}break;
case CV_BasicType_LONG:{result = str8_lit("S32");}break;
case CV_BasicType_QUAD:{result = str8_lit("S64");}break;
case CV_BasicType_OCT:{result = str8_lit("S128");}break;
case CV_BasicType_UCHAR:{result = str8_lit("UCHAR");}break;
case CV_BasicType_USHORT:{result = str8_lit("U16");}break;
case CV_BasicType_ULONG:{result = str8_lit("U32");}break;
case CV_BasicType_UQUAD:{result = str8_lit("U64");}break;
case CV_BasicType_UOCT:{result = str8_lit("U128");}break;
case CV_BasicType_BOOL8:{result = str8_lit("B8");}break;
case CV_BasicType_BOOL16:{result = str8_lit("B16");}break;
case CV_BasicType_BOOL32:{result = str8_lit("B32");}break;
case CV_BasicType_BOOL64:{result = str8_lit("B64");}break;
case CV_BasicType_FLOAT32:{result = str8_lit("F32");}break;
case CV_BasicType_FLOAT64:{result = str8_lit("F64");}break;
case CV_BasicType_FLOAT80:{result = str8_lit("F80");}break;
case CV_BasicType_FLOAT128:{result = str8_lit("F128");}break;
case CV_BasicType_FLOAT48:{result = str8_lit("F48");}break;
case CV_BasicType_FLOAT32PP:{result = str8_lit("F32PP");}break;
case CV_BasicType_FLOAT16:{result = str8_lit("F16");}break;
case CV_BasicType_COMPLEX32:{result = str8_lit("ComplexF32");}break;
case CV_BasicType_COMPLEX64:{result = str8_lit("ComplexF64");}break;
case CV_BasicType_COMPLEX80:{result = str8_lit("ComplexF80");}break;
case CV_BasicType_COMPLEX128:{result = str8_lit("ComplexF128");}break;
case CV_BasicType_BIT:{result = str8_lit("");}break;
case CV_BasicType_PASCHAR:{result = str8_lit("");}break;
case CV_BasicType_BOOL32FF:{result = str8_lit("B32FF");}break;
case CV_BasicType_INT8:{result = str8_lit("S8");}break;
case CV_BasicType_UINT8:{result = str8_lit("U8");}break;
case CV_BasicType_RCHAR:{result = str8_lit("char");}break;
case CV_BasicType_WCHAR:{result = str8_lit("WCHAR");}break;
case CV_BasicType_INT16:{result = str8_lit("S16");}break;
case CV_BasicType_UINT16:{result = str8_lit("U16");}break;
case CV_BasicType_INT32:{result = str8_lit("S32");}break;
case CV_BasicType_UINT32:{result = str8_lit("U32");}break;
case CV_BasicType_INT64:{result = str8_lit("S64");}break;
case CV_BasicType_UINT64:{result = str8_lit("U64");}break;
case CV_BasicType_INT128:{result = str8_lit("S128");}break;
case CV_BasicType_UINT128:{result = str8_lit("U128");}break;
case CV_BasicType_CHAR16:{result = str8_lit("CHAR16");}break;
case CV_BasicType_CHAR32:{result = str8_lit("CHAR32");}break;
case CV_BasicType_CHAR8:{result = str8_lit("char");}break;
case CV_BasicType_PTR:{result = str8_lit("PTR");}break;
}
return result;
}
internal String8
cv_string_from_leaf_kind(CV_LeafKind v)
{
String8 result = str8_lit("<Unknown CV_LeafKind>");
switch(v)
{
default:{}break;
case CV_LeafKind_MODIFIER_16t:{result = str8_lit("MODIFIER_16t");}break;
case CV_LeafKind_POINTER_16t:{result = str8_lit("POINTER_16t");}break;
case CV_LeafKind_ARRAY_16t:{result = str8_lit("ARRAY_16t");}break;
case CV_LeafKind_CLASS_16t:{result = str8_lit("CLASS_16t");}break;
case CV_LeafKind_STRUCTURE_16t:{result = str8_lit("STRUCTURE_16t");}break;
case CV_LeafKind_UNION_16t:{result = str8_lit("UNION_16t");}break;
case CV_LeafKind_ENUM_16t:{result = str8_lit("ENUM_16t");}break;
case CV_LeafKind_PROCEDURE_16t:{result = str8_lit("PROCEDURE_16t");}break;
case CV_LeafKind_MFUNCTION_16t:{result = str8_lit("MFUNCTION_16t");}break;
case CV_LeafKind_VTSHAPE:{result = str8_lit("VTSHAPE");}break;
case CV_LeafKind_COBOL0_16t:{result = str8_lit("COBOL0_16t");}break;
case CV_LeafKind_COBOL1:{result = str8_lit("COBOL1");}break;
case CV_LeafKind_BARRAY_16t:{result = str8_lit("BARRAY_16t");}break;
case CV_LeafKind_LABEL:{result = str8_lit("LABEL");}break;
case CV_LeafKind_NULL:{result = str8_lit("NULL");}break;
case CV_LeafKind_NOTTRAN:{result = str8_lit("NOTTRAN");}break;
case CV_LeafKind_DIMARRAY_16t:{result = str8_lit("DIMARRAY_16t");}break;
case CV_LeafKind_VFTPATH_16t:{result = str8_lit("VFTPATH_16t");}break;
case CV_LeafKind_PRECOMP_16t:{result = str8_lit("PRECOMP_16t");}break;
case CV_LeafKind_ENDPRECOMP:{result = str8_lit("ENDPRECOMP");}break;
case CV_LeafKind_OEM_16t:{result = str8_lit("OEM_16t");}break;
case CV_LeafKind_TYPESERVER_ST:{result = str8_lit("TYPESERVER_ST");}break;
case CV_LeafKind_SKIP_16t:{result = str8_lit("SKIP_16t");}break;
case CV_LeafKind_ARGLIST_16t:{result = str8_lit("ARGLIST_16t");}break;
case CV_LeafKind_DEFARG_16t:{result = str8_lit("DEFARG_16t");}break;
case CV_LeafKind_LIST:{result = str8_lit("LIST");}break;
case CV_LeafKind_FIELDLIST_16t:{result = str8_lit("FIELDLIST_16t");}break;
case CV_LeafKind_DERIVED_16t:{result = str8_lit("DERIVED_16t");}break;
case CV_LeafKind_BITFIELD_16t:{result = str8_lit("BITFIELD_16t");}break;
case CV_LeafKind_METHODLIST_16t:{result = str8_lit("METHODLIST_16t");}break;
case CV_LeafKind_DIMCONU_16t:{result = str8_lit("DIMCONU_16t");}break;
case CV_LeafKind_DIMCONLU_16t:{result = str8_lit("DIMCONLU_16t");}break;
case CV_LeafKind_DIMVARU_16t:{result = str8_lit("DIMVARU_16t");}break;
case CV_LeafKind_DIMVARLU_16t:{result = str8_lit("DIMVARLU_16t");}break;
case CV_LeafKind_REFSYM:{result = str8_lit("REFSYM");}break;
case CV_LeafKind_BCLASS_16t:{result = str8_lit("BCLASS_16t");}break;
case CV_LeafKind_VBCLASS_16t:{result = str8_lit("VBCLASS_16t");}break;
case CV_LeafKind_IVBCLASS_16t:{result = str8_lit("IVBCLASS_16t");}break;
case CV_LeafKind_ENUMERATE_ST:{result = str8_lit("ENUMERATE_ST");}break;
case CV_LeafKind_FRIENDFCN_16t:{result = str8_lit("FRIENDFCN_16t");}break;
case CV_LeafKind_INDEX_16t:{result = str8_lit("INDEX_16t");}break;
case CV_LeafKind_MEMBER_16t:{result = str8_lit("MEMBER_16t");}break;
case CV_LeafKind_STMEMBER_16t:{result = str8_lit("STMEMBER_16t");}break;
case CV_LeafKind_METHOD_16t:{result = str8_lit("METHOD_16t");}break;
case CV_LeafKind_NESTTYPE_16t:{result = str8_lit("NESTTYPE_16t");}break;
case CV_LeafKind_VFUNCTAB_16t:{result = str8_lit("VFUNCTAB_16t");}break;
case CV_LeafKind_FRIENDCLS_16t:{result = str8_lit("FRIENDCLS_16t");}break;
case CV_LeafKind_ONEMETHOD_16t:{result = str8_lit("ONEMETHOD_16t");}break;
case CV_LeafKind_VFUNCOFF_16t:{result = str8_lit("VFUNCOFF_16t");}break;
case CV_LeafKind_TI16_MAX:{result = str8_lit("TI16_MAX");}break;
case CV_LeafKind_MODIFIER:{result = str8_lit("MODIFIER");}break;
case CV_LeafKind_POINTER:{result = str8_lit("POINTER");}break;
case CV_LeafKind_ARRAY_ST:{result = str8_lit("ARRAY_ST");}break;
case CV_LeafKind_CLASS_ST:{result = str8_lit("CLASS_ST");}break;
case CV_LeafKind_STRUCTURE_ST:{result = str8_lit("STRUCTURE_ST");}break;
case CV_LeafKind_UNION_ST:{result = str8_lit("UNION_ST");}break;
case CV_LeafKind_ENUM_ST:{result = str8_lit("ENUM_ST");}break;
case CV_LeafKind_PROCEDURE:{result = str8_lit("PROCEDURE");}break;
case CV_LeafKind_MFUNCTION:{result = str8_lit("MFUNCTION");}break;
case CV_LeafKind_COBOL0:{result = str8_lit("COBOL0");}break;
case CV_LeafKind_BARRAY:{result = str8_lit("BARRAY");}break;
case CV_LeafKind_DIMARRAY_ST:{result = str8_lit("DIMARRAY_ST");}break;
case CV_LeafKind_VFTPATH:{result = str8_lit("VFTPATH");}break;
case CV_LeafKind_PRECOMP_ST:{result = str8_lit("PRECOMP_ST");}break;
case CV_LeafKind_OEM:{result = str8_lit("OEM");}break;
case CV_LeafKind_ALIAS_ST:{result = str8_lit("ALIAS_ST");}break;
case CV_LeafKind_OEM2:{result = str8_lit("OEM2");}break;
case CV_LeafKind_SKIP:{result = str8_lit("SKIP");}break;
case CV_LeafKind_ARGLIST:{result = str8_lit("ARGLIST");}break;
case CV_LeafKind_DEFARG_ST:{result = str8_lit("DEFARG_ST");}break;
case CV_LeafKind_FIELDLIST:{result = str8_lit("FIELDLIST");}break;
case CV_LeafKind_DERIVED:{result = str8_lit("DERIVED");}break;
case CV_LeafKind_BITFIELD:{result = str8_lit("BITFIELD");}break;
case CV_LeafKind_METHODLIST:{result = str8_lit("METHODLIST");}break;
case CV_LeafKind_DIMCONU:{result = str8_lit("DIMCONU");}break;
case CV_LeafKind_DIMCONLU:{result = str8_lit("DIMCONLU");}break;
case CV_LeafKind_DIMVARU:{result = str8_lit("DIMVARU");}break;
case CV_LeafKind_DIMVARLU:{result = str8_lit("DIMVARLU");}break;
case CV_LeafKind_BCLASS:{result = str8_lit("BCLASS");}break;
case CV_LeafKind_VBCLASS:{result = str8_lit("VBCLASS");}break;
case CV_LeafKind_IVBCLASS:{result = str8_lit("IVBCLASS");}break;
case CV_LeafKind_FRIENDFCN_ST:{result = str8_lit("FRIENDFCN_ST");}break;
case CV_LeafKind_INDEX:{result = str8_lit("INDEX");}break;
case CV_LeafKind_MEMBER_ST:{result = str8_lit("MEMBER_ST");}break;
case CV_LeafKind_STMEMBER_ST:{result = str8_lit("STMEMBER_ST");}break;
case CV_LeafKind_METHOD_ST:{result = str8_lit("METHOD_ST");}break;
case CV_LeafKind_NESTTYPE_ST:{result = str8_lit("NESTTYPE_ST");}break;
case CV_LeafKind_VFUNCTAB:{result = str8_lit("VFUNCTAB");}break;
case CV_LeafKind_FRIENDCLS:{result = str8_lit("FRIENDCLS");}break;
case CV_LeafKind_ONEMETHOD_ST:{result = str8_lit("ONEMETHOD_ST");}break;
case CV_LeafKind_VFUNCOFF:{result = str8_lit("VFUNCOFF");}break;
case CV_LeafKind_NESTTYPEEX_ST:{result = str8_lit("NESTTYPEEX_ST");}break;
case CV_LeafKind_MEMBERMODIFY_ST:{result = str8_lit("MEMBERMODIFY_ST");}break;
case CV_LeafKind_MANAGED_ST:{result = str8_lit("MANAGED_ST");}break;
case CV_LeafKind_ST_MAX:{result = str8_lit("ST_MAX");}break;
case CV_LeafKind_TYPESERVER:{result = str8_lit("TYPESERVER");}break;
case CV_LeafKind_ENUMERATE:{result = str8_lit("ENUMERATE");}break;
case CV_LeafKind_ARRAY:{result = str8_lit("ARRAY");}break;
case CV_LeafKind_CLASS:{result = str8_lit("CLASS");}break;
case CV_LeafKind_STRUCTURE:{result = str8_lit("STRUCTURE");}break;
case CV_LeafKind_UNION:{result = str8_lit("UNION");}break;
case CV_LeafKind_ENUM:{result = str8_lit("ENUM");}break;
case CV_LeafKind_DIMARRAY:{result = str8_lit("DIMARRAY");}break;
case CV_LeafKind_PRECOMP:{result = str8_lit("PRECOMP");}break;
case CV_LeafKind_ALIAS:{result = str8_lit("ALIAS");}break;
case CV_LeafKind_DEFARG:{result = str8_lit("DEFARG");}break;
case CV_LeafKind_FRIENDFCN:{result = str8_lit("FRIENDFCN");}break;
case CV_LeafKind_MEMBER:{result = str8_lit("MEMBER");}break;
case CV_LeafKind_STMEMBER:{result = str8_lit("STMEMBER");}break;
case CV_LeafKind_METHOD:{result = str8_lit("METHOD");}break;
case CV_LeafKind_NESTTYPE:{result = str8_lit("NESTTYPE");}break;
case CV_LeafKind_ONEMETHOD:{result = str8_lit("ONEMETHOD");}break;
case CV_LeafKind_NESTTYPEEX:{result = str8_lit("NESTTYPEEX");}break;
case CV_LeafKind_MEMBERMODIFY:{result = str8_lit("MEMBERMODIFY");}break;
case CV_LeafKind_MANAGED:{result = str8_lit("MANAGED");}break;
case CV_LeafKind_TYPESERVER2:{result = str8_lit("TYPESERVER2");}break;
case CV_LeafKind_STRIDED_ARRAY:{result = str8_lit("STRIDED_ARRAY");}break;
case CV_LeafKind_HLSL:{result = str8_lit("HLSL");}break;
case CV_LeafKind_MODIFIER_EX:{result = str8_lit("MODIFIER_EX");}break;
case CV_LeafKind_INTERFACE:{result = str8_lit("INTERFACE");}break;
case CV_LeafKind_BINTERFACE:{result = str8_lit("BINTERFACE");}break;
case CV_LeafKind_VECTOR:{result = str8_lit("VECTOR");}break;
case CV_LeafKind_MATRIX:{result = str8_lit("MATRIX");}break;
case CV_LeafKind_VFTABLE:{result = str8_lit("VFTABLE");}break;
case CV_LeafKind_CLASS2:{result = str8_lit("CLASS2");}break;
case CV_LeafKind_STRUCT2:{result = str8_lit("STRUCT2");}break;
}
return result;
}
internal U64
cv_header_struct_size_from_sym_kind(CV_SymKind v)
{
U64 result = 0;
switch(v)
{
default:{}break;
case CV_SymKind_COMPILE:{result = sizeof(CV_SymCompile);}break;
case CV_SymKind_SSEARCH:{result = sizeof(CV_SymStartSearch);}break;
case CV_SymKind_RETURN:{result = sizeof(CV_SymReturn);}break;
case CV_SymKind_SLINK32:{result = sizeof(CV_SymSLink32);}break;
case CV_SymKind_OEM:{result = sizeof(CV_SymOEM);}break;
case CV_SymKind_VFTABLE32:{result = sizeof(CV_SymVPath32);}break;
case CV_SymKind_FRAMEPROC:{result = sizeof(CV_SymFrameproc);}break;
case CV_SymKind_ANNOTATION:{result = sizeof(CV_SymAnnotation);}break;
case CV_SymKind_OBJNAME:{result = sizeof(CV_SymObjname);}break;
case CV_SymKind_THUNK32:{result = sizeof(CV_SymThunk32);}break;
case CV_SymKind_BLOCK32:{result = sizeof(CV_SymBlock32);}break;
case CV_SymKind_LABEL32:{result = sizeof(CV_SymLabel32);}break;
case CV_SymKind_REGISTER:{result = sizeof(CV_SymRegister);}break;
case CV_SymKind_CONSTANT:{result = sizeof(CV_SymConstant);}break;
case CV_SymKind_UDT:{result = sizeof(CV_SymUDT);}break;
case CV_SymKind_MANYREG:{result = sizeof(CV_SymManyreg);}break;
case CV_SymKind_BPREL32:{result = sizeof(CV_SymBPRel32);}break;
case CV_SymKind_LDATA32:{result = sizeof(CV_SymData32);}break;
case CV_SymKind_GDATA32:{result = sizeof(CV_SymData32);}break;
case CV_SymKind_PUB32:{result = sizeof(CV_SymPub32);}break;
case CV_SymKind_LPROC32:{result = sizeof(CV_SymProc32);}break;
case CV_SymKind_GPROC32:{result = sizeof(CV_SymProc32);}break;
case CV_SymKind_REGREL32:{result = sizeof(CV_SymRegrel32);}break;
case CV_SymKind_LTHREAD32:{result = sizeof(CV_SymThread32);}break;
case CV_SymKind_GTHREAD32:{result = sizeof(CV_SymThread32);}break;
case CV_SymKind_COMPILE2:{result = sizeof(CV_SymCompile2);}break;
case CV_SymKind_MANYREG2:{result = sizeof(CV_SymManyreg2);}break;
case CV_SymKind_LOCALSLOT:{result = sizeof(CV_SymSlot);}break;
case CV_SymKind_MANFRAMEREL:{result = sizeof(CV_SymAttrFrameRel);}break;
case CV_SymKind_MANREGISTER:{result = sizeof(CV_SymAttrReg);}break;
case CV_SymKind_MANMANYREG:{result = sizeof(CV_SymAttrManyReg);}break;
case CV_SymKind_MANREGREL:{result = sizeof(CV_SymAttrRegRel);}break;
case CV_SymKind_UNAMESPACE:{result = sizeof(CV_SymUNamespace);}break;
case CV_SymKind_PROCREF:{result = sizeof(CV_SymRef2);}break;
case CV_SymKind_DATAREF:{result = sizeof(CV_SymRef2);}break;
case CV_SymKind_LPROCREF:{result = sizeof(CV_SymRef2);}break;
case CV_SymKind_TRAMPOLINE:{result = sizeof(CV_SymTrampoline);}break;
case CV_SymKind_ATTR_FRAMEREL:{result = sizeof(CV_SymAttrFrameRel);}break;
case CV_SymKind_ATTR_REGISTER:{result = sizeof(CV_SymAttrReg);}break;
case CV_SymKind_ATTR_REGREL:{result = sizeof(CV_SymAttrRegRel);}break;
case CV_SymKind_ATTR_MANYREG:{result = sizeof(CV_SymAttrManyReg);}break;
case CV_SymKind_SEPCODE:{result = sizeof(CV_SymSepcode);}break;
case CV_SymKind_SECTION:{result = sizeof(CV_SymSection);}break;
case CV_SymKind_COFFGROUP:{result = sizeof(CV_SymCoffGroup);}break;
case CV_SymKind_EXPORT:{result = sizeof(CV_SymExport);}break;
case CV_SymKind_CALLSITEINFO:{result = sizeof(CV_SymCallSiteInfo);}break;
case CV_SymKind_FRAMECOOKIE:{result = sizeof(CV_SymFrameCookie);}break;
case CV_SymKind_DISCARDED:{result = sizeof(CV_SymDiscarded);}break;
case CV_SymKind_COMPILE3:{result = sizeof(CV_SymCompile3);}break;
case CV_SymKind_ENVBLOCK:{result = sizeof(CV_SymEnvBlock);}break;
case CV_SymKind_LOCAL:{result = sizeof(CV_SymLocal);}break;
case CV_SymKind_DEFRANGE_SUBFIELD:{result = sizeof(CV_SymDefrangeSubfield);}break;
case CV_SymKind_DEFRANGE_REGISTER:{result = sizeof(CV_SymDefrangeRegister);}break;
case CV_SymKind_DEFRANGE_FRAMEPOINTER_REL:{result = sizeof(CV_SymDefrangeFramepointerRel);}break;
case CV_SymKind_DEFRANGE_SUBFIELD_REGISTER:{result = sizeof(CV_SymDefrangeSubfieldRegister);}break;
case CV_SymKind_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:{result = sizeof(CV_SymDefrangeFramepointerRelFullScope);}break;
case CV_SymKind_DEFRANGE_REGISTER_REL:{result = sizeof(CV_SymDefrangeRegisterRel);}break;
case CV_SymKind_BUILDINFO:{result = sizeof(CV_SymBuildInfo);}break;
case CV_SymKind_INLINESITE:{result = sizeof(CV_SymInlineSite);}break;
case CV_SymKind_FILESTATIC:{result = sizeof(CV_SymFileStatic);}break;
case CV_SymKind_CALLEES:{result = sizeof(CV_SymFunctionList);}break;
case CV_SymKind_CALLERS:{result = sizeof(CV_SymFunctionList);}break;
case CV_SymKind_POGODATA:{result = sizeof(CV_SymPogoInfo);}break;
case CV_SymKind_INLINESITE2:{result = sizeof(CV_SymInlineSite2);}break;
case CV_SymKind_HEAPALLOCSITE:{result = sizeof(CV_SymHeapAllocSite);}break;
case CV_SymKind_MOD_TYPEREF:{result = sizeof(CV_SymModTypeRef);}break;
case CV_SymKind_REF_MINIPDB:{result = sizeof(CV_SymRefMiniPdb);}break;
case CV_SymKind_FASTLINK:{result = sizeof(CV_SymFastLink);}break;
case CV_SymKind_INLINEES:{result = sizeof(CV_SymInlinees);}break;
}
return result;
}
internal U64
cv_header_struct_size_from_leaf_kind(CV_LeafKind v)
{
U64 result = 0;
switch(v)
{
default:{}break;
case CV_LeafKind_VTSHAPE:{result = sizeof(CV_LeafVTShape);}break;
case CV_LeafKind_LABEL:{result = sizeof(CV_LeafLabel);}break;
case CV_LeafKind_MODIFIER:{result = sizeof(CV_LeafModifier);}break;
case CV_LeafKind_POINTER:{result = sizeof(CV_LeafPointer);}break;
case CV_LeafKind_PROCEDURE:{result = sizeof(CV_LeafProcedure);}break;
case CV_LeafKind_MFUNCTION:{result = sizeof(CV_LeafMFunction);}break;
case CV_LeafKind_VFTPATH:{result = sizeof(CV_LeafVFPath);}break;
case CV_LeafKind_SKIP:{result = sizeof(CV_LeafSkip);}break;
case CV_LeafKind_ARGLIST:{result = sizeof(CV_LeafArgList);}break;
case CV_LeafKind_BITFIELD:{result = sizeof(CV_LeafBitField);}break;
case CV_LeafKind_METHODLIST:{result = sizeof(CV_LeafMethodListMember);}break;
case CV_LeafKind_BCLASS:{result = sizeof(CV_LeafBClass);}break;
case CV_LeafKind_VBCLASS:{result = sizeof(CV_LeafVBClass);}break;
case CV_LeafKind_INDEX:{result = sizeof(CV_LeafIndex);}break;
case CV_LeafKind_VFUNCTAB:{result = sizeof(CV_LeafVFuncTab);}break;
case CV_LeafKind_VFUNCOFF:{result = sizeof(CV_LeafVFuncOff);}break;
case CV_LeafKind_TYPESERVER:{result = sizeof(CV_LeafTypeServer);}break;
case CV_LeafKind_ENUMERATE:{result = sizeof(CV_LeafEnumerate);}break;
case CV_LeafKind_ARRAY:{result = sizeof(CV_LeafArray);}break;
case CV_LeafKind_CLASS:{result = sizeof(CV_LeafStruct);}break;
case CV_LeafKind_STRUCTURE:{result = sizeof(CV_LeafStruct);}break;
case CV_LeafKind_UNION:{result = sizeof(CV_LeafUnion);}break;
case CV_LeafKind_ENUM:{result = sizeof(CV_LeafEnum);}break;
case CV_LeafKind_PRECOMP:{result = sizeof(CV_LeafPreComp);}break;
case CV_LeafKind_ALIAS:{result = sizeof(CV_LeafAlias);}break;
case CV_LeafKind_MEMBER:{result = sizeof(CV_LeafMember);}break;
case CV_LeafKind_STMEMBER:{result = sizeof(CV_LeafStMember);}break;
case CV_LeafKind_METHOD:{result = sizeof(CV_LeafMethod);}break;
case CV_LeafKind_NESTTYPE:{result = sizeof(CV_LeafNestType);}break;
case CV_LeafKind_ONEMETHOD:{result = sizeof(CV_LeafOneMethod);}break;
case CV_LeafKind_NESTTYPEEX:{result = sizeof(CV_LeafNestTypeEx);}break;
case CV_LeafKind_TYPESERVER2:{result = sizeof(CV_LeafTypeServer2);}break;
case CV_LeafKind_INTERFACE:{result = sizeof(CV_LeafStruct);}break;
case CV_LeafKind_CLASS2:{result = sizeof(CV_LeafStruct2);}break;
case CV_LeafKind_STRUCT2:{result = sizeof(CV_LeafStruct2);}break;
}
return result;
}
C_LINKAGE_BEGIN
C_LINKAGE_END
+523
View File
@@ -0,0 +1,523 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
//- GENERATED CODE
#ifndef CODEVIEW_META_H
#define CODEVIEW_META_H
typedef U16 CV_NumericKind;
typedef enum CV_NumericKindEnum
{
CV_NumericKind_CHAR = 0x8000,
CV_NumericKind_SHORT = 0x8001,
CV_NumericKind_USHORT = 0x8002,
CV_NumericKind_LONG = 0x8003,
CV_NumericKind_ULONG = 0x8004,
CV_NumericKind_FLOAT32 = 0x8005,
CV_NumericKind_FLOAT64 = 0x8006,
CV_NumericKind_FLOAT80 = 0x8007,
CV_NumericKind_FLOAT128 = 0x8008,
CV_NumericKind_QUADWORD = 0x8009,
CV_NumericKind_UQUADWORD = 0x800a,
CV_NumericKind_FLOAT48 = 0x800b,
CV_NumericKind_COMPLEX32 = 0x800c,
CV_NumericKind_COMPLEX64 = 0x800d,
CV_NumericKind_COMPLEX80 = 0x800e,
CV_NumericKind_COMPLEX128 = 0x800f,
CV_NumericKind_VARSTRING = 0x8010,
CV_NumericKind_OCTWORD = 0x8017,
CV_NumericKind_UOCTWORD = 0x8018,
CV_NumericKind_DECIMAL = 0x8019,
CV_NumericKind_DATE = 0x801a,
CV_NumericKind_UTF8STRING = 0x801b,
CV_NumericKind_FLOAT16 = 0x801c,
} CV_NumericKindEnum;
typedef U16 CV_Arch;
typedef enum CV_ArchEnum
{
CV_Arch_8080 = 0x00,
CV_Arch_8086 = 0x01,
CV_Arch_80286 = 0x02,
CV_Arch_80386 = 0x03,
CV_Arch_80486 = 0x04,
CV_Arch_PENTIUM = 0x05,
CV_Arch_PENTIUMII = 0x06,
CV_Arch_PENTIUMIII = 0x07,
CV_Arch_MIPS = 0x10,
CV_Arch_MIPS16 = 0x11,
CV_Arch_MIPS32 = 0x12,
CV_Arch_MIPS64 = 0x13,
CV_Arch_MIPSI = 0x14,
CV_Arch_MIPSII = 0x15,
CV_Arch_MIPSIII = 0x16,
CV_Arch_MIPSIV = 0x17,
CV_Arch_MIPSV = 0x18,
CV_Arch_M68000 = 0x20,
CV_Arch_M68010 = 0x21,
CV_Arch_M68020 = 0x22,
CV_Arch_M68030 = 0x23,
CV_Arch_M68040 = 0x24,
CV_Arch_ALPHA = 0x30,
CV_Arch_ALPHA_21164 = 0x31,
CV_Arch_ALPHA_21164A = 0x32,
CV_Arch_ALPHA_21264 = 0x33,
CV_Arch_ALPHA_21364 = 0x34,
CV_Arch_PPC601 = 0x40,
CV_Arch_PPC603 = 0x41,
CV_Arch_PPC604 = 0x42,
CV_Arch_PPC620 = 0x43,
CV_Arch_PPCFP = 0x44,
CV_Arch_PPCBE = 0x45,
CV_Arch_SH3 = 0x50,
CV_Arch_SH3E = 0x51,
CV_Arch_SH3DSP = 0x52,
CV_Arch_SH4 = 0x53,
CV_Arch_SHMEDIA = 0x54,
CV_Arch_ARM3 = 0x60,
CV_Arch_ARM4 = 0x61,
CV_Arch_ARM4T = 0x62,
CV_Arch_ARM5 = 0x63,
CV_Arch_ARM5T = 0x64,
CV_Arch_ARM6 = 0x65,
CV_Arch_ARM_XMAC = 0x66,
CV_Arch_ARM_WMMX = 0x67,
CV_Arch_ARM7 = 0x68,
CV_Arch_OMNI = 0x70,
CV_Arch_IA64_1 = 0x80,
CV_Arch_IA64_2 = 0x81,
CV_Arch_CEE = 0x90,
CV_Arch_AM33 = 0xA0,
CV_Arch_M32R = 0xB0,
CV_Arch_TRICORE = 0xC0,
CV_Arch_X64 = 0xD0,
CV_Arch_EBC = 0xE0,
CV_Arch_THUMB = 0xF0,
CV_Arch_ARMNT = 0xF4,
CV_Arch_ARM64 = 0xF6,
CV_Arch_D3D11_SHADER = 0x100,
CV_Arch_IA64 = CV_Arch_IA64_1,
CV_Arch_PENTIUMPRO = CV_Arch_PENTIUMII,
CV_Arch_MIPSR4000 = CV_Arch_MIPS,
CV_Arch_ALPHA_21064 = CV_Arch_ALPHA,
CV_Arch_AMD64 = CV_Arch_X64,
} CV_ArchEnum;
typedef U16 CV_AllReg;
typedef enum CV_AllRegEnum
{
CV_AllReg_ERR = 30000,
CV_AllReg_TEB = 30001,
CV_AllReg_TIMER = 30002,
CV_AllReg_EFAD1 = 30003,
CV_AllReg_EFAD2 = 30004,
CV_AllReg_EFAD3 = 30005,
CV_AllReg_VFRAME = 30006,
CV_AllReg_HANDLE = 30007,
CV_AllReg_PARAMS = 30008,
CV_AllReg_LOCALS = 30009,
CV_AllReg_TID = 30010,
CV_AllReg_ENV = 30011,
CV_AllReg_CMDLN = 30012,
} CV_AllRegEnum;
typedef U16 CV_SymKind;
typedef enum CV_SymKindEnum
{
CV_SymKind_COMPILE = 0x0001,
CV_SymKind_REGISTER_16t = 0x0002,
CV_SymKind_CONSTANT_16t = 0x0003,
CV_SymKind_UDT_16t = 0x0004,
CV_SymKind_SSEARCH = 0x0005,
CV_SymKind_END = 0x0006,
CV_SymKind_SKIP = 0x0007,
CV_SymKind_CVRESERVE = 0x0008,
CV_SymKind_OBJNAME_ST = 0x0009,
CV_SymKind_ENDARG = 0x000a,
CV_SymKind_COBOLUDT_16t = 0x000b,
CV_SymKind_MANYREG_16t = 0x000c,
CV_SymKind_RETURN = 0x000d,
CV_SymKind_ENTRYTHIS = 0x000e,
CV_SymKind_BPREL16 = 0x0100,
CV_SymKind_LDATA16 = 0x0101,
CV_SymKind_GDATA16 = 0x0102,
CV_SymKind_PUB16 = 0x0103,
CV_SymKind_LPROC16 = 0x0104,
CV_SymKind_GPROC16 = 0x0105,
CV_SymKind_THUNK16 = 0x0106,
CV_SymKind_BLOCK16 = 0x0107,
CV_SymKind_WITH16 = 0x0108,
CV_SymKind_LABEL16 = 0x0109,
CV_SymKind_CEXMODEL16 = 0x010a,
CV_SymKind_VFTABLE16 = 0x010b,
CV_SymKind_REGREL16 = 0x010c,
CV_SymKind_BPREL32_16t = 0x0200,
CV_SymKind_LDATA32_16t = 0x0201,
CV_SymKind_GDATA32_16t = 0x0202,
CV_SymKind_PUB32_16t = 0x0203,
CV_SymKind_LPROC32_16t = 0x0204,
CV_SymKind_GPROC32_16t = 0x0205,
CV_SymKind_THUNK32_ST = 0x0206,
CV_SymKind_BLOCK32_ST = 0x0207,
CV_SymKind_WITH32_ST = 0x0208,
CV_SymKind_LABEL32_ST = 0x0209,
CV_SymKind_CEXMODEL32 = 0x020a,
CV_SymKind_VFTABLE32_16t = 0x020b,
CV_SymKind_REGREL32_16t = 0x020c,
CV_SymKind_LTHREAD32_16t = 0x020d,
CV_SymKind_GTHREAD32_16t = 0x020e,
CV_SymKind_SLINK32 = 0x020f,
CV_SymKind_LPROCMIPS_16t = 0x0300,
CV_SymKind_GPROCMIPS_16t = 0x0301,
CV_SymKind_PROCREF_ST = 0x0400,
CV_SymKind_DATAREF_ST = 0x0401,
CV_SymKind_ALIGN = 0x0402,
CV_SymKind_LPROCREF_ST = 0x0403,
CV_SymKind_OEM = 0x0404,
CV_SymKind_TI16_MAX = 0x1000,
CV_SymKind_CONSTANT_ST = 0x1002,
CV_SymKind_UDT_ST = 0x1003,
CV_SymKind_COBOLUDT_ST = 0x1004,
CV_SymKind_MANYREG_ST = 0x1005,
CV_SymKind_BPREL32_ST = 0x1006,
CV_SymKind_LDATA32_ST = 0x1007,
CV_SymKind_GDATA32_ST = 0x1008,
CV_SymKind_PUB32_ST = 0x1009,
CV_SymKind_LPROC32_ST = 0x100a,
CV_SymKind_GPROC32_ST = 0x100b,
CV_SymKind_VFTABLE32 = 0x100c,
CV_SymKind_REGREL32_ST = 0x100d,
CV_SymKind_LTHREAD32_ST = 0x100e,
CV_SymKind_GTHREAD32_ST = 0x100f,
CV_SymKind_LPROCMIPS_ST = 0x1010,
CV_SymKind_GPROCMIPS_ST = 0x1011,
CV_SymKind_FRAMEPROC = 0x1012,
CV_SymKind_COMPILE2_ST = 0x1013,
CV_SymKind_MANYREG2_ST = 0x1014,
CV_SymKind_LPROCIA64_ST = 0x1015,
CV_SymKind_GPROCIA64_ST = 0x1016,
CV_SymKind_LOCALSLOT_ST = 0x1017,
CV_SymKind_PARAMSLOT_ST = 0x1018,
CV_SymKind_ANNOTATION = 0x1019,
CV_SymKind_GMANPROC_ST = 0x101a,
CV_SymKind_LMANPROC_ST = 0x101b,
CV_SymKind_RESERVED1 = 0x101c,
CV_SymKind_RESERVED2 = 0x101d,
CV_SymKind_RESERVED3 = 0x101e,
CV_SymKind_RESERVED4 = 0x101f,
CV_SymKind_LMANDATA_ST = 0x1020,
CV_SymKind_GMANDATA_ST = 0x1021,
CV_SymKind_MANFRAMEREL_ST = 0x1022,
CV_SymKind_MANREGISTER_ST = 0x1023,
CV_SymKind_MANSLOT_ST = 0x1024,
CV_SymKind_MANMANYREG_ST = 0x1025,
CV_SymKind_MANREGREL_ST = 0x1026,
CV_SymKind_MANMANYREG2_ST = 0x1027,
CV_SymKind_MANTYPREF = 0x1028,
CV_SymKind_UNAMESPACE_ST = 0x1029,
CV_SymKind_ST_MAX = 0x1100,
CV_SymKind_OBJNAME = 0x1101,
CV_SymKind_THUNK32 = 0x1102,
CV_SymKind_BLOCK32 = 0x1103,
CV_SymKind_WITH32 = 0x1104,
CV_SymKind_LABEL32 = 0x1105,
CV_SymKind_REGISTER = 0x1106,
CV_SymKind_CONSTANT = 0x1107,
CV_SymKind_UDT = 0x1108,
CV_SymKind_COBOLUDT = 0x1109,
CV_SymKind_MANYREG = 0x110a,
CV_SymKind_BPREL32 = 0x110b,
CV_SymKind_LDATA32 = 0x110c,
CV_SymKind_GDATA32 = 0x110d,
CV_SymKind_PUB32 = 0x110e,
CV_SymKind_LPROC32 = 0x110f,
CV_SymKind_GPROC32 = 0x1110,
CV_SymKind_REGREL32 = 0x1111,
CV_SymKind_LTHREAD32 = 0x1112,
CV_SymKind_GTHREAD32 = 0x1113,
CV_SymKind_LPROCMIPS = 0x1114,
CV_SymKind_GPROCMIPS = 0x1115,
CV_SymKind_COMPILE2 = 0x1116,
CV_SymKind_MANYREG2 = 0x1117,
CV_SymKind_LPROCIA64 = 0x1118,
CV_SymKind_GPROCIA64 = 0x1119,
CV_SymKind_LOCALSLOT = 0x111a,
CV_SymKind_PARAMSLOT = 0x111b,
CV_SymKind_LMANDATA = 0x111c,
CV_SymKind_GMANDATA = 0x111d,
CV_SymKind_MANFRAMEREL = 0x111e,
CV_SymKind_MANREGISTER = 0x111f,
CV_SymKind_MANSLOT = 0x1120,
CV_SymKind_MANMANYREG = 0x1121,
CV_SymKind_MANREGREL = 0x1122,
CV_SymKind_MANMANYREG2 = 0x1123,
CV_SymKind_UNAMESPACE = 0x1124,
CV_SymKind_PROCREF = 0x1125,
CV_SymKind_DATAREF = 0x1126,
CV_SymKind_LPROCREF = 0x1127,
CV_SymKind_ANNOTATIONREF = 0x1128,
CV_SymKind_TOKENREF = 0x1129,
CV_SymKind_GMANPROC = 0x112a,
CV_SymKind_LMANPROC = 0x112b,
CV_SymKind_TRAMPOLINE = 0x112c,
CV_SymKind_MANCONSTANT = 0x112d,
CV_SymKind_ATTR_FRAMEREL = 0x112e,
CV_SymKind_ATTR_REGISTER = 0x112f,
CV_SymKind_ATTR_REGREL = 0x1130,
CV_SymKind_ATTR_MANYREG = 0x1131,
CV_SymKind_SEPCODE = 0x1132,
CV_SymKind_DEFRANGE_2005 = 0x1134,
CV_SymKind_DEFRANGE2_2005 = 0x1135,
CV_SymKind_SECTION = 0x1136,
CV_SymKind_COFFGROUP = 0x1137,
CV_SymKind_EXPORT = 0x1138,
CV_SymKind_CALLSITEINFO = 0x1139,
CV_SymKind_FRAMECOOKIE = 0x113a,
CV_SymKind_DISCARDED = 0x113b,
CV_SymKind_COMPILE3 = 0x113c,
CV_SymKind_ENVBLOCK = 0x113d,
CV_SymKind_LOCAL = 0x113e,
CV_SymKind_DEFRANGE = 0x113f,
CV_SymKind_DEFRANGE_SUBFIELD = 0x1140,
CV_SymKind_DEFRANGE_REGISTER = 0x1141,
CV_SymKind_DEFRANGE_FRAMEPOINTER_REL = 0x1142,
CV_SymKind_DEFRANGE_SUBFIELD_REGISTER = 0x1143,
CV_SymKind_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE = 0x1144,
CV_SymKind_DEFRANGE_REGISTER_REL = 0x1145,
CV_SymKind_LPROC32_ID = 0x1146,
CV_SymKind_GPROC32_ID = 0x1147,
CV_SymKind_LPROCMIPS_ID = 0x1148,
CV_SymKind_GPROCMIPS_ID = 0x1149,
CV_SymKind_LPROCIA64_ID = 0x114a,
CV_SymKind_GPROCIA64_ID = 0x114b,
CV_SymKind_BUILDINFO = 0x114c,
CV_SymKind_INLINESITE = 0x114d,
CV_SymKind_INLINESITE_END = 0x114e,
CV_SymKind_PROC_ID_END = 0x114f,
CV_SymKind_DEFRANGE_HLSL = 0x1150,
CV_SymKind_GDATA_HLSL = 0x1151,
CV_SymKind_LDATA_HLSL = 0x1152,
CV_SymKind_FILESTATIC = 0x1153,
CV_SymKind_LPROC32_DPC = 0x1155,
CV_SymKind_LPROC32_DPC_ID = 0x1156,
CV_SymKind_DEFRANGE_DPC_PTR_TAG = 0x1157,
CV_SymKind_DPC_SYM_TAG_MAP = 0x1158,
CV_SymKind_ARMSWITCHTABLE = 0x1159,
CV_SymKind_CALLEES = 0x115a,
CV_SymKind_CALLERS = 0x115b,
CV_SymKind_POGODATA = 0x115c,
CV_SymKind_INLINESITE2 = 0x115d,
CV_SymKind_HEAPALLOCSITE = 0x115e,
CV_SymKind_MOD_TYPEREF = 0x115f,
CV_SymKind_REF_MINIPDB = 0x1160,
CV_SymKind_PDBMAP = 0x1161,
CV_SymKind_GDATA_HLSL32 = 0x1162,
CV_SymKind_LDATA_HLSL32 = 0x1163,
CV_SymKind_GDATA_HLSL32_EX = 0x1164,
CV_SymKind_LDATA_HLSL32_EX = 0x1165,
CV_SymKind_FASTLINK = 0x1167,
CV_SymKind_INLINEES = 0x1168,
} CV_SymKindEnum;
typedef U8 CV_BasicType;
typedef enum CV_BasicTypeEnum
{
CV_BasicType_NOTYPE = 0x00,
CV_BasicType_ABS = 0x01,
CV_BasicType_SEGMENT = 0x02,
CV_BasicType_VOID = 0x03,
CV_BasicType_CURRENCY = 0x04,
CV_BasicType_NBASICSTR = 0x05,
CV_BasicType_FBASICSTR = 0x06,
CV_BasicType_NOTTRANS = 0x07,
CV_BasicType_HRESULT = 0x08,
CV_BasicType_CHAR = 0x10,
CV_BasicType_SHORT = 0x11,
CV_BasicType_LONG = 0x12,
CV_BasicType_QUAD = 0x13,
CV_BasicType_OCT = 0x14,
CV_BasicType_UCHAR = 0x20,
CV_BasicType_USHORT = 0x21,
CV_BasicType_ULONG = 0x22,
CV_BasicType_UQUAD = 0x23,
CV_BasicType_UOCT = 0x24,
CV_BasicType_BOOL8 = 0x30,
CV_BasicType_BOOL16 = 0x31,
CV_BasicType_BOOL32 = 0x32,
CV_BasicType_BOOL64 = 0x33,
CV_BasicType_FLOAT32 = 0x40,
CV_BasicType_FLOAT64 = 0x41,
CV_BasicType_FLOAT80 = 0x42,
CV_BasicType_FLOAT128 = 0x43,
CV_BasicType_FLOAT48 = 0x44,
CV_BasicType_FLOAT32PP = 0x45,
CV_BasicType_FLOAT16 = 0x46,
CV_BasicType_COMPLEX32 = 0x50,
CV_BasicType_COMPLEX64 = 0x51,
CV_BasicType_COMPLEX80 = 0x52,
CV_BasicType_COMPLEX128 = 0x53,
CV_BasicType_BIT = 0x60,
CV_BasicType_PASCHAR = 0x61,
CV_BasicType_BOOL32FF = 0x62,
CV_BasicType_INT8 = 0x68,
CV_BasicType_UINT8 = 0x69,
CV_BasicType_RCHAR = 0x70,
CV_BasicType_WCHAR = 0x71,
CV_BasicType_INT16 = 0x72,
CV_BasicType_UINT16 = 0x73,
CV_BasicType_INT32 = 0x74,
CV_BasicType_UINT32 = 0x75,
CV_BasicType_INT64 = 0x76,
CV_BasicType_UINT64 = 0x77,
CV_BasicType_INT128 = 0x78,
CV_BasicType_UINT128 = 0x79,
CV_BasicType_CHAR16 = 0x7a,
CV_BasicType_CHAR32 = 0x7b,
CV_BasicType_CHAR8 = 0x7c,
CV_BasicType_PTR = 0xf0,
} CV_BasicTypeEnum;
typedef U16 CV_LeafKind;
typedef enum CV_LeafKindEnum
{
CV_LeafKind_MODIFIER_16t = 0x0001,
CV_LeafKind_POINTER_16t = 0x0002,
CV_LeafKind_ARRAY_16t = 0x0003,
CV_LeafKind_CLASS_16t = 0x0004,
CV_LeafKind_STRUCTURE_16t = 0x0005,
CV_LeafKind_UNION_16t = 0x0006,
CV_LeafKind_ENUM_16t = 0x0007,
CV_LeafKind_PROCEDURE_16t = 0x0008,
CV_LeafKind_MFUNCTION_16t = 0x0009,
CV_LeafKind_VTSHAPE = 0x000a,
CV_LeafKind_COBOL0_16t = 0x000b,
CV_LeafKind_COBOL1 = 0x000c,
CV_LeafKind_BARRAY_16t = 0x000d,
CV_LeafKind_LABEL = 0x000e,
CV_LeafKind_NULL = 0x000f,
CV_LeafKind_NOTTRAN = 0x0010,
CV_LeafKind_DIMARRAY_16t = 0x0011,
CV_LeafKind_VFTPATH_16t = 0x0012,
CV_LeafKind_PRECOMP_16t = 0x0013,
CV_LeafKind_ENDPRECOMP = 0x0014,
CV_LeafKind_OEM_16t = 0x0015,
CV_LeafKind_TYPESERVER_ST = 0x0016,
CV_LeafKind_SKIP_16t = 0x0200,
CV_LeafKind_ARGLIST_16t = 0x0201,
CV_LeafKind_DEFARG_16t = 0x0202,
CV_LeafKind_LIST = 0x0203,
CV_LeafKind_FIELDLIST_16t = 0x0204,
CV_LeafKind_DERIVED_16t = 0x0205,
CV_LeafKind_BITFIELD_16t = 0x0206,
CV_LeafKind_METHODLIST_16t = 0x0207,
CV_LeafKind_DIMCONU_16t = 0x0208,
CV_LeafKind_DIMCONLU_16t = 0x0209,
CV_LeafKind_DIMVARU_16t = 0x020a,
CV_LeafKind_DIMVARLU_16t = 0x020b,
CV_LeafKind_REFSYM = 0x020c,
CV_LeafKind_BCLASS_16t = 0x0400,
CV_LeafKind_VBCLASS_16t = 0x0401,
CV_LeafKind_IVBCLASS_16t = 0x0402,
CV_LeafKind_ENUMERATE_ST = 0x0403,
CV_LeafKind_FRIENDFCN_16t = 0x0404,
CV_LeafKind_INDEX_16t = 0x0405,
CV_LeafKind_MEMBER_16t = 0x0406,
CV_LeafKind_STMEMBER_16t = 0x0407,
CV_LeafKind_METHOD_16t = 0x0408,
CV_LeafKind_NESTTYPE_16t = 0x0409,
CV_LeafKind_VFUNCTAB_16t = 0x040a,
CV_LeafKind_FRIENDCLS_16t = 0x040b,
CV_LeafKind_ONEMETHOD_16t = 0x040c,
CV_LeafKind_VFUNCOFF_16t = 0x040d,
CV_LeafKind_TI16_MAX = 0x1000,
CV_LeafKind_MODIFIER = 0x1001,
CV_LeafKind_POINTER = 0x1002,
CV_LeafKind_ARRAY_ST = 0x1003,
CV_LeafKind_CLASS_ST = 0x1004,
CV_LeafKind_STRUCTURE_ST = 0x1005,
CV_LeafKind_UNION_ST = 0x1006,
CV_LeafKind_ENUM_ST = 0x1007,
CV_LeafKind_PROCEDURE = 0x1008,
CV_LeafKind_MFUNCTION = 0x1009,
CV_LeafKind_COBOL0 = 0x100a,
CV_LeafKind_BARRAY = 0x100b,
CV_LeafKind_DIMARRAY_ST = 0x100c,
CV_LeafKind_VFTPATH = 0x100d,
CV_LeafKind_PRECOMP_ST = 0x100e,
CV_LeafKind_OEM = 0x100f,
CV_LeafKind_ALIAS_ST = 0x1010,
CV_LeafKind_OEM2 = 0x1011,
CV_LeafKind_SKIP = 0x1200,
CV_LeafKind_ARGLIST = 0x1201,
CV_LeafKind_DEFARG_ST = 0x1202,
CV_LeafKind_FIELDLIST = 0x1203,
CV_LeafKind_DERIVED = 0x1204,
CV_LeafKind_BITFIELD = 0x1205,
CV_LeafKind_METHODLIST = 0x1206,
CV_LeafKind_DIMCONU = 0x1207,
CV_LeafKind_DIMCONLU = 0x1208,
CV_LeafKind_DIMVARU = 0x1209,
CV_LeafKind_DIMVARLU = 0x120a,
CV_LeafKind_BCLASS = 0x1400,
CV_LeafKind_VBCLASS = 0x1401,
CV_LeafKind_IVBCLASS = 0x1402,
CV_LeafKind_FRIENDFCN_ST = 0x1403,
CV_LeafKind_INDEX = 0x1404,
CV_LeafKind_MEMBER_ST = 0x1405,
CV_LeafKind_STMEMBER_ST = 0x1406,
CV_LeafKind_METHOD_ST = 0x1407,
CV_LeafKind_NESTTYPE_ST = 0x1408,
CV_LeafKind_VFUNCTAB = 0x1409,
CV_LeafKind_FRIENDCLS = 0x140a,
CV_LeafKind_ONEMETHOD_ST = 0x140b,
CV_LeafKind_VFUNCOFF = 0x140c,
CV_LeafKind_NESTTYPEEX_ST = 0x140d,
CV_LeafKind_MEMBERMODIFY_ST = 0x140e,
CV_LeafKind_MANAGED_ST = 0x140f,
CV_LeafKind_ST_MAX = 0x1500,
CV_LeafKind_TYPESERVER = 0x1501,
CV_LeafKind_ENUMERATE = 0x1502,
CV_LeafKind_ARRAY = 0x1503,
CV_LeafKind_CLASS = 0x1504,
CV_LeafKind_STRUCTURE = 0x1505,
CV_LeafKind_UNION = 0x1506,
CV_LeafKind_ENUM = 0x1507,
CV_LeafKind_DIMARRAY = 0x1508,
CV_LeafKind_PRECOMP = 0x1509,
CV_LeafKind_ALIAS = 0x150a,
CV_LeafKind_DEFARG = 0x150b,
CV_LeafKind_FRIENDFCN = 0x150c,
CV_LeafKind_MEMBER = 0x150d,
CV_LeafKind_STMEMBER = 0x150e,
CV_LeafKind_METHOD = 0x150f,
CV_LeafKind_NESTTYPE = 0x1510,
CV_LeafKind_ONEMETHOD = 0x1511,
CV_LeafKind_NESTTYPEEX = 0x1512,
CV_LeafKind_MEMBERMODIFY = 0x1513,
CV_LeafKind_MANAGED = 0x1514,
CV_LeafKind_TYPESERVER2 = 0x1515,
CV_LeafKind_STRIDED_ARRAY = 0x1516,
CV_LeafKind_HLSL = 0x1517,
CV_LeafKind_MODIFIER_EX = 0x1518,
CV_LeafKind_INTERFACE = 0x1519,
CV_LeafKind_BINTERFACE = 0x151a,
CV_LeafKind_VECTOR = 0x151b,
CV_LeafKind_MATRIX = 0x151c,
CV_LeafKind_VFTABLE = 0x151d,
CV_LeafKind_CLASS2 = 0x1608,
CV_LeafKind_STRUCT2 = 0x1609,
} CV_LeafKindEnum;
internal String8 cv_string_from_numeric_kind(CV_NumericKind v);
internal String8 cv_string_from_arch(CV_Arch v);
internal String8 cv_string_from_sym_kind(CV_SymKind v);
internal String8 cv_string_from_basic_type(CV_BasicType v);
internal String8 cv_type_name_from_basic_type(CV_BasicType v);
internal String8 cv_string_from_leaf_kind(CV_LeafKind v);
internal U64 cv_header_struct_size_from_sym_kind(CV_SymKind v);
internal U64 cv_header_struct_size_from_leaf_kind(CV_LeafKind v);
C_LINKAGE_BEGIN
C_LINKAGE_END
#endif // CODEVIEW_META_H
+10
View File
@@ -11,6 +11,16 @@ typedef U32 COFF_TimeStamp;
#pragma pack(push,1)
typedef struct COFF_Guid COFF_Guid;
struct COFF_Guid
{
U32 data1;
U16 data2;
U16 data3;
U32 data4;
U32 data5;
};
typedef U16 COFF_Flags;
enum
{
+16 -20
View File
@@ -49,37 +49,33 @@ CTRL_ExceptionCodeKindTable:
////////////////////////////////
//~ rjf: Generators
@table_gen_enum CTRL_ExceptionCodeKind:
@enum CTRL_ExceptionCodeKind:
{
`CTRL_ExceptionCodeKind_Null,`;
@expand(CTRL_ExceptionCodeKindTable a) `CTRL_ExceptionCodeKind_$(a.name),`;
`CTRL_ExceptionCodeKind_COUNT`;
Null,
@expand(CTRL_ExceptionCodeKindTable a) `$(a.name)`,
COUNT,
}
@table_gen_data(type:U32, fallback:0)
ctrl_exception_code_kind_code_table:
@data(U32) ctrl_exception_code_kind_code_table:
{
`0,`;
@expand(CTRL_ExceptionCodeKindTable a) `$(a.code),`;
`0`;
@expand(CTRL_ExceptionCodeKindTable a) `$(a.code)`;
}
@table_gen_data(type:String8, fallback:`{0}`)
ctrl_exception_code_kind_display_string_table:
@data(String8) ctrl_exception_code_kind_display_string_table:
{
`{0},`;
@expand(CTRL_ExceptionCodeKindTable a) `str8_lit_comp("$(a.display_string)"),`;
`{0}`;
@expand(CTRL_ExceptionCodeKindTable a) `str8_lit_comp("$(a.display_string)")`;
}
@table_gen_data(type:String8, fallback:`{0}`)
ctrl_exception_code_kind_lowercase_code_string_table:
@data(String8) ctrl_exception_code_kind_lowercase_code_string_table:
{
`{0},`;
@expand(CTRL_ExceptionCodeKindTable a) `str8_lit_comp("$(a.lower_name)"),`;
`{0}`;
@expand(CTRL_ExceptionCodeKindTable a) `str8_lit_comp("$(a.lower_name)")`;
}
@table_gen_data(type:B8, fallback:0)
ctrl_exception_code_kind_default_enable_table:
@data(B8) ctrl_exception_code_kind_default_enable_table:
{
`0,`;
@expand(CTRL_ExceptionCodeKindTable a) `$(a.default),`;
`0`;
@expand(CTRL_ExceptionCodeKindTable a) `$(a.default)`;
}
+1611 -1370
View File
File diff suppressed because it is too large Load Diff
+232 -106
View File
@@ -10,16 +10,7 @@
typedef U64 CTRL_MsgID;
typedef U64 CTRL_MachineID;
#define CTRL_MachineID_Client (1)
////////////////////////////////
//~ rjf: Handle Type
typedef struct CTRL_Handle CTRL_Handle;
struct CTRL_Handle
{
U64 u64[1];
};
#define CTRL_MachineID_Local (1)
////////////////////////////////
//~ rjf: Machine/Handle Pair Types
@@ -28,7 +19,7 @@ typedef struct CTRL_MachineIDHandlePair CTRL_MachineIDHandlePair;
struct CTRL_MachineIDHandlePair
{
CTRL_MachineID machine_id;
CTRL_Handle handle;
DMN_Handle handle;
};
typedef struct CTRL_MachineIDHandlePairNode CTRL_MachineIDHandlePairNode;
@@ -46,6 +37,73 @@ struct CTRL_MachineIDHandlePairList
U64 count;
};
////////////////////////////////
//~ rjf: Entity Types
typedef enum CTRL_EntityKind
{
CTRL_EntityKind_Null,
CTRL_EntityKind_Root,
CTRL_EntityKind_Machine,
CTRL_EntityKind_Process,
CTRL_EntityKind_Thread,
CTRL_EntityKind_Module,
CTRL_EntityKind_EntryPoint,
CTRL_EntityKind_COUNT
}
CTRL_EntityKind;
typedef struct CTRL_Entity CTRL_Entity;
struct CTRL_Entity
{
CTRL_Entity *first;
CTRL_Entity *last;
CTRL_Entity *next;
CTRL_Entity *prev;
CTRL_Entity *parent;
CTRL_EntityKind kind;
Architecture arch;
CTRL_MachineID machine_id;
DMN_Handle handle;
U64 id;
Rng1U64 vaddr_range;
String8 string;
};
typedef struct CTRL_EntityHashNode CTRL_EntityHashNode;
struct CTRL_EntityHashNode
{
CTRL_EntityHashNode *next;
CTRL_EntityHashNode *prev;
CTRL_Entity *entity;
};
typedef struct CTRL_EntityHashSlot CTRL_EntityHashSlot;
struct CTRL_EntityHashSlot
{
CTRL_EntityHashNode *first;
CTRL_EntityHashNode *last;
};
typedef struct CTRL_EntityStringChunkNode CTRL_EntityStringChunkNode;
struct CTRL_EntityStringChunkNode
{
CTRL_EntityStringChunkNode *next;
U64 size;
};
typedef struct CTRL_EntityStore CTRL_EntityStore;
struct CTRL_EntityStore
{
Arena *arena;
CTRL_Entity *root;
CTRL_Entity *free;
CTRL_EntityHashSlot *hash_slots;
CTRL_EntityHashNode *hash_node_free;
U64 hash_slots_count;
CTRL_EntityStringChunkNode *free_string_chunks[8];
};
////////////////////////////////
//~ rjf: Unwind Types
@@ -105,8 +163,8 @@ struct CTRL_TrapList
typedef struct CTRL_Spoof CTRL_Spoof;
struct CTRL_Spoof
{
CTRL_Handle process;
CTRL_Handle thread;
DMN_Handle process;
DMN_Handle thread;
U64 vaddr;
U64 new_ip_value;
};
@@ -159,8 +217,7 @@ struct CTRL_UserBreakpointList
typedef enum CTRL_MsgKind
{
CTRL_MsgKind_Null,
CTRL_MsgKind_LaunchAndHandshake,
CTRL_MsgKind_LaunchAndInit,
CTRL_MsgKind_Launch,
CTRL_MsgKind_Attach,
CTRL_MsgKind_Kill,
CTRL_MsgKind_Detach,
@@ -171,20 +228,27 @@ typedef enum CTRL_MsgKind
}
CTRL_MsgKind;
typedef U32 CTRL_RunFlags;
enum
{
CTRL_RunFlag_StopOnEntryPoint = (1<<0),
};
typedef struct CTRL_Msg CTRL_Msg;
struct CTRL_Msg
{
CTRL_MsgKind kind;
CTRL_RunFlags run_flags;
CTRL_MsgID msg_id;
CTRL_MachineID machine_id;
CTRL_Handle entity;
CTRL_Handle parent;
DMN_Handle entity;
DMN_Handle parent;
U32 entity_id;
U32 exit_code;
B32 env_inherit;
U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64];
String8 path;
String8List strings;
String8List entry_points;
String8List cmd_line_string_list;
String8List env_string_list;
CTRL_TrapList traps;
@@ -238,13 +302,6 @@ typedef enum CTRL_EventKind
CTRL_EventKind_MemDecommit,
CTRL_EventKind_MemRelease,
//- rjf: ctrl requests
CTRL_EventKind_LaunchAndHandshakeDone,
CTRL_EventKind_LaunchAndInitDone,
CTRL_EventKind_AttachDone,
CTRL_EventKind_KillDone,
CTRL_EventKind_DetachDone,
CTRL_EventKind_COUNT
}
CTRL_EventKind;
@@ -254,6 +311,7 @@ typedef enum CTRL_EventCause
CTRL_EventCause_Null,
CTRL_EventCause_Error,
CTRL_EventCause_Finished,
CTRL_EventCause_EntryPoint,
CTRL_EventCause_UserBreakpoint,
CTRL_EventCause_InterruptedByTrap,
CTRL_EventCause_InterruptedByException,
@@ -281,8 +339,8 @@ struct CTRL_Event
CTRL_ExceptionKind exception_kind;
CTRL_MsgID msg_id;
CTRL_MachineID machine_id;
CTRL_Handle entity;
CTRL_Handle parent;
DMN_Handle entity;
DMN_Handle parent;
Architecture arch;
U64 u64_code;
U32 entity_id;
@@ -320,7 +378,8 @@ struct CTRL_ProcessMemoryRangeHashNode
B32 zero_terminated;
Rng1U64 vaddr_range_clamped;
U128 hash;
U64 memgen_idx;
U64 mem_gen;
U64 last_time_requested_us;
B32 is_taken;
};
@@ -338,7 +397,7 @@ struct CTRL_ProcessMemoryCacheNode
CTRL_ProcessMemoryCacheNode *prev;
Arena *arena;
CTRL_MachineID machine_id;
CTRL_Handle process;
DMN_Handle process;
U64 range_hash_slots_count;
CTRL_ProcessMemoryRangeHashSlot *range_hash_slots;
};
@@ -372,6 +431,47 @@ struct CTRL_ProcessMemorySlice
String8 data;
U64 *byte_bad_flags;
U64 *byte_changed_flags;
B32 stale;
B32 any_byte_bad;
B32 any_byte_changed;
};
////////////////////////////////
//~ rjf: Thread Register Cache Types
typedef struct CTRL_ThreadRegCacheNode CTRL_ThreadRegCacheNode;
struct CTRL_ThreadRegCacheNode
{
CTRL_ThreadRegCacheNode *next;
CTRL_ThreadRegCacheNode *prev;
CTRL_MachineID machine_id;
DMN_Handle thread;
U64 block_size;
void *block;
U64 reg_gen;
};
typedef struct CTRL_ThreadRegCacheSlot CTRL_ThreadRegCacheSlot;
struct CTRL_ThreadRegCacheSlot
{
CTRL_ThreadRegCacheNode *first;
CTRL_ThreadRegCacheNode *last;
};
typedef struct CTRL_ThreadRegCacheStripe CTRL_ThreadRegCacheStripe;
struct CTRL_ThreadRegCacheStripe
{
Arena *arena;
OS_Handle rw_mutex;
};
typedef struct CTRL_ThreadRegCache CTRL_ThreadRegCache;
struct CTRL_ThreadRegCache
{
U64 slots_count;
CTRL_ThreadRegCacheSlot *slots;
U64 stripes_count;
CTRL_ThreadRegCacheStripe *stripes;
};
////////////////////////////////
@@ -388,16 +488,14 @@ struct CTRL_State
{
Arena *arena;
CTRL_WakeupFunctionType *wakeup_hook;
U64 run_idx;
U64 memgen_idx;
U64 reggen_idx;
// rjf: name -> register/alias hash tables for eval
EVAL_String2NumMap arch_string2reg_tables[Architecture_COUNT];
EVAL_String2NumMap arch_string2alias_tables[Architecture_COUNT];
// rjf: process memory cache
// rjf: caches
CTRL_ProcessMemoryCache process_memory_cache;
CTRL_ThreadRegCache thread_reg_cache;
// rjf: user -> ctrl msg ring buffer
U64 u2c_ring_size;
@@ -417,10 +515,11 @@ struct CTRL_State
// rjf: ctrl thread state
OS_Handle ctrl_thread;
Arena *demon_event_arena;
DEMON_EventNode *first_demon_event_node;
DEMON_EventNode *last_demon_event_node;
DEMON_EventNode *free_demon_event_node;
CTRL_EntityStore *ctrl_thread_entity_store;
Arena *dmn_event_arena;
DMN_EventNode *first_dmn_event_node;
DMN_EventNode *last_dmn_event_node;
DMN_EventNode *free_dmn_event_node;
Arena *user_entry_point_arena;
String8List user_entry_points;
U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64];
@@ -443,24 +542,21 @@ struct CTRL_State
//~ rjf: Globals
global CTRL_State *ctrl_state = 0;
////////////////////////////////
//~ rjf: Main Layer Initialization
internal void ctrl_init(CTRL_WakeupFunctionType *wakeup_hook);
read_only global CTRL_Entity ctrl_entity_nil =
{
&ctrl_entity_nil,
&ctrl_entity_nil,
&ctrl_entity_nil,
&ctrl_entity_nil,
&ctrl_entity_nil,
};
////////////////////////////////
//~ rjf: Basic Type Functions
internal U64 ctrl_hash_from_string(String8 string);
internal CTRL_EventCause ctrl_event_cause_from_demon_event_kind(DEMON_EventKind event_kind);
internal B32 ctrl_handle_match(CTRL_Handle a, CTRL_Handle b);
////////////////////////////////
//~ rjf: Ctrl <-> Demon Handle Translation Functions
internal DEMON_Handle ctrl_demon_handle_from_ctrl(CTRL_Handle h);
internal CTRL_Handle ctrl_handle_from_demon(DEMON_Handle h);
internal U64 ctrl_hash_from_machine_id_handle(CTRL_MachineID machine_id, DMN_Handle handle);
internal CTRL_EventCause ctrl_event_cause_from_dmn_event_kind(DMN_EventKind event_kind);
////////////////////////////////
//~ rjf: Machine/Handle Pair Type Functions
@@ -479,8 +575,6 @@ internal CTRL_TrapList ctrl_trap_list_copy(Arena *arena, CTRL_TrapList *src);
internal void ctrl_user_breakpoint_list_push(Arena *arena, CTRL_UserBreakpointList *list, CTRL_UserBreakpoint *bp);
internal CTRL_UserBreakpointList ctrl_user_breakpoint_list_copy(Arena *arena, CTRL_UserBreakpointList *src);
internal void ctrl_append_resolved_module_user_bp_traps(Arena *arena, DEMON_Handle process, DEMON_Handle module, CTRL_UserBreakpointList *user_bps, DEMON_TrapChunkList *traps_out);
internal void ctrl_append_resolved_process_user_bp_traps(Arena *arena, DEMON_Handle process, CTRL_UserBreakpointList *user_bps, DEMON_TrapChunkList *traps_out);
////////////////////////////////
//~ rjf: Message Type Functions
@@ -507,97 +601,129 @@ internal String8 ctrl_serialized_string_from_event(Arena *arena, CTRL_Event *eve
internal CTRL_Event ctrl_event_from_serialized_string(Arena *arena, String8 string);
////////////////////////////////
//~ rjf: Shared Functions
//~ rjf: Entity Type Functions
//- rjf: run index
internal U64 ctrl_run_idx(void);
internal U64 ctrl_memgen_idx(void);
internal U64 ctrl_reggen_idx(void);
//- rjf: cache creation/destruction
internal CTRL_EntityStore *ctrl_entity_store_alloc(void);
internal void ctrl_entity_store_release(CTRL_EntityStore *store);
//- rjf: halt everything
internal void ctrl_halt(void);
//- rjf: string allocation/deletion
internal String8 ctrl_entity_string_alloc(CTRL_EntityStore *store, String8 string);
internal void ctrl_entity_string_release(CTRL_EntityStore *store, String8 string);
//- rjf: exe -> dbg path mapping
internal String8 ctrl_inferred_og_dbg_path_from_exe_path(Arena *arena, String8 exe_path);
internal String8 ctrl_forced_og_dbg_path_from_exe_path(Arena *arena, String8 exe_path);
internal String8 ctrl_natural_og_dbg_path_from_exe_path(Arena *arena, String8 exe_path);
internal String8 ctrl_og_dbg_path_from_exe_path(Arena *arena, String8 exe_path);
//- rjf: entity construction/deletion
internal CTRL_Entity *ctrl_entity_alloc(CTRL_EntityStore *store, CTRL_Entity *parent, CTRL_EntityKind kind, Architecture arch, CTRL_MachineID machine_id, DMN_Handle handle, U64 id);
internal void ctrl_entity_release(CTRL_EntityStore *store, CTRL_Entity *entity);
//- rjf: handle -> arch
internal Architecture ctrl_arch_from_handle(CTRL_MachineID machine, CTRL_Handle handle);
//- rjf: entity equipment
internal void ctrl_entity_equip_string(CTRL_EntityStore *store, CTRL_Entity *entity, String8 string);
//- rjf: process memory reading/writing
internal U64 ctrl_process_read(CTRL_MachineID machine_id, CTRL_Handle process, Rng1U64 range, void *dst);
internal B32 ctrl_process_write(CTRL_MachineID machine_id, CTRL_Handle process, Rng1U64 range, void *src);
//- rjf: entity store lookups
internal CTRL_Entity *ctrl_entity_from_machine_id_handle(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle handle);
//- rjf: applying events to entity caches
internal void ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list);
////////////////////////////////
//~ rjf: Main Layer Initialization
internal void ctrl_init(void);
////////////////////////////////
//~ rjf: Wakeup Callback Registration
internal void ctrl_set_wakeup_hook(CTRL_WakeupFunctionType *wakeup_hook);
////////////////////////////////
//~ rjf: Process Memory Functions
//- rjf: process memory cache interaction
internal U128 ctrl_hash_store_key_from_process_vaddr_range(CTRL_MachineID machine_id, CTRL_Handle process, Rng1U64 range, B32 zero_terminated);
internal U128 ctrl_stored_hash_from_process_vaddr_range(CTRL_MachineID machine_id, CTRL_Handle process, Rng1U64 range, B32 zero_terminated, U64 endt_us);
internal U128 ctrl_calc_hash_store_key_from_process_vaddr_range(CTRL_MachineID machine_id, DMN_Handle process, Rng1U64 range, B32 zero_terminated);
internal U128 ctrl_stored_hash_from_process_vaddr_range(CTRL_MachineID machine_id, DMN_Handle process, Rng1U64 range, B32 zero_terminated, B32 *out_is_stale, U64 endt_us);
//- rjf: bundled key/stream helper
internal U128 ctrl_hash_store_key_from_process_vaddr_range(CTRL_MachineID machine_id, DMN_Handle process, Rng1U64 range, B32 zero_terminated);
//- rjf: process memory cache reading helpers
internal CTRL_ProcessMemorySlice ctrl_query_cached_data_from_process_vaddr_range(Arena *arena, CTRL_MachineID machine_id, CTRL_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, CTRL_Handle process, U64 vaddr, U64 limit, U64 endt_us);
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);
//- rjf: register reading/writing
internal void *ctrl_reg_block_from_thread(CTRL_MachineID machine_id, CTRL_Handle thread);
internal B32 ctrl_thread_write_reg_block(CTRL_MachineID machine_id, CTRL_Handle thread, void *block);
internal U64 ctrl_rip_from_thread(CTRL_MachineID machine_id, CTRL_Handle thread);
internal B32 ctrl_thread_write_rip(CTRL_MachineID machine_id, CTRL_Handle thread, U64 rip);
internal U64 ctrl_tls_root_vaddr_from_thread(CTRL_MachineID machine_id, CTRL_Handle thread);
//- rjf: process memory writing
internal B32 ctrl_process_write(CTRL_MachineID machine_id, DMN_Handle process, Rng1U64 range, void *src);
//- rjf: process * vaddr -> module
internal CTRL_Handle ctrl_module_from_process_vaddr(CTRL_MachineID machine_id, CTRL_Handle process, U64 vaddr);
////////////////////////////////
//~ rjf: Thread Register Functions
//- rjf: unwinding
internal CTRL_Unwind ctrl_unwind_from_process_thread(Arena *arena, CTRL_MachineID machine_id, CTRL_Handle process, CTRL_Handle thread);
//- rjf: thread register cache reading
internal void *ctrl_query_cached_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle thread);
internal U64 ctrl_query_cached_tls_root_vaddr_from_thread(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle thread);
internal U64 ctrl_query_cached_rip_from_thread(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle thread);
//- rjf: thread register writing
internal B32 ctrl_thread_write_reg_block(CTRL_MachineID machine_id, DMN_Handle thread, void *block);
////////////////////////////////
//~ rjf: Unwinding Functions
internal CTRL_Unwind ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle thread, U64 endt_us);
////////////////////////////////
//~ rjf: Halting All Attached Processes
internal void ctrl_halt(void);
////////////////////////////////
//~ rjf: Shared Accessor Functions
//- rjf: generation counters
internal U64 ctrl_run_gen(void);
internal U64 ctrl_mem_gen(void);
internal U64 ctrl_reg_gen(void);
//- rjf: name -> register/alias hash tables, for eval
internal EVAL_String2NumMap *ctrl_string2reg_from_arch(Architecture arch);
internal EVAL_String2NumMap *ctrl_string2alias_from_arch(Architecture arch);
////////////////////////////////
//~ rjf: User -> Ctrl Communication
//~ rjf: Control-Thread Functions
//- rjf: user -> control thread communication
internal B32 ctrl_u2c_push_msgs(CTRL_MsgList *msgs, U64 endt_us);
internal CTRL_MsgList ctrl_u2c_pop_msgs(Arena *arena);
////////////////////////////////
//~ rjf: Ctrl -> User Communication
//- rjf: control -> user thread communication
internal void ctrl_c2u_push_events(CTRL_EventList *events);
internal CTRL_EventList ctrl_c2u_pop_events(Arena *arena);
////////////////////////////////
//~ rjf: User -> Memory Stream Communication
internal B32 ctrl_u2ms_enqueue_req(CTRL_MachineID machine_id, CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us);
internal void ctrl_u2ms_dequeue_req(CTRL_MachineID *out_machine_id, CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated);
////////////////////////////////
//~ rjf: Control-Thread-Only Functions
//- rjf: entry point
internal void ctrl_thread__entry_point(void *p);
//- rjf: breakpoint resolution
internal void ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_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: attached process running/event gathering
internal DEMON_Event *ctrl_thread__next_demon_event(Arena *arena, CTRL_Msg *msg, DEMON_RunCtrls *run_ctrls, CTRL_Spoof *spoof);
internal DMN_Event *ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, DMN_RunCtrls *run_ctrls, CTRL_Spoof *spoof);
//- rjf: eval helpers
internal B32 ctrl_eval_memory_read(void *u, void *out, U64 addr, U64 size);
//- rjf: msg kind implementations
internal void ctrl_thread__launch_and_handshake(CTRL_Msg *msg);
internal void ctrl_thread__launch_and_init(CTRL_Msg *msg);
internal void ctrl_thread__attach(CTRL_Msg *msg);
internal void ctrl_thread__kill(CTRL_Msg *msg);
internal void ctrl_thread__detach(CTRL_Msg *msg);
internal void ctrl_thread__run(CTRL_Msg *msg);
internal void ctrl_thread__single_step(CTRL_Msg *msg);
internal void ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
internal void ctrl_thread__attach(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
internal void ctrl_thread__kill(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
internal void ctrl_thread__detach(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
internal void ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
internal void ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
////////////////////////////////
//~ rjf: Memory-Stream-Thread-Only Functions
//~ rjf: Memory-Stream Thread Functions
//- rjf: user -> memory stream communication
internal B32 ctrl_u2ms_enqueue_req(CTRL_MachineID machine_id, DMN_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us);
internal void ctrl_u2ms_dequeue_req(CTRL_MachineID *out_machine_id, DMN_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated);
//- rjf: entry point
internal void ctrl_mem_stream_thread__entry_point(void *p);
#endif //CTRL_CORE_H
#endif // CTRL_CORE_H
+1 -1
View File
@@ -74,4 +74,4 @@
#include "ctrl_core.h"
#endif //CTRL_INC_H
#endif // CTRL_INC_H
+171
View File
@@ -3,3 +3,174 @@
//- GENERATED CODE
C_LINKAGE_BEGIN
U32 ctrl_exception_code_kind_code_table[38] =
{
0,
0x40010005,
0x40010008,
0x40080201,
0x40080202,
0x0000071a,
0x80000002,
0xc0000005,
0xc0000006,
0xc0000008,
0xc0000017,
0xc000001d,
0xc0000025,
0xc0000026,
0xc000008c,
0xc000008d,
0xc000008e,
0xc000008f,
0xc0000090,
0xc0000091,
0xc0000092,
0xc0000093,
0xc0000094,
0xc0000095,
0xc0000096,
0xc00000fd,
0xc0000135,
0xc0000138,
0xc0000139,
0xc0000142,
0xc00002b4,
0xc00002b5,
0xc0000420,
0xc06d007e,
0xc06d007f,
0xe073616e,
0xe0736171,
0x0000087a,
};
String8 ctrl_exception_code_kind_display_string_table[38] =
{
{0},
str8_lit_comp("(Win32) Control-C"),
str8_lit_comp("(Win32) Control-Break"),
str8_lit_comp("(Win32) WinRT Originate Error"),
str8_lit_comp("(Win32) WinRT Transform Error"),
str8_lit_comp("(Win32) RPC Call Cancelled"),
str8_lit_comp("(Win32) Data Type Misalignment"),
str8_lit_comp("(Win32) Access Violation"),
str8_lit_comp("(Win32) In Page Error"),
str8_lit_comp("(Win32) Invalid Handle Specified"),
str8_lit_comp("(Win32) Not Enough Quota"),
str8_lit_comp("(Win32) Illegal Instruction"),
str8_lit_comp("(Win32) Cannot Continue From Exception"),
str8_lit_comp("(Win32) Invalid Exception Disposition Returned By Handler"),
str8_lit_comp("(Win32) Array Bounds Exceeded"),
str8_lit_comp("(Win32) Floating-Point Denormal Operand"),
str8_lit_comp("(Win32) Floating-Point Division By Zero"),
str8_lit_comp("(Win32) Floating-Point Inexact Result"),
str8_lit_comp("(Win32) Floating-Point Invalid Operation"),
str8_lit_comp("(Win32) Floating-Point Overflow"),
str8_lit_comp("(Win32) Floating-Point Stack Check"),
str8_lit_comp("(Win32) Floating-Point Underflow"),
str8_lit_comp("(Win32) Integer Division By Zero"),
str8_lit_comp("(Win32) Integer Overflow"),
str8_lit_comp("(Win32) Privileged Instruction"),
str8_lit_comp("(Win32) Stack Overflow"),
str8_lit_comp("(Win32) Unable To Locate DLL"),
str8_lit_comp("(Win32) Ordinal Not Found"),
str8_lit_comp("(Win32) Entry Point Not Found"),
str8_lit_comp("(Win32) DLL Initialization Failed"),
str8_lit_comp("(Win32) Floating Point SSE Multiple Faults"),
str8_lit_comp("(Win32) Floating Point SSE Multiple Traps"),
str8_lit_comp("(Win32) Assertion Failed"),
str8_lit_comp("(Win32) Module Not Found"),
str8_lit_comp("(Win32) Procedure Not Found"),
str8_lit_comp("(Win32) Sanitizer Error Detected"),
str8_lit_comp("(Win32) Sanitizer Raw Access Violation"),
str8_lit_comp("(Win32) DirectX Debug Layer"),
};
String8 ctrl_exception_code_kind_lowercase_code_string_table[38] =
{
{0},
str8_lit_comp("win32_ctrl_c"),
str8_lit_comp("win32_ctrl_break"),
str8_lit_comp("win32_win_rt_originate_error"),
str8_lit_comp("win32_win_rt_transform_error"),
str8_lit_comp("win32_rpc_call_cancelled"),
str8_lit_comp("win32_datatype_misalignment"),
str8_lit_comp("win32_access_violation"),
str8_lit_comp("win32_in_page_error"),
str8_lit_comp("win32_invalid_handle"),
str8_lit_comp("win32_not_enough_quota"),
str8_lit_comp("win32_illegal_instruction"),
str8_lit_comp("win32_cannot_continue_exception"),
str8_lit_comp("win32_invalid_exception_disposition"),
str8_lit_comp("win32_array_bounds_exceeded"),
str8_lit_comp("win32_floating_point_denormal_operand"),
str8_lit_comp("win32_floating_point_division_by_zero"),
str8_lit_comp("win32_floating_point_inexact_result"),
str8_lit_comp("win32_floating_point_invalid_operation"),
str8_lit_comp("win32_floating_point_overflow"),
str8_lit_comp("win32_floating_point_stack_check"),
str8_lit_comp("win32_floating_point_underflow"),
str8_lit_comp("win32_integer_division_by_zero"),
str8_lit_comp("win32_integer_overflow"),
str8_lit_comp("win32_privileged_instruction"),
str8_lit_comp("win32_stack_overflow"),
str8_lit_comp("win32_unable_to_locate_dll"),
str8_lit_comp("win32_ordinal_not_found"),
str8_lit_comp("win32_entry_point_not_found"),
str8_lit_comp("win32_dll_initialization_failed"),
str8_lit_comp("win32_floating_point_sse_multiple_faults"),
str8_lit_comp("win32_floating_point_sse_multiple_traps"),
str8_lit_comp("win32_assertion_failed"),
str8_lit_comp("win32_module_not_found"),
str8_lit_comp("win32_procedure_not_found"),
str8_lit_comp("win32_sanitizer_error_detected"),
str8_lit_comp("win32_sanitizer_raw_access_violation"),
str8_lit_comp("win32_directx_debug_layer"),
};
B8 ctrl_exception_code_kind_default_enable_table[38] =
{
0,
1,
1,
0,
0,
0,
0,
1,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
1,
0,
1,
};
C_LINKAGE_END
+7 -169
View File
@@ -46,176 +46,14 @@ CTRL_ExceptionCodeKind_Win32ProcedureNotFound,
CTRL_ExceptionCodeKind_Win32SanitizerErrorDetected,
CTRL_ExceptionCodeKind_Win32SanitizerRawAccessViolation,
CTRL_ExceptionCodeKind_Win32DirectXDebugLayer,
CTRL_ExceptionCodeKind_COUNT
CTRL_ExceptionCodeKind_COUNT,
} CTRL_ExceptionCodeKind;
U32 ctrl_exception_code_kind_code_table[] =
{
0,
0x40010005,
0x40010008,
0x40080201,
0x40080202,
0x0000071a,
0x80000002,
0xc0000005,
0xc0000006,
0xc0000008,
0xc0000017,
0xc000001d,
0xc0000025,
0xc0000026,
0xc000008c,
0xc000008d,
0xc000008e,
0xc000008f,
0xc0000090,
0xc0000091,
0xc0000092,
0xc0000093,
0xc0000094,
0xc0000095,
0xc0000096,
0xc00000fd,
0xc0000135,
0xc0000138,
0xc0000139,
0xc0000142,
0xc00002b4,
0xc00002b5,
0xc0000420,
0xc06d007e,
0xc06d007f,
0xe073616e,
0xe0736171,
0x0000087a,
};
String8 ctrl_exception_code_kind_display_string_table[] =
{
{0},
str8_lit_comp("(Win32) Control-C"),
str8_lit_comp("(Win32) Control-Break"),
str8_lit_comp("(Win32) WinRT Originate Error"),
str8_lit_comp("(Win32) WinRT Transform Error"),
str8_lit_comp("(Win32) RPC Call Cancelled"),
str8_lit_comp("(Win32) Data Type Misalignment"),
str8_lit_comp("(Win32) Access Violation"),
str8_lit_comp("(Win32) In Page Error"),
str8_lit_comp("(Win32) Invalid Handle Specified"),
str8_lit_comp("(Win32) Not Enough Quota"),
str8_lit_comp("(Win32) Illegal Instruction"),
str8_lit_comp("(Win32) Cannot Continue From Exception"),
str8_lit_comp("(Win32) Invalid Exception Disposition Returned By Handler"),
str8_lit_comp("(Win32) Array Bounds Exceeded"),
str8_lit_comp("(Win32) Floating-Point Denormal Operand"),
str8_lit_comp("(Win32) Floating-Point Division By Zero"),
str8_lit_comp("(Win32) Floating-Point Inexact Result"),
str8_lit_comp("(Win32) Floating-Point Invalid Operation"),
str8_lit_comp("(Win32) Floating-Point Overflow"),
str8_lit_comp("(Win32) Floating-Point Stack Check"),
str8_lit_comp("(Win32) Floating-Point Underflow"),
str8_lit_comp("(Win32) Integer Division By Zero"),
str8_lit_comp("(Win32) Integer Overflow"),
str8_lit_comp("(Win32) Privileged Instruction"),
str8_lit_comp("(Win32) Stack Overflow"),
str8_lit_comp("(Win32) Unable To Locate DLL"),
str8_lit_comp("(Win32) Ordinal Not Found"),
str8_lit_comp("(Win32) Entry Point Not Found"),
str8_lit_comp("(Win32) DLL Initialization Failed"),
str8_lit_comp("(Win32) Floating Point SSE Multiple Faults"),
str8_lit_comp("(Win32) Floating Point SSE Multiple Traps"),
str8_lit_comp("(Win32) Assertion Failed"),
str8_lit_comp("(Win32) Module Not Found"),
str8_lit_comp("(Win32) Procedure Not Found"),
str8_lit_comp("(Win32) Sanitizer Error Detected"),
str8_lit_comp("(Win32) Sanitizer Raw Access Violation"),
str8_lit_comp("(Win32) DirectX Debug Layer"),
};
String8 ctrl_exception_code_kind_lowercase_code_string_table[] =
{
{0},
str8_lit_comp("win32_ctrl_c"),
str8_lit_comp("win32_ctrl_break"),
str8_lit_comp("win32_win_rt_originate_error"),
str8_lit_comp("win32_win_rt_transform_error"),
str8_lit_comp("win32_rpc_call_cancelled"),
str8_lit_comp("win32_datatype_misalignment"),
str8_lit_comp("win32_access_violation"),
str8_lit_comp("win32_in_page_error"),
str8_lit_comp("win32_invalid_handle"),
str8_lit_comp("win32_not_enough_quota"),
str8_lit_comp("win32_illegal_instruction"),
str8_lit_comp("win32_cannot_continue_exception"),
str8_lit_comp("win32_invalid_exception_disposition"),
str8_lit_comp("win32_array_bounds_exceeded"),
str8_lit_comp("win32_floating_point_denormal_operand"),
str8_lit_comp("win32_floating_point_division_by_zero"),
str8_lit_comp("win32_floating_point_inexact_result"),
str8_lit_comp("win32_floating_point_invalid_operation"),
str8_lit_comp("win32_floating_point_overflow"),
str8_lit_comp("win32_floating_point_stack_check"),
str8_lit_comp("win32_floating_point_underflow"),
str8_lit_comp("win32_integer_division_by_zero"),
str8_lit_comp("win32_integer_overflow"),
str8_lit_comp("win32_privileged_instruction"),
str8_lit_comp("win32_stack_overflow"),
str8_lit_comp("win32_unable_to_locate_dll"),
str8_lit_comp("win32_ordinal_not_found"),
str8_lit_comp("win32_entry_point_not_found"),
str8_lit_comp("win32_dll_initialization_failed"),
str8_lit_comp("win32_floating_point_sse_multiple_faults"),
str8_lit_comp("win32_floating_point_sse_multiple_traps"),
str8_lit_comp("win32_assertion_failed"),
str8_lit_comp("win32_module_not_found"),
str8_lit_comp("win32_procedure_not_found"),
str8_lit_comp("win32_sanitizer_error_detected"),
str8_lit_comp("win32_sanitizer_raw_access_violation"),
str8_lit_comp("win32_directx_debug_layer"),
};
B8 ctrl_exception_code_kind_default_enable_table[] =
{
0,
1,
1,
0,
0,
0,
0,
1,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
1,
0,
1,
};
C_LINKAGE_BEGIN
extern U32 ctrl_exception_code_kind_code_table[38];
extern String8 ctrl_exception_code_kind_display_string_table[38];
extern String8 ctrl_exception_code_kind_lowercase_code_string_table[38];
extern B8 ctrl_exception_code_kind_default_enable_table[38];
C_LINKAGE_END
#endif // CTRL_META_H
-540
View File
@@ -1,540 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Main Layer Initialization
internal void
dasm_init(void)
{
Arena *arena = arena_alloc();
dasm_shared = push_array(arena, DASM_Shared, 1);
dasm_shared->arena = arena;
dasm_shared->entity_map.slots_count = 1024;
dasm_shared->entity_map.slots = push_array(arena, DASM_EntitySlot, dasm_shared->entity_map.slots_count);
dasm_shared->entity_map_stripes.count = 64;
dasm_shared->entity_map_stripes.v = push_array(arena, DASM_Stripe, dasm_shared->entity_map_stripes.count);
for(U64 idx = 0; idx < dasm_shared->entity_map_stripes.count; idx += 1)
{
dasm_shared->entity_map_stripes.v[idx].arena = arena_alloc();
dasm_shared->entity_map_stripes.v[idx].rw_mutex = os_rw_mutex_alloc();
dasm_shared->entity_map_stripes.v[idx].cv = os_condition_variable_alloc();
}
dasm_shared->u2d_ring_mutex = os_mutex_alloc();
dasm_shared->u2d_ring_cv = os_condition_variable_alloc();
dasm_shared->u2d_ring_size = KB(64);
dasm_shared->u2d_ring_base = push_array_no_zero(arena, U8, dasm_shared->u2d_ring_size);
dasm_shared->decode_thread_count = Max(1, os_logical_core_count()-1);
dasm_shared->decode_threads = push_array(arena, OS_Handle, dasm_shared->decode_thread_count);
for(U64 idx = 0; idx < dasm_shared->decode_thread_count; idx += 1)
{
dasm_shared->decode_threads[idx] = os_launch_thread(dasm_decode_thread_entry_point, (void *)idx, 0);
}
}
////////////////////////////////
//~ rjf: Basic Helpers
internal U64
dasm_hash_from_string(String8 string)
{
U64 result = 5381;
for(U64 i = 0; i < string.size; i += 1)
{
result = ((result << 5) + result) + string.str[i];
}
return result;
}
////////////////////////////////
//~ rjf: Instruction Type Functions
internal void
dasm_inst_chunk_list_push(Arena *arena, DASM_InstChunkList *list, U64 cap, DASM_Inst *inst)
{
DASM_InstChunkNode *node = list->last;
if(node == 0 || node->count >= node->cap)
{
node = push_array(arena, DASM_InstChunkNode, 1);
node->v = push_array_no_zero(arena, DASM_Inst, cap);
node->cap = cap;
SLLQueuePush(list->first, list->last, node);
list->node_count += 1;
}
MemoryCopyStruct(&node->v[node->count], inst);
node->count += 1;
list->inst_count += 1;
}
internal DASM_InstArray
dasm_inst_array_from_chunk_list(Arena *arena, DASM_InstChunkList *list)
{
DASM_InstArray array = {0};
array.count = list->inst_count;
array.v = push_array_no_zero(arena, DASM_Inst, array.count);
U64 idx = 0;
for(DASM_InstChunkNode *n = list->first; n != 0; n = n->next)
{
MemoryCopy(array.v+idx, n->v, sizeof(DASM_Inst)*n->count);
idx += n->count;
}
return array;
}
internal U64
dasm_inst_array_idx_from_off__linear_scan(DASM_InstArray *array, U64 off)
{
U64 result = 0;
for(U64 idx = 0; idx < array->count; idx += 1)
{
if(array->v[idx].off == off)
{
result = idx;
break;
}
}
return result;
}
internal U64
dasm_inst_array_off_from_idx(DASM_InstArray *array, U64 idx)
{
U64 off = 0;
if(idx < array->count)
{
off = array->v[idx].off;
}
return off;
}
////////////////////////////////
//~ rjf: Disassembly Functions
#include "third_party/udis86/config.h"
#include "third_party/udis86/udis86.h"
#include "third_party/udis86/libudis86/decode.c"
#include "third_party/udis86/libudis86/itab.c"
#include "third_party/udis86/libudis86/syn-att.c"
#include "third_party/udis86/libudis86/syn-intel.c"
#include "third_party/udis86/libudis86/syn.c"
#include "third_party/udis86/libudis86/udis86.c"
internal DASM_InstChunkList
dasm_inst_chunk_list_from_arch_addr_data(Arena *arena, U64 *bytes_processed_counter, Architecture arch, U64 addr, String8 data)
{
DASM_InstChunkList inst_list = {0};
switch(arch)
{
default:{}break;
//- rjf: x86/x64 decoding
case Architecture_x64:
case Architecture_x86:
{
// rjf: grab context
struct ud udc;
ud_init(&udc);
ud_set_mode(&udc, bit_size_from_arch(arch));
ud_set_pc(&udc, addr);
ud_set_input_buffer(&udc, data.str, data.size);
ud_set_vendor(&udc, UD_VENDOR_ANY);
ud_set_syntax(&udc, UD_SYN_INTEL);
// rjf: disassemble
U64 byte_process_start_off = 0;
for(U64 off = 0; off < data.size;)
{
// rjf: disassemble one instruction
U64 size = ud_disassemble(&udc);
if(size == 0)
{
break;
}
// rjf: analyze
struct ud_operand *first_op = (struct ud_operand *)ud_insn_opr(&udc, 0);
U64 rel_voff = (first_op != 0 && first_op->type == UD_OP_JIMM) ? ud_syn_rel_target(&udc, first_op) : 0;
// rjf: push
String8 string = push_str8f(arena, "%s", udc.asm_buf);
DASM_Inst inst = {string, off, rel_voff};
dasm_inst_chunk_list_push(arena, &inst_list, 1024, &inst);
// rjf: increment
off += size;
if(bytes_processed_counter != 0 && (off-byte_process_start_off >= 1000))
{
ins_atomic_u64_add_eval(bytes_processed_counter, (off-byte_process_start_off));
byte_process_start_off = off;
}
}
}break;
}
return inst_list;
}
////////////////////////////////
//~ rjf: Cache Lookups
//- rjf: opening handles & correllation with module
internal DASM_Handle
dasm_handle_from_ctrl_process_range(CTRL_MachineID machine, CTRL_Handle process, Rng1U64 vaddr_range)
{
DASM_Handle result = {0};
if(machine != 0 && process.u64[0] != 0)
{
U64 hash = dasm_hash_from_string(str8_struct(&process));
U64 slot_idx = hash%dasm_shared->entity_map.slots_count;
U64 stripe_idx = slot_idx%dasm_shared->entity_map_stripes.count;
DASM_EntitySlot *slot = &dasm_shared->entity_map.slots[slot_idx];
DASM_Stripe *stripe = &dasm_shared->entity_map_stripes.v[stripe_idx];
OS_MutexScopeW(stripe->rw_mutex)
{
DASM_Entity *entity = 0;
for(DASM_Entity *e = slot->first; e != 0; e = e->next)
{
if(e->machine_id == machine &&
ctrl_handle_match(e->process, process) &&
MemoryMatchStruct(&e->vaddr_range, &vaddr_range))
{
entity = e;
break;
}
}
if(entity == 0)
{
entity = push_array(stripe->arena, DASM_Entity, 1);
SLLQueuePush(slot->first, slot->last, entity);
entity->machine_id = machine;
entity->process = process;
entity->vaddr_range= vaddr_range;
entity->id = ins_atomic_u64_inc_eval(&dasm_shared->entity_id_gen);
entity->decode_inst_arena = arena_alloc__sized(MB(256), KB(64));
entity->decode_string_arena = arena_alloc__sized(GB(1), KB(64));
}
result.u64[0] = hash;
result.u64[1] = entity->id;
}
}
return result;
}
//- rjf: asking for top-level info of a handle
internal DASM_BinaryInfo
dasm_binary_info_from_handle(Arena *arena, DASM_Handle handle)
{
DASM_BinaryInfo info = {0};
{
U64 hash = handle.u64[0];
U64 id = handle.u64[1];
U64 slot_idx = hash%dasm_shared->entity_map.slots_count;
U64 stripe_idx = slot_idx%dasm_shared->entity_map_stripes.count;
DASM_EntitySlot *slot = &dasm_shared->entity_map.slots[slot_idx];
DASM_Stripe *stripe = &dasm_shared->entity_map_stripes.v[stripe_idx];
OS_MutexScopeR(stripe->rw_mutex)
{
DASM_Entity *entity = 0;
for(DASM_Entity *e = slot->first; e != 0; e = e->next)
{
if(e->id == id)
{
entity = e;
break;
}
}
if(entity != 0)
{
info.machine_id = entity->machine_id;
info.process = entity->process;
info.vaddr_range = entity->vaddr_range;
info.bytes_processed = ins_atomic_u64_eval(&entity->bytes_processed);
info.bytes_to_process = ins_atomic_u64_eval(&entity->bytes_to_process);
}
}
}
return info;
}
//- rjf: asking for decoded instructions
internal DASM_InstArray
dasm_inst_array_from_handle(Arena *arena, DASM_Handle handle, U64 endt_us)
{
DASM_InstArray result = {0};
if(handle.u64[0] != 0 || handle.u64[1] != 0)
{
U64 hash = handle.u64[0];
U64 id = handle.u64[1];
U64 slot_idx = hash%dasm_shared->entity_map.slots_count;
U64 stripe_idx = slot_idx%dasm_shared->entity_map_stripes.count;
DASM_EntitySlot *slot = &dasm_shared->entity_map.slots[slot_idx];
DASM_Stripe *stripe = &dasm_shared->entity_map_stripes.v[stripe_idx];
B32 sent = 0;
OS_MutexScopeR(stripe->rw_mutex) for(;;)
{
DASM_Entity *entity = 0;
for(DASM_Entity *e = slot->first; e != 0; e = e->next)
{
if(e->id == id)
{
entity = e;
break;
}
}
U64 last_time_sent_us = 0;
if(entity != 0)
{
U64 bytes_processed = ins_atomic_u64_eval(&entity->bytes_processed);
U64 bytes_to_process = ins_atomic_u64_eval(&entity->bytes_to_process);
last_time_sent_us = ins_atomic_u64_eval(&entity->last_time_sent_us);
if(bytes_processed == bytes_to_process && bytes_processed != 0)
{
result.count = entity->decode_inst_array.count;
result.v = push_array_no_zero(arena, DASM_Inst, result.count);
MemoryCopy(result.v, entity->decode_inst_array.v, sizeof(DASM_Inst)*result.count);
for(U64 idx = 0; idx < result.count; idx += 1)
{
result.v[idx].string = push_str8_copy(arena, result.v[idx].string);
}
break;
}
}
if(!sent && entity != 0 && last_time_sent_us+10000 <= os_now_microseconds())
{
DASM_DecodeRequest req = {handle};
sent = dasm_u2d_enqueue_request(&req, endt_us);
ins_atomic_u64_eval_assign(&entity->last_time_sent_us, os_now_microseconds());
}
if(os_now_microseconds() >= endt_us)
{
break;
}
os_condition_variable_wait_rw_r(stripe->cv, stripe->rw_mutex, endt_us);
}
}
return result;
}
////////////////////////////////
//~ rjf: Decode Threads
internal B32
dasm_u2d_enqueue_request(DASM_DecodeRequest *req, U64 endt_us)
{
B32 result = 0;
OS_MutexScope(dasm_shared->u2d_ring_mutex) for(;;)
{
U64 unconsumed_size = (dasm_shared->u2d_ring_write_pos-dasm_shared->u2d_ring_read_pos);
U64 available_size = (dasm_shared->u2d_ring_size-unconsumed_size);
if(available_size >= sizeof(*req))
{
result = 1;
dasm_shared->u2d_ring_write_pos += ring_write_struct(dasm_shared->u2d_ring_base, dasm_shared->u2d_ring_size, dasm_shared->u2d_ring_write_pos, req);
dasm_shared->u2d_ring_write_pos += 7;
dasm_shared->u2d_ring_write_pos -= dasm_shared->u2d_ring_write_pos%8;
break;
}
if(os_now_microseconds() >= endt_us)
{
break;
}
os_condition_variable_wait(dasm_shared->u2d_ring_cv, dasm_shared->u2d_ring_mutex, endt_us);
}
if(result)
{
os_condition_variable_broadcast(dasm_shared->u2d_ring_cv);
}
return result;
}
internal DASM_DecodeRequest
dasm_u2d_dequeue_request(void)
{
DASM_DecodeRequest req = {0};
OS_MutexScope(dasm_shared->u2d_ring_mutex) for(;;)
{
U64 unconsumed_size = (dasm_shared->u2d_ring_write_pos-dasm_shared->u2d_ring_read_pos);
if(unconsumed_size >= sizeof(DASM_DecodeRequest))
{
dasm_shared->u2d_ring_read_pos += ring_read_struct(dasm_shared->u2d_ring_base, dasm_shared->u2d_ring_size, dasm_shared->u2d_ring_read_pos, &req);
dasm_shared->u2d_ring_read_pos += 7;
dasm_shared->u2d_ring_read_pos -= dasm_shared->u2d_ring_read_pos%8;
break;
}
os_condition_variable_wait(dasm_shared->u2d_ring_cv, dasm_shared->u2d_ring_mutex, max_U64);
}
os_condition_variable_broadcast(dasm_shared->u2d_ring_cv);
return req;
}
internal void
dasm_decode_thread_entry_point(void *p)
{
TCTX tctx_;
tctx_init_and_equip(&tctx_);
for(;;)
{
Temp scratch = scratch_begin(0, 0);
//- rjf: get next request & unpack
DASM_DecodeRequest req = dasm_u2d_dequeue_request();
DASM_Handle handle = req.handle;
U64 hash = handle.u64[0];
U64 id = handle.u64[1];
U64 slot_idx = hash%dasm_shared->entity_map.slots_count;
U64 stripe_idx = slot_idx%dasm_shared->entity_map_stripes.count;
DASM_EntitySlot *slot = &dasm_shared->entity_map.slots[slot_idx];
DASM_Stripe *stripe = &dasm_shared->entity_map_stripes.v[stripe_idx];
//- rjf: request -> ctrl info
B32 is_first_to_task = 0;
CTRL_MachineID ctrl_machine_id = 0;
CTRL_Handle ctrl_process = {0};
Rng1U64 vaddr_range = {0};
Architecture arch = Architecture_Null;
U64 *bytes_processed_counter = 0;
OS_MutexScopeR(stripe->rw_mutex)
{
DASM_Entity *entity = 0;
for(DASM_Entity *e = slot->first; e != 0; e = e->next)
{
if(e->id == id)
{
entity = e;
break;
}
}
if(entity != 0)
{
U64 initial_working_count = ins_atomic_u32_eval_cond_assign(&entity->working_count, 1, 0);
if(initial_working_count == 0)
{
is_first_to_task = 1;
ctrl_machine_id = entity->machine_id;
ctrl_process = entity->process;
vaddr_range = entity->vaddr_range;
arch = ctrl_arch_from_handle(ctrl_machine_id, ctrl_process);
bytes_processed_counter = &entity->bytes_processed;
U64 bytes_to_process = dim_1u64(vaddr_range);
ins_atomic_u64_eval_assign(&entity->bytes_processed, 0);
ins_atomic_u64_eval_assign(&entity->bytes_to_process, bytes_to_process);
}
}
}
//- rjf: bad handle or machine id -> bad task
B32 good_task = (is_first_to_task && ctrl_process.u64[0] != 0 && ctrl_machine_id != 0 && arch != Architecture_Null && bytes_processed_counter != 0);
//- rjf: good task -> clear entity's info
if(good_task)
{
OS_MutexScopeW(stripe->rw_mutex)
{
DASM_Entity *entity = 0;
for(DASM_Entity *e = slot->first; e != 0; e = e->next)
{
if(e->id == id)
{
entity = e;
break;
}
}
if(entity != 0)
{
arena_clear(entity->decode_inst_arena);
arena_clear(entity->decode_string_arena);
MemoryZeroStruct(&entity->decode_inst_array);
}
}
}
//- rjf: good task -> read process memory & decode instructions - stop each
// 4k and write into cache, so users can read incremental results
if(good_task)
{
U64 chunk_size = KB(4);
for(U64 off = 0; vaddr_range.min+off < vaddr_range.max; off += chunk_size)
{
Rng1U64 chunk_vaddr_range = r1u64(vaddr_range.min+off, vaddr_range.min+off+chunk_size);
chunk_vaddr_range.min = ClampTop(chunk_vaddr_range.min, vaddr_range.max);
chunk_vaddr_range.max = ClampTop(chunk_vaddr_range.max, vaddr_range.max);
//- rjf: read next chunk & decode
String8 data = {0};
DASM_InstChunkList inst_list = {0};
if(good_task)
{
data.str = push_array_no_zero(scratch.arena, U8, dim_1u64(chunk_vaddr_range));
data.size = ctrl_process_read(ctrl_machine_id, ctrl_process, chunk_vaddr_range, data.str);
if(data.size != 0)
{
inst_list = dasm_inst_chunk_list_from_arch_addr_data(scratch.arena, bytes_processed_counter, arch, chunk_vaddr_range.min, data);
}
}
//- rjf: write into cache
{
OS_MutexScopeW(stripe->rw_mutex)
{
DASM_Entity *entity = 0;
for(DASM_Entity *e = slot->first; e != 0; e = e->next)
{
if(e->id == id)
{
entity = e;
break;
}
}
if(entity != 0)
{
DASM_Inst *new_chunk_base = push_array(entity->decode_inst_arena, DASM_Inst, inst_list.inst_count);
U64 off = 0;
for(DASM_InstChunkNode *node = inst_list.first; node != 0; node = node->next)
{
MemoryCopy(new_chunk_base+off, node->v, sizeof(DASM_Inst)*node->count);
off += node->count;
}
for(U64 idx = 0; idx < inst_list.inst_count; idx += 1)
{
new_chunk_base[idx].string = push_str8_copy(entity->decode_string_arena, new_chunk_base[idx].string);
}
entity->decode_inst_array.count += inst_list.inst_count;
if(entity->decode_inst_array.v == 0)
{
entity->decode_inst_array.v = new_chunk_base;
}
}
}
os_condition_variable_broadcast(stripe->cv);
}
}
}
//- rjf: mark task as complete
if(good_task)
{
OS_MutexScopeR(stripe->rw_mutex)
{
DASM_Entity *entity = 0;
for(DASM_Entity *e = slot->first; e != 0; e = e->next)
{
if(e->id == id)
{
entity = e;
break;
}
}
if(entity != 0)
{
U64 bytes_to_process = ins_atomic_u64_eval(&entity->bytes_to_process);
ins_atomic_u64_eval_assign(&entity->bytes_processed, bytes_to_process);
ins_atomic_u64_eval_assign(&entity->working_count, 0);
}
}
}
scratch_end(scratch);
}
}
-206
View File
@@ -1,206 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DASM_H
#define DASM_H
////////////////////////////////
//~ rjf: Handle Type
typedef struct DASM_Handle DASM_Handle;
struct DASM_Handle
{
U64 u64[2];
};
////////////////////////////////
//~ rjf: Instruction Types
typedef struct DASM_Inst DASM_Inst;
struct DASM_Inst
{
String8 string;
U64 off;
U64 addr;
};
typedef struct DASM_InstChunkNode DASM_InstChunkNode;
struct DASM_InstChunkNode
{
DASM_InstChunkNode *next;
DASM_Inst *v;
U64 cap;
U64 count;
};
typedef struct DASM_InstChunkList DASM_InstChunkList;
struct DASM_InstChunkList
{
DASM_InstChunkNode *first;
DASM_InstChunkNode *last;
U64 node_count;
U64 inst_count;
};
typedef struct DASM_InstArray DASM_InstArray;
struct DASM_InstArray
{
DASM_Inst *v;
U64 count;
};
////////////////////////////////
//~ rjf: Striped Access Types
typedef struct DASM_Stripe DASM_Stripe;
struct DASM_Stripe
{
Arena *arena;
OS_Handle cv;
OS_Handle rw_mutex;
};
typedef struct DASM_StripeTable DASM_StripeTable;
struct DASM_StripeTable
{
U64 count;
DASM_Stripe *v;
};
////////////////////////////////
//~ rjf: Entity Cache Types
typedef struct DASM_Entity DASM_Entity;
struct DASM_Entity
{
DASM_Entity *next;
// rjf: key info
CTRL_MachineID machine_id;
CTRL_Handle process;
Rng1U64 vaddr_range;
U64 id;
// rjf: top-level info
U64 last_time_sent_us;
U64 working_count;
U64 bytes_processed;
U64 bytes_to_process;
// rjf: decoded instruction data
Arena *decode_inst_arena;
Arena *decode_string_arena;
DASM_InstArray decode_inst_array;
};
typedef struct DASM_EntitySlot DASM_EntitySlot;
struct DASM_EntitySlot
{
DASM_Entity *first;
DASM_Entity *last;
};
typedef struct DASM_EntityMap DASM_EntityMap;
struct DASM_EntityMap
{
U64 slots_count;
DASM_EntitySlot *slots;
};
////////////////////////////////
//~ rjf: Introspection Info Types
typedef struct DASM_BinaryInfo DASM_BinaryInfo;
struct DASM_BinaryInfo
{
CTRL_MachineID machine_id;
CTRL_Handle process;
Rng1U64 vaddr_range;
U64 bytes_processed;
U64 bytes_to_process;
};
////////////////////////////////
//~ rjf: Decode Request Types
typedef struct DASM_DecodeRequest DASM_DecodeRequest;
struct DASM_DecodeRequest
{
DASM_Handle handle;
};
////////////////////////////////
//~ rjf: Shared State
typedef struct DASM_Shared DASM_Shared;
struct DASM_Shared
{
Arena *arena;
// rjf: entity table
DASM_EntityMap entity_map;
DASM_StripeTable entity_map_stripes;
U64 entity_id_gen;
// rjf: user -> decode ring
OS_Handle u2d_ring_mutex;
OS_Handle u2d_ring_cv;
U64 u2d_ring_size;
U8 *u2d_ring_base;
U64 u2d_ring_write_pos;
U64 u2d_ring_read_pos;
// rjf: decode threads
U64 decode_thread_count;
OS_Handle *decode_threads;
};
////////////////////////////////
//~ rjf: Globals
global DASM_Shared *dasm_shared = 0;
////////////////////////////////
//~ rjf: Main Layer Initialization
internal void dasm_init(void);
////////////////////////////////
//~ rjf: Basic Helpers
internal U64 dasm_hash_from_string(String8 string);
////////////////////////////////
//~ rjf: Instruction Type Functions
internal void dasm_inst_chunk_list_push(Arena *arena, DASM_InstChunkList *list, U64 cap, DASM_Inst *inst);
internal DASM_InstArray dasm_inst_array_from_chunk_list(Arena *arena, DASM_InstChunkList *list);
internal U64 dasm_inst_array_idx_from_off__linear_scan(DASM_InstArray *array, U64 off);
internal U64 dasm_inst_array_off_from_idx(DASM_InstArray *array, U64 idx);
////////////////////////////////
//~ rjf: Disassembly Functions
internal DASM_InstChunkList dasm_inst_chunk_list_from_arch_addr_data(Arena *arena, U64 *bytes_processed_counter, Architecture arch, U64 addr, String8 data);
////////////////////////////////
//~ rjf: Cache Lookups
//- rjf: opening handles & correllation with module
internal DASM_Handle dasm_handle_from_ctrl_process_range(CTRL_MachineID machine, CTRL_Handle process, Rng1U64 vaddr_range);
//- rjf: asking for top-level info of a handle
internal DASM_BinaryInfo dasm_binary_info_from_handle(Arena *arena, DASM_Handle handle);
//- rjf: asking for decoded instructions
internal DASM_InstArray dasm_inst_array_from_handle(Arena *arena, DASM_Handle handle, U64 endt_us);
////////////////////////////////
//~ rjf: Decode Threads
internal B32 dasm_u2d_enqueue_request(DASM_DecodeRequest *req, U64 endt_us);
internal DASM_DecodeRequest dasm_u2d_dequeue_request(void);
internal void dasm_decode_thread_entry_point(void *p);
#endif //DASM_H
+599
View File
@@ -0,0 +1,599 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Third Party Includes
#include "third_party/udis86/config.h"
#include "third_party/udis86/udis86.h"
#include "third_party/udis86/libudis86/decode.c"
#include "third_party/udis86/libudis86/itab.c"
#include "third_party/udis86/libudis86/syn-att.c"
#include "third_party/udis86/libudis86/syn-intel.c"
#include "third_party/udis86/libudis86/syn.c"
#include "third_party/udis86/libudis86/udis86.c"
////////////////////////////////
//~ rjf: Instruction Type Functions
internal void
dasm_inst_chunk_list_push(Arena *arena, DASM_InstChunkList *list, U64 cap, DASM_Inst *inst)
{
DASM_InstChunkNode *node = list->last;
if(node == 0 || node->count >= node->cap)
{
node = push_array(arena, DASM_InstChunkNode, 1);
node->v = push_array_no_zero(arena, DASM_Inst, cap);
node->cap = cap;
SLLQueuePush(list->first, list->last, node);
list->node_count += 1;
}
MemoryCopyStruct(&node->v[node->count], inst);
node->count += 1;
list->inst_count += 1;
}
internal DASM_InstArray
dasm_inst_array_from_chunk_list(Arena *arena, DASM_InstChunkList *list)
{
DASM_InstArray array = {0};
array.count = list->inst_count;
array.v = push_array_no_zero(arena, DASM_Inst, array.count);
U64 idx = 0;
for(DASM_InstChunkNode *n = list->first; n != 0; n = n->next)
{
MemoryCopy(array.v+idx, n->v, sizeof(DASM_Inst)*n->count);
idx += n->count;
}
return array;
}
internal U64
dasm_inst_array_idx_from_code_off__linear_scan(DASM_InstArray *array, U64 off)
{
U64 result = 0;
for(U64 idx = 0; idx < array->count; idx += 1)
{
if(array->v[idx].code_off == off)
{
result = idx;
break;
}
}
return result;
}
internal U64
dasm_inst_array_code_off_from_idx(DASM_InstArray *array, U64 idx)
{
U64 off = 0;
if(idx < array->count)
{
off = array->v[idx].code_off;
}
return off;
}
////////////////////////////////
//~ rjf: Main Layer Initialization
internal void
dasm_init(void)
{
Arena *arena = arena_alloc();
dasm_shared = push_array(arena, DASM_Shared, 1);
dasm_shared->arena = arena;
dasm_shared->slots_count = 1024;
dasm_shared->stripes_count = Min(dasm_shared->slots_count, os_logical_core_count());
dasm_shared->slots = push_array(arena, DASM_Slot, dasm_shared->slots_count);
dasm_shared->stripes = push_array(arena, DASM_Stripe, dasm_shared->stripes_count);
for(U64 idx = 0; idx < dasm_shared->stripes_count; idx += 1)
{
dasm_shared->stripes[idx].arena = arena_alloc();
dasm_shared->stripes[idx].rw_mutex = os_rw_mutex_alloc();
dasm_shared->stripes[idx].cv = os_condition_variable_alloc();
}
dasm_shared->u2p_ring_size = KB(64);
dasm_shared->u2p_ring_base = push_array_no_zero(arena, U8, dasm_shared->u2p_ring_size);
dasm_shared->u2p_ring_cv = os_condition_variable_alloc();
dasm_shared->u2p_ring_mutex = os_mutex_alloc();
dasm_shared->parse_thread_count = 1;
dasm_shared->parse_threads = push_array(arena, OS_Handle, dasm_shared->parse_thread_count);
for(U64 idx = 0; idx < dasm_shared->parse_thread_count; idx += 1)
{
dasm_shared->parse_threads[idx] = os_launch_thread(dasm_parse_thread__entry_point, (void *)idx, 0);
}
dasm_shared->evictor_thread = os_launch_thread(dasm_evictor_thread__entry_point, 0, 0);
}
////////////////////////////////
//~ rjf: User Clock
internal void
dasm_user_clock_tick(void)
{
ins_atomic_u64_inc_eval(&dasm_shared->user_clock_idx);
}
internal U64
dasm_user_clock_idx(void)
{
U64 idx = ins_atomic_u64_eval(&dasm_shared->user_clock_idx);
return idx;
}
////////////////////////////////
//~ rjf: Scoped Access
internal DASM_Scope *
dasm_scope_open(void)
{
if(dasm_tctx == 0)
{
Arena *arena = arena_alloc();
dasm_tctx = push_array(arena, DASM_TCTX, 1);
dasm_tctx->arena = arena;
}
DASM_Scope *scope = dasm_tctx->free_scope;
if(scope != 0)
{
SLLStackPop(dasm_tctx->free_scope);
}
else
{
scope = push_array_no_zero(dasm_tctx->arena, DASM_Scope, 1);
}
MemoryZeroStruct(scope);
return scope;
}
internal void
dasm_scope_close(DASM_Scope *scope)
{
for(DASM_Touch *t = scope->top_touch, *next = 0; t != 0; t = next)
{
next = t->next;
U64 slot_idx = t->hash.u64[1]%dasm_shared->slots_count;
U64 stripe_idx = slot_idx%dasm_shared->stripes_count;
DASM_Slot *slot = &dasm_shared->slots[slot_idx];
DASM_Stripe *stripe = &dasm_shared->stripes[stripe_idx];
OS_MutexScopeR(stripe->rw_mutex)
{
for(DASM_Node *n = slot->first; n != 0; n = n->next)
{
if(u128_match(t->hash, n->hash) &&
t->addr == n->addr &&
t->arch == n->arch &&
t->style_flags == n->style_flags &&
t->syntax == n->syntax)
{
ins_atomic_u64_dec_eval(&n->scope_ref_count);
break;
}
}
}
SLLStackPush(dasm_tctx->free_touch, t);
}
SLLStackPush(dasm_tctx->free_scope, scope);
}
internal void
dasm_scope_touch_node__stripe_r_guarded(DASM_Scope *scope, DASM_Node *node)
{
DASM_Touch *touch = dasm_tctx->free_touch;
ins_atomic_u64_inc_eval(&node->scope_ref_count);
ins_atomic_u64_eval_assign(&node->last_time_touched_us, os_now_microseconds());
ins_atomic_u64_eval_assign(&node->last_user_clock_idx_touched, dasm_user_clock_idx());
if(touch != 0)
{
SLLStackPop(dasm_tctx->free_touch);
}
else
{
touch = push_array_no_zero(dasm_tctx->arena, DASM_Touch, 1);
}
MemoryZeroStruct(touch);
touch->hash = node->hash;
touch->addr = node->addr;
touch->arch = node->arch;
touch->style_flags = node->style_flags;
touch->syntax = node->syntax;
SLLStackPush(scope->top_touch, touch);
}
////////////////////////////////
//~ rjf: Cache Lookups
internal DASM_Info
dasm_info_from_hash_addr_arch_style(DASM_Scope *scope, U128 hash, U64 addr, Architecture arch, DASM_StyleFlags style_flags, DASM_Syntax syntax)
{
DASM_Info info = {0};
if(!u128_match(hash, u128_zero()))
{
U64 slot_idx = hash.u64[1]%dasm_shared->slots_count;
U64 stripe_idx = slot_idx%dasm_shared->stripes_count;
DASM_Slot *slot = &dasm_shared->slots[slot_idx];
DASM_Stripe *stripe = &dasm_shared->stripes[stripe_idx];
B32 found = 0;
OS_MutexScopeR(stripe->rw_mutex)
{
for(DASM_Node *n = slot->first; n != 0; n = n->next)
{
if(u128_match(hash, n->hash) &&
addr == n->addr &&
arch == n->arch &&
style_flags == n->style_flags &&
syntax == n->syntax)
{
MemoryCopyStruct(&info, &n->info);
found = 1;
dasm_scope_touch_node__stripe_r_guarded(scope, n);
break;
}
}
}
B32 node_is_new = 0;
if(!found)
{
OS_MutexScopeW(stripe->rw_mutex)
{
DASM_Node *node = 0;
for(DASM_Node *n = slot->first; n != 0; n = n->next)
{
if(u128_match(hash, n->hash) &&
addr == n->addr &&
arch == n->arch &&
style_flags == n->style_flags &&
syntax == n->syntax)
{
node = n;
break;
}
}
if(node == 0)
{
node = stripe->free_node;
if(node)
{
SLLStackPop(stripe->free_node);
}
else
{
node = push_array_no_zero(stripe->arena, DASM_Node, 1);
}
MemoryZeroStruct(node);
DLLPushBack(slot->first, slot->last, node);
node->hash = hash;
node->addr = addr;
node->arch = arch;
node->style_flags = style_flags;
node->syntax = syntax;
node_is_new = 1;
}
}
}
if(node_is_new)
{
dasm_u2p_enqueue_req(hash, addr, arch, style_flags, syntax, max_U64);
}
}
return info;
}
internal DASM_Info
dasm_info_from_key_addr_arch_style(DASM_Scope *scope, U128 key, U64 addr, Architecture arch, DASM_StyleFlags style_flags, DASM_Syntax syntax, U128 *hash_out)
{
DASM_Info result = {0};
for(U64 rewind_idx = 0; rewind_idx < 2; rewind_idx += 1)
{
U128 hash = hs_hash_from_key(key, rewind_idx);
result = dasm_info_from_hash_addr_arch_style(scope, hash, addr, arch, style_flags, syntax);
if(result.insts.count != 0)
{
if(hash_out)
{
*hash_out = hash;
}
break;
}
}
return result;
}
////////////////////////////////
//~ rjf: Parse Threads
internal B32
dasm_u2p_enqueue_req(U128 hash, U64 addr, Architecture arch, DASM_StyleFlags style_flags, DASM_Syntax syntax, U64 endt_us)
{
B32 good = 0;
OS_MutexScope(dasm_shared->u2p_ring_mutex) for(;;)
{
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(addr)+sizeof(arch))
{
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);
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, &addr);
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, &arch);
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, &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, &syntax);
break;
}
if(os_now_microseconds() >= endt_us)
{
break;
}
os_condition_variable_wait(dasm_shared->u2p_ring_cv, dasm_shared->u2p_ring_mutex, endt_us);
}
if(good)
{
os_condition_variable_broadcast(dasm_shared->u2p_ring_cv);
}
return good;
}
internal void
dasm_u2p_dequeue_req(U128 *hash_out, U64 *addr_out, Architecture *arch_out, DASM_StyleFlags *style_flags_out, DASM_Syntax *syntax_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(*addr_out)+sizeof(*arch_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, 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, addr_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, arch_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, style_flags_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, syntax_out);
break;
}
os_condition_variable_wait(dasm_shared->u2p_ring_cv, dasm_shared->u2p_ring_mutex, max_U64);
}
os_condition_variable_broadcast(dasm_shared->u2p_ring_mutex);
}
internal void
dasm_parse_thread__entry_point(void *p)
{
ThreadNameF("[dasm] parse thread #%I64u", (U64)p);
for(;;)
{
Temp scratch = scratch_begin(0, 0);
//- rjf: get next request
U128 hash = {0};
U64 addr = 0;
Architecture arch = Architecture_Null;
DASM_StyleFlags style_flags = 0;
DASM_Syntax syntax = DASM_Syntax_Intel;
dasm_u2p_dequeue_req(&hash, &addr, &arch, &style_flags, &syntax);
HS_Scope *hs_scope = hs_scope_open();
//- rjf: unpack hash
U64 slot_idx = hash.u64[1]%dasm_shared->slots_count;
U64 stripe_idx = slot_idx%dasm_shared->stripes_count;
DASM_Slot *slot = &dasm_shared->slots[slot_idx];
DASM_Stripe *stripe = &dasm_shared->stripes[stripe_idx];
//- rjf: take task
B32 got_task = 0;
OS_MutexScopeR(stripe->rw_mutex)
{
for(DASM_Node *n = slot->first; n != 0; n = n->next)
{
if(u128_match(n->hash, hash) &&
n->addr == addr &&
n->arch == arch &&
n->style_flags == style_flags &&
n->syntax == syntax)
{
got_task = !ins_atomic_u32_eval_cond_assign(&n->is_working, 1, 0);
break;
}
}
}
//- rjf: hash -> data
String8 data = {0};
if(got_task)
{
data = hs_data_from_hash(hs_scope, hash);
}
//- rjf: data * arch * addr -> decode artifacts
DASM_InstChunkList inst_list = {0};
String8List inst_strings = {0};
if(got_task)
{
switch(arch)
{
default:{}break;
//- rjf: x86/x64 decoding
case Architecture_x64:
case Architecture_x86:
{
// rjf: grab context
struct ud udc;
ud_init(&udc);
ud_set_mode(&udc, bit_size_from_arch(arch));
ud_set_pc(&udc, addr);
ud_set_input_buffer(&udc, data.str, data.size);
ud_set_vendor(&udc, UD_VENDOR_ANY);
ud_set_syntax(&udc, syntax == DASM_Syntax_Intel ? UD_SYN_INTEL : UD_SYN_ATT);
// rjf: disassemble
U64 byte_process_start_off = 0;
for(U64 off = 0; off < data.size;)
{
// rjf: disassemble one instruction
U64 size = ud_disassemble(&udc);
if(size == 0)
{
break;
}
// rjf: analyze
struct ud_operand *first_op = (struct ud_operand *)ud_insn_opr(&udc, 0);
U64 rel_voff = (first_op != 0 && first_op->type == UD_OP_JIMM) ? ud_syn_rel_target(&udc, first_op) : 0;
// rjf: push
String8 addr_part = {0};
if(style_flags & DASM_StyleFlag_Addresses)
{
addr_part = push_str8f(scratch.arena, "%016I64X ", addr+off);
}
String8 code_bytes_part = {0};
if(style_flags & DASM_StyleFlag_CodeBytes)
{
String8List code_bytes_strings = {0};
str8_list_push(scratch.arena, &code_bytes_strings, str8_lit("{"));
for(U64 byte_idx = 0; byte_idx < size || byte_idx < 16; byte_idx += 1)
{
if(byte_idx < size)
{
str8_list_pushf(scratch.arena, &code_bytes_strings, "%02x%s ", (U32)data.str[off+byte_idx], byte_idx == size-1 ? "}" : "");
}
else if(byte_idx < 8)
{
str8_list_push(scratch.arena, &code_bytes_strings, str8_lit(" "));
}
}
str8_list_push(scratch.arena, &code_bytes_strings, str8_lit(" "));
code_bytes_part = str8_list_join(scratch.arena, &code_bytes_strings, 0);
}
String8 inst_string = push_str8f(scratch.arena, "%S%S%s", addr_part, code_bytes_part, udc.asm_buf);
DASM_Inst inst = {off, rel_voff, r1u64(inst_strings.total_size + inst_strings.node_count,
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
dasm_inst_chunk_list_push(scratch.arena, &inst_list, 1024, &inst);
str8_list_push(scratch.arena, &inst_strings, inst_string);
// rjf: increment
off += size;
}
}break;
}
}
//- rjf: artifacts -> value bundle
Arena *info_arena = 0;
DASM_Info info = {0};
if(got_task)
{
//- rjf: produce joined text
Arena *text_arena = arena_alloc();
StringJoin text_join = {0};
text_join.sep = str8_lit("\n");
String8 text = str8_list_join(text_arena, &inst_strings, &text_join);
//- rjf: produce unique key for this disassembly's text
U128 text_key = {0};
{
U64 hash_data[] =
{
hash.u64[0],
hash.u64[1],
addr,
(U64)arch,
(U64)style_flags,
(U64)syntax,
0x4d534144,
};
text_key = hs_hash_from_data(str8((U8 *)hash_data, sizeof(hash_data)));
}
//- rjf: submit text data to hash store
U128 text_hash = hs_submit_data(text_key, &text_arena, text);
//- rjf: produce value bundle
info_arena = arena_alloc();
info.text_key = text_key;
info.insts = dasm_inst_array_from_chunk_list(info_arena, &inst_list);
}
//- rjf: commit results to cache
if(got_task) OS_MutexScopeW(stripe->rw_mutex)
{
for(DASM_Node *n = slot->first; n != 0; n = n->next)
{
if(u128_match(n->hash, hash) &&
addr == n->addr &&
arch == n->arch &&
style_flags == n->style_flags &&
syntax == n->syntax)
{
n->info_arena = info_arena;
MemoryCopyStruct(&n->info, &info);
ins_atomic_u32_eval_assign(&n->is_working, 0);
ins_atomic_u64_inc_eval(&n->load_count);
break;
}
}
}
hs_scope_close(hs_scope);
scratch_end(scratch);
}
}
////////////////////////////////
//~ rjf: Evictor Threads
internal void
dasm_evictor_thread__entry_point(void *p)
{
ThreadNameF("[dasm] evictor thread");
for(;;)
{
U64 check_time_us = os_now_microseconds();
U64 check_time_user_clocks = dasm_user_clock_idx();
U64 evict_threshold_us = 10*1000000;
U64 evict_threshold_user_clocks = 10;
for(U64 slot_idx = 0; slot_idx < dasm_shared->slots_count; slot_idx += 1)
{
U64 stripe_idx = slot_idx%dasm_shared->stripes_count;
DASM_Slot *slot = &dasm_shared->slots[slot_idx];
DASM_Stripe *stripe = &dasm_shared->stripes[stripe_idx];
B32 slot_has_work = 0;
OS_MutexScopeR(stripe->rw_mutex)
{
for(DASM_Node *n = slot->first; n != 0; n = n->next)
{
if(n->scope_ref_count == 0 &&
n->last_time_touched_us+evict_threshold_us <= check_time_us &&
n->last_user_clock_idx_touched+evict_threshold_user_clocks <= check_time_user_clocks &&
n->load_count != 0 &&
n->is_working == 0)
{
slot_has_work = 1;
break;
}
}
}
if(slot_has_work) OS_MutexScopeW(stripe->rw_mutex)
{
for(DASM_Node *n = slot->first, *next = 0; n != 0; n = next)
{
next = n->next;
if(n->scope_ref_count == 0 &&
n->last_time_touched_us+evict_threshold_us <= check_time_us &&
n->last_user_clock_idx_touched+evict_threshold_user_clocks <= check_time_user_clocks &&
n->load_count != 0 &&
n->is_working == 0)
{
DLLRemove(slot->first, slot->last, n);
if(n->info_arena != 0)
{
arena_release(n->info_arena);
}
SLLStackPush(stripe->free_node, n);
}
}
}
os_sleep_milliseconds(5);
}
os_sleep_milliseconds(1000);
}
}
+231
View File
@@ -0,0 +1,231 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DASM_CACHE_H
#define DASM_CACHE_H
////////////////////////////////
//~ rjf: Stringification Types
typedef U32 DASM_StyleFlags;
enum
{
DASM_StyleFlag_Addresses = (1<<0),
DASM_StyleFlag_CodeBytes = (1<<1),
};
typedef enum DASM_Syntax
{
DASM_Syntax_Intel,
DASM_Syntax_ATT,
DASM_Syntax_COUNT
}
DASM_Syntax;
////////////////////////////////
//~ rjf: Instruction Types
typedef struct DASM_Inst DASM_Inst;
struct DASM_Inst
{
U64 code_off;
U64 addr;
Rng1U64 text_range;
};
typedef struct DASM_InstChunkNode DASM_InstChunkNode;
struct DASM_InstChunkNode
{
DASM_InstChunkNode *next;
DASM_Inst *v;
U64 cap;
U64 count;
};
typedef struct DASM_InstChunkList DASM_InstChunkList;
struct DASM_InstChunkList
{
DASM_InstChunkNode *first;
DASM_InstChunkNode *last;
U64 node_count;
U64 inst_count;
};
typedef struct DASM_InstArray DASM_InstArray;
struct DASM_InstArray
{
DASM_Inst *v;
U64 count;
};
////////////////////////////////
//~ rjf: Value Bundle Type
typedef struct DASM_Info DASM_Info;
struct DASM_Info
{
U128 text_key;
DASM_InstArray insts;
};
////////////////////////////////
//~ rjf: Cache Types
typedef struct DASM_Node DASM_Node;
struct DASM_Node
{
// rjf: links
DASM_Node *next;
DASM_Node *prev;
// rjf: key
U128 hash;
U64 addr;
Architecture arch;
DASM_StyleFlags style_flags;
DASM_Syntax syntax;
// rjf: value
Arena *info_arena;
DASM_Info info;
// rjf: metadata
B32 is_working;
U64 scope_ref_count;
U64 last_time_touched_us;
U64 last_user_clock_idx_touched;
U64 load_count;
};
typedef struct DASM_Slot DASM_Slot;
struct DASM_Slot
{
DASM_Node *first;
DASM_Node *last;
};
typedef struct DASM_Stripe DASM_Stripe;
struct DASM_Stripe
{
Arena *arena;
OS_Handle rw_mutex;
OS_Handle cv;
DASM_Node *free_node;
};
////////////////////////////////
//~ rjf: Scoped Access Types
typedef struct DASM_Touch DASM_Touch;
struct DASM_Touch
{
DASM_Touch *next;
U128 hash;
U64 addr;
Architecture arch;
DASM_StyleFlags style_flags;
DASM_Syntax syntax;
};
typedef struct DASM_Scope DASM_Scope;
struct DASM_Scope
{
DASM_Scope *next;
DASM_Touch *top_touch;
};
////////////////////////////////
//~ rjf: Thread Context
typedef struct DASM_TCTX DASM_TCTX;
struct DASM_TCTX
{
Arena *arena;
DASM_Scope *free_scope;
DASM_Touch *free_touch;
};
////////////////////////////////
//~ rjf: Shared State
typedef struct DASM_Shared DASM_Shared;
struct DASM_Shared
{
Arena *arena;
// rjf: user clock
U64 user_clock_idx;
// rjf: cache
U64 slots_count;
U64 stripes_count;
DASM_Slot *slots;
DASM_Stripe *stripes;
// rjf: user -> parse thread
U64 u2p_ring_size;
U8 *u2p_ring_base;
U64 u2p_ring_write_pos;
U64 u2p_ring_read_pos;
OS_Handle u2p_ring_cv;
OS_Handle u2p_ring_mutex;
// rjf: parse threads
U64 parse_thread_count;
OS_Handle *parse_threads;
// rjf: evictor thread
OS_Handle evictor_thread;
};
////////////////////////////////
//~ rjf: Globals
thread_static DASM_TCTX *dasm_tctx = 0;
global DASM_Shared *dasm_shared = 0;
////////////////////////////////
//~ rjf: Instruction Type Functions
internal void dasm_inst_chunk_list_push(Arena *arena, DASM_InstChunkList *list, U64 cap, DASM_Inst *inst);
internal DASM_InstArray dasm_inst_array_from_chunk_list(Arena *arena, DASM_InstChunkList *list);
internal U64 dasm_inst_array_idx_from_code_off__linear_scan(DASM_InstArray *array, U64 off);
internal U64 dasm_inst_array_code_off_from_idx(DASM_InstArray *array, U64 idx);
////////////////////////////////
//~ rjf: Main Layer Initialization
internal void dasm_init(void);
////////////////////////////////
//~ rjf: User Clock
internal void dasm_user_clock_tick(void);
internal U64 dasm_user_clock_idx(void);
////////////////////////////////
//~ rjf: Scoped Access
internal DASM_Scope *dasm_scope_open(void);
internal void dasm_scope_close(DASM_Scope *scope);
internal void dasm_scope_touch_node__stripe_r_guarded(DASM_Scope *scope, DASM_Node *node);
////////////////////////////////
//~ rjf: Cache Lookups
internal DASM_Info dasm_info_from_hash_addr_arch_style(DASM_Scope *scope, U128 hash, U64 addr, Architecture arch, DASM_StyleFlags style_flags, DASM_Syntax syntax);
internal DASM_Info dasm_info_from_key_addr_arch_style(DASM_Scope *scope, U128 key, U64 addr, Architecture arch, DASM_StyleFlags style_flags, DASM_Syntax syntax, U128 *hash_out);
////////////////////////////////
//~ rjf: Parse Threads
internal B32 dasm_u2p_enqueue_req(U128 hash, U64 addr, Architecture arch, DASM_StyleFlags style_flags, DASM_Syntax syntax, U64 endt_us);
internal void dasm_u2p_dequeue_req(U128 *hash_out, U64 *addr_out, Architecture *arch_out, DASM_StyleFlags *style_flags_out, DASM_Syntax *syntax_out);
internal void dasm_parse_thread__entry_point(void *p);
////////////////////////////////
//~ rjf: Evictor Threads
internal void dasm_evictor_thread__entry_point(void *p);
#endif // DASM_CACHE_H
+111 -109
View File
@@ -11,7 +11,7 @@ dbgi_init(void)
dbgi_shared = push_array(arena, DBGI_Shared, 1);
dbgi_shared->arena = arena;
dbgi_shared->force_slots_count = 1024;
dbgi_shared->force_stripes_count = 64;
dbgi_shared->force_stripes_count = Min(dbgi_shared->force_slots_count, os_logical_core_count());
dbgi_shared->force_slots = push_array(arena, DBGI_ForceSlot, dbgi_shared->force_slots_count);
dbgi_shared->force_stripes = push_array(arena, DBGI_ForceStripe, dbgi_shared->force_stripes_count);
for(U64 idx = 0; idx < dbgi_shared->force_stripes_count; idx += 1)
@@ -21,7 +21,7 @@ dbgi_init(void)
dbgi_shared->force_stripes[idx].cv = os_condition_variable_alloc();
}
dbgi_shared->binary_slots_count = 1024;
dbgi_shared->binary_stripes_count = 64;
dbgi_shared->binary_stripes_count = Min(dbgi_shared->binary_slots_count, os_logical_core_count());
dbgi_shared->binary_slots = push_array(arena, DBGI_BinarySlot, dbgi_shared->binary_slots_count);
dbgi_shared->binary_stripes = push_array(arena, DBGI_BinaryStripe, dbgi_shared->binary_stripes_count);
for(U64 idx = 0; idx < dbgi_shared->binary_stripes_count; idx += 1)
@@ -31,7 +31,7 @@ dbgi_init(void)
dbgi_shared->binary_stripes[idx].cv = os_condition_variable_alloc();
}
dbgi_shared->fuzzy_search_slots_count = 64;
dbgi_shared->fuzzy_search_stripes_count = 8;
dbgi_shared->fuzzy_search_stripes_count = Min(dbgi_shared->fuzzy_search_slots_count, os_logical_core_count());
dbgi_shared->fuzzy_search_slots = push_array(arena, DBGI_FuzzySearchSlot, dbgi_shared->fuzzy_search_slots_count);
dbgi_shared->fuzzy_search_stripes = push_array(arena, DBGI_FuzzySearchStripe, dbgi_shared->fuzzy_search_stripes_count);
for(U64 idx = 0; idx < dbgi_shared->fuzzy_search_stripes_count; idx += 1)
@@ -85,12 +85,12 @@ dbgi_ensure_tctx_inited(void)
//~ rjf: Helpers
internal U64
dbgi_hash_from_string(String8 string)
dbgi_hash_from_string(String8 string, StringMatchFlags match_flags)
{
U64 result = 5381;
for(U64 i = 0; i < string.size; i += 1)
{
result = ((result << 5) + result) + string.str[i];
result = ((result << 5) + result) + ((match_flags & StringMatchFlag_CaseInsensitive) ? char_to_lower(string.str[i]) : string.str[i]);
}
return result;
}
@@ -111,7 +111,7 @@ dbgi_fuzzy_item_num_from_array_element_idx__linear_search(DBGI_FuzzySearchItemAr
}
internal String8
dbgi_fuzzy_item_string_from_rdbg_target_element_idx(RADDBG_Parsed *rdbg, DBGI_FuzzySearchTarget target, U64 element_idx)
dbgi_fuzzy_item_string_from_rdi_target_element_idx(RDI_Parsed *rdi, DBGI_FuzzySearchTarget target, U64 element_idx)
{
String8 result = {0};
switch(target)
@@ -119,31 +119,31 @@ dbgi_fuzzy_item_string_from_rdbg_target_element_idx(RADDBG_Parsed *rdbg, DBGI_Fu
// NOTE(rjf): no default - warn if we miss a case
case DBGI_FuzzySearchTarget_Procedures:
{
RADDBG_Procedure *proc = raddbg_element_from_idx(rdbg, procedures, element_idx);
RDI_Procedure *proc = rdi_element_from_idx(rdi, procedures, element_idx);
U64 name_size = 0;
U8 *name_base = raddbg_string_from_idx(rdbg, proc->name_string_idx, &name_size);
U8 *name_base = rdi_string_from_idx(rdi, proc->name_string_idx, &name_size);
result = str8(name_base, name_size);
}break;
case DBGI_FuzzySearchTarget_GlobalVariables:
{
RADDBG_GlobalVariable *gvar = raddbg_element_from_idx(rdbg, global_variables, element_idx);
RDI_GlobalVariable *gvar = rdi_element_from_idx(rdi, global_variables, element_idx);
U64 name_size = 0;
U8 *name_base = raddbg_string_from_idx(rdbg, gvar->name_string_idx, &name_size);
U8 *name_base = rdi_string_from_idx(rdi, gvar->name_string_idx, &name_size);
result = str8(name_base, name_size);
}break;
case DBGI_FuzzySearchTarget_ThreadVariables:
{
RADDBG_ThreadVariable *tvar = raddbg_element_from_idx(rdbg, thread_variables, element_idx);
RDI_ThreadVariable *tvar = rdi_element_from_idx(rdi, thread_variables, element_idx);
U64 name_size = 0;
U8 *name_base = raddbg_string_from_idx(rdbg, tvar->name_string_idx, &name_size);
U8 *name_base = rdi_string_from_idx(rdi, tvar->name_string_idx, &name_size);
result = str8(name_base, name_size);
}break;
case DBGI_FuzzySearchTarget_UDTs:
{
RADDBG_UDT *udt = raddbg_element_from_idx(rdbg, udts, element_idx);
RADDBG_TypeNode *type_node = raddbg_element_from_idx(rdbg, type_nodes, udt->self_type_idx);
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 = raddbg_string_from_idx(rdbg, type_node->user_defined.name_string_idx, &name_size);
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 DBGI_FuzzySearchTarget_COUNT:{}break;
@@ -157,7 +157,8 @@ dbgi_fuzzy_item_string_from_rdbg_target_element_idx(RADDBG_Parsed *rdbg, DBGI_Fu
internal void
dbgi_force_exe_path_dbg_path(String8 exe_path, String8 dbg_path)
{
U64 hash = dbgi_hash_from_string(exe_path);
StringMatchFlags match_flags = path_match_flags_from_os(operating_system_from_context());
U64 hash = dbgi_hash_from_string(exe_path, match_flags);
U64 slot_idx = hash%dbgi_shared->force_slots_count;
U64 stripe_idx = slot_idx%dbgi_shared->force_stripes_count;
DBGI_ForceSlot *slot = &dbgi_shared->force_slots[slot_idx];
@@ -167,7 +168,7 @@ dbgi_force_exe_path_dbg_path(String8 exe_path, String8 dbg_path)
DBGI_ForceNode *node = 0;
for(DBGI_ForceNode *n = slot->first; n != 0; n = n->next)
{
if(str8_match(n->exe_path, exe_path, 0))
if(str8_match(n->exe_path, exe_path, match_flags))
{
node = n;
break;
@@ -192,7 +193,8 @@ internal String8
dbgi_forced_dbg_path_from_exe_path(Arena *arena, String8 exe_path)
{
String8 result = {0};
U64 hash = dbgi_hash_from_string(exe_path);
StringMatchFlags match_flags = path_match_flags_from_os(operating_system_from_context());
U64 hash = dbgi_hash_from_string(exe_path, match_flags);
U64 slot_idx = hash%dbgi_shared->force_slots_count;
U64 stripe_idx = slot_idx%dbgi_shared->force_stripes_count;
DBGI_ForceSlot *slot = &dbgi_shared->force_slots[slot_idx];
@@ -202,7 +204,7 @@ dbgi_forced_dbg_path_from_exe_path(Arena *arena, String8 exe_path)
DBGI_ForceNode *node = 0;
for(DBGI_ForceNode *n = slot->first; n != 0; n = n->next)
{
if(str8_match(exe_path, n->exe_path, 0))
if(str8_match(exe_path, n->exe_path, match_flags))
{
node = n;
break;
@@ -297,7 +299,8 @@ dbgi_binary_open(String8 exe_path)
{
Temp scratch = scratch_begin(0, 0);
exe_path = path_normalized_from_string(scratch.arena, exe_path);
U64 hash = dbgi_hash_from_string(exe_path);
StringMatchFlags match_flags = path_match_flags_from_os(operating_system_from_context());
U64 hash = dbgi_hash_from_string(exe_path, match_flags);
U64 slot_idx = hash%dbgi_shared->binary_slots_count;
U64 stripe_idx = slot_idx%dbgi_shared->binary_stripes_count;
DBGI_BinarySlot *slot = &dbgi_shared->binary_slots[slot_idx];
@@ -308,7 +311,7 @@ dbgi_binary_open(String8 exe_path)
DBGI_Binary *binary = 0;
for(DBGI_Binary *bin = slot->first; bin != 0; bin = bin->next)
{
if(str8_match(bin->exe_path, exe_path, 0))
if(str8_match(bin->exe_path, exe_path, match_flags))
{
binary = bin;
break;
@@ -336,7 +339,8 @@ dbgi_binary_close(String8 exe_path)
{
Temp scratch = scratch_begin(0, 0);
exe_path = path_normalized_from_string(scratch.arena, exe_path);
U64 hash = dbgi_hash_from_string(exe_path);
StringMatchFlags match_flags = path_match_flags_from_os(operating_system_from_context());
U64 hash = dbgi_hash_from_string(exe_path, match_flags);
U64 slot_idx = hash%dbgi_shared->binary_slots_count;
U64 stripe_idx = slot_idx%dbgi_shared->binary_stripes_count;
DBGI_BinarySlot *slot = &dbgi_shared->binary_slots[slot_idx];
@@ -346,7 +350,7 @@ dbgi_binary_close(String8 exe_path)
DBGI_Binary *binary = 0;
for(DBGI_Binary *bin = slot->first; bin != 0; bin = bin->next)
{
if(str8_match(bin->exe_path, exe_path, 0))
if(str8_match(bin->exe_path, exe_path, match_flags))
{
binary = bin;
break;
@@ -361,8 +365,7 @@ dbgi_binary_close(String8 exe_path)
if(need_deletion) for(;;)
{
os_rw_mutex_drop_w(stripe->rw_mutex);
for(U64 start_t = os_now_microseconds();
os_now_microseconds() <= start_t + 250;);
for(U64 start_t = os_now_microseconds(); os_now_microseconds() <= start_t + 250;);
os_rw_mutex_take_w(stripe->rw_mutex);
if(binary->refcount == 0 && ins_atomic_u64_eval(&binary->scope_touch_count) == 0)
{
@@ -393,7 +396,8 @@ dbgi_parse_from_exe_path(DBGI_Scope *scope, String8 exe_path, U64 endt_us)
DBGI_Parse *parse = &dbgi_parse_nil;
if(exe_path.size != 0)
{
U64 hash = dbgi_hash_from_string(exe_path);
StringMatchFlags match_flags = path_match_flags_from_os(operating_system_from_context());
U64 hash = dbgi_hash_from_string(exe_path, match_flags);
U64 slot_idx = hash%dbgi_shared->binary_slots_count;
U64 stripe_idx = slot_idx%dbgi_shared->binary_stripes_count;
DBGI_BinarySlot *slot = &dbgi_shared->binary_slots[slot_idx];
@@ -404,7 +408,7 @@ dbgi_parse_from_exe_path(DBGI_Scope *scope, String8 exe_path, U64 endt_us)
DBGI_Binary *binary = 0;
for(DBGI_Binary *bin = slot->first; bin != 0; bin = bin->next)
{
if(str8_match(bin->exe_path, exe_path, 0))
if(str8_match(bin->exe_path, exe_path, match_flags))
{
binary = bin;
break;
@@ -446,6 +450,7 @@ dbgi_fuzzy_search_items_from_key_exe_query(DBGI_Scope *scope, U128 key, String8
Temp scratch = scratch_begin(0, 0);
DBGI_FuzzySearchItemArray items = {0};
exe_path = path_normalized_from_string(scratch.arena, exe_path);
StringMatchFlags match_flags = path_match_flags_from_os(operating_system_from_context());
{
//- rjf: unpack key
U64 slot_idx = key.u64[1]%dbgi_shared->fuzzy_search_slots_count;
@@ -481,7 +486,7 @@ dbgi_fuzzy_search_items_from_key_exe_query(DBGI_Scope *scope, U128 key, String8
// rjf: try to grab last valid results for this key/query; determine if stale
B32 stale = 1;
if(str8_match(exe_path, node->buckets[node->gen%ArrayCount(node->buckets)].exe_path, 0) &&
if(str8_match(exe_path, node->buckets[node->gen%ArrayCount(node->buckets)].exe_path, match_flags) &&
target == node->buckets[node->gen%ArrayCount(node->buckets)].target &&
node->gen != 0)
{
@@ -632,17 +637,16 @@ dbgi_p2u_pop_events(Arena *arena, U64 endt_us)
internal void
dbgi_parse_thread_entry_point(void *p)
{
TCTX tctx_;
tctx_init_and_equip(&tctx_);
ProfThreadName("[dbgi] parse #%I64U", (U64)p);
ThreadNameF("[dbgi] parse #%I64U", (U64)p);
for(;;)
{
Temp scratch = scratch_begin(0, 0);
//- rjf: grab next path & unpack
String8 exe_path = dbgi_u2p_dequeue_exe_path(scratch.arena);
StringMatchFlags match_flags = path_match_flags_from_os(operating_system_from_context());
ProfBegin("begin task for \"%.*s\"", str8_varg(exe_path));
U64 hash = dbgi_hash_from_string(exe_path);
U64 hash = dbgi_hash_from_string(exe_path, path_match_flags_from_os(operating_system_from_context()));
U64 slot_idx = hash%dbgi_shared->binary_slots_count;
U64 stripe_idx = slot_idx%dbgi_shared->binary_stripes_count;
DBGI_BinarySlot *slot = &dbgi_shared->binary_slots[slot_idx];
@@ -656,7 +660,7 @@ dbgi_parse_thread_entry_point(void *p)
DBGI_Binary *binary = 0;
for(DBGI_Binary *bin = slot->first; bin != 0; bin = bin->next)
{
if(str8_match(bin->exe_path, exe_path, 0))
if(str8_match(bin->exe_path, exe_path, match_flags))
{
binary = bin;
break;
@@ -686,7 +690,7 @@ dbgi_parse_thread_entry_point(void *p)
void *exe_file_base = 0;
if(do_task)
{
exe_file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, exe_path);
exe_file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite, exe_path);
exe_file_props = os_properties_from_file(exe_file);
exe_file_map = os_file_map_open(OS_AccessFlag_Read, exe_file);
exe_file_base = os_file_map_view_open(exe_file_map, OS_AccessFlag_Read, r1u64(0, exe_file_props.size));
@@ -769,7 +773,7 @@ dbgi_parse_thread_entry_point(void *p)
}
if(!og_dbg_format_is_known)
{
if(data.size >= 8 && *(U64 *)data.str == RADDBG_MAGIC_CONSTANT)
if(data.size >= 8 && *(U64 *)data.str == RDI_MAGIC_CONSTANT)
{
og_dbg_format_is_known = 1;
og_dbg_is_raddbg = 1;
@@ -801,54 +805,54 @@ dbgi_parse_thread_entry_point(void *p)
}
//- rjf: given O.G. path & analysis, determine RADDBG file path
String8 raddbg_path = {0};
String8 raddbgi_path = {0};
if(do_task)
{
if(og_dbg_is_raddbg)
{
raddbg_path = og_dbg_path;
raddbgi_path = og_dbg_path;
}
else if(og_dbg_format_is_known && og_dbg_is_pdb)
{
raddbg_path = push_str8f(scratch.arena, "%S.raddbg", str8_chop_last_dot(og_dbg_path));
raddbgi_path = push_str8f(scratch.arena, "%S.raddbgi", str8_chop_last_dot(og_dbg_path));
}
}
//- rjf: check if raddbg file is up-to-date
B32 raddbg_file_is_up_to_date = 0;
B32 raddbgi_file_is_up_to_date = 0;
if(do_task)
{
if(raddbg_path.size != 0)
if(raddbgi_path.size != 0)
{
FileProperties props = os_properties_from_file_path(raddbg_path);
raddbg_file_is_up_to_date = (props.modified > og_dbg_props.modified);
FileProperties props = os_properties_from_file_path(raddbgi_path);
raddbgi_file_is_up_to_date = (props.modified > og_dbg_props.modified);
}
}
//- rjf: if raddbg file is up to date based on timestamp, check the
// encoding generation number, to see if we need to regenerate it
// encoding generation number & size, to see if we need to regenerate it
// regardless
if(do_task && raddbg_file_is_up_to_date)
if(do_task && raddbgi_file_is_up_to_date)
{
OS_Handle file = {0};
OS_Handle file_map = {0};
FileProperties file_props = {0};
void *file_base = 0;
file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, raddbg_path);
file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, raddbgi_path);
file_map = os_file_map_open(OS_AccessFlag_Read, file);
file_props = os_properties_from_file(file);
file_base = os_file_map_view_open(file_map, OS_AccessFlag_Read, r1u64(0, file_props.size));
if(sizeof(RADDBG_Header) <= file_props.size)
if(sizeof(RDI_Header) <= file_props.size)
{
RADDBG_Header *header = (RADDBG_Header*)file_base;
if(header->encoding_version != RADDBG_ENCODING_VERSION)
RDI_Header *header = (RDI_Header*)file_base;
if(header->encoding_version != RDI_ENCODING_VERSION)
{
raddbg_file_is_up_to_date = 0;
raddbgi_file_is_up_to_date = 0;
}
}
else
{
raddbg_file_is_up_to_date = 0;
raddbgi_file_is_up_to_date = 0;
}
os_file_map_view_close(file_map, file_base);
os_file_map_close(file_map);
@@ -858,14 +862,14 @@ dbgi_parse_thread_entry_point(void *p)
//- rjf: raddbg file not up-to-date? we need to generate it
if(do_task)
{
if(!raddbg_file_is_up_to_date) ProfScope("generate raddbg file")
if(!raddbgi_file_is_up_to_date) ProfScope("generate raddbg file")
{
if(og_dbg_is_pdb)
{
// rjf: push conversion task begin event
{
DBGI_Event event = {DBGI_EventKind_ConversionStarted};
event.string = raddbg_path;
event.string = raddbgi_path;
dbgi_p2u_push_event(&event);
}
@@ -882,7 +886,7 @@ dbgi_parse_thread_entry_point(void *p)
//str8_list_pushf(scratch.arena, &opts.cmd_line, "--capture");
str8_list_pushf(scratch.arena, &opts.cmd_line, "--exe:%S", exe_path);
str8_list_pushf(scratch.arena, &opts.cmd_line, "--pdb:%S", og_dbg_path);
str8_list_pushf(scratch.arena, &opts.cmd_line, "--out:%S", raddbg_path);
str8_list_pushf(scratch.arena, &opts.cmd_line, "--out:%S", raddbgi_path);
os_launch_process(&opts, &process);
}
@@ -894,7 +898,7 @@ dbgi_parse_thread_entry_point(void *p)
B32 wait_done = os_process_wait(process, os_now_microseconds()+1000);
if(wait_done)
{
raddbg_file_is_up_to_date = 1;
raddbgi_file_is_up_to_date = 1;
break;
}
if(os_now_microseconds()-start_wait_t > 10000000 && og_dbg_props.size < MB(64))
@@ -907,7 +911,7 @@ dbgi_parse_thread_entry_point(void *p)
// rjf: push conversion task end event
{
DBGI_Event event = {DBGI_EventKind_ConversionEnded};
event.string = raddbg_path;
event.string = raddbgi_path;
dbgi_p2u_push_event(&event);
}
}
@@ -917,7 +921,7 @@ dbgi_parse_thread_entry_point(void *p)
// rjf: push conversion task failure event
{
DBGI_Event event = {DBGI_EventKind_ConversionFailureUnsupportedFormat};
event.string = raddbg_path;
event.string = raddbgi_path;
dbgi_p2u_push_event(&event);
}
}
@@ -925,16 +929,16 @@ dbgi_parse_thread_entry_point(void *p)
}
//- rjf: open raddbg file & gather info
OS_Handle raddbg_file = {0};
OS_Handle raddbg_file_map = {0};
FileProperties raddbg_file_props = {0};
void *raddbg_file_base = 0;
if(do_task && raddbg_file_is_up_to_date)
OS_Handle raddbgi_file = {0};
OS_Handle raddbgi_file_map = {0};
FileProperties raddbgi_file_props = {0};
void *raddbgi_file_base = 0;
if(do_task && raddbgi_file_is_up_to_date)
{
raddbg_file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, raddbg_path);
raddbg_file_map = os_file_map_open(OS_AccessFlag_Read, raddbg_file);
raddbg_file_props = os_properties_from_file(raddbg_file);
raddbg_file_base = os_file_map_view_open(raddbg_file_map, OS_AccessFlag_Read, r1u64(0, raddbg_file_props.size));
raddbgi_file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite, raddbgi_path);
raddbgi_file_map = os_file_map_open(OS_AccessFlag_Read, raddbgi_file);
raddbgi_file_props = os_properties_from_file(raddbgi_file);
raddbgi_file_base = os_file_map_view_open(raddbgi_file_map, OS_AccessFlag_Read, r1u64(0, raddbgi_file_props.size));
}
//- rjf: cache write, step 0: busy-loop-wait for all scope touches to be done
@@ -944,7 +948,7 @@ dbgi_parse_thread_entry_point(void *p)
{
OS_MutexScopeR(stripe->rw_mutex) for(DBGI_Binary *bin = slot->first; bin != 0; bin = bin->next)
{
if(str8_match(bin->exe_path, exe_path, 0) &&
if(str8_match(bin->exe_path, exe_path, match_flags) &&
bin->scope_touch_count == 0)
{
done = 1;
@@ -958,22 +962,22 @@ dbgi_parse_thread_entry_point(void *p)
// either EXE or raddbg file is new. if so, clear all old results &
// store new top-level info
B32 binary_refcount_is_zero = 0;
B32 raddbg_or_exe_file_is_updated = 0;
B32 raddbgi_or_exe_file_is_updated = 0;
if(do_task) ProfScope("cache write, step 1: check if raddbg is new & clear")
{
OS_MutexScopeW(stripe->rw_mutex) for(DBGI_Binary *bin = slot->first; bin != 0; bin = bin->next)
{
if(str8_match(bin->exe_path, exe_path, 0))
if(str8_match(bin->exe_path, exe_path, match_flags))
{
if(bin->refcount == 0)
{
binary_refcount_is_zero = 1;
break;
}
if(bin->parse.dbg_props.modified != raddbg_file_props.modified ||
if(bin->parse.dbg_props.modified != raddbgi_file_props.modified ||
bin->parse.exe_props.modified != exe_file_props.modified)
{
raddbg_or_exe_file_is_updated = 1;
raddbgi_or_exe_file_is_updated = 1;
// rjf: clean up old stuff
if(bin->parse.arena != 0) { arena_release(bin->parse.arena); }
@@ -991,10 +995,10 @@ dbgi_parse_thread_entry_point(void *p)
bin->exe_file_map = exe_file_map;
bin->parse.exe_base = exe_file_base;
bin->parse.exe_props = exe_file_props;
bin->dbg_file = raddbg_file;
bin->dbg_file_map = raddbg_file_map;
bin->parse.dbg_base = raddbg_file_base;
bin->parse.dbg_props = raddbg_file_props;
bin->dbg_file = raddbgi_file;
bin->dbg_file_map = raddbgi_file_map;
bin->parse.dbg_base = raddbgi_file_base;
bin->parse.dbg_props = raddbgi_file_props;
bin->gen += 1;
}
break;
@@ -1004,11 +1008,11 @@ dbgi_parse_thread_entry_point(void *p)
//- rjf: raddbg file or exe is not new? cache can stay unmodified, close
// handles & skip to end.
if(do_task) if((!raddbg_or_exe_file_is_updated && raddbg_file_is_up_to_date) || binary_refcount_is_zero)
if(do_task) if((!raddbgi_or_exe_file_is_updated && raddbgi_file_is_up_to_date) || binary_refcount_is_zero)
{
os_file_map_view_close(raddbg_file_map, raddbg_file_base);
os_file_map_close(raddbg_file_map);
os_file_close(raddbg_file);
os_file_map_view_close(raddbgi_file_map, raddbgi_file_base);
os_file_map_close(raddbgi_file_map);
os_file_close(raddbgi_file);
os_file_map_view_close(exe_file_map, exe_file_base);
os_file_map_close(exe_file_map);
os_file_close(exe_file);
@@ -1017,14 +1021,14 @@ dbgi_parse_thread_entry_point(void *p)
}
//- rjf: parse raddbg info
RADDBG_Parsed raddbg_parsed = dbgi_parse_nil.rdbg;
RDI_Parsed rdi_parsed = dbgi_parse_nil.rdi;
U64 arch_addr_size = 8;
if(do_task)
{
RADDBG_ParseStatus parse_status = raddbg_parse((U8 *)raddbg_file_base, raddbg_file_props.size, &raddbg_parsed);
if(raddbg_parsed.top_level_info != 0)
RDI_ParseStatus parse_status = rdi_parse((U8 *)raddbgi_file_base, raddbgi_file_props.size, &rdi_parsed);
if(rdi_parsed.top_level_info != 0)
{
arch_addr_size = raddbg_addr_size_from_arch(raddbg_parsed.top_level_info->architecture);
arch_addr_size = rdi_addr_size_from_arch(rdi_parsed.top_level_info->architecture);
}
}
@@ -1034,7 +1038,7 @@ dbgi_parse_thread_entry_point(void *p)
{
OS_MutexScopeW(stripe->rw_mutex) for(DBGI_Binary *bin = slot->first; bin != 0; bin = bin->next)
{
if(str8_match(bin->exe_path, exe_path, 0))
if(str8_match(bin->exe_path, exe_path, match_flags))
{
String8 dbg_path = og_dbg_path;
if(dbg_path.size == 0)
@@ -1053,7 +1057,7 @@ dbgi_parse_thread_entry_point(void *p)
bin->parse.arena = parse_arena;
bin->parse.dbg_path = push_str8_copy(parse_arena, dbg_path);
MemoryCopyStruct(&bin->parse.pe, &exe_pe_info);
MemoryCopyStruct(&bin->parse.rdbg, &raddbg_parsed);
MemoryCopyStruct(&bin->parse.rdi, &rdi_parsed);
bin->parse.gen = bin->gen;
break;
}
@@ -1071,7 +1075,7 @@ dbgi_parse_thread_entry_point(void *p)
{
OS_MutexScopeW(stripe->rw_mutex) for(DBGI_Binary *bin = slot->first; bin != 0; bin = bin->next)
{
if(str8_match(bin->exe_path, exe_path, 0))
if(str8_match(bin->exe_path, exe_path, match_flags))
{
bin->flags &= ~DBGI_BinaryFlag_ParseInFlight;
break;
@@ -1154,9 +1158,7 @@ dbgi_qsort_compare_fuzzy_search_items(DBGI_FuzzySearchItem *a, DBGI_FuzzySearchI
internal void
dbgi_fuzzy_thread__entry_point(void *p)
{
TCTX tctx_;
tctx_init_and_equip(&tctx_);
ProfThreadName("[dbgi] fuzzy search #%I64U", (U64)p);
ThreadNameF("[dbgi] fuzzy search #%I64U", (U64)p);
DBGI_FuzzySearchThread *thread = &dbgi_shared->fuzzy_threads[(U64)p];
for(;;)
{
@@ -1197,9 +1199,9 @@ dbgi_fuzzy_thread__entry_point(void *p)
//- rjf: exe_path -> dbgi_parse, raddbg
DBGI_Parse *dbgi = dbgi_parse_from_exe_path(scope, exe_path, max_U64);
RADDBG_Parsed *rdbg = &dbgi->rdbg;
RDI_Parsed *rdi = &dbgi->rdi;
//- rjf: rdbg * query -> item list
//- rjf: rdi * query -> item list
U64 table_ptr_off = 0;
U64 element_name_idx_off = 0;
U64 element_count = 0;
@@ -1210,49 +1212,49 @@ dbgi_fuzzy_thread__entry_point(void *p)
case DBGI_FuzzySearchTarget_COUNT:{}break;
case DBGI_FuzzySearchTarget_Procedures:
{
table_ptr_off = OffsetOf(RADDBG_Parsed, procedures);
element_name_idx_off = OffsetOf(RADDBG_Procedure, name_string_idx);
element_count = rdbg->procedures_count;
element_size = sizeof(RADDBG_Procedure);
table_ptr_off = OffsetOf(RDI_Parsed, procedures);
element_name_idx_off = OffsetOf(RDI_Procedure, name_string_idx);
element_count = rdi->procedures_count;
element_size = sizeof(RDI_Procedure);
}break;
case DBGI_FuzzySearchTarget_GlobalVariables:
{
table_ptr_off = OffsetOf(RADDBG_Parsed, global_variables);
element_name_idx_off = OffsetOf(RADDBG_GlobalVariable, name_string_idx);
element_count = rdbg->global_variables_count;
element_size = sizeof(RADDBG_GlobalVariable);
table_ptr_off = OffsetOf(RDI_Parsed, global_variables);
element_name_idx_off = OffsetOf(RDI_GlobalVariable, name_string_idx);
element_count = rdi->global_variables_count;
element_size = sizeof(RDI_GlobalVariable);
}break;
case DBGI_FuzzySearchTarget_ThreadVariables:
{
table_ptr_off = OffsetOf(RADDBG_Parsed, thread_variables);
element_name_idx_off = OffsetOf(RADDBG_ThreadVariable, name_string_idx);
element_count = rdbg->thread_variables_count;
element_size = sizeof(RADDBG_ThreadVariable);
table_ptr_off = OffsetOf(RDI_Parsed, thread_variables);
element_name_idx_off = OffsetOf(RDI_ThreadVariable, name_string_idx);
element_count = rdi->thread_variables_count;
element_size = sizeof(RDI_ThreadVariable);
}break;
case DBGI_FuzzySearchTarget_UDTs:
{
table_ptr_off = OffsetOf(RADDBG_Parsed, udts);
element_count = rdbg->udts_count;
element_size = sizeof(RADDBG_UDT);
table_ptr_off = OffsetOf(RDI_Parsed, udts);
element_count = rdi->udts_count;
element_size = sizeof(RDI_UDT);
}break;
}
DBGI_FuzzySearchItemChunkList items_list = {0};
if(task_is_good)
{
void *table_base = (U8*)rdbg + table_ptr_off;
void *table_base = (U8*)rdi + table_ptr_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(target == DBGI_FuzzySearchTarget_UDTs)
{
RADDBG_UDT *udt = (RADDBG_UDT *)element;
RADDBG_TypeNode *type_node = raddbg_element_from_idx(rdbg, type_nodes, udt->self_type_idx);
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 = raddbg_string_from_idx(rdbg, name_idx, &name_size);
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);
+21 -21
View File
@@ -18,7 +18,7 @@ struct DBGI_Parse
void *dbg_base;
FileProperties dbg_props;
PE_BinInfo pe;
RADDBG_Parsed rdbg;
RDI_Parsed rdi;
};
////////////////////////////////
@@ -341,24 +341,24 @@ global DBGI_Parse dbgi_parse_nil =
0,
0,
0,
&raddbg_binary_section_nil, 1,
&raddbg_file_path_node_nil, 1,
&raddbg_source_file_nil, 1,
&raddbg_unit_nil, 1,
&raddbg_vmap_entry_nil, 1,
&raddbg_type_node_nil, 1,
&raddbg_udt_nil, 1,
&raddbg_member_nil, 1,
&raddbg_enum_member_nil, 1,
&raddbg_global_variable_nil, 1,
&raddbg_vmap_entry_nil, 1,
&raddbg_thread_variable_nil, 1,
&raddbg_procedure_nil, 1,
&raddbg_scope_nil, 1,
&raddbg_voff_nil, 1,
&raddbg_vmap_entry_nil, 1,
&raddbg_local_nil, 1,
&raddbg_location_block_nil, 1,
&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,
},
@@ -377,9 +377,9 @@ internal void dbgi_ensure_tctx_inited(void);
////////////////////////////////
//~ rjf: Helpers
internal U64 dbgi_hash_from_string(String8 string);
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_rdbg_target_element_idx(RADDBG_Parsed *rdbg, DBGI_FuzzySearchTarget target, 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
-231
View File
@@ -1,231 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//- allen: Acceleration Layer Functions
//- accel helpers
internal DEMON_AccelModule*
demon_accel_module_alloc(void){
DEMON_AccelModule *result = demon_free_module_accel;
if (result != 0){
SLLStackPop(demon_free_module_accel);
}
else{
result = push_array_no_zero(demon_ent_arena, DEMON_AccelModule, 1);
}
MemoryZeroStruct(result);
return(result);
}
internal void
demon_accel_module_free(DEMON_AccelModule *module){
SLLStackPush(demon_free_module_accel, module);
}
internal DEMON_AccelThread*
demon_accel_thread_alloc(void){
DEMON_AccelThread *result = demon_free_thread_accel;
if (result != 0){
SLLStackPop(demon_free_thread_accel);
}
else{
result = push_array_no_zero(demon_ent_arena, DEMON_AccelThread, 1);
}
MemoryZeroStruct(result);
return(result);
}
internal void
demon_accel_thread_free(DEMON_AccelThread *thread){
SLLStackPush(demon_free_thread_accel, thread);
}
internal DEMON_AccelThread*
demon_accel_from_thread(DEMON_Entity *thread){
DEMON_AccelThread *accel = (DEMON_AccelThread*)thread->accel;
if (accel == 0){
accel = demon_accel_thread_alloc();
thread->accel = accel;
}
return(accel);
}
//- operations on demon objects
internal String8
demon_accel_full_path_from_module(Arena *arena, DEMON_Entity *module){
DEMON_AccelModule *accel = (DEMON_AccelModule*)module->accel;
String8 result = {0};
// first time
if (accel == 0){
result = demon_os_full_path_from_module(arena, module);
// build chain
DEMON_AccelModule *last_accel = 0;
U8 *ptr = result.str;
U8 *opl = result.str + result.size;
for (;ptr < opl;){
U64 size = (U64)(ptr - opl);
U64 clamped_size = ClampTop(result.size, sizeof(Member(DEMON_AccelModule, buf)));
DEMON_AccelModule *node = demon_accel_module_alloc();
SLLQueuePush(accel, last_accel, node);
node->total_size = result.size;
MemoryCopy(node->buf, ptr, clamped_size);
ptr += clamped_size;
}
// store in module
module->accel = accel;
}
// read from accel
else{
U64 size = accel->total_size;
U8 *str = push_array_no_zero(arena, U8, size + 1);
// copy chain contents to buffer
U8 *ptr = str;
for (DEMON_AccelModule *node = accel;
node != 0;
node = node->next){
U64 total_size = node->total_size;
U64 clamped_size = ClampTop(total_size, sizeof(node->buf));
MemoryCopy(ptr, node->buf, clamped_size);
ptr += clamped_size;
}
*ptr = 0;
// fill result
result.str = str;
result.size = size;
}
return(result);
}
internal U64
demon_accel_stack_base_vaddr_from_thread(DEMON_Entity *thread){
// get accel data
DEMON_AccelThread *accel = demon_accel_from_thread(thread);
// fill stack base
if (!accel->has_stack_base){
accel->has_stack_base = 1;
accel->stack_base = demon_os_stack_base_vaddr_from_thread(thread);
}
return(accel->stack_base);
}
internal U64
demon_accel_tls_root_vaddr_from_thread(DEMON_Entity *thread){
// get accel data
DEMON_AccelThread *accel = demon_accel_from_thread(thread);
// fill tls root
if (!accel->has_tls_root){
accel->has_tls_root = 1;
accel->tls_root = demon_os_tls_root_vaddr_from_thread(thread);
}
return(accel->tls_root);
}
internal void*
demon_accel_read_regs(DEMON_Entity *thread){
// get accel data
DEMON_AccelThread *accel = demon_accel_from_thread(thread);
// update reg cache
if (accel->reg_cache_time != demon_time){
accel->reg_cache_time = demon_time;
B32 success = demon_os_read_regs(thread, &accel->regs);
if (!success){
MemoryZeroStruct(&accel->regs);
}
}
return(&accel->regs);
}
internal void
demon_accel_write_regs(DEMON_Entity *thread, void *data){
// get accel data
DEMON_AccelThread *accel = demon_accel_from_thread(thread);
// low level write
B32 success = 0;
U64 data_size = 0;
switch (thread->arch){
case Architecture_x86:
{
data_size = sizeof(REGS_RegBlockX86);
success = demon_os_write_regs_x86(thread, (REGS_RegBlockX86*)data);
}break;
case Architecture_x64:
{
data_size = sizeof(REGS_RegBlockX64);
success = demon_os_write_regs_x64(thread, (REGS_RegBlockX64*)data);
}break;
}
// update cache
if (success){
accel->reg_cache_time = demon_time;
MemoryCopy(&accel->regs, data, data_size);
}
}
internal void
demon_accel_low_level_write_regs(DEMON_Entity *thread){
// NOTE(allen): This is a tricky one. It's just a way to enable some internal
// optimizations. Instead of forcing the user to pass in register data
// to write out and copy to the cache, the "user" is other demon code that
// knows what it's doing. So it grabs the cache memory (through a call to
// `demon_accel_read_regs`) modifies it in place and then calls this.
// So we just have to write the cache contents directly out to OS.
// get accel data
DEMON_AccelThread *accel = demon_accel_from_thread(thread);
switch (thread->arch){
case Architecture_x86:
{
demon_os_write_regs_x86(thread, &accel->regs.x86);
}break;
case Architecture_x64:
{
demon_os_write_regs_x64(thread, &accel->regs.x64);
}break;
}
}
//- entity accel free
internal void
demon_accel_free(DEMON_Entity *entity){
switch (entity->kind){
case DEMON_EntityKind_Module:
{
if (entity->accel != 0){
for (DEMON_AccelModule *node = (DEMON_AccelModule*)entity->accel, *next = 0;
node != 0;
node = next){
next = node->next;
demon_accel_module_free(node);
}
}
}break;
case DEMON_EntityKind_Thread:
{
if (entity->accel != 0){
demon_accel_thread_free((DEMON_AccelThread*)entity->accel);
}
}break;
}
}
-66
View File
@@ -1,66 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DEMON_ACCEL_H
#define DEMON_ACCEL_H
////////////////////////////////
//~ allen: Acceleration Data
typedef struct DEMON_AccelModule DEMON_AccelModule;
struct DEMON_AccelModule
{
DEMON_AccelModule *next;
U64 total_size;
U8 buf[240];
};
typedef union DEMON_AccelThread DEMON_AccelThread;
union DEMON_AccelThread
{
DEMON_AccelThread *next;
struct{
B32 has_stack_base;
B32 has_tls_root;
U64 stack_base;
U64 tls_root;
U64 reg_cache_time;
union{
REGS_RegBlockX64 x64;
REGS_RegBlockX86 x86;
} regs;
};
};
////////////////////////////////
//~ allen: Acceleration Globals
global DEMON_AccelModule *demon_free_module_accel = 0;
global DEMON_AccelThread *demon_free_thread_accel = 0;
////////////////////////////////
//~ allen: Acceleration Layer Functions
//- accel helpers
internal DEMON_AccelModule *demon_accel_module_alloc(void);
internal void demon_accel_module_free(DEMON_AccelModule *module);
internal DEMON_AccelThread *demon_accel_thread_alloc(void);
internal void demon_accel_thread_free(DEMON_AccelThread *thread);
internal DEMON_AccelThread *demon_accel_from_thread(DEMON_Entity *thread);
//- operations on demon objects
internal String8 demon_accel_full_path_from_module(Arena *arena, DEMON_Entity *module);
internal U64 demon_accel_stack_base_vaddr_from_thread(DEMON_Entity *thread);
internal U64 demon_accel_tls_root_vaddr_from_thread(DEMON_Entity *thread);
internal void* demon_accel_read_regs(DEMON_Entity *thread);
internal void demon_accel_write_regs(DEMON_Entity *thread, void *data);
internal void demon_accel_low_level_write_regs(DEMON_Entity *thread);
//- entity accel free
internal void demon_accel_free(DEMON_Entity *entity);
#endif //DEMON_ACCEL_H
-270
View File
@@ -1,270 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
// NOTE(allen): State Safety Helper
internal B32
demon_access_begin(void){
B32 result = 0;
if (demon_primary_thread){
Assert(demon_run_state);
result = 1;
}
else{
os_mutex_take(demon_state_mutex);
if (demon_run_state){
os_mutex_drop(demon_state_mutex);
}
else{
result = 1;
}
}
return(result);
}
internal void
demon_access_end(void){
if (!demon_primary_thread){
os_mutex_drop(demon_state_mutex);
}
}
////////////////////////////////
// NOTE(allen): Entity System
internal void
demon_common_init(void){
// access control mechanism
demon_state_mutex = os_mutex_alloc();
// time
demon_time = 1;
// setup arena
demon_ent_arena = arena_alloc();
// setup map
demon_ent_map = push_array(demon_ent_arena, DEMON_Map, 1);
demon_ent_map->bucket_count = 4093;
demon_ent_map->buckets = push_array(demon_ent_arena, DEMON_MapSlot*, demon_ent_map->bucket_count);
// setup entity memory
U64 reserve_size_unaligned = (DEMON_ENTITY_CAP)*sizeof(DEMON_Entity);
U64 reserve_size = AlignPow2(reserve_size_unaligned, DEMON_ENTITY_CMT_SIZE);
demon_ent_cmt = demon_ent_pos = demon_ent_base = (DEMON_Entity*)os_reserve(reserve_size);
demon_ent_opl = demon_ent_base + (reserve_size/sizeof(DEMON_Entity));
Assert(demon_ent_base != 0);
// setup root
demon_ent_root = demon_ent_alloc();
demon_ent_root->kind = DEMON_EntityKind_Root;
}
internal DEMON_Entity*
demon_ent_alloc(void){
DEMON_Entity *result = demon_ent_free;
if (result != 0){
SLLStackPop(demon_ent_free);
}
else{
if (demon_ent_pos < demon_ent_opl){
if (ensure_commit(&demon_ent_cmt, demon_ent_pos + 1, DEMON_ENTITY_CMT_SIZE)){
result = demon_ent_pos;
demon_ent_pos += 1;
}
}
}
if (result != 0){
U32 gen = result->gen;
MemoryZeroStruct(result);
result->gen = gen;
}
return(result);
}
//- handle <-> entity pointer
internal DEMON_Entity*
demon_ent_ptr_from_handle(DEMON_Handle handle){
Assert(demon_ent_base != 0);
DEMON_Entity *result = 0;
U32 index = (U32)(handle & 0xFFFFFFFF);
U64 count = (U64)(demon_ent_pos - demon_ent_base);
if (0 < index && index < count){
DEMON_Entity *entity = demon_ent_base + index;
U32 gen = (U32)(handle >> 32);
if (gen == entity->gen){
result = entity;
}
}
return(result);
}
internal DEMON_Handle
demon_ent_handle_from_ptr(DEMON_Entity *entity){
Assert(demon_ent_base != 0);
DEMON_Handle result = {0};
if (demon_ent_base < entity && entity < demon_ent_pos){
U32 index = (U32)(entity - demon_ent_base);
U64 gen = entity->gen;
result = (gen << 32) | index;
}
return(result);
}
//- high level entity alloc,init,release
internal DEMON_Entity*
demon_ent_new(DEMON_Entity *parent, DEMON_EntityKind kind, U64 id){
Assert(demon_ent_base != 0);
DEMON_Entity *result = demon_ent_alloc();
if (result != 0){
result->kind = kind;
result->id = id;
result->arch = parent->arch;
result->parent = parent;
DLLPushBack(parent->first, parent->last, result);
demon_ent_map_save(kind, id, result);
}
return(result);
}
internal void
demon_ent_release_single(DEMON_Entity *entity){
switch (entity->kind){
case DEMON_EntityKind_Process: demon_proc_count -= 1; break;
case DEMON_EntityKind_Thread: demon_thread_count -= 1; break;
case DEMON_EntityKind_Module: demon_module_count -= 1; break;
}
demon_accel_free(entity);
demon_os_entity_cleanup(entity);
DEMON_MapRef ref = demon_ent_map_find(entity->kind, entity->id);
demon_ent_map_erase(ref);
entity->gen += 1;
}
internal void
demon_ent_release_children(DEMON_Entity *root){
Assert(demon_ent_base != 0);
if (root->first != 0){
for (DEMON_Entity *node = root->first;
node != 0;
node = node->next){
demon_ent_release_children(node);
demon_ent_release_single(node);
}
root->last->next = demon_ent_free;
demon_ent_free = root->first;
root->first = 0;
root->last = 0;
}
}
internal void
demon_ent_release_root_and_children(DEMON_Entity *root){
Assert(demon_ent_base != 0);
Assert(root->parent != 0);
// release children
demon_ent_release_children(root);
// release root
DEMON_Entity *parent = root->parent;
demon_ent_release_single(root);
DLLRemove(parent->first, parent->last, root);
SLLStackPush(demon_ent_free, root);
}
//- entity map
internal U64
demon_ent_map_hash(U16 kind, U64 id){
U64 result = ((U64)kind << 32) ^ id;
return(result);
}
internal void
demon_ent_map_save(U16 kind, U64 id, DEMON_Entity *entity){
Assert(demon_ent_base != 0);
DEMON_Map *map = demon_ent_map;
// allocate a new slot
DEMON_MapSlot *slot = map->free_slots;
if (slot != 0){
SLLStackPop(map->free_slots);
}
else{
slot = push_array_no_zero(demon_ent_arena, DEMON_MapSlot, 1);
}
// fill slot
slot->kind = kind;
slot->id = id;
slot->entity = entity;
// insert into bucket
U64 hash = demon_ent_map_hash(kind, id);
U64 bucket_index = hash%map->bucket_count;
SLLStackPush(map->buckets[bucket_index], slot);
}
internal DEMON_MapRef
demon_ent_map_find(U16 kind, U64 id){
Assert(demon_ent_base != 0);
DEMON_Map *map = demon_ent_map;
// scan bucket
DEMON_MapRef result = {0};
U64 hash = demon_ent_map_hash(kind, id);
U64 bucket_index = hash%map->bucket_count;
for (DEMON_MapSlot **ptr = &map->buckets[bucket_index], *slot = 0;
*ptr != 0;
ptr = &slot->next){
slot = *ptr;
if (slot->kind == kind && slot->id == id){
result.slot = slot;
result.ptr_to_slot = ptr;
break;
}
}
return(result);
}
internal DEMON_Entity*
demon_ent_map_entity_from_id(U16 kind, U64 id){
DEMON_Entity *result = 0;
DEMON_MapRef ref = demon_ent_map_find(kind, id);
if (ref.slot != 0){
result = ref.slot->entity;
}
return(result);
}
internal void
demon_ent_map_erase(DEMON_MapRef ref){
Assert(demon_ent_base != 0);
DEMON_Map *map = demon_ent_map;
// move slot to free list
if (ref.slot != 0){
*ref.ptr_to_slot = ref.slot->next;
SLLStackPush(map->free_slots, ref.slot);
}
}
////////////////////////////////
// NOTE(allen): Event Helpers
internal DEMON_Event*
demon_push_event(Arena *arena, DEMON_EventList *list, DEMON_EventKind kind){
DEMON_EventNode *n = push_array(arena, DEMON_EventNode, 1);
DEMON_Event *result = &n->v;
SLLQueuePush(list->first, list->last, n);
list->count += 1;
result->kind = kind;
return(result);
}
-150
View File
@@ -1,150 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DEMON_COMMON_H
#define DEMON_COMMON_H
////////////////////////////////
//~ allen: DEMON Entity System
typedef enum DEMON_EntityKind
{
DEMON_EntityKind_NULL,
DEMON_EntityKind_Root,
DEMON_EntityKind_Process,
DEMON_EntityKind_Thread,
DEMON_EntityKind_Module,
DEMON_EntityKind_COUNT
}
DEMON_EntityKind;
typedef struct DEMON_Entity DEMON_Entity;
struct DEMON_Entity
{
// TODO(allen): these could be U32s
DEMON_Entity *next;
DEMON_Entity *prev;
DEMON_Entity *parent;
DEMON_Entity *first;
DEMON_Entity *last;
DEMON_EntityKind kind;
Architecture arch;
U32 gen;
U64 id;
U64 addr_range_dim;
// each OS backend decides how to use `ext` for each entity kind
union{
void *ext;
U64 ext_u64;
};
// the accel layer attaches some extra information to some entities
void *accel;
};
//- id -> entity map
typedef struct DEMON_MapSlot DEMON_MapSlot;
struct DEMON_MapSlot
{
DEMON_MapSlot *next;
U16 kind;
U64 id;
DEMON_Entity *entity;
};
typedef struct DEMON_Map DEMON_Map;
struct DEMON_Map
{
DEMON_MapSlot **buckets;
U64 bucket_count;
DEMON_MapSlot *free_slots;
};
typedef struct DEMON_MapRef DEMON_MapRef;
struct DEMON_MapRef
{
DEMON_MapSlot *slot;
DEMON_MapSlot **ptr_to_slot;
};
//- rjf: entity extrusive list
typedef struct DEMON_EntityNode DEMON_EntityNode;
struct DEMON_EntityNode
{
DEMON_EntityNode *next;
DEMON_Entity *entity;
};
////////////////////////////////
//~ allen: Demon Globals
thread_static B32 demon_primary_thread = 0;
global B32 demon_run_state = 0;
global OS_Handle demon_state_mutex = {0};
global U64 demon_time = 0;
global Arena *demon_ent_arena = 0;
global DEMON_Map *demon_ent_map = 0;
global DEMON_Entity *demon_ent_free = 0;
global DEMON_Entity *demon_ent_root = 0;
global DEMON_Entity *demon_ent_base = 0;
global DEMON_Entity *demon_ent_pos = 0;
global DEMON_Entity *demon_ent_opl = 0;
global void *demon_ent_cmt = 0;
global U64 demon_proc_count = 0;
global U64 demon_thread_count = 0;
global U64 demon_module_count = 0;
#if !defined(DEMON_ENTITY_CMT_SIZE)
# define DEMON_ENTITY_CMT_SIZE KB(64)
#endif
#if !defined(DEMON_ENTITY_CAP)
# define DEMON_ENTITY_CAP 65536
#endif
StaticAssert(IsPow2(DEMON_ENTITY_CMT_SIZE), check_demon_entity_cmt_size);
////////////////////////////////
//~ allen: State Safety Helper
internal B32 demon_access_begin(void);
internal void demon_access_end(void);
////////////////////////////////
//~ allen: Entity System
internal void demon_common_init(void);
internal DEMON_Entity* demon_ent_alloc(void);
//- handle <-> entity pointer
internal DEMON_Entity* demon_ent_ptr_from_handle(DEMON_Handle handle);
internal DEMON_Handle demon_ent_handle_from_ptr(DEMON_Entity *entity);
//- high level entity alloc,init,release
internal DEMON_Entity* demon_ent_new(DEMON_Entity *parent, DEMON_EntityKind kind, U64 id);
internal void demon_ent_release_single(DEMON_Entity *entity);
internal void demon_ent_release_children(DEMON_Entity *root);
internal void demon_ent_release_root_and_children(DEMON_Entity *root);
//- entity map
internal U64 demon_ent_map_hash(U16 kind, U64 id);
internal void demon_ent_map_save(U16 kind, U64 id, DEMON_Entity *entity);
internal DEMON_MapRef demon_ent_map_find(U16 kind, U64 id);
internal DEMON_Entity* demon_ent_map_entity_from_id(U16 kind, U64 id);
internal void demon_ent_map_erase(DEMON_MapRef map_ref);
////////////////////////////////
//~ allen: Event Helpers
internal DEMON_Event* demon_push_event(Arena *arena, DEMON_EventList *list, DEMON_EventKind kind);
#endif //DEMON_COMMON_H
+66 -784
View File
@@ -2,148 +2,34 @@
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Main Layer Initialization
//~ rjf: Basic Type Functions (Helpers, Implemented Once)
internal void
demon_init(void){
demon_common_init();
demon_os_init();
//- rjf: handles
internal DMN_Handle
dmn_handle_zero(void)
{
DMN_Handle h = {0};
return h;
}
////////////////////////////////
//~ rjf: Basic Type Functions
//- rjf: stringizing
internal String8
demon_string_from_event_kind(DEMON_EventKind kind){
String8 result = str8_lit("unknown");
switch (kind){
default: break;
case DEMON_EventKind_Error: result = str8_lit("Error"); break;
case DEMON_EventKind_HandshakeComplete: result = str8_lit("HandshakeComplete"); break;
case DEMON_EventKind_CreateProcess: result = str8_lit("CreateProcess"); break;
case DEMON_EventKind_ExitProcess: result = str8_lit("ExitProcess"); break;
case DEMON_EventKind_CreateThread: result = str8_lit("CreateThread"); break;
case DEMON_EventKind_ExitThread: result = str8_lit("ExitThread"); break;
case DEMON_EventKind_LoadModule: result = str8_lit("LoadModule"); break;
case DEMON_EventKind_UnloadModule: result = str8_lit("UnloadModule"); break;
case DEMON_EventKind_Breakpoint: result = str8_lit("Breakpoint"); break;
case DEMON_EventKind_Trap: result = str8_lit("Trap"); break;
case DEMON_EventKind_SingleStep: result = str8_lit("SingleStep"); break;
case DEMON_EventKind_Exception: result = str8_lit("Exception"); break;
case DEMON_EventKind_Halt: result = str8_lit("Halt"); break;
case DEMON_EventKind_Memory: result = str8_lit("Memory"); break;
case DEMON_EventKind_DebugString: result = str8_lit("DebugString"); break;
case DEMON_EventKind_SetThreadName: result = str8_lit("SetThreadName"); break;
}
return(result);
}
internal String8
demon_string_from_memory_event_kind(DEMON_MemoryEventKind kind){
String8 result = str8_lit("unknown");
switch (kind){
default: break;
case DEMON_MemoryEventKind_Commit: result = str8_lit("Commit"); break;
case DEMON_MemoryEventKind_Reserve: result = str8_lit("Reserve"); break;
case DEMON_MemoryEventKind_Decommit: result = str8_lit("Decommit"); break;
case DEMON_MemoryEventKind_Release: result = str8_lit("Release"); break;
}
return(result);
}
internal String8
demon_string_from_exception_kind(DEMON_ExceptionKind kind){
String8 result = str8_lit("unknown");
switch (kind){
default: break;
case DEMON_ExceptionKind_MemoryRead: result = str8_lit("MemoryRead"); break;
case DEMON_ExceptionKind_MemoryWrite: result = str8_lit("MemoryWrite"); break;
case DEMON_ExceptionKind_MemoryExecute: result = str8_lit("MemoryExecute"); break;
case DEMON_ExceptionKind_CppThrow: result = str8_lit("CppThrow"); break;
}
return(result);
}
internal void
demon_string_list_from_event(Arena *arena, String8List *out, DEMON_Event *event){
B32 need_exception_info = (event->kind == DEMON_EventKind_Exception ||
event->kind == DEMON_EventKind_Breakpoint ||
event->kind == DEMON_EventKind_Halt ||
event->kind == DEMON_EventKind_SingleStep);
// allen: kind
String8 kind_string = demon_string_from_event_kind(event->kind);
str8_list_pushf(arena, out, "%S: { (%i)", kind_string, event->kind);
// rjf: basics
{
str8_list_pushf(arena, out, " process: (%I64x)", event->process);
str8_list_pushf(arena, out, " thread: (%I64x)", event->thread);
str8_list_pushf(arena, out, " module: (%I64x)", event->module);
str8_list_pushf(arena, out, " address: (%I64x)", event->address, event->address);
str8_list_pushf(arena, out, " size: (0x%I64x, %I64u)", event->size, event->size);
}
// rjf: string
if (event->string.size != 0){
str8_list_pushf(arena, out, " string: \"%S\"", event->string);
}
// rjf: exception info
if (need_exception_info){
str8_list_pushf(arena, out, " code: (0x%x, %i)", event->code, event->code);
str8_list_pushf(arena, out, " flags: (0x%x, %i)", event->flags, event->flags);
str8_list_pushf(arena, out, " signo: (0x%x, %i)", event->signo, event->signo);
str8_list_pushf(arena, out, " sigcode: (0x%x, %i)", event->sigcode, event->sigcode);
}
// rjf: need error info
if (event->kind == DEMON_EventKind_Error){
str8_list_pushf(arena, out, " error_kind: (0x%x, %i)", event->error_kind, event->error_kind);
}
// rjf: memory event kind info
if (event->memory_kind != DEMON_MemoryEventKind_Null){
String8 memory_kind_string = demon_string_from_memory_event_kind(event->memory_kind);
str8_list_pushf(arena, out, " memory_kind: (%S, %i)",
memory_kind_string, event->memory_kind);
}
// rjf: exception kind
if (need_exception_info){
String8 exception_kind_string = demon_string_from_exception_kind(event->exception_kind);
str8_list_pushf(arena, out, " exception_kind: (%S, %i)",
exception_kind_string, event->exception_kind);
}
// rjf: instruction ptr
if (event->instruction_pointer != 0){
str8_list_pushf(arena, out, " instruction_pointer: (%I64x)", event->instruction_pointer);
}
// rjf: stack ptr
if (event->stack_pointer != 0){
str8_list_pushf(arena, out, " stack_pointer: (%I64x)", event->stack_pointer);
}
str8_list_pushf(arena, out, " user_data: (0x%I64x, %I64u)",
event->user_data, event->user_data);
str8_list_pushf(arena, out, "}");
internal B32
dmn_handle_match(DMN_Handle a, DMN_Handle b)
{
return a.u32[0] == b.u32[0] && a.u32[1] == b.u32[1];
}
//- rjf: trap chunk lists
internal void
demon_trap_chunk_list_push(Arena *arena, DEMON_TrapChunkList *list, U64 cap, DEMON_Trap *trap)
dmn_trap_chunk_list_push(Arena *arena, DMN_TrapChunkList *list, U64 cap, DMN_Trap *trap)
{
DEMON_TrapChunkNode *node = list->last;
DMN_TrapChunkNode *node = list->last;
if(node == 0 || node->count >= node->cap)
{
node = push_array(arena, DEMON_TrapChunkNode, 1);
node = push_array(arena, DMN_TrapChunkNode, 1);
node->cap = cap;
node->v = push_array_no_zero(arena, DEMON_Trap, node->cap);
node->v = push_array_no_zero(arena, DMN_Trap, node->cap);
SLLQueuePush(list->first, list->last, node);
list->node_count += 1;
}
@@ -153,7 +39,7 @@ demon_trap_chunk_list_push(Arena *arena, DEMON_TrapChunkList *list, U64 cap, DEM
}
internal void
demon_trap_chunk_list_concat_in_place(DEMON_TrapChunkList *dst, DEMON_TrapChunkList *to_push)
dmn_trap_chunk_list_concat_in_place(DMN_TrapChunkList *dst, DMN_TrapChunkList *to_push)
{
if(dst->last == 0)
{
@@ -170,11 +56,11 @@ demon_trap_chunk_list_concat_in_place(DEMON_TrapChunkList *dst, DEMON_TrapChunkL
}
internal void
demon_trap_chunk_list_concat_shallow_copy(Arena *arena, DEMON_TrapChunkList *dst, DEMON_TrapChunkList *to_push)
dmn_trap_chunk_list_concat_shallow_copy(Arena *arena, DMN_TrapChunkList *dst, DMN_TrapChunkList *to_push)
{
for(DEMON_TrapChunkNode *src_n = to_push->first; src_n != 0; src_n = src_n->next)
for(DMN_TrapChunkNode *src_n = to_push->first; src_n != 0; src_n = src_n->next)
{
DEMON_TrapChunkNode *dst_n = push_array(arena, DEMON_TrapChunkNode, 1);
DMN_TrapChunkNode *dst_n = push_array(arena, DMN_TrapChunkNode, 1);
dst_n->v = src_n->v;
dst_n->cap = src_n->cap;
dst_n->count = src_n->count;
@@ -187,685 +73,81 @@ demon_trap_chunk_list_concat_shallow_copy(Arena *arena, DEMON_TrapChunkList *dst
//- rjf: handle lists
internal void
demon_handle_list_push(Arena *arena, DEMON_HandleList *list, DEMON_Handle handle)
dmn_handle_list_push(Arena *arena, DMN_HandleList *list, DMN_Handle handle)
{
DEMON_HandleNode *node = push_array(arena, DEMON_HandleNode, 1);
DMN_HandleNode *node = push_array(arena, DMN_HandleNode, 1);
SLLQueuePush(list->first, list->last, node);
node->v = handle;
list->count += 1;
}
internal DEMON_HandleArray
demon_handle_array_from_list(Arena *arena, DEMON_HandleList *list)
internal DMN_HandleArray
dmn_handle_array_from_list(Arena *arena, DMN_HandleList *list)
{
DEMON_HandleArray array = {0};
DMN_HandleArray array = {0};
array.count = list->count;
array.handles = push_array_no_zero(arena, DEMON_Handle, array.count);
array.handles = push_array_no_zero(arena, DMN_Handle, array.count);
U64 idx = 0;
for(DEMON_HandleNode *n = list->first; n != 0; n = n->next, idx += 1)
for(DMN_HandleNode *n = list->first; n != 0; n = n->next, idx += 1)
{
array.handles[idx] = n->v;
}
return array;
}
internal DEMON_HandleArray
demon_handle_array_copy(Arena *arena, DEMON_HandleArray *src)
internal DMN_HandleArray
dmn_handle_array_copy(Arena *arena, DMN_HandleArray *src)
{
DEMON_HandleArray dst = {0};
DMN_HandleArray dst = {0};
dst.count = src->count;
dst.handles = push_array_no_zero(arena, DEMON_Handle, dst.count);
MemoryCopy(dst.handles, src->handles, sizeof(DEMON_Handle)*dst.count);
dst.handles = push_array_no_zero(arena, DMN_Handle, dst.count);
MemoryCopy(dst.handles, src->handles, sizeof(DMN_Handle)*dst.count);
return dst;
}
////////////////////////////////
//~ rjf: Primary Thread & Exclusive Mode Controls
//- rjf: event list building
internal void
demon_primary_thread_begin(void){
demon_primary_thread = 1;
}
internal void
demon_exclusive_mode_begin(void){
Assert(demon_primary_thread);
os_mutex_take(demon_state_mutex);
demon_run_state = 1;
os_mutex_drop(demon_state_mutex);
}
internal void
demon_exclusive_mode_end(void){
Assert(demon_primary_thread);
os_mutex_take(demon_state_mutex);
demon_run_state = 0;
os_mutex_drop(demon_state_mutex);
}
////////////////////////////////
//~ rjf: Running/Halting
internal DEMON_EventList
demon_run(Arena *arena, DEMON_RunCtrls *ctrls)
internal DMN_Event *
dmn_event_list_push(Arena *arena, DMN_EventList *list)
{
Assert(demon_primary_thread);
Temp scratch = scratch_begin(&arena, 1);
// convert controls to os controls
B32 full_conversion = 1;
DEMON_OS_RunCtrls os_ctrls = {0};
DMN_EventNode *n = push_array(arena, DMN_EventNode, 1);
SLLQueuePush(list->first, list->last, n);
list->count += 1;
DMN_Event *result = &n->v;
return result;
}
////////////////////////////////
//~ rjf: Thread Reading Helper Functions (Helpers, Implemented Once)
internal U64
dmn_rip_from_thread(DMN_Handle thread)
{
U64 result = 0;
Temp scratch = scratch_begin(0, 0);
{
// convert single_step_thread
if (ctrls->single_step_thread != 0){
DEMON_Entity *sst_entity = demon_ent_ptr_from_handle(ctrls->single_step_thread);
if (sst_entity != 0 &&
sst_entity->kind == DEMON_EntityKind_Thread){
os_ctrls.single_step_thread = sst_entity;
}
else{
full_conversion = 0;
goto finish_conversion;
}
}
// convert exception handling flag
os_ctrls.ignore_previous_exception = ctrls->ignore_previous_exception;
// convert fronzen threads
os_ctrls.run_entities_are_unfrozen = ctrls->run_entities_are_unfrozen;
os_ctrls.run_entities_are_processes = ctrls->run_entities_are_processes;
os_ctrls.run_entity_count = ctrls->run_entity_count;
os_ctrls.run_entities = push_array_no_zero(scratch.arena, DEMON_Entity*, ctrls->run_entity_count);
{
DEMON_EntityKind expected_entity_kind = DEMON_EntityKind_Thread;
if (os_ctrls.run_entities_are_processes){
expected_entity_kind = DEMON_EntityKind_Process;
}
DEMON_Handle *src = ctrls->run_entities;
DEMON_Entity **dst = os_ctrls.run_entities;
for (U64 i = 0; i < ctrls->run_entity_count; i += 1, src += 1, dst += 1){
DEMON_Entity *frozen_thread = demon_ent_ptr_from_handle(*src);
if (frozen_thread != 0 &&
frozen_thread->kind == expected_entity_kind){
*dst = frozen_thread;
}
else{
full_conversion = 0;
goto finish_conversion;
}
}
}
// convert traps
os_ctrls.traps = push_array_no_zero(scratch.arena, DEMON_OS_Trap, ctrls->traps.trap_count);
{
DEMON_OS_Trap *dst = os_ctrls.traps;
for (DEMON_TrapChunkNode *node = ctrls->traps.first;
node != 0;
node = node->next){
DEMON_Trap *src = node->v;
U64 node_trap_count = node->count;
for (U64 i = 0; i < node_trap_count; i += 1, src += 1){
if (src->process != 0){
DEMON_Entity *trap_process = demon_ent_ptr_from_handle(src->process);
if (trap_process != 0 &&
trap_process->kind == DEMON_EntityKind_Process){
dst->process = trap_process;
dst->address = src->address;
dst += 1;
}
else{
full_conversion = 0;
goto finish_conversion;
}
}
}
}
os_ctrls.trap_count = (U64)(dst - os_ctrls.traps);
}
finish_conversion:;
Architecture arch = dmn_arch_from_thread(thread);
U64 reg_block_size = regs_block_size_from_architecture(arch);
void *reg_block = push_array(scratch.arena, U8, reg_block_size);
dmn_thread_read_reg_block(thread, reg_block);
result = regs_rip_from_arch_block(arch, reg_block);
}
// call the OS implementation of run
DEMON_EventList result = {0};
if (full_conversion){
result = demon_os_run(arena, &os_ctrls);
}
else{
DEMON_Event *event = demon_push_event(arena, &result, DEMON_EventKind_Error);
event->error_kind = DEMON_ErrorKind_InvalidHandle;
}
scratch_end(scratch);
return(result);
}
internal void
demon_halt(U64 code, U64 user_data){
demon_os_halt(code, user_data);
return result;
}
internal U64
demon_get_time_counter(void){
return(demon_time);
}
////////////////////////////////
//~ rjf: Target Process Launching/Attaching/Killing/Detaching/Halting
internal U32
demon_launch_process(OS_LaunchOptions *options){
Assert(demon_primary_thread);
U32 result = demon_os_launch_process(options);
return(result);
}
internal B32
demon_attach_process(U32 pid){
Assert(demon_primary_thread);
B32 result = demon_os_attach_process(pid);
return(result);
}
internal B32
demon_kill_process(DEMON_Handle process, U32 exit_code){
Assert(demon_primary_thread);
B32 result = 0;
DEMON_Entity *entity = demon_ent_ptr_from_handle(process);
if (entity != 0 &&
entity->kind == DEMON_EntityKind_Process){
result = demon_os_kill_process(entity, exit_code);
}
return(result);
}
internal B32
demon_detach_process(DEMON_Handle process){
Assert(demon_primary_thread);
B32 result = 0;
DEMON_Entity *entity = demon_ent_ptr_from_handle(process);
if (entity != 0 &&
entity->kind == DEMON_EntityKind_Process){
result = demon_os_detach_process(entity);
}
return(result);
}
////////////////////////////////
//~ rjf: Entity Functions
//- rjf: basics
internal B32
demon_object_exists(DEMON_Handle object){
B32 result = 0;
if (demon_access_begin()){
DEMON_Entity *entity = demon_ent_ptr_from_handle(object);
result = (entity != 0);
demon_access_end();
}
return(result);
}
//- rjf: introspection
internal Architecture
demon_arch_from_object(DEMON_Handle object){
Architecture result = Architecture_Null;
if (demon_access_begin()){
DEMON_Entity *entity = demon_ent_ptr_from_handle(object);
if (entity != 0){
result = (Architecture)entity->arch;
}
demon_access_end();
}
return(result);
}
internal U64
demon_base_vaddr_from_module(DEMON_Handle module){
U64 result = 0;
if (demon_access_begin()){
DEMON_Entity *entity = demon_ent_ptr_from_handle(module);
if (entity != 0 && entity->kind == DEMON_EntityKind_Module){
result = entity->id;
}
demon_access_end();
}
return(result);
}
internal Rng1U64
demon_vaddr_range_from_module(DEMON_Handle module)
dmn_rsp_from_thread(DMN_Handle thread)
{
Rng1U64 result = {0};
if(demon_access_begin())
U64 result = 0;
Temp scratch = scratch_begin(0, 0);
{
DEMON_Entity *entity = demon_ent_ptr_from_handle(module);
if(entity != 0 && entity->kind == DEMON_EntityKind_Module)
{
result = r1u64(entity->id, entity->id+entity->addr_range_dim);
}
demon_access_end();
Architecture arch = dmn_arch_from_thread(thread);
U64 reg_block_size = regs_block_size_from_architecture(arch);
void *reg_block = push_array(scratch.arena, U8, reg_block_size);
dmn_thread_read_reg_block(thread, reg_block);
result = regs_rsp_from_arch_block(arch, reg_block);
}
return(result);
}
internal String8
demon_full_path_from_module(Arena *arena, DEMON_Handle module){
String8 result = {0};
if (demon_access_begin()){
DEMON_Entity *entity = demon_ent_ptr_from_handle(module);
if (entity != 0 &&
entity->kind == DEMON_EntityKind_Module){
result = demon_accel_full_path_from_module(arena, entity);
}
demon_access_end();
}
return(result);
}
internal U64
demon_stack_base_vaddr_from_thread(DEMON_Handle thread){
U64 result = 0;
if (demon_access_begin()){
DEMON_Entity *entity = demon_ent_ptr_from_handle(thread);
if (entity != 0 && entity->kind == DEMON_EntityKind_Thread){
result = demon_accel_stack_base_vaddr_from_thread(entity);
}
demon_access_end();
}
return(result);
}
internal U64
demon_tls_root_vaddr_from_thread(DEMON_Handle handle){
U64 result = 0;
if (demon_access_begin()){
DEMON_Entity *entity = demon_ent_ptr_from_handle(handle);
if (entity != 0 &&
entity->kind == DEMON_EntityKind_Thread){
result = demon_accel_tls_root_vaddr_from_thread(entity);
}
demon_access_end();
}
return(result);
}
internal DEMON_HandleArray
demon_all_processes(Arena *arena){
DEMON_HandleArray result = {0};
if (demon_access_begin()){
DEMON_Handle *handles = push_array_no_zero(arena, DEMON_Handle, demon_proc_count);
DEMON_Handle *handle_opl = handles + demon_proc_count;
DEMON_Handle *handle_ptr = handles;
for (DEMON_Entity *process = demon_ent_root->first;
process != 0 && handle_ptr < handle_opl;
process = process->next){
if (process->kind == DEMON_EntityKind_Process){
*handle_ptr = demon_ent_handle_from_ptr(process);
handle_ptr += 1;
}
}
result.handles = handles;
result.count = (U64)(handle_ptr - handles);
U64 unused_count = demon_proc_count - result.count;
arena_put_back(arena, sizeof(DEMON_Handle)*unused_count);
demon_access_end();
}
return(result);
}
internal DEMON_HandleArray
demon_threads_from_process(Arena *arena, DEMON_Handle process){
DEMON_HandleArray result = {0};
if (demon_access_begin()){
DEMON_Handle *handles = push_array_no_zero(arena, DEMON_Handle, demon_thread_count);
DEMON_Handle *handle_opl = handles + demon_thread_count;
DEMON_Handle *handle_ptr = handles;
DEMON_Entity *process_ptr = demon_ent_ptr_from_handle(process);
if (process_ptr != 0 && process_ptr->kind == DEMON_EntityKind_Process){
for (DEMON_Entity *thread = process_ptr->first;
thread != 0 && handle_ptr < handle_opl;
thread = thread->next){
if (thread->kind == DEMON_EntityKind_Thread){
*handle_ptr = demon_ent_handle_from_ptr(thread);
handle_ptr += 1;
}
}
}
result.handles = handles;
result.count = (U64)(handle_ptr - handles);
U64 unused_count = demon_thread_count - result.count;
arena_put_back(arena, sizeof(DEMON_Handle)*unused_count);
demon_access_end();
}
return(result);
}
internal DEMON_HandleArray
demon_modules_from_process(Arena *arena, DEMON_Handle process){
DEMON_HandleArray result = {0};
if (demon_access_begin()){
DEMON_Handle *handles = push_array_no_zero(arena, DEMON_Handle, demon_module_count);
DEMON_Handle *handle_opl = handles + demon_module_count;
DEMON_Handle *handle_ptr = handles;
DEMON_Entity *process_ptr = demon_ent_ptr_from_handle(process);
if (process_ptr != 0 && process_ptr->kind == DEMON_EntityKind_Process){
for (DEMON_Entity *module = process_ptr->first;
module != 0 && handle_ptr < handle_opl;
module = module->next){
if (module->kind == DEMON_EntityKind_Module){
*handle_ptr = demon_ent_handle_from_ptr(module);
handle_ptr += 1;
}
}
}
result.handles = handles;
result.count = (U64)(handle_ptr - handles);
U64 unused_count = demon_module_count - result.count;
arena_put_back(arena, sizeof(DEMON_Handle)*unused_count);
demon_access_end();
}
return(result);
}
//- rjf: target process memory allocation/protection
internal U64
demon_reserve_memory(DEMON_Handle process, U64 size){
U64 result = 0;
if (demon_access_begin()){
DEMON_Entity *entity = demon_ent_ptr_from_handle(process);
if (entity != 0 &&
entity->kind == DEMON_EntityKind_Process){
result = demon_os_reserve_memory(entity, size);
}
demon_access_end();
}
return(result);
}
internal B32
demon_set_memory_protect_flags(DEMON_Handle process, U64 page_vaddr, U64 size, DEMON_MemoryProtectFlags flags){
B32 result = 0;
if (demon_access_begin()){
DEMON_Entity *entity = demon_ent_ptr_from_handle(process);
if (entity != 0 &&
entity->kind == DEMON_EntityKind_Process){
demon_os_set_memory_protect_flags(entity, page_vaddr, size, flags);
result = 1;
}
demon_access_end();
}
return(result);
}
internal B32
demon_release_memory(DEMON_Handle process, U64 vaddr, U64 size){
B32 result = 0;
if (demon_access_begin()){
DEMON_Entity *entity = demon_ent_ptr_from_handle(process);
if (entity != 0 &&
entity->kind == DEMON_EntityKind_Process){
demon_os_release_memory(entity, vaddr, size);
result = 1;
}
demon_access_end();
}
return(result);
}
//- rjf: target process memory reading/writing
internal U64
demon_read_memory(DEMON_Handle process, void *dst, U64 src_address, U64 size){
U64 bytes_read = 0;
if (demon_access_begin()){
DEMON_Entity *entity = demon_ent_ptr_from_handle(process);
if (entity != 0 &&
entity->kind == DEMON_EntityKind_Process){
bytes_read = demon_os_read_memory(entity, dst, src_address, size);
}
demon_access_end();
}
return(bytes_read);
}
internal B32
demon_write_memory(DEMON_Handle process, U64 dst_address, void *src, U64 size){
B32 result = 0;
if (demon_access_begin()){
DEMON_Entity *entity = demon_ent_ptr_from_handle(process);
if (entity != 0 &&
entity->kind == DEMON_EntityKind_Process){
result = demon_os_write_memory(entity, dst_address, src, size);
}
demon_access_end();
}
return(result);
}
#define READ_BLOCK_SIZE 4096
internal U64
demon_read_memory_amap_aligned(DEMON_Handle process, void *dst, U64 src_address, U64 size){
// Algorithm:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ^ ^ ^
// MIN MAX SMAX
// [MIN,MAX) - range attempting to read
// [MAX,SMAX) - range not yet proven to be impossible to read
Assert(src_address%READ_BLOCK_SIZE == 0);
Assert(size%READ_BLOCK_SIZE == 0);
U64 read_size = 0;
U64 min = 0;
U64 max = size;
U64 smax = max;
for (;;){
if (max <= min){
break;
}
// attempt to read range
U64 attempt_size = max - min;
B32 success = demon_read_memory(process, (U8*)dst + min, src_address + min, attempt_size);
if (success){
// increase successful read size
read_size += attempt_size;
// adjust range up
min = max;
max = smax;
}
else{
// mark this point as too far
smax = max - READ_BLOCK_SIZE;
// bisect the range for the next read attempt
U64 mid = (min + max)/2;
U64 aligned_mid = AlignDownPow2(mid, READ_BLOCK_SIZE);
max = aligned_mid;
}
}
U64 result = read_size;
return(result);
}
internal U64
demon_read_memory_amap(DEMON_Handle process, void *dst, U64 src_address, U64 size){
U64 read_size = 0;
if (demon_access_begin()){
B32 done = 0;
U64 read_opl = src_address + size;
// pre-aligned part -- [SRC,PRE_OPL)
U64 src_block_opl = AlignPow2(src_address, READ_BLOCK_SIZE);
U64 pre_opl = Min(src_block_opl, read_opl);
if(src_address < pre_opl)
{
U64 attempt_size = pre_opl - src_address;
if(!demon_read_memory(process, dst, src_address, attempt_size))
{
done = 1;
}
else
{
read_size += attempt_size;
}
}
// aligned part -- [PRE_OPL,POST_FIRST)
U64 read_opl_block_base = AlignDownPow2(read_opl, READ_BLOCK_SIZE);
U64 post_first = Max(read_opl_block_base, pre_opl);
if (!done && pre_opl < post_first){
U64 off = pre_opl - src_address;
U64 attempt_size = post_first - pre_opl;
U64 actual_size = demon_read_memory_amap_aligned(process, (U8*)dst + off,
pre_opl, attempt_size);
read_size += actual_size;
if (actual_size < attempt_size){
done = 1;
}
}
// post-aligned part -- [POST_FIRST,READ_OPL)
if (!done && post_first < read_opl){
U64 off = post_first - src_address;
U64 attempt_size = read_opl - post_first;
if (!demon_read_memory(process, (U8*)dst + off, post_first, attempt_size)){
done = 1;
}
else
{
read_size += attempt_size;
}
}
demon_access_end();
}
U64 result = read_size;
return(result);
}
#undef READ_BLOCK_SIZE
//- rjf: thread registers reading/writing
internal void*
demon_read_regs(DEMON_Handle thread){
void *result = 0;
if (demon_access_begin()){
DEMON_Entity *entity = demon_ent_ptr_from_handle(thread);
if (entity != 0 &&
entity->kind == DEMON_EntityKind_Thread){
result = demon_accel_read_regs(entity);
}
demon_access_end();
}
return(result);
}
internal B32
demon_write_regs(DEMON_Handle thread, void *data){
B32 result = 0;
if (demon_access_begin()){
DEMON_Entity *entity = demon_ent_ptr_from_handle(thread);
if (entity != 0 &&
entity->kind == DEMON_EntityKind_Thread){
demon_accel_write_regs(entity, data);
result = 1;
}
demon_access_end();
}
return(result);
}
internal U64
demon_read_ip(DEMON_Handle thread){
U64 result = 0;
if (demon_access_begin()){
DEMON_Entity *entity = demon_ent_ptr_from_handle(thread);
if (entity != 0 &&
entity->kind == DEMON_EntityKind_Thread){
void *regs = demon_accel_read_regs(entity);
result = regs_rip_from_arch_block((Architecture)entity->arch, regs);
}
demon_access_end();
}
return(result);
}
internal U64
demon_read_sp(DEMON_Handle thread){
U64 result = 0;
if (demon_access_begin()){
DEMON_Entity *entity = demon_ent_ptr_from_handle(thread);
if (entity != 0 &&
entity->kind == DEMON_EntityKind_Thread){
void *regs = demon_accel_read_regs(entity);
result = regs_rsp_from_arch_block((Architecture)entity->arch, regs);
}
demon_access_end();
}
return(result);
}
internal void
demon_write_ip(DEMON_Handle thread, U64 ip){
if (demon_access_begin()){
DEMON_Entity *entity = demon_ent_ptr_from_handle(thread);
if (entity != 0 &&
entity->kind == DEMON_EntityKind_Thread){
void *regs = demon_accel_read_regs(entity);
regs_arch_block_write_rip((Architecture)entity->arch, regs, ip);
demon_accel_write_regs(entity, regs);
}
demon_access_end();
}
}
////////////////////////////////
//~ rjf: Process Listing
internal void
demon_proc_iter_begin(DEMON_ProcessIter *iter){
demon_os_proc_iter_begin(iter);
}
internal B32
demon_proc_iter_next(Arena *arena, DEMON_ProcessIter *iter, DEMON_ProcessInfo *info_out){
return(demon_os_proc_iter_next(arena, iter, info_out));
}
internal void
demon_proc_iter_end(DEMON_ProcessIter *iter){
demon_os_proc_iter_end(iter);
scratch_end(scratch);
return result;
}
+136 -192
View File
@@ -5,111 +5,70 @@
#define DEMON_CORE_H
////////////////////////////////
//~ allen: Demon Low Level Entities
//~ rjf: Control-Thread-Only Context
//
// An instance of this struct must ONLY be returned by dmn_ctrl_begin, and only
// used by the thread which called it. All APIs which can ONLY run on the
// control thread, which blocks to control & receive events, will take this
// parameter. All other APIs can be called from any thread.
typedef U64 DEMON_Handle;
typedef struct DEMON_HandleNode DEMON_HandleNode;
struct DEMON_HandleNode
typedef struct DMN_CtrlCtx DMN_CtrlCtx;
struct DMN_CtrlCtx
{
DEMON_HandleNode *next;
DEMON_Handle v;
U64 u64 [1];
};
typedef struct DEMON_HandleList DEMON_HandleList;
struct DEMON_HandleList
////////////////////////////////
//~ rjf: Handle Types
typedef union DMN_Handle DMN_Handle;
union DMN_Handle
{
DEMON_HandleNode *first;
DEMON_HandleNode *last;
U32 u32[2];
U64 u64[1];
};
typedef struct DMN_HandleNode DMN_HandleNode;
struct DMN_HandleNode
{
DMN_HandleNode *next;
DMN_Handle v;
};
typedef struct DMN_HandleList DMN_HandleList;
struct DMN_HandleList
{
DMN_HandleNode *first;
DMN_HandleNode *last;
U64 count;
};
typedef struct DEMON_HandleArray DEMON_HandleArray;
struct DEMON_HandleArray
typedef struct DMN_HandleArray DMN_HandleArray;
struct DMN_HandleArray
{
DEMON_Handle *handles;
DMN_Handle *handles;
U64 count;
};
////////////////////////////////
//~ rjf: Memory Protection Flags
//~ rjf: Generated Code
typedef U32 DEMON_MemoryProtectFlags;
enum{
DEMON_MemoryProtectFlag_Read = (1<<0),
DEMON_MemoryProtectFlag_Write = (1<<1),
DEMON_MemoryProtectFlag_Execute = (1<<2),
};
#include "generated/demon.meta.h"
////////////////////////////////
//~ allen: Demon Event Types
//~ rjf: Event Types
typedef enum DEMON_EventKind
typedef struct DMN_Event DMN_Event;
struct DMN_Event
{
DEMON_EventKind_Null,
DEMON_EventKind_Error,
DEMON_EventKind_HandshakeComplete,
DEMON_EventKind_CreateProcess,
DEMON_EventKind_ExitProcess,
DEMON_EventKind_CreateThread,
DEMON_EventKind_ExitThread,
DEMON_EventKind_LoadModule,
DEMON_EventKind_UnloadModule,
DEMON_EventKind_Breakpoint,
DEMON_EventKind_Trap,
DEMON_EventKind_SingleStep,
DEMON_EventKind_Exception,
DEMON_EventKind_Halt,
DEMON_EventKind_Memory,
DEMON_EventKind_DebugString,
DEMON_EventKind_SetThreadName,
DEMON_EventKind_COUNT
}
DEMON_EventKind;
typedef enum DEMON_ErrorKind
{
DEMON_ErrorKind_Null,
DEMON_ErrorKind_NotInitialized,
DEMON_ErrorKind_NotAttached,
DEMON_ErrorKind_UnexpectedFailure,
DEMON_ErrorKind_InvalidHandle,
}
DEMON_ErrorKind;
typedef enum DEMON_MemoryEventKind
{
DEMON_MemoryEventKind_Null,
DEMON_MemoryEventKind_Commit,
DEMON_MemoryEventKind_Reserve,
DEMON_MemoryEventKind_Decommit,
DEMON_MemoryEventKind_Release,
DEMON_MemoryEventKind_COUNT
}
DEMON_MemoryEventKind;
typedef enum DEMON_ExceptionKind
{
DEMON_ExceptionKind_Null,
DEMON_ExceptionKind_MemoryRead,
DEMON_ExceptionKind_MemoryWrite,
DEMON_ExceptionKind_MemoryExecute,
DEMON_ExceptionKind_CppThrow,
DEMON_ExceptionKind_COUNT
}
DEMON_ExceptionKind;
typedef struct DEMON_Event DEMON_Event;
struct DEMON_Event
{
// TODO(allen): condense
DEMON_EventKind kind;
DEMON_ErrorKind error_kind;
DEMON_MemoryEventKind memory_kind;
DEMON_ExceptionKind exception_kind;
DEMON_Handle process;
DEMON_Handle thread;
DEMON_Handle module;
DMN_EventKind kind;
DMN_ErrorKind error_kind;
DMN_MemoryEventKind memory_kind;
DMN_ExceptionKind exception_kind;
DMN_Handle process;
DMN_Handle thread;
DMN_Handle module;
Architecture arch;
U64 address;
U64 size;
String8 string;
@@ -123,171 +82,156 @@ struct DEMON_Event
B32 exception_repeated;
};
typedef struct DEMON_EventNode DEMON_EventNode;
struct DEMON_EventNode
typedef struct DMN_EventNode DMN_EventNode;
struct DMN_EventNode
{
DEMON_EventNode *next;
DEMON_Event v;
DMN_EventNode *next;
DMN_Event v;
};
typedef struct DEMON_EventList DEMON_EventList;
struct DEMON_EventList
typedef struct DMN_EventList DMN_EventList;
struct DMN_EventList
{
DEMON_EventNode *first;
DEMON_EventNode *last;
DMN_EventNode *first;
DMN_EventNode *last;
U64 count;
};
////////////////////////////////
//~ allen: Demon Run Control Types
//~ rjf: Run Control Types
typedef struct DEMON_Trap DEMON_Trap;
struct DEMON_Trap
typedef struct DMN_Trap DMN_Trap;
struct DMN_Trap
{
DEMON_Handle process;
U64 address;
DMN_Handle process;
U64 vaddr;
U64 id;
};
typedef struct DEMON_TrapChunkNode DEMON_TrapChunkNode;
struct DEMON_TrapChunkNode
typedef struct DMN_TrapChunkNode DMN_TrapChunkNode;
struct DMN_TrapChunkNode
{
DEMON_TrapChunkNode *next;
DEMON_Trap *v;
DMN_TrapChunkNode *next;
DMN_Trap *v;
U64 cap;
U64 count;
};
typedef struct DEMON_TrapChunkList DEMON_TrapChunkList;
struct DEMON_TrapChunkList
typedef struct DMN_TrapChunkList DMN_TrapChunkList;
struct DMN_TrapChunkList
{
DEMON_TrapChunkNode *first;
DEMON_TrapChunkNode *last;
DMN_TrapChunkNode *first;
DMN_TrapChunkNode *last;
U64 node_count;
U64 trap_count;
};
typedef struct DEMON_RunCtrls DEMON_RunCtrls;
struct DEMON_RunCtrls
typedef struct DMN_RunCtrls DMN_RunCtrls;
struct DMN_RunCtrls
{
DEMON_Handle single_step_thread;
DMN_Handle single_step_thread;
B8 ignore_previous_exception;
B8 run_entities_are_unfrozen;
B8 run_entities_are_processes;
DEMON_Handle *run_entities;
DMN_Handle *run_entities;
U64 run_entity_count;
DEMON_TrapChunkList traps;
DMN_TrapChunkList traps;
};
////////////////////////////////
//~ allen: Demon Process Listing
//~ rjf: System Process Listing Types
typedef struct DEMON_ProcessIter DEMON_ProcessIter;
struct DEMON_ProcessIter
typedef struct DMN_ProcessIter DMN_ProcessIter;
struct DMN_ProcessIter
{
U64 v[2];
};
typedef struct DEMON_ProcessInfo DEMON_ProcessInfo;
struct DEMON_ProcessInfo
typedef struct DMN_ProcessInfo DMN_ProcessInfo;
struct DMN_ProcessInfo
{
String8 name;
U32 pid;
};
////////////////////////////////
//~ rjf: Main Layer Initialization
//~ rjf: Basic Type Functions (Helpers, Implemented Once)
internal void demon_init(void);
////////////////////////////////
//~ rjf: Basic Type Functions
//- rjf: stringizing
internal String8 demon_string_from_event_kind(DEMON_EventKind kind);
internal String8 demon_string_from_memory_event_kind(DEMON_MemoryEventKind kind);
internal String8 demon_string_from_exception_kind(DEMON_ExceptionKind kind);
internal void demon_string_list_from_event(Arena *arena, String8List *out, DEMON_Event *event);
//- rjf: handles
internal DMN_Handle dmn_handle_zero(void);
internal B32 dmn_handle_match(DMN_Handle a, DMN_Handle b);
//- rjf: trap chunk lists
internal void demon_trap_chunk_list_push(Arena *arena, DEMON_TrapChunkList *list, U64 cap, DEMON_Trap *trap);
internal void demon_trap_chunk_list_concat_in_place(DEMON_TrapChunkList *dst, DEMON_TrapChunkList *to_push);
internal void demon_trap_chunk_list_concat_shallow_copy(Arena *arena, DEMON_TrapChunkList *dst, DEMON_TrapChunkList *to_push);
internal void dmn_trap_chunk_list_push(Arena *arena, DMN_TrapChunkList *list, U64 cap, DMN_Trap *trap);
internal void dmn_trap_chunk_list_concat_in_place(DMN_TrapChunkList *dst, DMN_TrapChunkList *to_push);
internal void dmn_trap_chunk_list_concat_shallow_copy(Arena *arena, DMN_TrapChunkList *dst, DMN_TrapChunkList *to_push);
//- rjf: handle lists
internal void demon_handle_list_push(Arena *arena, DEMON_HandleList *list, DEMON_Handle handle);
internal DEMON_HandleArray demon_handle_array_from_list(Arena *arena, DEMON_HandleList *list);
internal DEMON_HandleArray demon_handle_array_copy(Arena *arena, DEMON_HandleArray *src);
internal void dmn_handle_list_push(Arena *arena, DMN_HandleList *list, DMN_Handle handle);
internal DMN_HandleArray dmn_handle_array_from_list(Arena *arena, DMN_HandleList *list);
internal DMN_HandleArray dmn_handle_array_copy(Arena *arena, DMN_HandleArray *src);
//- rjf: event list building
internal DMN_Event *dmn_event_list_push(Arena *arena, DMN_EventList *list);
////////////////////////////////
//~ rjf: Primary Thread & Exclusive Mode Controls
//~ rjf: Thread Reading Helper Functions (Helpers, Implemented Once)
internal void demon_primary_thread_begin(void);
internal void demon_exclusive_mode_begin(void);
internal void demon_exclusive_mode_end(void);
internal U64 dmn_rip_from_thread(DMN_Handle thread);
internal U64 dmn_rsp_from_thread(DMN_Handle thread);
////////////////////////////////
//~ rjf: Running/Halting
//~ rjf: @dmn_os_hooks Main Layer Initialization (Implemented Per-OS)
internal DEMON_EventList demon_run(Arena *arena, DEMON_RunCtrls *ctrls);
internal void demon_halt(U64 code, U64 user_data);
internal U64 demon_get_time_counter(void);
internal void dmn_init(void);
////////////////////////////////
//~ rjf: Target Process Launching/Attaching/Killing/Detaching/Halting
//~ rjf: @dmn_os_hooks Blocking Control Thread Operations (Implemented Per-OS)
internal U32 demon_launch_process(OS_LaunchOptions *options);
internal B32 demon_attach_process(U32 pid);
internal B32 demon_kill_process(DEMON_Handle process, U32 exit_code);
internal B32 demon_detach_process(DEMON_Handle process);
internal DMN_CtrlCtx *dmn_ctrl_begin(void);
internal void dmn_ctrl_exclusive_access_begin(void);
internal void dmn_ctrl_exclusive_access_end(void);
#define DMN_CtrlExclusiveAccessScope DeferLoop(dmn_ctrl_exclusive_access_begin(), dmn_ctrl_exclusive_access_end())
internal U32 dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_LaunchOptions *options);
internal B32 dmn_ctrl_attach(DMN_CtrlCtx *ctx, U32 pid);
internal B32 dmn_ctrl_kill(DMN_CtrlCtx *ctx, DMN_Handle process, U32 exit_code);
internal B32 dmn_ctrl_detach(DMN_CtrlCtx *ctx, DMN_Handle process);
internal DMN_EventList dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls);
////////////////////////////////
//~ rjf: Entity Functions
//~ rjf: @dmn_os_hooks Halting (Implemented Per-OS)
//- rjf: basics
internal B32 demon_object_exists(DEMON_Handle object);
//- rjf: introspection
internal Architecture demon_arch_from_object(DEMON_Handle object);
internal U64 demon_base_vaddr_from_module(DEMON_Handle module);
internal Rng1U64 demon_vaddr_range_from_module(DEMON_Handle module);
internal String8 demon_full_path_from_module(Arena *arena, DEMON_Handle module);
internal U64 demon_stack_base_vaddr_from_thread(DEMON_Handle thread);
internal U64 demon_tls_root_vaddr_from_thread(DEMON_Handle thread);
internal DEMON_HandleArray demon_all_processes(Arena *arena);
internal DEMON_HandleArray demon_threads_from_process(Arena *arena, DEMON_Handle process);
internal DEMON_HandleArray demon_modules_from_process(Arena *arena, DEMON_Handle process);
//- rjf: target process memory allocation/protection
internal U64 demon_reserve_memory(DEMON_Handle process, U64 size);
internal B32 demon_set_memory_protect_flags(DEMON_Handle process, U64 page_vaddr, U64 size, DEMON_MemoryProtectFlags flags);
internal B32 demon_release_memory(DEMON_Handle process, U64 vaddr, U64 size);
//- rjf: target process memory reading/writing
internal U64 demon_read_memory(DEMON_Handle process, void *dst, U64 src_address, U64 size);
internal B32 demon_write_memory(DEMON_Handle process, U64 dst_address, void *src, U64 size);
internal U64 demon_read_memory_amap_aligned(DEMON_Handle process, void *dst, U64 src_address, U64 size);
internal U64 demon_read_memory_amap(DEMON_Handle process, void *dst, U64 src_address, U64 size);
//- rjf: thread registers reading/writing
// IMPORTANT(allen): This API is _trusting_ you. You should never modify the data pointed
// at by that void pointer! It is pointing to the internal cache of the registers, so it
// will become invalid after a call to demon_write_regs, or demon_run. Use it to read
// what you need and be done ASAP and we can avoid an extra copy baked into the API.
internal void *demon_read_regs(DEMON_Handle thread);
internal B32 demon_write_regs(DEMON_Handle thread, void *data);
// TODO(allen): These might be a bad idea when we try to extend to ARM
// They make sense for x86/x64 abstraction, which often needs identical
// code paths except for these parts. Revisit this when ARM is integrated.
internal U64 demon_read_ip(DEMON_Handle thread);
internal U64 demon_read_sp(DEMON_Handle thread);
internal void demon_write_ip(DEMON_Handle thread, U64 ip);
internal void dmn_halt(U64 code, U64 user_data);
////////////////////////////////
//~ rjf: Process Listing
//~ rjf: @dmn_os_hooks Introspection Functions (Implemented Per-OS)
internal void demon_proc_iter_begin(DEMON_ProcessIter *iter);
internal B32 demon_proc_iter_next(Arena *arena, DEMON_ProcessIter *iter, DEMON_ProcessInfo *info_out);
internal void demon_proc_iter_end(DEMON_ProcessIter *iter);
//- rjf: run/memory/register counters
internal U64 dmn_run_gen(void);
internal U64 dmn_mem_gen(void);
internal U64 dmn_reg_gen(void);
#endif //DEMON_CORE_H
//- rjf: non-blocking-control-thread access barriers
internal B32 dmn_access_open(void);
internal void dmn_access_close(void);
#define DMN_AccessScope DeferLoopChecked(dmn_access_open(), dmn_access_close())
//- rjf: processes
internal U64 dmn_process_read(DMN_Handle process, Rng1U64 range, void *dst);
internal B32 dmn_process_write(DMN_Handle process, Rng1U64 range, void *src);
#define dmn_process_read_struct(process, vaddr, ptr) dmn_process_read((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
#define dmn_process_write_struct(process, vaddr, ptr) dmn_process_write((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
//- rjf: threads
internal Architecture dmn_arch_from_thread(DMN_Handle handle);
internal U64 dmn_stack_base_vaddr_from_thread(DMN_Handle handle);
internal U64 dmn_tls_root_vaddr_from_thread(DMN_Handle handle);
internal B32 dmn_thread_read_reg_block(DMN_Handle handle, void *reg_block);
internal B32 dmn_thread_write_reg_block(DMN_Handle handle, void *reg_block);
//- rjf: system process listing
internal void dmn_process_iter_begin(DMN_ProcessIter *iter);
internal B32 dmn_process_iter_next(Arena *arena, DMN_ProcessIter *iter, DMN_ProcessInfo *info_out);
internal void dmn_process_iter_end(DMN_ProcessIter *iter);
#endif // DEMON_CORE_H
+80
View File
@@ -0,0 +1,80 @@
////////////////////////////////
//~ rjf: Event Kind Tables
@table(name)
DMN_EventKindTable:
{
{Null}
{Error}
{HandshakeComplete}
{CreateProcess}
{ExitProcess}
{CreateThread}
{ExitThread}
{LoadModule}
{UnloadModule}
{Breakpoint}
{Trap}
{SingleStep}
{Exception}
{Halt}
{Memory}
{DebugString}
{SetThreadName}
}
@table(name)
DMN_ErrorKindTable:
{
{Null}
{NotAttached}
{UnexpectedFailure}
{InvalidHandle}
}
@table(name)
DMN_MemoryEventKindTable:
{
{Null}
{Commit}
{Reserve}
{Decommit}
{Release}
}
@table(name)
DMN_ExceptionKindTable:
{
{Null}
{MemoryRead}
{MemoryWrite}
{MemoryExecute}
{CppThrow}
}
////////////////////////////////
//~ rjf: Generators
@enum DMN_EventKind:
{
@expand(DMN_EventKindTable a) `$(a.name)`,
COUNT
}
@enum DMN_ErrorKind:
{
@expand(DMN_ErrorKindTable a) `$(a.name)`,
COUNT
}
@enum DMN_MemoryEventKind:
{
@expand(DMN_MemoryEventKindTable a) `$(a.name)`,
COUNT
}
@enum DMN_ExceptionKind:
{
@expand(DMN_ExceptionKindTable a) `$(a.name)`,
COUNT
}
+2 -7
View File
@@ -2,14 +2,9 @@
// Licensed under the MIT license (https://opensource.org/license/mit/)
#include "demon_core.c"
#include "demon_common.c"
#include "demon_accel.c"
#include "demon_os.c"
#if OS_WINDOWS
# include "win32/demon_os_win32.c"
#elif OS_LINUX
# include "linux/demon_os_linux.c"
# include "win32/demon_core_win32.c"
#else
# error No Demon Implementation for This OS
# error Demon layer backend not defined for this operating system.
#endif
+3 -8
View File
@@ -5,16 +5,11 @@
#define DEMON_INC_H
#include "demon_core.h"
#include "demon_common.h"
#include "demon_accel.h"
#include "demon_os.h"
#if OS_WINDOWS
# include "win32/demon_os_win32.h"
#elif OS_LINUX
# include "linux/demon_os_linux.h"
# include "win32/demon_core_win32.h"
#else
# error No Demon Implementation for This OS
# error Demon layer backend not defined for this operating system.
#endif
#endif //DEMON_INC_H
#endif // DEMON_INC_H
-28
View File
@@ -1,28 +0,0 @@
////////////////////////////////
//~ rjf: Helpers
internal B32
demon_os_read_regs(DEMON_Entity *thread, void *dst)
{
B32 result = 0;
switch(thread->arch)
{
default:{}break;
case Architecture_x86:{result = demon_os_read_regs_x86(thread, (REGS_RegBlockX86 *)dst);}break;
case Architecture_x64:{result = demon_os_read_regs_x64(thread, (REGS_RegBlockX64 *)dst);}break;
}
return result;
}
internal B32
demon_os_write_regs(DEMON_Entity *thread, void *src)
{
B32 result = 0;
switch(thread->arch)
{
default:{}break;
case Architecture_x86:{result = demon_os_write_regs_x86(thread, (REGS_RegBlockX86 *)src);}break;
case Architecture_x64:{result = demon_os_write_regs_x64(thread, (REGS_RegBlockX64 *)src);}break;
}
return result;
}
-98
View File
@@ -1,98 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DEMON_OS_H
#define DEMON_OS_H
// NOTE(allen):
// These are the functions that the OS backends actually implement.
// Demon objects go through a handle validation layer but it is a lot more
// convenient in the OS backends to implement these versions which take the
// already validated DEMON_Entity*. These are also more convenient to call from
// the backend layer, which lets us avoid converting back and forth between
// handles and pointers a lot.
////////////////////////////////
//~ NOTE(allen): Demon OS Run Control Types
typedef struct DEMON_OS_Trap DEMON_OS_Trap;
struct DEMON_OS_Trap
{
DEMON_Entity *process;
U64 address;
};
typedef struct DEMON_OS_RunCtrls DEMON_OS_RunCtrls;
struct DEMON_OS_RunCtrls
{
DEMON_Entity *single_step_thread;
B8 ignore_previous_exception;
B8 run_entities_are_unfrozen;
B8 run_entities_are_processes;
DEMON_Entity **run_entities;
U64 run_entity_count;
DEMON_OS_Trap *traps;
U64 trap_count;
};
////////////////////////////////
//~ rjf: Helpers
internal B32 demon_os_read_regs(DEMON_Entity *thread, void *dst);
internal B32 demon_os_write_regs(DEMON_Entity *thread, void *src);
////////////////////////////////
//~ rjf: @demon_os_hooks Main Layer Initialization
internal void demon_os_init(void);
////////////////////////////////
//~ rjf: @demon_os_hooks Running/Halting
internal DEMON_EventList demon_os_run(Arena *arena, DEMON_OS_RunCtrls *controls);
internal void demon_os_halt(U64 code, U64 user_data);
////////////////////////////////
//~ rjf: @demon_os_hooks Target Process Launching/Attaching/Killing/Detaching/Halting
internal U32 demon_os_launch_process(OS_LaunchOptions *options);
internal B32 demon_os_attach_process(U32 pid);
internal B32 demon_os_kill_process(DEMON_Entity *process, U32 exit_code);
internal B32 demon_os_detach_process(DEMON_Entity *process);
////////////////////////////////
//~ rjf: @demon_os_hooks Entity Functions
//- rjf: cleanup
internal void demon_os_entity_cleanup(DEMON_Entity *entity);
//- rjf: introspection
internal String8 demon_os_full_path_from_module(Arena *arena, DEMON_Entity *module);
internal U64 demon_os_stack_base_vaddr_from_thread(DEMON_Entity *thread);
internal U64 demon_os_tls_root_vaddr_from_thread(DEMON_Entity *thread);
//- rjf: target process memory allocation/protection
internal U64 demon_os_reserve_memory(DEMON_Entity *process, U64 size);
internal void demon_os_set_memory_protect_flags(DEMON_Entity *process, U64 page_vaddr, U64 size, DEMON_MemoryProtectFlags flags);
internal void demon_os_release_memory(DEMON_Entity *process, U64 vaddr, U64 size);
//- rjf: target process memory reading/writing
internal U64 demon_os_read_memory(DEMON_Entity *process, void *dst, U64 src_address, U64 size);
internal B32 demon_os_write_memory(DEMON_Entity *process, U64 dst_address, void *src, U64 size);
#define demon_os_read_struct(p,dst,src) demon_os_read_memory((p), (dst), (src), sizeof(*(dst)))
#define demon_os_write_struct(p,dst,src) demon_os_write_memory((p), (dst), (src), sizeof(*(src)))
//- rjf: thread registers reading/writing
internal B32 demon_os_read_regs_x86(DEMON_Entity *thread, REGS_RegBlockX86 *dst);
internal B32 demon_os_write_regs_x86(DEMON_Entity *thread, REGS_RegBlockX86 *src);
internal B32 demon_os_read_regs_x64(DEMON_Entity *thread, REGS_RegBlockX64 *dst);
internal B32 demon_os_write_regs_x64(DEMON_Entity *thread, REGS_RegBlockX64 *src);
////////////////////////////////
//~ rjf: @demon_os_hooks Process Listing
internal void demon_os_proc_iter_begin(DEMON_ProcessIter *iter);
internal B32 demon_os_proc_iter_next(Arena *arena, DEMON_ProcessIter *iter, DEMON_ProcessInfo *info_out);
internal void demon_os_proc_iter_end(DEMON_ProcessIter *iter);
#endif //DEMON_OS_H
@@ -1,4 +1,8 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#include "regs/raddbg/generated/regs_raddbg.meta.c"
//- GENERATED CODE
C_LINKAGE_BEGIN
C_LINKAGE_END
+63
View File
@@ -0,0 +1,63 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
//- GENERATED CODE
#ifndef DEMON_META_H
#define DEMON_META_H
typedef enum DMN_EventKind
{
DMN_EventKind_Null,
DMN_EventKind_Error,
DMN_EventKind_HandshakeComplete,
DMN_EventKind_CreateProcess,
DMN_EventKind_ExitProcess,
DMN_EventKind_CreateThread,
DMN_EventKind_ExitThread,
DMN_EventKind_LoadModule,
DMN_EventKind_UnloadModule,
DMN_EventKind_Breakpoint,
DMN_EventKind_Trap,
DMN_EventKind_SingleStep,
DMN_EventKind_Exception,
DMN_EventKind_Halt,
DMN_EventKind_Memory,
DMN_EventKind_DebugString,
DMN_EventKind_SetThreadName,
DMN_EventKind_COUNT,
} DMN_EventKind;
typedef enum DMN_ErrorKind
{
DMN_ErrorKind_Null,
DMN_ErrorKind_NotAttached,
DMN_ErrorKind_UnexpectedFailure,
DMN_ErrorKind_InvalidHandle,
DMN_ErrorKind_COUNT,
} DMN_ErrorKind;
typedef enum DMN_MemoryEventKind
{
DMN_MemoryEventKind_Null,
DMN_MemoryEventKind_Commit,
DMN_MemoryEventKind_Reserve,
DMN_MemoryEventKind_Decommit,
DMN_MemoryEventKind_Release,
DMN_MemoryEventKind_COUNT,
} DMN_MemoryEventKind;
typedef enum DMN_ExceptionKind
{
DMN_ExceptionKind_Null,
DMN_ExceptionKind_MemoryRead,
DMN_ExceptionKind_MemoryWrite,
DMN_ExceptionKind_MemoryExecute,
DMN_ExceptionKind_CppThrow,
DMN_ExceptionKind_COUNT,
} DMN_ExceptionKind;
C_LINKAGE_BEGIN
C_LINKAGE_END
#endif // DEMON_META_H
-65
View File
@@ -1,65 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
// exe //
#include "base/base_inc.h"
#include "os/os_inc.h"
#include "demon/demon_inc.h"
#include "syms_helpers/syms_internal_overrides.h"
#include "syms/syms_inc.h"
#include "syms_helpers/syms_helpers.h"
#include "base/base_inc.c"
#include "os/os_inc.c"
#include "demon/demon_inc.c"
#include "syms_helpers/syms_internal_overrides.c"
#include "syms/syms_inc.c"
#include "syms_helpers/syms_helpers.c"
int
main(int argument_count, char **arguments)
{
os_init(argument_count, arguments);
Arena *arena = arena_alloc();
demon_init();
//- rjf: find PID of mule_loop.exe
String8 attach_process_name = str8_lit("mule_loop.exe");
U32 pid = 0;
{
DEMON_ProcessIter it = {0};
demon_proc_iter_begin(&it);
for(DEMON_ProcessInfo info = {0}; demon_proc_iter_next(arena, &it, &info);)
{
if(str8_match(info.name, attach_process_name, 0))
{
pid = info.pid;
break;
}
}
demon_proc_iter_end(&it);
}
//- rjf: attach
B32 attach_good = demon_attach_process(pid);
//- rjf: get events
DEMON_RunCtrls ctrls = {0};
DEMON_EventList events = demon_run(arena, ctrls);
for(DEMON_Event *event = events.first; event != 0; event = event->next)
{
int x = 0;
}
#if 0
//- rjf: try to break in the loop
DEMON_RunCtrls ctrls = {0};
DEMON_Trap trap = {0};
{
U64 loop_bp = 0x0000000140001074;
ctrls.trap_count = 1;
ctrls.traps = &trap;
}
#endif
}
-166
View File
@@ -1,166 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#include "base/base_inc.h"
#include "os/os_inc.h"
#include "demon/demon_inc.h"
#include "syms_helpers/syms_internal_overrides.h"
#include "syms/syms_inc.h"
#include "syms_helpers/syms_helpers.h"
#include "base/base_inc.c"
#include "os/os_inc.c"
#include "demon/demon_inc.c"
#include "syms_helpers/syms_internal_overrides.c"
#include "syms/syms_inc.c"
#include "syms_helpers/syms_helpers.c"
internal SYMS_String8
file_load_func_for_syms(void *user, SYMS_Arena *arena, SYMS_String8 file_name){
String8 data = os_read_file(arena, str8_from_syms(file_name));
SYMS_String8 result = syms_from_str8(data);
return(result);
}
int
main(int argument_count, char **arguments)
{
os_init(argument_count, arguments);
Temp scratch = scratch_begin(0, 0);
// setup
demon_init();
// parse arguments
String8 executable_file_name = {0};
U64 bp_address = 0;
{
String8List command_line_arguments = os_get_command_line_arguments();
CmdLine cmd_line = cmd_line_from_string_list(scratch.arena, command_line_arguments);
if (cmd_line.inputs.first != 0){
executable_file_name = cmd_line.inputs.first->string;
}
String8 bp_string = cmd_line_string(cmd_line, str8_lit("bp"));
try_u64_from_str8_c_rules(bp_string, &bp_address);
}
// check parameters
if (bp_address == 0 || executable_file_name.size == 0){
printf("bad parameters\n");
exit(0);
}
// demon launch
OS_LaunchOptions launch_opts = {0};
str8_list_push(scratch.arena, &launch_opts.cmd_line, executable_file_name);
launch_opts.path = os_get_path(scratch.arena, OS_SystemPath_Current);
U32 process_id = demon_launch_process(&launch_opts);
if (process_id == 0){
printf("could not launch: '%.*s'\n", str8_varg(executable_file_name));
exit(0);
}
// demon loop
{
DEMON_Handle process = 0;
DEMON_Handle thread = 0;
B32 hit_bp = false;
U64 single_step_counter = 0;
U64 counter = 0;
for (;;){
Temp temp = temp_begin(scratch.arena);
DEMON_RunCtrls run_controls = {0};
DEMON_Trap traps[1];
if (!hit_bp){
if (process != 0){
run_controls.trap_count = 1;
run_controls.traps = traps;
run_controls.traps[0].process = process;
run_controls.traps[0].address = bp_address;
}
}
else{
run_controls.single_step_thread = thread;
}
DEMON_EventList events = demon_run(temp.arena, run_controls);
for (DEMON_Event *event = events.first;
event != 0;
event = event->next, counter += 1){
// update tracking state
switch (event->kind){
case DEMON_EventKind_CreateProcess:
{
process = event->process;
}break;
case DEMON_EventKind_ExitProcess:
{
if (event->process == process){
process = 0;
}
}break;
case DEMON_EventKind_CreateThread:
{
thread = event->thread;
}break;
case DEMON_EventKind_Breakpoint:
{
hit_bp = true;
}break;
case DEMON_EventKind_SingleStep:
{
single_step_counter += 1;
SYMS_RegX64 regs1 = {0};
demon_read_x64_regs(thread, &regs1);
demon_write_x64_regs(thread, &regs1);
SYMS_RegX64 regs2 = {0};
demon_read_x64_regs(thread, &regs2);
if (!MemoryMatchStruct(&regs1, &regs2)){
printf("mismatch at single_step_counter=%llu\n", single_step_counter);
}
if (single_step_counter == 1000){
goto end_loop;
}
}break;
case DEMON_EventKind_NotAttached:
{
fprintf(stderr, "not attached - exiting\n");
goto end_loop;
}break;
case DEMON_EventKind_NotInitialized:
case DEMON_EventKind_UnexpectedFailure:
{
fprintf(stderr, "unexpected error - exiting\n");
goto end_loop;
}break;
}
}
goto end_it;
end_loop:
temp_end(temp);
goto loop_exit;
end_it:;
}
loop_exit:;
}
printf("[done]\n");
scratch_end(scratch);
}
-250
View File
@@ -1,250 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#include "base/base_inc.h"
#include "os/os_inc.h"
#include "demon/demon_inc.h"
#include "syms_helpers/syms_internal_overrides.h"
#include "syms/syms_inc.h"
#include "syms_helpers/syms_helpers.h"
#include "base/base_inc.c"
#include "os/os_inc.c"
#include "demon/demon_inc.c"
#include "syms_helpers/syms_internal_overrides.c"
#include "syms/syms_inc.c"
#include "syms_helpers/syms_helpers.c"
internal SYMS_String8
file_load_func_for_syms(void *user, SYMS_Arena *arena, SYMS_String8 file_name){
String8 data = os_read_file(arena, str8_from_syms(file_name));
SYMS_String8 result = syms_from_str8(data);
return(result);
}
int
main(int argument_count, char **arguments)
{
os_init(argument_count, arguments);
demon_init();
String8Node node[2];
#define TARGET_EXE "C:\\devel\\projects\\debugger\\build\\mule_unwind_20210511_clang11_lldlink.exe"
OS_LaunchOptions options = {0};
#if OS_WINDOWS
str8_list_push(&options.cmd_line, &node[0], str8_lit(TARGET_EXE));
options.path = str8_lit("C:\\devel\\projects\\debugger\\build\\");
#else
str8_list_push(&options.cmd_line, &node[0], str8_lit("/home/allenw/projects_copy/debugger/build/mule_main"));
options.path = str8_lit("/home/allenw/projects_copy/debugger/build/");
#endif
U32 process_id = demon_launch_process(&options);
if (process_id == 0){
printf("Could not launch process\n");
exit(1);
}
#if OS_WINDOWS
U64 bp_addr = 0x140001134;
#else
U64 bp_addr = 0x400918;
#endif
DEMON_Handle process = 0;
DEMON_Handle thread = 0;
DEMON_Handle module = 0;
U64 module_base = 0;
SYMS_Group *group = 0;
B32 hit_bp = false;
U64 counter = 0;
for (;;){
DEMON_RunCtrls run_controls = {0};
DEMON_Trap trap_memory[2];
DEMON_Trap *trap_ptr = trap_memory;
if (process != 0 && !hit_bp){
trap_ptr->process = process;
trap_ptr->address = bp_addr;
trap_ptr += 1;
}
run_controls.traps = trap_memory;
run_controls.trap_count = (U64)(trap_ptr - trap_memory);
Temp scratch = scratch_begin(0, 0);
DEMON_EventList events = demon_run(scratch.arena, run_controls);
for (DEMON_Event *event = events.first;
event != 0;
event = event->next){
printf("STEP[%05llx] -- ", counter);
counter += 1;
switch (event->kind){
case DEMON_EventKind_NotInitialized:
{
printf("Not Initialized\n");
exit(1);
}break;
case DEMON_EventKind_NotAttached:
{
printf("Not Attached\n");
exit(1);
}break;
case DEMON_EventKind_UnexpectedFailure:
{
printf("Unexpected Failure\n");
exit(1);
}break;
case DEMON_EventKind_CreateProcess:
{
printf("Create Process\n");
if (process == 0){
process = event->process;
}
}break;
case DEMON_EventKind_CreateThread:
{
printf("Create Thread\n");
if (thread == 0){
thread = event->thread;
}
}break;
case DEMON_EventKind_LoadModule:
{
Temp temp = temp_begin(scratch.arena);
String8 file_name = demon_full_path_from_module(scratch.arena, event->module);
printf("Load Module: %.*s\n", str8_varg(file_name));
if (module == 0 && str8_match(file_name, str8_lit(TARGET_EXE), 0)){
module = event->module;
module_base = event->address;
// setup syms group
group = syms_group_alloc();
SYMS_FileLoadCtx ctx = {0};
ctx.file_load_func = file_load_func_for_syms;
SYMS_String8List file_names = {0};
syms_string_list_push(group->arena, &file_names, syms_from_str8(file_name));
SYMS_FileInfOptions opts = {0};
SYMS_FileInfResult inf_result = syms_file_inf_infer_from_file_list(group->arena, ctx, file_names, &opts);
syms_group_init(group, &inf_result.data_parsed);
}
temp_end(temp);
}break;
case DEMON_EventKind_ExitProcess:
{
printf("Exit Process\n");
exit(0);
}break;
case DEMON_EventKind_ExitThread:
{
printf("Exit Thread\n");
}break;
case DEMON_EventKind_UnloadModule:
{
printf("Unload Module\n");
}break;
case DEMON_EventKind_Breakpoint:
{
Architecture arch = demon_arch_from_object(event->process);
U64 ip = event->instruction_pointer;
printf("Breakpoint: %llx\n", ip);
hit_bp = true;
//- unwind
// setup bin
SYMS_String8 bin_data = group->bin_data;
SYMS_BinAccel *generic_bin = group->bin;
SYMS_PeBinAccel *pe_bin = 0;
if (generic_bin->format == SYMS_FileFormat_PE){
pe_bin = (SYMS_PeBinAccel*)generic_bin;
}
if (pe_bin != 0){
// read regs
SYMS_RegX64 regs = {0};
demon_read_x64_regs(event->thread, &regs);
// read stack
SYMS_U64 sp = regs.rsp.u64;
SYMS_U64 sp_rounded_down = sp&~(KB(4) - 1);
SYMS_String8 stack_memory = {0};
stack_memory.size = KB(8);
stack_memory.str = push_array_no_zero(scratch.arena, U8, stack_memory.size);
SYMS_U64 stack_memory_addr = sp_rounded_down;
stack_memory.size = demon_read_memory_amap(event->process, stack_memory.str,
stack_memory_addr, stack_memory.size);
// unwind loop
U64 counter = 1;
for (;; counter += 1){
printf("%02llu: ip=%llx; sp=%llx\n", counter, regs.rip.u64, regs.rsp.u64);
SYMS_MemoryView memview = syms_memory_view_make(stack_memory, stack_memory_addr);
SYMS_UnwindResult unwind_result = syms_unwind_pe_x64(bin_data, pe_bin, module_base, &memview, &regs);
if (unwind_result.dead){
break;
}
}
}
}break;
case DEMON_EventKind_Trap:
{
Architecture arch = demon_arch_from_object(event->process);
U64 ip = event->instruction_pointer;
printf("Trap: %llx\n", ip);
}break;
case DEMON_EventKind_SingleStep:
{
printf("Single Step: %llx\n", event->instruction_pointer);
}break;
case DEMON_EventKind_Exception:
{
printf("Exception: %llx\n", event->instruction_pointer);
}break;
case DEMON_EventKind_Halt:
{
printf("Halt\n");
}break;
case DEMON_EventKind_Memory:
{
printf("Memory\n");
}break;
default:
{
printf("Unhandled Event\n");
exit(1);
}break;
}
}
scratch_end(scratch);
}
printf("Done\n");
}
-935
View File
@@ -1,935 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
// NOTE(rjf): (18 October 2021) Notes on Win32 process halting via
// DebugBreakProcess:
//
// Calling DebugBreakProcess seems to cause a few events to come back:
// 1. Thread Creation Event
// 2. Breakpoint Event (with the thread matching that of #1)
// 3. Thread Exiting Event (matching #1)
//
// Having done this experiment on a single-threaded program (mule_loop.exe),
// I can only infer that what is happening here is that when DebugBreakProcess
// is called, it first injects a thread into the target process that runs
// code with an int3. This is very similar to the old approach that Demon
// took.
//
// It's going to be difficult to distinguish between these CreateThreads and
// ExitThreads from others (not caused by halting), even though we can match
// the hit breakpoint to the associated thread.
//
// What could be possible (in order to distinguish the hit breakpoint as a
// halt event, instead of an arbitrary breakpoint) is looking at the breakpoint
// address. This injected thread has a breakpoint that's different from the
// initial breakpoint that the kernel automatically hits when a process is
// first being debugged.
//
// With DebugBreakProcess:
// - first breakpoint that is hit: 0x7ff8ad9806b0 in kernel code
// - last breakpoint that is hit: 0x7ff8ad950860 in kernel code (halt)
//
// Without DebugBreakProcess:
// - first breakpoint that is hit: 0x7ff8ad9806b0
//
// NOTE(rjf): (18 October 2021) Notes on suspending processes via
// NtSuspendProcess:
//
// NtSuspendProcess is an undocumented API that is exported by ntdll. It is
// fairly simple but could be unstable. To call it, the main trick is that
// you need a handle with certain privileges (PROCESS_SUSPEND_RESUME), so
// you can't just take any handle and use it.
//
// To use it, we can manually load it from ntdll, grab an elevated handle
// for a given process HANDLE, and then call it. We can resume, then, with
// NtResumeProcess.
//
// Other than this, our options seem to more-or-less lie in individually
// suspending all of the threads in the process-to-be-halted.
#include <windows.h>
#include "base/base_inc.h"
#include "os/os_inc.h"
#include "syms_helpers/syms_internal_overrides.h"
#include "syms/syms_inc.h"
#include "syms_helpers/syms_helpers.h"
#include "base/base_inc.c"
#include "os/os_inc.c"
#include "syms_helpers/syms_internal_overrides.c"
#include "syms/syms_inc.c"
#include "syms_helpers/syms_helpers.c"
typedef LONG NtSuspendProcessFunction(HANDLE ProcessHandle);
global NtSuspendProcessFunction *NtSuspendProcess = 0;
////////////////////////////////
// NOTE(allen): Win32 Demon Exceptions
#define DEMON_W32_EXCEPTION_BREAKPOINT 0x80000003u
#define DEMON_W32_EXCEPTION_SINGLE_STEP 0x80000004u
#define DEMON_W32_EXCEPTION_LONG_JUMP 0x80000026u
#define DEMON_W32_EXCEPTION_ACCESS_VIOLATION 0xC0000005u
#define DEMON_W32_EXCEPTION_ARRAY_BOUNDS_EXCEEDED 0xC000008Cu
#define DEMON_W32_EXCEPTION_DATA_TYPE_MISALIGNMENT 0x80000002u
#define DEMON_W32_EXCEPTION_GUARD_PAGE_VIOLATION 0x80000001u
#define DEMON_W32_EXCEPTION_FLT_DENORMAL_OPERAND 0xC000008Du
#define DEMON_W32_EXCEPTION_FLT_DEVIDE_BY_ZERO 0xC000008Eu
#define DEMON_W32_EXCEPTION_FLT_INEXACT_RESULT 0xC000008Fu
#define DEMON_W32_EXCEPTION_FLT_INVALID_OPERATION 0xC0000090u
#define DEMON_W32_EXCEPTION_FLT_OVERFLOW 0xC0000091u
#define DEMON_W32_EXCEPTION_FLT_STACK_CHECK 0xC0000092u
#define DEMON_W32_EXCEPTION_FLT_UNDERFLOW 0xC0000093u
#define DEMON_W32_EXCEPTION_INT_DIVIDE_BY_ZERO 0xC0000094u
#define DEMON_W32_EXCEPTION_INT_OVERFLOW 0xC0000095u
#define DEMON_W32_EXCEPTION_PRIVILEGED_INSTRUCTION 0xC0000096u
#define DEMON_W32_EXCEPTION_ILLEGAL_INSTRUCTION 0xC000001Du
#define DEMON_W32_EXCEPTION_IN_PAGE_ERROR 0xC0000006u
#define DEMON_W32_EXCEPTION_INVALID_DISPOSITION 0xC0000026u
#define DEMON_W32_EXCEPTION_NONCONTINUABLE 0xC0000025u
#define DEMON_W32_EXCEPTION_STACK_OVERFLOW 0xC00000FDu
#define DEMON_W32_EXCEPTION_INVALID_HANDLE 0xC0000008u
#define DEMON_W32_EXCEPTION_UNWIND_CONSOLIDATE 0x80000029u
#define DEMON_W32_EXCEPTION_DLL_NOT_FOUND 0xC0000135u
#define DEMON_W32_EXCEPTION_ORDINAL_NOT_FOUND 0xC0000138u
#define DEMON_W32_EXCEPTION_ENTRY_POINT_NOT_FOUND 0xC0000139u
#define DEMON_W32_EXCEPTION_DLL_INIT_FAILED 0xC0000142u
#define DEMON_W32_EXCEPTION_CONTROL_C_EXIT 0xC000013Au
#define DEMON_W32_EXCEPTION_FLT_MULTIPLE_FAULTS 0xC00002B4u
#define DEMON_W32_EXCEPTION_FLT_MULTIPLE_TRAPS 0xC00002B5u
#define DEMON_W32_EXCEPTION_NAT_CONSUMPTION 0xC00002C9u
#define DEMON_W32_EXCEPTION_HEAP_CORRUPTION 0xC0000374u
#define DEMON_W32_EXCEPTION_STACK_BUFFER_OVERRUN 0xC0000409u
#define DEMON_W32_EXCEPTION_INVALID_CRUNTIME_PARAM 0xC0000417u
#define DEMON_W32_EXCEPTION_ASSERT_FAILURE 0xC0000420u
#define DEMON_W32_EXCEPTION_NO_MEMORY 0xC0000017u
#define DEMON_W32_EXCEPTION_THROW 0xE06D7363u
////////////////////////////////
// NOTE(allen): Win32 Demon Register API Codes
#define DEMON_W32_CTX_X86 0x00010000
#define DEMON_W32_CTX_X64 0x00100000
#define DEMON_W32_CTX_INTEL_CONTROL 0x0001
#define DEMON_W32_CTX_INTEL_INTEGER 0x0002
#define DEMON_W32_CTX_INTEL_SEGMENTS 0x0004
#define DEMON_W32_CTX_INTEL_FLOATS 0x0008
#define DEMON_W32_CTX_INTEL_DEBUG 0x0010
#define DEMON_W32_CTX_INTEL_EXTENDED 0x0020
#define DEMON_W32_CTX_INTEL_XSTATE 0x0040
#define DEMON_W32_CTX_X86_ALL (DEMON_W32_CTX_X86 | \
DEMON_W32_CTX_INTEL_CONTROL | DEMON_W32_CTX_INTEL_INTEGER | \
DEMON_W32_CTX_INTEL_SEGMENTS | DEMON_W32_CTX_INTEL_DEBUG | \
DEMON_W32_CTX_INTEL_EXTENDED)
#define DEMON_W32_CTX_X64_ALL (DEMON_W32_CTX_X64 | \
DEMON_W32_CTX_INTEL_CONTROL | DEMON_W32_CTX_INTEL_INTEGER | \
DEMON_W32_CTX_INTEL_SEGMENTS | DEMON_W32_CTX_INTEL_FLOATS | \
DEMON_W32_CTX_INTEL_DEBUG)
struct TEST_DebugEvent
{
String8 name;
U64 process_id;
U64 thread_id;
HANDLE process;
HANDLE thread;
U64 addr;
DEBUG_EVENT evt;
};
struct TEST_Trap
{
HANDLE process;
U64 address;
};
internal U16
test_w32_real_tag_word_from_xsave(XSAVE_FORMAT *fxsave)
{
U16 result = 0;
U32 top = (fxsave->StatusWord >> 11) & 7;
for (U32 fpr = 0; fpr < 8; fpr += 1){
U32 tag = 3;
if (fxsave->TagWord & (1 << fpr)){
U32 st = (fpr - top)&7;
SYMS_Reg80 *fp = (SYMS_Reg80*)&fxsave->FloatRegisters[st*16];
U16 exponent = fp->sign1_exp15 & bitmask15;
U64 integer_part = fp->int1_frac63 >> 63;
U64 fraction_part = fp->int1_frac63 & bitmask63;
// tag: 0 - normal; 1 - zero; 2 - special
tag = 2;
if (exponent == 0){
if (integer_part == 0 && fraction_part == 0){
tag = 1;
}
}
else if (exponent != bitmask15 && integer_part != 0){
tag = 0;
}
}
result |= tag << (2 * fpr);
}
return(result);
}
internal U16
test_w32_xsave_tag_word_from_real_tag_word(U16 ftw)
{
U16 compact = 0;
for (U32 fpr = 0; fpr < 8; fpr++){
U32 tag = (ftw >> (fpr * 2)) & 3;
if (tag != 3){
compact |= (1 << fpr);
}
}
return(compact);
}
internal B32
test_w32_read_x64_regs(HANDLE thread, SYMS_RegX64 *dst)
{
Temp scratch = scratch_begin(0, 0);
// NOTE(allen): Check available features
U32 feature_mask = GetEnabledXStateFeatures();
B32 avx_enabled = !!(feature_mask & XSTATE_MASK_AVX);
// NOTE(allen): Setup the context
CONTEXT *ctx = 0;
U32 ctx_flags = DEMON_W32_CTX_X64_ALL;
if (avx_enabled){
ctx_flags |= DEMON_W32_CTX_INTEL_XSTATE;
}
DWORD size = 0;
InitializeContext(0, ctx_flags, 0, &size);
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){
void *ctx_memory = push_array(scratch.arena, U8, size);
if (!InitializeContext(ctx_memory, ctx_flags, &ctx, &size)){
ctx = 0;
}
}
B32 avx_available = false;
if (ctx != 0){
// NOTE(allen): Finish Context Setup
if (avx_enabled){
SetXStateFeaturesMask(ctx, XSTATE_MASK_AVX);
}
// NOTE(allen): Determine what features are available on this particular ctx
// TODO(allen): Experiment carefully with this nonsense.
// Does avx_enabled = avx_available in all circumstances or not?
DWORD64 xstate_flags = 0;
if (GetXStateFeaturesMask(ctx, &xstate_flags)){
if (xstate_flags & XSTATE_MASK_AVX){
avx_available = true;
}
}
}
// get thread context
HANDLE thread_handle = thread;
if (!GetThreadContext(thread_handle, ctx)){
ctx = 0;
}
B32 result = false;
if (ctx != 0){
result = true;
// NOTE(allen): Convert CONTEXT -> SYMS_RegX64
dst->rax.u64 = ctx->Rax;
dst->rcx.u64 = ctx->Rcx;
dst->rdx.u64 = ctx->Rdx;
dst->rbx.u64 = ctx->Rbx;
dst->rsp.u64 = ctx->Rsp;
dst->rbp.u64 = ctx->Rbp;
dst->rsi.u64 = ctx->Rsi;
dst->rdi.u64 = ctx->Rdi;
dst->r8.u64 = ctx->R8;
dst->r9.u64 = ctx->R9;
dst->r10.u64 = ctx->R10;
dst->r11.u64 = ctx->R11;
dst->r12.u64 = ctx->R12;
dst->r13.u64 = ctx->R13;
dst->r14.u64 = ctx->R14;
dst->r15.u64 = ctx->R15;
dst->rip.u64 = ctx->Rip;
dst->cs.u16 = ctx->SegCs;
dst->ds.u16 = ctx->SegDs;
dst->es.u16 = ctx->SegEs;
dst->fs.u16 = ctx->SegFs;
dst->gs.u16 = ctx->SegGs;
dst->ss.u16 = ctx->SegSs;
dst->dr0.u32 = ctx->Dr0;
dst->dr1.u32 = ctx->Dr1;
dst->dr2.u32 = ctx->Dr2;
dst->dr3.u32 = ctx->Dr3;
dst->dr6.u32 = ctx->Dr6;
dst->dr7.u32 = ctx->Dr7;
// NOTE(allen): This bit is "supposed to always be 1" I guess.
// TODO(allen): Not sure what this is all about but I haven't investigated it yet.
// This might be totally not necessary or something.
dst->rflags.u64 = ctx->EFlags | 0x2;
XSAVE_FORMAT *xsave = &ctx->FltSave;
dst->fcw.u16 = xsave->ControlWord;
dst->fsw.u16 = xsave->StatusWord;
dst->ftw.u16 = test_w32_real_tag_word_from_xsave(xsave);
dst->fop.u16 = xsave->ErrorOpcode;
dst->fcs.u16 = xsave->ErrorSelector;
dst->fds.u16 = xsave->DataSelector;
dst->fip.u32 = xsave->ErrorOffset;
dst->fdp.u32 = xsave->DataOffset;
dst->mxcsr.u32 = xsave->MxCsr;
dst->mxcsr_mask.u32 = xsave->MxCsr_Mask;
M128A *float_s = xsave->FloatRegisters;
SYMS_Reg80 *float_d = &dst->fpr0;
for (U32 n = 0; n < 8; n += 1, float_s += 1, float_d += 1){
MemoryCopy(float_d, float_s, sizeof(*float_d));
}
if (!avx_available){
M128A *xmm_s = xsave->XmmRegisters;
SYMS_Reg256 *xmm_d = &dst->ymm0;
for (U32 n = 0; n < 16; n += 1, xmm_s += 1, xmm_d += 1){
MemoryCopy(xmm_d, xmm_s, sizeof(*xmm_s));
}
}
if (avx_available){
DWORD part0_length = 0;
M128A *part0 = (M128A*)LocateXStateFeature(ctx, XSTATE_LEGACY_SSE, &part0_length);
DWORD part1_length = 0;
M128A *part1 = (M128A*)LocateXStateFeature(ctx, XSTATE_AVX, &part1_length);
Assert(part0_length == part1_length);
DWORD count = part0_length/sizeof(part0[0]);
count = ClampTop(count, 16);
SYMS_Reg256 *ymm_d = &dst->ymm0;
for (DWORD i = 0;
i < count;
i += 1, part0 += 1, part1 += 1, ymm_d += 1){
// TODO(allen): Are we writing these out in the right order? Seems weird right?
ymm_d->u64[3] = part0->Low;
ymm_d->u64[2] = part0->High;
ymm_d->u64[1] = part1->Low;
ymm_d->u64[0] = part1->High;
}
}
}
scratch_end(scratch);
return(result);
}
internal B32
test_w32_write_x64_regs(HANDLE thread, SYMS_RegX64 *src)
{
Temp scratch = scratch_begin(0, 0);
// NOTE(allen): Check available features
U32 feature_mask = GetEnabledXStateFeatures();
B32 avx_enabled = !!(feature_mask & XSTATE_MASK_AVX);
// NOTE(allen): Setup the context
CONTEXT *ctx = 0;
U32 ctx_flags = DEMON_W32_CTX_X64_ALL;
if (avx_enabled){
ctx_flags |= DEMON_W32_CTX_INTEL_XSTATE;
}
DWORD size = 0;
InitializeContext(0, ctx_flags, 0, &size);
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){
void *ctx_memory = push_array(scratch.arena, U8, size);
if (!InitializeContext(ctx_memory, ctx_flags, &ctx, &size)){
ctx = 0;
}
}
B32 avx_available = false;
if (ctx != 0){
// NOTE(allen): Finish Context Setup
if (avx_enabled){
SetXStateFeaturesMask(ctx, XSTATE_MASK_AVX);
}
// NOTE(allen): Determine what features are available on this particular ctx
// TODO(allen): Experiment carefully with this nonsense.
// Does avx_enabled = avx_available in all circumstances or not?
DWORD64 xstate_flags = 0;
if (GetXStateFeaturesMask(ctx, &xstate_flags)){
if (xstate_flags & XSTATE_MASK_AVX){
avx_available = true;
}
}
}
B32 result = false;
if (ctx != 0){
// NOTE(allen): Convert SYMS_RegX64 -> CONTEXT
ctx->ContextFlags = ctx_flags;
ctx->MxCsr = src->mxcsr.u32 & src->mxcsr_mask.u32;
ctx->Rax = src->rax.u64;
ctx->Rcx = src->rcx.u64;
ctx->Rdx = src->rdx.u64;
ctx->Rbx = src->rbx.u64;
ctx->Rsp = src->rsp.u64;
ctx->Rbp = src->rbp.u64;
ctx->Rsi = src->rsi.u64;
ctx->Rdi = src->rdi.u64;
ctx->R8 = src->r8.u64;
ctx->R9 = src->r9.u64;
ctx->R10 = src->r10.u64;
ctx->R11 = src->r11.u64;
ctx->R12 = src->r12.u64;
ctx->R13 = src->r13.u64;
ctx->R14 = src->r14.u64;
ctx->R15 = src->r15.u64;
ctx->Rip = src->rip.u64;
ctx->SegCs = src->cs.u16;
ctx->SegDs = src->ds.u16;
ctx->SegEs = src->es.u16;
ctx->SegFs = src->fs.u16;
ctx->SegGs = src->gs.u16;
ctx->SegSs = src->ss.u16;
ctx->Dr0 = src->dr0.u32;
ctx->Dr1 = src->dr1.u32;
ctx->Dr2 = src->dr2.u32;
ctx->Dr3 = src->dr3.u32;
ctx->Dr6 = src->dr6.u32;
ctx->Dr7 = src->dr7.u32;
ctx->EFlags = src->rflags.u64;
XSAVE_FORMAT *fxsave = &ctx->FltSave;
fxsave->ControlWord = src->fcw.u16;
fxsave->StatusWord = src->fsw.u16;
fxsave->TagWord = test_w32_xsave_tag_word_from_real_tag_word(src->ftw.u16);
fxsave->ErrorOpcode = src->fop.u16;
fxsave->ErrorSelector = src->fcs.u16;
fxsave->DataSelector = src->fds.u16;
fxsave->ErrorOffset = src->fip.u32;
fxsave->DataOffset = src->fdp.u32;
M128A *float_d = fxsave->FloatRegisters;
SYMS_Reg80 *float_s = &src->fpr0;
for (U32 n = 0;
n < 8;
n += 1, float_s += 1, float_d += 1){
MemoryCopy(float_d, float_s, 10);
}
if (!avx_available){
M128A *xmm_d = fxsave->XmmRegisters;
SYMS_Reg256 *xmm_s = &src->ymm0;
for (U32 n = 0;
n < 8;
n += 1, xmm_d += 1, xmm_s += 1){
MemoryCopy(xmm_d, xmm_s, sizeof(*xmm_d));
}
}
if (avx_available){
DWORD part0_length = 0;
M128A *part0 = (M128A*)LocateXStateFeature(ctx, XSTATE_LEGACY_SSE, &part0_length);
DWORD part1_length = 0;
M128A *part1 = (M128A*)LocateXStateFeature(ctx, XSTATE_AVX, &part1_length);
Assert(part0_length == part1_length);
DWORD count = part0_length/sizeof(part0[0]);
count = ClampTop(count, 16);
SYMS_Reg256 *ymm_d = &src->ymm0;
for (DWORD i = 0;
i < count;
i += 1, part0 += 1, part1 += 1, ymm_d += 1){
// TODO(allen): Are we writing these out in the right order? Seems weird right?
part0->Low = ymm_d->u64[3];
part0->High = ymm_d->u64[2];
part1->Low = ymm_d->u64[1];
part1->High = ymm_d->u64[0];
}
}
//- set thread context
HANDLE thread_handle = thread;
if (SetThreadContext(thread_handle, ctx)){
result = true;
}
}
scratch_end(scratch);
return(result);
}
internal B32
test_w32_read_memory(HANDLE process_handle, void *dst, U64 src_address, U64 size)
{
B32 result = true;
U8 *ptr = (U8*)dst;
U8 *opl = ptr + size;
U64 cursor = src_address;
for (;ptr < opl;){
SIZE_T to_read = (SIZE_T)(opl - ptr);
SIZE_T actual_read = 0;
if (!ReadProcessMemory(process_handle, (LPCVOID)cursor, ptr, to_read, &actual_read)){
result = false;
break;
}
ptr += actual_read;
cursor += actual_read;
}
return(result);
}
internal B32
test_w32_write_memory(HANDLE process_handle, U64 dst_address, void *src, U64 size)
{
B32 result = true;
U8 *ptr = (U8*)src;
U8 *opl = ptr + size;
U64 cursor = dst_address;
for (;ptr < opl;){
SIZE_T to_write = (SIZE_T)(opl - ptr);
SIZE_T actual_write = 0;
if (!WriteProcessMemory(process_handle, (LPVOID)cursor, ptr, to_write, &actual_write)){
result = false;
break;
}
ptr += actual_write;
cursor += actual_write;
}
return(result);
}
internal B32
test_launch_process(OS_LaunchOptions *options)
{
B32 result = false;
Temp scratch = scratch_begin(0, 0);
StringJoin join_params = {0};
join_params.pre = str8_lit("\"");
join_params.sep = str8_lit("\" \"");
join_params.post = str8_lit("\"");
String8 cmd = str8_list_join(scratch.arena, &options->cmd_line, &join_params);
StringJoin join_params2 = {0};
join_params2.sep = str8_lit("\0");
join_params2.post = str8_lit("\0");
String8 env = str8_list_join(scratch.arena, &options->env, &join_params2);
String16 cmd16 = str16_from_8(scratch.arena, cmd);
String16 dir16 = str16_from_8(scratch.arena, options->path);
String16 env16 = str16_from_8(scratch.arena, env);
DWORD access_flags = PROCESS_QUERY_INFORMATION | DEBUG_PROCESS | PROCESS_VM_READ | PROCESS_VM_WRITE;
STARTUPINFOW startup_info = {sizeof(startup_info)};
PROCESS_INFORMATION process_info = {0};
if (CreateProcessW(0, (WCHAR*)cmd16.str, 0, 0, 0, access_flags, (WCHAR*)env16.str, (WCHAR*)dir16.str,
&startup_info, &process_info))
{
CloseHandle(process_info.hProcess);
CloseHandle(process_info.hThread);
result = true;
}
scratch_end(scratch);
return(result);
}
global HANDLE g_process_1 = 0;
global DWORD g_process_id_1 = 0;
global U64 g_process_injection_addr_1 = 0;
global HANDLE g_process_2 = 0;
global DWORD g_process_id_2 = 0;
internal B32
test_w32_inject_thread(HANDLE process, U64 start_address)
{
B32 result = false;
LPTHREAD_START_ROUTINE start = (LPTHREAD_START_ROUTINE)start_address;
HANDLE thread = CreateRemoteThread(process, 0, 0, start, 0, 0, 0);
if(thread != 0)
{
CloseHandle(thread);
result = true;
}
return result;
}
internal void
test_halt(void)
{
test_w32_inject_thread(g_process_1, g_process_injection_addr_1);
}
internal TEST_DebugEvent
test_run_process(HANDLE step_thread, HANDLE suspend_thread, U64 traps_count, TEST_Trap *traps)
{
Temp scratch = scratch_begin(0, 0);
TEST_DebugEvent result = {0};
//- rjf: freeze thread
if(suspend_thread)
{
DWORD result = SuspendThread(suspend_thread);
DWORD error = GetLastError();
int x = 0;
}
//- rjf: write traps
U8 *trap_swap_bytes = push_array_no_zero(scratch.arena, U8, traps_count);
{
TEST_Trap *trap = traps;
for(U64 i = 0; i < traps_count; i += 1, trap += 1)
{
if(test_w32_read_memory(trap->process, trap_swap_bytes + i, trap->address, 1))
{
U8 int3 = 0xCC;
test_w32_write_memory(trap->process, trap->address, &int3, 1);
}
else
{
trap_swap_bytes[i] = 0xCC;
}
}
}
//- rjf: set single step bit
if(step_thread != 0)
{
SYMS_RegX64 regs = {0};
test_w32_read_x64_regs(step_thread, &regs);
regs.rflags.u64 |= 0x100;
test_w32_write_x64_regs(step_thread, &regs);
}
//- rjf: continue
local_persist B32 need_resume = 0;
local_persist DWORD resume_pid = 0;
local_persist DWORD resume_tid = 0;
if(need_resume)
{
need_resume = 0;
ContinueDebugEvent(resume_pid, resume_tid, DBG_CONTINUE);
}
//- rjf: get event
DEBUG_EVENT evt = {0};
if(WaitForDebugEvent(&evt, INFINITE))
{
need_resume = 1;
resume_pid = evt.dwProcessId;
resume_tid = evt.dwThreadId;
result.evt = evt;
switch(evt.dwDebugEventCode)
{
default:break;
case CREATE_PROCESS_DEBUG_EVENT:
{
result.name = str8_lit("create process");
result.process_id = evt.dwProcessId;
result.process = evt.u.CreateProcessInfo.hProcess;
result.thread_id = evt.dwThreadId;
result.thread = evt.u.CreateProcessInfo.hThread;
if(g_process_1 == 0)
{
g_process_1 = result.process;
g_process_id_1 = result.process_id;
// injection memory
{
U8 injection_code[64];
injection_code[0] = 0xCC;
injection_code[1] = 0xC3;
for (U64 i = 2; i < 64; i += 1){
injection_code[i] = 0xCC;
}
U64 injection_size = 64;
U64 injection_address = (U64)VirtualAllocEx(g_process_1, 0, injection_size, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE);
test_w32_write_memory(g_process_1, injection_address, injection_code, sizeof(injection_code));
g_process_injection_addr_1 = injection_address;
}
}
else
{
g_process_2 = result.process;
g_process_id_2 = result.process_id;
}
}break;
case EXIT_PROCESS_DEBUG_EVENT:
{
result.name = str8_lit("exit process");
result.process_id = evt.dwProcessId;
}break;
case CREATE_THREAD_DEBUG_EVENT:
{
result.name = str8_lit("create thread");
result.thread_id = evt.dwThreadId;
result.thread = evt.u.CreateThread.hThread;
}break;
case EXIT_THREAD_DEBUG_EVENT:
{
result.name = str8_lit("exit thread");
result.thread_id = evt.dwThreadId;
}break;
case LOAD_DLL_DEBUG_EVENT:
{
result.name = str8_lit("load dll");
}break;
case UNLOAD_DLL_DEBUG_EVENT:
{
result.name = str8_lit("unload dll");
}break;
case EXCEPTION_DEBUG_EVENT:
{
result.name = str8_lit("exception");
EXCEPTION_DEBUG_INFO *edi = &evt.u.Exception;
EXCEPTION_RECORD *exception = &edi->ExceptionRecord;
switch(exception->ExceptionCode)
{
case DEMON_W32_EXCEPTION_BREAKPOINT:
{
result.name = str8_lit("breakpoint");
result.addr = (U64)exception->ExceptionAddress;
}break;
case DEMON_W32_EXCEPTION_SINGLE_STEP:
{
result.name = str8_lit("single_step");
}break;
case DEMON_W32_EXCEPTION_THROW:
{
result.name = str8_lit("exception throw");
}break;
case DEMON_W32_EXCEPTION_ACCESS_VIOLATION:
case DEMON_W32_EXCEPTION_IN_PAGE_ERROR:
{
result.name = str8_lit("exception access violation");
}break;
default:
{
}break;
}
}break;
case OUTPUT_DEBUG_STRING_EVENT:
{
Temp scratch = scratch_begin(0, 0);
result.name = str8_lit("output debug string");
U64 string_address = (U64)evt.u.DebugString.lpDebugStringData;
U64 string_size = (U64)evt.u.DebugString.nDebugStringLength;
// TODO(allen): is the string in UTF-8 or UTF-16?
U8 *buffer = push_array_no_zero(scratch.arena, U8, string_size + 1);
test_w32_read_memory(g_process_id_1 == evt.dwProcessId ? g_process_1 : g_process_2, buffer, string_address, string_size);
buffer[string_size] = 0;
printf("%s\n", buffer);
scratch_end(scratch);
}break;
case RIP_EVENT:
{
result.name = str8_lit("rip event");
}break;
}
}
//- rjf: set single step bit
if(step_thread != 0)
{
SYMS_RegX64 regs = {0};
test_w32_read_x64_regs(step_thread, &regs);
regs.rflags.u64 &= ~0x100;
test_w32_write_x64_regs(step_thread, &regs);
}
//- rjf: unset traps
{
TEST_Trap *trap = traps;
for(U64 i = 0; i < traps_count; i += 1, trap += 1)
{
U8 og_byte = trap_swap_bytes[i];
if(og_byte != 0xCC)
{
test_w32_write_memory(trap->process, trap->address, &og_byte, 1);
}
}
}
//- rjf: resume thread
if(suspend_thread)
{
ResumeThread(suspend_thread);
}
scratch_end(scratch);
return result;
}
internal DWORD
test_halter_thread(void *params)
{
HANDLE original_process_handle = params;
Sleep(1500);
test_halt();
#if 0
DWORD process_id = GetProcessId(original_process_handle);
HANDLE elevated_process_handle = OpenProcess(PROCESS_SUSPEND_RESUME, 0, process_id);
LONG result = NtSuspendProcess(elevated_process_handle);
CloseHandle(elevated_process_handle);
DebugBreakProcess(process);
#endif
return 0;
}
int
main(int argument_count, char **arguments)
{
os_init(argument_count, arguments);
Arena *arena = arena_alloc();
NtSuspendProcess = (NtSuspendProcessFunction *)GetProcAddress(GetModuleHandle("ntdll"), "NtSuspendProcess");
// rjf: launch
{
OS_LaunchOptions opts = {0};
opts.path = os_get_path(arena, OS_SystemPath_Current);
str8_list_push(arena, &opts.cmd_line, str8_lit("R:\\projects\\debugger\\build\\mule_loop.exe"));
B32 launch_good = test_launch_process(&opts);
int x = 0;
}
// rjf: get process/thread handles
HANDLE process = 0;
HANDLE thread1 = 0;
U64 thread1_id = 0;
{
for(TEST_DebugEvent evt = {0};;)
{
evt = test_run_process(0, 0, 0, 0);
if(evt.process)
{
process = evt.process;
}
if(evt.thread)
{
thread1 = evt.thread;
thread1_id = evt.thread_id;
}
if(process != 0 && thread1 != 0)
{
break;
}
}
}
// rjf: get first breakpoint
{
for(TEST_DebugEvent evt = {0};;)
{
evt = test_run_process(0, 0, 0, 0);
if(evt.evt.dwDebugEventCode == EXCEPTION_DEBUG_EVENT)
{
break;
}
}
}
// rjf: launch halter thread
DWORD halter_id = 0;
{
CreateThread(0, 0, test_halter_thread, process, 0, &halter_id);
}
// rjf: run + wait for event
for(;;)
{
TEST_DebugEvent evt = test_run_process(0, 0, 0, 0);
int x = 0;
}
#if 0
//- rjf: run until 2nd thread starts up
HANDLE thread2 = 0;
U64 thread2_id = 0;
{
for(TEST_DebugEvent evt = {0};;)
{
evt = test_run_process(0, 0, 0, 0/*ArrayCount(traps), traps*/);
if(evt.thread)
{
thread2 = evt.thread;
thread2_id = evt.thread_id;
break;
}
}
}
//- rjf: wait for first output string
{
for(TEST_DebugEvent evt = {0};;)
{
evt = test_run_process(0, 0, 0, 0);
if(evt.evt.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT)
{
break;
}
}
}
//- rjf: wait for bps
{
// U64 thread1_stop_vaddr = 0x0000000140001119;
// U64 thread2_stop_vaddr = 0x00000001400010C8;
// TEST_Trap traps[] =
{
// {process, thread1_stop_vaddr},
//{process, thread2_stop_vaddr},
};
TEST_DebugEvent evt = {0};
//for(;;)
{
evt = test_run_process(0, thread2, 0, 0/*ArrayCount(traps), traps*/);
int x = 0;
}
for(;;) {}
}
#endif
}
-874
View File
@@ -1,874 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#include <windows.h>
#include "base/base_inc.h"
#include "os/os_inc.h"
#include "syms_helpers/syms_internal_overrides.h"
#include "syms/syms_inc.h"
#include "syms_helpers/syms_helpers.h"
#include "base/base_inc.c"
#include "os/os_inc.c"
#include "syms_helpers/syms_internal_overrides.c"
#include "syms/syms_inc.c"
#include "syms_helpers/syms_helpers.c"
////////////////////////////////
// NOTE(allen): Win32 Demon Exceptions
#define DEMON_W32_EXCEPTION_BREAKPOINT 0x80000003u
#define DEMON_W32_EXCEPTION_SINGLE_STEP 0x80000004u
#define DEMON_W32_EXCEPTION_LONG_JUMP 0x80000026u
#define DEMON_W32_EXCEPTION_ACCESS_VIOLATION 0xC0000005u
#define DEMON_W32_EXCEPTION_ARRAY_BOUNDS_EXCEEDED 0xC000008Cu
#define DEMON_W32_EXCEPTION_DATA_TYPE_MISALIGNMENT 0x80000002u
#define DEMON_W32_EXCEPTION_GUARD_PAGE_VIOLATION 0x80000001u
#define DEMON_W32_EXCEPTION_FLT_DENORMAL_OPERAND 0xC000008Du
#define DEMON_W32_EXCEPTION_FLT_DEVIDE_BY_ZERO 0xC000008Eu
#define DEMON_W32_EXCEPTION_FLT_INEXACT_RESULT 0xC000008Fu
#define DEMON_W32_EXCEPTION_FLT_INVALID_OPERATION 0xC0000090u
#define DEMON_W32_EXCEPTION_FLT_OVERFLOW 0xC0000091u
#define DEMON_W32_EXCEPTION_FLT_STACK_CHECK 0xC0000092u
#define DEMON_W32_EXCEPTION_FLT_UNDERFLOW 0xC0000093u
#define DEMON_W32_EXCEPTION_INT_DIVIDE_BY_ZERO 0xC0000094u
#define DEMON_W32_EXCEPTION_INT_OVERFLOW 0xC0000095u
#define DEMON_W32_EXCEPTION_PRIVILEGED_INSTRUCTION 0xC0000096u
#define DEMON_W32_EXCEPTION_ILLEGAL_INSTRUCTION 0xC000001Du
#define DEMON_W32_EXCEPTION_IN_PAGE_ERROR 0xC0000006u
#define DEMON_W32_EXCEPTION_INVALID_DISPOSITION 0xC0000026u
#define DEMON_W32_EXCEPTION_NONCONTINUABLE 0xC0000025u
#define DEMON_W32_EXCEPTION_STACK_OVERFLOW 0xC00000FDu
#define DEMON_W32_EXCEPTION_INVALID_HANDLE 0xC0000008u
#define DEMON_W32_EXCEPTION_UNWIND_CONSOLIDATE 0x80000029u
#define DEMON_W32_EXCEPTION_DLL_NOT_FOUND 0xC0000135u
#define DEMON_W32_EXCEPTION_ORDINAL_NOT_FOUND 0xC0000138u
#define DEMON_W32_EXCEPTION_ENTRY_POINT_NOT_FOUND 0xC0000139u
#define DEMON_W32_EXCEPTION_DLL_INIT_FAILED 0xC0000142u
#define DEMON_W32_EXCEPTION_CONTROL_C_EXIT 0xC000013Au
#define DEMON_W32_EXCEPTION_FLT_MULTIPLE_FAULTS 0xC00002B4u
#define DEMON_W32_EXCEPTION_FLT_MULTIPLE_TRAPS 0xC00002B5u
#define DEMON_W32_EXCEPTION_NAT_CONSUMPTION 0xC00002C9u
#define DEMON_W32_EXCEPTION_HEAP_CORRUPTION 0xC0000374u
#define DEMON_W32_EXCEPTION_STACK_BUFFER_OVERRUN 0xC0000409u
#define DEMON_W32_EXCEPTION_INVALID_CRUNTIME_PARAM 0xC0000417u
#define DEMON_W32_EXCEPTION_ASSERT_FAILURE 0xC0000420u
#define DEMON_W32_EXCEPTION_NO_MEMORY 0xC0000017u
#define DEMON_W32_EXCEPTION_THROW 0xE06D7363u
////////////////////////////////
// NOTE(allen): Win32 Demon Register API Codes
#define DEMON_W32_CTX_X86 0x00010000
#define DEMON_W32_CTX_X64 0x00100000
#define DEMON_W32_CTX_INTEL_CONTROL 0x0001
#define DEMON_W32_CTX_INTEL_INTEGER 0x0002
#define DEMON_W32_CTX_INTEL_SEGMENTS 0x0004
#define DEMON_W32_CTX_INTEL_FLOATS 0x0008
#define DEMON_W32_CTX_INTEL_DEBUG 0x0010
#define DEMON_W32_CTX_INTEL_EXTENDED 0x0020
#define DEMON_W32_CTX_INTEL_XSTATE 0x0040
#define DEMON_W32_CTX_X86_ALL (DEMON_W32_CTX_X86 | \
DEMON_W32_CTX_INTEL_CONTROL | DEMON_W32_CTX_INTEL_INTEGER | \
DEMON_W32_CTX_INTEL_SEGMENTS | DEMON_W32_CTX_INTEL_DEBUG | \
DEMON_W32_CTX_INTEL_EXTENDED)
#define DEMON_W32_CTX_X64_ALL (DEMON_W32_CTX_X64 | \
DEMON_W32_CTX_INTEL_CONTROL | DEMON_W32_CTX_INTEL_INTEGER | \
DEMON_W32_CTX_INTEL_SEGMENTS | DEMON_W32_CTX_INTEL_FLOATS | \
DEMON_W32_CTX_INTEL_DEBUG)
struct TEST_DebugEvent
{
String8 name;
U64 process_id;
U64 thread_id;
HANDLE process;
HANDLE thread;
U64 addr;
DEBUG_EVENT evt;
};
struct TEST_Trap
{
HANDLE process;
U64 address;
};
internal U16
test_w32_real_tag_word_from_xsave(XSAVE_FORMAT *fxsave)
{
U16 result = 0;
U32 top = (fxsave->StatusWord >> 11) & 7;
for (U32 fpr = 0; fpr < 8; fpr += 1){
U32 tag = 3;
if (fxsave->TagWord & (1 << fpr)){
U32 st = (fpr - top)&7;
SYMS_Reg80 *fp = (SYMS_Reg80*)&fxsave->FloatRegisters[st*16];
U16 exponent = fp->sign1_exp15 & bitmask15;
U64 integer_part = fp->int1_frac63 >> 63;
U64 fraction_part = fp->int1_frac63 & bitmask63;
// tag: 0 - normal; 1 - zero; 2 - special
tag = 2;
if (exponent == 0){
if (integer_part == 0 && fraction_part == 0){
tag = 1;
}
}
else if (exponent != bitmask15 && integer_part != 0){
tag = 0;
}
}
result |= tag << (2 * fpr);
}
return(result);
}
internal U16
test_w32_xsave_tag_word_from_real_tag_word(U16 ftw)
{
U16 compact = 0;
for (U32 fpr = 0; fpr < 8; fpr++){
U32 tag = (ftw >> (fpr * 2)) & 3;
if (tag != 3){
compact |= (1 << fpr);
}
}
return(compact);
}
internal B32
test_w32_read_x64_regs(HANDLE thread, SYMS_RegX64 *dst)
{
Temp scratch = scratch_begin(0, 0);
// NOTE(allen): Check available features
U32 feature_mask = GetEnabledXStateFeatures();
B32 avx_enabled = !!(feature_mask & XSTATE_MASK_AVX);
// NOTE(allen): Setup the context
CONTEXT *ctx = 0;
U32 ctx_flags = DEMON_W32_CTX_X64_ALL;
if (avx_enabled){
ctx_flags |= DEMON_W32_CTX_INTEL_XSTATE;
}
DWORD size = 0;
InitializeContext(0, ctx_flags, 0, &size);
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){
void *ctx_memory = push_array(scratch.arena, U8, size);
if (!InitializeContext(ctx_memory, ctx_flags, &ctx, &size)){
ctx = 0;
}
}
B32 avx_available = false;
if (ctx != 0){
// NOTE(allen): Finish Context Setup
if (avx_enabled){
SetXStateFeaturesMask(ctx, XSTATE_MASK_AVX);
}
// NOTE(allen): Determine what features are available on this particular ctx
// TODO(allen): Experiment carefully with this nonsense.
// Does avx_enabled = avx_available in all circumstances or not?
DWORD64 xstate_flags = 0;
if (GetXStateFeaturesMask(ctx, &xstate_flags)){
if (xstate_flags & XSTATE_MASK_AVX){
avx_available = true;
}
}
}
// get thread context
HANDLE thread_handle = thread;
if (!GetThreadContext(thread_handle, ctx)){
ctx = 0;
}
B32 result = false;
if (ctx != 0){
result = true;
// NOTE(allen): Convert CONTEXT -> SYMS_RegX64
dst->rax.u64 = ctx->Rax;
dst->rcx.u64 = ctx->Rcx;
dst->rdx.u64 = ctx->Rdx;
dst->rbx.u64 = ctx->Rbx;
dst->rsp.u64 = ctx->Rsp;
dst->rbp.u64 = ctx->Rbp;
dst->rsi.u64 = ctx->Rsi;
dst->rdi.u64 = ctx->Rdi;
dst->r8.u64 = ctx->R8;
dst->r9.u64 = ctx->R9;
dst->r10.u64 = ctx->R10;
dst->r11.u64 = ctx->R11;
dst->r12.u64 = ctx->R12;
dst->r13.u64 = ctx->R13;
dst->r14.u64 = ctx->R14;
dst->r15.u64 = ctx->R15;
dst->rip.u64 = ctx->Rip;
dst->cs.u16 = ctx->SegCs;
dst->ds.u16 = ctx->SegDs;
dst->es.u16 = ctx->SegEs;
dst->fs.u16 = ctx->SegFs;
dst->gs.u16 = ctx->SegGs;
dst->ss.u16 = ctx->SegSs;
dst->dr0.u32 = ctx->Dr0;
dst->dr1.u32 = ctx->Dr1;
dst->dr2.u32 = ctx->Dr2;
dst->dr3.u32 = ctx->Dr3;
dst->dr6.u32 = ctx->Dr6;
dst->dr7.u32 = ctx->Dr7;
// NOTE(allen): This bit is "supposed to always be 1" I guess.
// TODO(allen): Not sure what this is all about but I haven't investigated it yet.
// This might be totally not necessary or something.
dst->rflags.u64 = ctx->EFlags | 0x2;
XSAVE_FORMAT *xsave = &ctx->FltSave;
dst->fcw.u16 = xsave->ControlWord;
dst->fsw.u16 = xsave->StatusWord;
dst->ftw.u16 = test_w32_real_tag_word_from_xsave(xsave);
dst->fop.u16 = xsave->ErrorOpcode;
dst->fcs.u16 = xsave->ErrorSelector;
dst->fds.u16 = xsave->DataSelector;
dst->fip.u32 = xsave->ErrorOffset;
dst->fdp.u32 = xsave->DataOffset;
dst->mxcsr.u32 = xsave->MxCsr;
dst->mxcsr_mask.u32 = xsave->MxCsr_Mask;
M128A *float_s = xsave->FloatRegisters;
SYMS_Reg80 *float_d = &dst->fpr0;
for (U32 n = 0; n < 8; n += 1, float_s += 1, float_d += 1){
MemoryCopy(float_d, float_s, sizeof(*float_d));
}
if (!avx_available){
M128A *xmm_s = xsave->XmmRegisters;
SYMS_Reg256 *xmm_d = &dst->ymm0;
for (U32 n = 0; n < 16; n += 1, xmm_s += 1, xmm_d += 1){
MemoryCopy(xmm_d, xmm_s, sizeof(*xmm_s));
}
}
if (avx_available){
DWORD part0_length = 0;
M128A *part0 = (M128A*)LocateXStateFeature(ctx, XSTATE_LEGACY_SSE, &part0_length);
DWORD part1_length = 0;
M128A *part1 = (M128A*)LocateXStateFeature(ctx, XSTATE_AVX, &part1_length);
Assert(part0_length == part1_length);
DWORD count = part0_length/sizeof(part0[0]);
count = ClampTop(count, 16);
SYMS_Reg256 *ymm_d = &dst->ymm0;
for (DWORD i = 0;
i < count;
i += 1, part0 += 1, part1 += 1, ymm_d += 1){
// TODO(allen): Are we writing these out in the right order? Seems weird right?
ymm_d->u64[3] = part0->Low;
ymm_d->u64[2] = part0->High;
ymm_d->u64[1] = part1->Low;
ymm_d->u64[0] = part1->High;
}
}
}
scratch_end(scratch);
return(result);
}
internal B32
test_w32_write_x64_regs(HANDLE thread, SYMS_RegX64 *src)
{
Temp scratch = scratch_begin(0, 0);
// NOTE(allen): Check available features
U32 feature_mask = GetEnabledXStateFeatures();
B32 avx_enabled = !!(feature_mask & XSTATE_MASK_AVX);
// NOTE(allen): Setup the context
CONTEXT *ctx = 0;
U32 ctx_flags = DEMON_W32_CTX_X64_ALL;
if (avx_enabled){
ctx_flags |= DEMON_W32_CTX_INTEL_XSTATE;
}
DWORD size = 0;
InitializeContext(0, ctx_flags, 0, &size);
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){
void *ctx_memory = push_array(scratch.arena, U8, size);
if (!InitializeContext(ctx_memory, ctx_flags, &ctx, &size)){
ctx = 0;
}
}
B32 avx_available = false;
if (ctx != 0){
// NOTE(allen): Finish Context Setup
if (avx_enabled){
SetXStateFeaturesMask(ctx, XSTATE_MASK_AVX);
}
// NOTE(allen): Determine what features are available on this particular ctx
// TODO(allen): Experiment carefully with this nonsense.
// Does avx_enabled = avx_available in all circumstances or not?
DWORD64 xstate_flags = 0;
if (GetXStateFeaturesMask(ctx, &xstate_flags)){
if (xstate_flags & XSTATE_MASK_AVX){
avx_available = true;
}
}
}
B32 result = false;
if (ctx != 0){
// NOTE(allen): Convert SYMS_RegX64 -> CONTEXT
ctx->ContextFlags = ctx_flags;
ctx->MxCsr = src->mxcsr.u32 & src->mxcsr_mask.u32;
ctx->Rax = src->rax.u64;
ctx->Rcx = src->rcx.u64;
ctx->Rdx = src->rdx.u64;
ctx->Rbx = src->rbx.u64;
ctx->Rsp = src->rsp.u64;
ctx->Rbp = src->rbp.u64;
ctx->Rsi = src->rsi.u64;
ctx->Rdi = src->rdi.u64;
ctx->R8 = src->r8.u64;
ctx->R9 = src->r9.u64;
ctx->R10 = src->r10.u64;
ctx->R11 = src->r11.u64;
ctx->R12 = src->r12.u64;
ctx->R13 = src->r13.u64;
ctx->R14 = src->r14.u64;
ctx->R15 = src->r15.u64;
ctx->Rip = src->rip.u64;
ctx->SegCs = src->cs.u16;
ctx->SegDs = src->ds.u16;
ctx->SegEs = src->es.u16;
ctx->SegFs = src->fs.u16;
ctx->SegGs = src->gs.u16;
ctx->SegSs = src->ss.u16;
ctx->Dr0 = src->dr0.u32;
ctx->Dr1 = src->dr1.u32;
ctx->Dr2 = src->dr2.u32;
ctx->Dr3 = src->dr3.u32;
ctx->Dr6 = src->dr6.u32;
ctx->Dr7 = src->dr7.u32;
ctx->EFlags = src->rflags.u64;
XSAVE_FORMAT *fxsave = &ctx->FltSave;
fxsave->ControlWord = src->fcw.u16;
fxsave->StatusWord = src->fsw.u16;
fxsave->TagWord = test_w32_xsave_tag_word_from_real_tag_word(src->ftw.u16);
fxsave->ErrorOpcode = src->fop.u16;
fxsave->ErrorSelector = src->fcs.u16;
fxsave->DataSelector = src->fds.u16;
fxsave->ErrorOffset = src->fip.u32;
fxsave->DataOffset = src->fdp.u32;
M128A *float_d = fxsave->FloatRegisters;
SYMS_Reg80 *float_s = &src->fpr0;
for (U32 n = 0;
n < 8;
n += 1, float_s += 1, float_d += 1){
MemoryCopy(float_d, float_s, 10);
}
if (!avx_available){
M128A *xmm_d = fxsave->XmmRegisters;
SYMS_Reg256 *xmm_s = &src->ymm0;
for (U32 n = 0;
n < 8;
n += 1, xmm_d += 1, xmm_s += 1){
MemoryCopy(xmm_d, xmm_s, sizeof(*xmm_d));
}
}
if (avx_available){
DWORD part0_length = 0;
M128A *part0 = (M128A*)LocateXStateFeature(ctx, XSTATE_LEGACY_SSE, &part0_length);
DWORD part1_length = 0;
M128A *part1 = (M128A*)LocateXStateFeature(ctx, XSTATE_AVX, &part1_length);
Assert(part0_length == part1_length);
DWORD count = part0_length/sizeof(part0[0]);
count = ClampTop(count, 16);
SYMS_Reg256 *ymm_d = &src->ymm0;
for (DWORD i = 0;
i < count;
i += 1, part0 += 1, part1 += 1, ymm_d += 1){
// TODO(allen): Are we writing these out in the right order? Seems weird right?
part0->Low = ymm_d->u64[3];
part0->High = ymm_d->u64[2];
part1->Low = ymm_d->u64[1];
part1->High = ymm_d->u64[0];
}
}
//- set thread context
HANDLE thread_handle = thread;
if (SetThreadContext(thread_handle, ctx)){
result = true;
}
}
scratch_end(scratch);
return(result);
}
internal B32
test_w32_read_memory(HANDLE process_handle, void *dst, U64 src_address, U64 size)
{
B32 result = true;
U8 *ptr = (U8*)dst;
U8 *opl = ptr + size;
U64 cursor = src_address;
for (;ptr < opl;){
SIZE_T to_read = (SIZE_T)(opl - ptr);
SIZE_T actual_read = 0;
if (!ReadProcessMemory(process_handle, (LPCVOID)cursor, ptr, to_read, &actual_read)){
result = false;
break;
}
ptr += actual_read;
cursor += actual_read;
}
return(result);
}
internal B32
test_w32_write_memory(HANDLE process_handle, U64 dst_address, void *src, U64 size)
{
B32 result = true;
U8 *ptr = (U8*)src;
U8 *opl = ptr + size;
U64 cursor = dst_address;
for (;ptr < opl;){
SIZE_T to_write = (SIZE_T)(opl - ptr);
SIZE_T actual_write = 0;
if (!WriteProcessMemory(process_handle, (LPVOID)cursor, ptr, to_write, &actual_write)){
result = false;
break;
}
ptr += actual_write;
cursor += actual_write;
}
return(result);
}
internal B32
test_launch_process(OS_LaunchOptions *options)
{
B32 result = false;
Temp scratch = scratch_begin(0, 0);
StringJoin join_params = {0};
join_params.pre = str8_lit("\"");
join_params.sep = str8_lit("\" \"");
join_params.post = str8_lit("\"");
String8 cmd = str8_list_join(scratch.arena, &options->cmd_line, &join_params);
StringJoin join_params2 = {0};
join_params2.sep = str8_lit("\0");
join_params2.post = str8_lit("\0");
String8 env = str8_list_join(scratch.arena, &options->env, &join_params2);
String16 cmd16 = str16_from_8(scratch.arena, cmd);
String16 dir16 = str16_from_8(scratch.arena, options->path);
String16 env16 = str16_from_8(scratch.arena, env);
DWORD access_flags = PROCESS_QUERY_INFORMATION | DEBUG_PROCESS | PROCESS_VM_READ | PROCESS_VM_WRITE;
STARTUPINFOW startup_info = {sizeof(startup_info)};
PROCESS_INFORMATION process_info = {0};
if (CreateProcessW(0, (WCHAR*)cmd16.str, 0, 0, 0, access_flags, (WCHAR*)env16.str, (WCHAR*)dir16.str,
&startup_info, &process_info))
{
CloseHandle(process_info.hProcess);
CloseHandle(process_info.hThread);
result = true;
}
scratch_end(scratch);
return(result);
}
global HANDLE g_process = 0;
global DWORD g_process_id = 0;
global HANDLE g_thread1 = 0;
global DWORD g_thread1_id = 0;
global HANDLE g_thread2 = 0;
global DWORD g_thread2_id = 0;
internal TEST_DebugEvent
test_run_process(HANDLE step_thread, HANDLE suspend_thread, U64 traps_count, TEST_Trap *traps)
{
Temp scratch = scratch_begin(0, 0);
TEST_DebugEvent result = {0};
//- rjf: freeze thread
if(suspend_thread)
{
DWORD result = SuspendThread(suspend_thread);
DWORD error = GetLastError();
int x = 0;
}
//- rjf: write traps
U8 *trap_swap_bytes = push_array_no_zero(scratch.arena, U8, traps_count);
{
TEST_Trap *trap = traps;
for(U64 i = 0; i < traps_count; i += 1, trap += 1)
{
if(test_w32_read_memory(trap->process, trap_swap_bytes + i, trap->address, 1))
{
U8 int3 = 0xCC;
test_w32_write_memory(trap->process, trap->address, &int3, 1);
}
else
{
trap_swap_bytes[i] = 0xCC;
}
}
}
//- rjf: set single step bit
if(step_thread != 0)
{
SYMS_RegX64 regs = {0};
test_w32_read_x64_regs(step_thread, &regs);
regs.rflags.u64 |= 0x100;
test_w32_write_x64_regs(step_thread, &regs);
}
//- rjf: continue
local_persist B32 need_resume = 0;
local_persist DWORD resume_pid = 0;
local_persist DWORD resume_tid = 0;
if(need_resume)
{
need_resume = 0;
ContinueDebugEvent(resume_pid, resume_tid, DBG_CONTINUE);
}
//- rjf: get event
DEBUG_EVENT evt = {0};
if(WaitForDebugEvent(&evt, INFINITE))
{
need_resume = 1;
resume_pid = evt.dwProcessId;
resume_tid = evt.dwThreadId;
result.evt = evt;
switch(evt.dwDebugEventCode)
{
default:break;
case CREATE_PROCESS_DEBUG_EVENT:
{
result.name = str8_lit("create process");
result.process_id = evt.dwProcessId;
result.process = evt.u.CreateProcessInfo.hProcess;
result.thread_id = evt.dwThreadId;
result.thread = evt.u.CreateProcessInfo.hThread;
if(g_process == 0)
{
g_process = result.process;
g_process_id = result.process_id;
}
if(g_thread1 == 0)
{
g_thread1 = result.thread;
g_thread1_id = result.thread_id;
}
}break;
case EXIT_PROCESS_DEBUG_EVENT:
{
result.name = str8_lit("exit process");
result.process_id = evt.dwProcessId;
}break;
case CREATE_THREAD_DEBUG_EVENT:
{
result.name = str8_lit("create thread");
result.thread_id = evt.dwThreadId;
result.thread = evt.u.CreateThread.hThread;
g_thread2 = result.thread;
g_thread2_id = result.thread_id;
}break;
case EXIT_THREAD_DEBUG_EVENT:
{
result.name = str8_lit("exit thread");
result.thread_id = evt.dwThreadId;
}break;
case LOAD_DLL_DEBUG_EVENT:
{
result.name = str8_lit("load dll");
}break;
case UNLOAD_DLL_DEBUG_EVENT:
{
result.name = str8_lit("unload dll");
}break;
case EXCEPTION_DEBUG_EVENT:
{
result.name = str8_lit("exception");
EXCEPTION_DEBUG_INFO *edi = &evt.u.Exception;
EXCEPTION_RECORD *exception = &edi->ExceptionRecord;
switch(exception->ExceptionCode)
{
case DEMON_W32_EXCEPTION_BREAKPOINT:
{
result.name = str8_lit("breakpoint");
result.addr = (U64)exception->ExceptionAddress;
local_persist B32 did_first_bp = 0;
if(did_first_bp != 0)
{
HANDLE thread = evt.dwThreadId == g_thread1_id ? g_thread1 : g_thread2;
SYMS_RegX64 regs = {0};
test_w32_read_x64_regs(thread, &regs);
regs.rip.u64 = result.addr;
test_w32_write_x64_regs(thread, &regs);
}
did_first_bp = 1;
}break;
case DEMON_W32_EXCEPTION_SINGLE_STEP:
{
result.name = str8_lit("single_step");
}break;
case DEMON_W32_EXCEPTION_THROW:
{
result.name = str8_lit("exception throw");
}break;
case DEMON_W32_EXCEPTION_ACCESS_VIOLATION:
case DEMON_W32_EXCEPTION_IN_PAGE_ERROR:
{
result.name = str8_lit("exception access violation");
}break;
default:
{
}break;
}
}break;
case OUTPUT_DEBUG_STRING_EVENT:
{
Temp scratch = scratch_begin(0, 0);
result.name = str8_lit("output debug string");
U64 string_address = (U64)evt.u.DebugString.lpDebugStringData;
U64 string_size = (U64)evt.u.DebugString.nDebugStringLength;
// TODO(allen): is the string in UTF-8 or UTF-16?
U8 *buffer = push_array_no_zero(scratch.arena, U8, string_size + 1);
test_w32_read_memory(g_process, buffer, string_address, string_size);
buffer[string_size] = 0;
printf("%s\n", buffer);
scratch_end(scratch);
}break;
case RIP_EVENT:
{
result.name = str8_lit("rip event");
}break;
}
}
//- rjf: set single step bit
if(step_thread != 0)
{
SYMS_RegX64 regs = {0};
test_w32_read_x64_regs(step_thread, &regs);
regs.rflags.u64 &= ~0x100;
test_w32_write_x64_regs(step_thread, &regs);
}
//- rjf: unset traps
{
TEST_Trap *trap = traps;
for(U64 i = 0; i < traps_count; i += 1, trap += 1)
{
U8 og_byte = trap_swap_bytes[i];
if(og_byte != 0xCC)
{
test_w32_write_memory(trap->process, trap->address, &og_byte, 1);
}
}
}
//- rjf: check for more events
for(int i = 0; i < 100; i += 1)
{
DEBUG_EVENT evt = {0};
if(WaitForDebugEvent(&evt, 0))
{
int x = 0;
}
}
//- rjf: resume thread
if(suspend_thread)
{
ResumeThread(suspend_thread);
}
scratch_end(scratch);
return result;
}
int
main(int argument_count, char **arguments)
{
os_init(argument_count, arguments);
Arena *arena = arena_alloc();
U64 before_loop_stop_vaddr = 0x0000000140001089;
U64 inner_loop_stop_vaddr = 0x0000000140001098;
// rjf: launch
{
OS_LaunchOptions opts = {0};
opts.path = os_get_path(arena, OS_SystemPath_Current);
str8_list_push(arena, &opts.cmd_line, str8_lit("R:\\projects\\debugger\\build\\mule_loop_threads_win32.exe"));
B32 launch_good = test_launch_process(&opts);
int x = 0;
}
// rjf: get process/thread handles
HANDLE process = 0;
HANDLE thread1 = 0;
U64 thread1_id = 0;
{
for(TEST_DebugEvent evt = {0};;)
{
evt = test_run_process(0, 0, 0, 0);
if(evt.process)
{
process = evt.process;
}
if(evt.thread)
{
thread1 = evt.thread;
thread1_id = evt.thread_id;
}
if(process != 0 && thread1 != 0)
{
break;
}
}
}
// rjf: get first breakpoint
{
for(TEST_DebugEvent evt = {0};;)
{
evt = test_run_process(0, 0, 0, 0);
if(evt.evt.dwDebugEventCode == EXCEPTION_DEBUG_EVENT)
{
break;
}
}
}
//- rjf: run until 2nd thread starts up
HANDLE thread2 = 0;
U64 thread2_id = 0;
{
TEST_Trap traps[] =
{
{process, before_loop_stop_vaddr},
};
int trap_count = 0; //ArrayCount(traps);
for(TEST_DebugEvent evt = {0};;)
{
evt = test_run_process(0, 0, trap_count, traps);
if(str8_match(evt.name, str8_lit("breakpoint"), 0))
{
trap_count = 0;
}
if(evt.thread)
{
thread2 = evt.thread;
thread2_id = evt.thread_id;
break;
}
}
}
//- rjf: wait for bps
{
Temp scratch = scratch_begin(0, 0);
TEST_Trap traps[] =
{
{process, 0x0000000140001098},
{process, 0x00000001400010fb},
{process, 0x00000001400010bc},
{process, 0x00000001400010d7},
};
for(int i = 0;; i += 1)
{
TEST_DebugEvent evt = test_run_process(0, 0, 1, &traps[i % ArrayCount(traps)]);
// rjf: check regs
{
U64 rip = 0;
SYMS_RegX64 *regs = push_array(scratch.arena, SYMS_RegX64, 1);
if(evt.evt.dwThreadId == g_thread1_id && test_w32_read_x64_regs(thread1, regs))
{
rip = regs->rip.u64;
}
if(evt.evt.dwThreadId == g_thread2_id && test_w32_read_x64_regs(thread2, regs))
{
rip = regs->rip.u64;
}
for(int i = 0; i < ArrayCount(traps); i += 1)
{
if(traps[i].address == rip)
{
printf("WRONG BP! 0x%I64x\n", rip);
break;
}
}
}
if(str8_match(evt.name, str8_lit("breakpoint"), 0))
{
HANDLE step = 0;
HANDLE suspend = 0;
step = evt.evt.dwThreadId == thread2_id ? thread2 : thread1;
suspend = step == thread2 ? thread1 : thread2;
evt = test_run_process(step, suspend, 0, 0);
}
}
scratch_end(scratch);
}
return 0;
}
File diff suppressed because it is too large Load Diff
+287
View File
@@ -0,0 +1,287 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DEMON_CORE_WIN32_H
#define DEMON_CORE_WIN32_H
////////////////////////////////
//~ rjf: Windows Includes
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <psapi.h>
#include <tlhelp32.h>
////////////////////////////////
//~ rjf: Win32 Exception Codes
#define DMN_W32_EXCEPTION_BREAKPOINT 0x80000003u
#define DMN_W32_EXCEPTION_SINGLE_STEP 0x80000004u
#define DMN_W32_EXCEPTION_LONG_JUMP 0x80000026u
#define DMN_W32_EXCEPTION_ACCESS_VIOLATION 0xC0000005u
#define DMN_W32_EXCEPTION_ARRAY_BOUNDS_EXCEEDED 0xC000008Cu
#define DMN_W32_EXCEPTION_DATA_TYPE_MISALIGNMENT 0x80000002u
#define DMN_W32_EXCEPTION_GUARD_PAGE_VIOLATION 0x80000001u
#define DMN_W32_EXCEPTION_FLT_DENORMAL_OPERAND 0xC000008Du
#define DMN_W32_EXCEPTION_FLT_DEVIDE_BY_ZERO 0xC000008Eu
#define DMN_W32_EXCEPTION_FLT_INEXACT_RESULT 0xC000008Fu
#define DMN_W32_EXCEPTION_FLT_INVALID_OPERATION 0xC0000090u
#define DMN_W32_EXCEPTION_FLT_OVERFLOW 0xC0000091u
#define DMN_W32_EXCEPTION_FLT_STACK_CHECK 0xC0000092u
#define DMN_W32_EXCEPTION_FLT_UNDERFLOW 0xC0000093u
#define DMN_W32_EXCEPTION_INT_DIVIDE_BY_ZERO 0xC0000094u
#define DMN_W32_EXCEPTION_INT_OVERFLOW 0xC0000095u
#define DMN_W32_EXCEPTION_PRIVILEGED_INSTRUCTION 0xC0000096u
#define DMN_W32_EXCEPTION_ILLEGAL_INSTRUCTION 0xC000001Du
#define DMN_W32_EXCEPTION_IN_PAGE_ERROR 0xC0000006u
#define DMN_W32_EXCEPTION_INVALID_DISPOSITION 0xC0000026u
#define DMN_W32_EXCEPTION_NONCONTINUABLE 0xC0000025u
#define DMN_W32_EXCEPTION_STACK_OVERFLOW 0xC00000FDu
#define DMN_W32_EXCEPTION_INVALID_HANDLE 0xC0000008u
#define DMN_W32_EXCEPTION_UNWIND_CONSOLIDATE 0x80000029u
#define DMN_W32_EXCEPTION_DLL_NOT_FOUND 0xC0000135u
#define DMN_W32_EXCEPTION_ORDINAL_NOT_FOUND 0xC0000138u
#define DMN_W32_EXCEPTION_ENTRY_POINT_NOT_FOUND 0xC0000139u
#define DMN_W32_EXCEPTION_DLL_INIT_FAILED 0xC0000142u
#define DMN_W32_EXCEPTION_CONTROL_C_EXIT 0xC000013Au
#define DMN_W32_EXCEPTION_FLT_MULTIPLE_FAULTS 0xC00002B4u
#define DMN_W32_EXCEPTION_FLT_MULTIPLE_TRAPS 0xC00002B5u
#define DMN_W32_EXCEPTION_NAT_CONSUMPTION 0xC00002C9u
#define DMN_W32_EXCEPTION_HEAP_CORRUPTION 0xC0000374u
#define DMN_W32_EXCEPTION_STACK_BUFFER_OVERRUN 0xC0000409u
#define DMN_W32_EXCEPTION_INVALID_CRUNTIME_PARAM 0xC0000417u
#define DMN_W32_EXCEPTION_ASSERT_FAILURE 0xC0000420u
#define DMN_W32_EXCEPTION_NO_MEMORY 0xC0000017u
#define DMN_W32_EXCEPTION_THROW 0xE06D7363u
#define DMN_W32_EXCEPTION_SET_THREAD_NAME 0x406d1388u
////////////////////////////////
//~ rjf: Win32 Register Codes
#define DMN_W32_CTX_X86 0x00010000
#define DMN_W32_CTX_X64 0x00100000
#define DMN_W32_CTX_INTEL_CONTROL 0x0001
#define DMN_W32_CTX_INTEL_INTEGER 0x0002
#define DMN_W32_CTX_INTEL_SEGMENTS 0x0004
#define DMN_W32_CTX_INTEL_FLOATS 0x0008
#define DMN_W32_CTX_INTEL_DEBUG 0x0010
#define DMN_W32_CTX_INTEL_EXTENDED 0x0020
#define DMN_W32_CTX_INTEL_XSTATE 0x0040
#define DMN_W32_CTX_X86_ALL (DMN_W32_CTX_X86 | \
DMN_W32_CTX_INTEL_CONTROL | DMN_W32_CTX_INTEL_INTEGER | \
DMN_W32_CTX_INTEL_SEGMENTS | DMN_W32_CTX_INTEL_DEBUG | \
DMN_W32_CTX_INTEL_EXTENDED)
#define DMN_W32_CTX_X64_ALL (DMN_W32_CTX_X64 | \
DMN_W32_CTX_INTEL_CONTROL | DMN_W32_CTX_INTEL_INTEGER | \
DMN_W32_CTX_INTEL_SEGMENTS | DMN_W32_CTX_INTEL_FLOATS | \
DMN_W32_CTX_INTEL_DEBUG)
////////////////////////////////
//~ rjf: Per-Entity State
typedef enum DMN_W32_EntityKind
{
DMN_W32_EntityKind_Null,
DMN_W32_EntityKind_Root,
DMN_W32_EntityKind_Process,
DMN_W32_EntityKind_Thread,
DMN_W32_EntityKind_Module,
DMN_W32_EntityKind_COUNT
}
DMN_W32_EntityKind;
typedef struct DMN_W32_Entity DMN_W32_Entity;
struct DMN_W32_Entity
{
DMN_W32_Entity *first;
DMN_W32_Entity *last;
DMN_W32_Entity *next;
DMN_W32_Entity *prev;
DMN_W32_Entity *parent;
DMN_W32_EntityKind kind;
U32 gen;
U64 id;
HANDLE handle;
Architecture arch;
union
{
struct
{
U64 injection_address;
B32 did_first_bp;
}
proc;
struct
{
U64 thread_local_base;
U64 last_name_hash;
U64 name_gather_time_us;
B32 last_run_reported_trap;
U64 last_run_reported_trap_pre_rip;
U64 last_run_reported_trap_post_rip;
}
thread;
struct
{
Rng1U64 vaddr_range;
U64 address_of_name_pointer;
B32 is_main;
B32 name_is_unicode;
}
module;
};
};
typedef struct DMN_W32_EntityNode DMN_W32_EntityNode;
struct DMN_W32_EntityNode
{
DMN_W32_EntityNode *next;
DMN_W32_Entity *v;
};
typedef struct DMN_W32_EntityIDHashNode DMN_W32_EntityIDHashNode;
struct DMN_W32_EntityIDHashNode
{
DMN_W32_EntityIDHashNode *next;
DMN_W32_EntityIDHashNode *prev;
U64 id;
DMN_W32_Entity *entity;
};
typedef struct DMN_W32_EntityIDHashSlot DMN_W32_EntityIDHashSlot;
struct DMN_W32_EntityIDHashSlot
{
DMN_W32_EntityIDHashNode *first;
DMN_W32_EntityIDHashNode *last;
};
////////////////////////////////
//~ rjf: Injection Types
typedef struct DMN_W32_InjectedBreak DMN_W32_InjectedBreak;
struct DMN_W32_InjectedBreak
{
U64 code;
U64 user_data;
};
#define DMN_W32_INJECTED_CODE_SIZE 32
////////////////////////////////
//~ rjf: Image Info Types
typedef struct DMN_W32_ImageInfo DMN_W32_ImageInfo;
struct DMN_W32_ImageInfo
{
Architecture arch;
U32 size;
};
////////////////////////////////
//~ rjf: Dynamically-Loaded Win32 Function Types
typedef HRESULT DMN_W32_GetThreadDescriptionFunctionType(HANDLE hThread, WCHAR **ppszThreadDescription);
////////////////////////////////
//~ rjf: Shared State Bundle
typedef struct DMN_W32_Shared DMN_W32_Shared;
struct DMN_W32_Shared
{
// rjf: top-level info
Arena *arena;
String8List env_strings;
// rjf: access locking mechanism
OS_Handle access_mutex;
B32 access_run_state;
// rjf: run/mem/reg gens
U64 run_gen;
U64 mem_gen;
U64 reg_gen;
// rjf: detaching info
Arena *detach_arena;
DMN_HandleList detach_processes;
// rjf: entity state
Arena *entities_arena;
DMN_W32_Entity *entities_base;
DMN_W32_Entity *entities_first_free;
U64 entities_count;
DMN_W32_EntityIDHashSlot *entities_id_hash_slots;
U64 entities_id_hash_slots_count;
DMN_W32_EntityIDHashNode *entities_id_hash_node_free;
// rjf: launch state
B32 new_process_pending;
// rjf: run results
B32 resume_needed;
U32 resume_pid;
U32 resume_tid;
B32 exception_not_handled;
// rjf: halting info
DMN_Handle halter_process;
U32 halter_tid;
};
////////////////////////////////
//~ rjf: Globals
global DMN_W32_Shared *dmn_w32_shared = 0;
global DMN_W32_Entity dmn_w32_entity_nil = {&dmn_w32_entity_nil, &dmn_w32_entity_nil, &dmn_w32_entity_nil, &dmn_w32_entity_nil, &dmn_w32_entity_nil};
global DMN_W32_GetThreadDescriptionFunctionType *dmn_w32_GetThreadDescription = 0;
thread_static B32 dmn_w32_ctrl_thread = 0;
////////////////////////////////
//~ rjf: Basic Helpers
internal U64 dmn_w32_hash_from_string(String8 string);
internal U64 dmn_w32_hash_from_id(U64 id);
////////////////////////////////
//~ rjf: Entity Helpers
//- rjf: entity <-> handle
internal DMN_Handle dmn_w32_handle_from_entity(DMN_W32_Entity *entity);
internal DMN_W32_Entity *dmn_w32_entity_from_handle(DMN_Handle handle);
//- rjf: entity allocation/deallocation
internal DMN_W32_Entity *dmn_w32_entity_alloc(DMN_W32_Entity *parent, DMN_W32_EntityKind kind, U64 id);
internal void dmn_w32_entity_release(DMN_W32_Entity *entity);
//- rjf: kind*id -> entity
internal DMN_W32_Entity *dmn_w32_entity_from_kind_id(DMN_W32_EntityKind kind, U64 id);
////////////////////////////////
//~ rjf: Module Info Extraction
internal String8 dmn_w32_full_path_from_module(Arena *arena, DMN_W32_Entity *module);
////////////////////////////////
//~ rjf: Win32-Level Process/Thread Reads/Writes
//- rjf: processes
internal U64 dmn_w32_process_read(HANDLE process, Rng1U64 range, void *dst);
internal B32 dmn_w32_process_write(HANDLE process, Rng1U64 range, void *src);
internal String8 dmn_w32_read_memory_str(Arena *arena, HANDLE process_handle, U64 address);
internal String16 dmn_w32_read_memory_str16(Arena *arena, HANDLE process_handle, U64 address);
#define dmn_w32_process_read_struct(process, vaddr, ptr) dmn_w32_process_read((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
#define dmn_w32_process_write_struct(process, vaddr, ptr) dmn_w32_process_write((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
internal DMN_W32_ImageInfo dmn_w32_image_info_from_process_base_vaddr(HANDLE process, U64 base_vaddr);
//- rjf: threads
internal U16 dmn_w32_real_tag_word_from_xsave(XSAVE_FORMAT *fxsave);
internal U16 dmn_w32_xsave_tag_word_from_real_tag_word(U16 ftw);
internal B32 dmn_w32_thread_read_reg_block(Architecture arch, HANDLE thread, void *reg_block);
internal B32 dmn_w32_thread_write_reg_block(Architecture arch, HANDLE thread, void *reg_block);
//- rjf: remote thread injection
internal DWORD dmn_w32_inject_thread(HANDLE process, U64 start_address);
#endif // DEMON_CORE_WIN32_H
File diff suppressed because it is too large Load Diff
-385
View File
@@ -1,385 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DEMON_OS_WIN32_H
#define DEMON_OS_WIN32_H
////////////////////////////////
//~ NOTE(allen): Win32 Demon Headers Negotation
// windows headers
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <psapi.h>
#include <tlhelp32.h>
////////////////////////////////
//~ NOTE(allen): Win32 Demon Types
//- entities
// Demon Win32 Entity Extensions
// Process: ext points to independently allocated DEMON_W32_Ext
// Thread : ext points to independently allocated DEMON_W32_Ext
// Module : ext set to HANDLE
typedef union DEMON_W32_Ext DEMON_W32_Ext;
union DEMON_W32_Ext
{
DEMON_W32_Ext *next;
struct{
HANDLE handle;
U64 injection_address;
B32 did_first_bp;
} proc;
struct{
HANDLE handle;
U64 thread_local_base;
U64 last_name_hash;
U64 name_gather_time_us;
B32 last_run_reported_trap;
U64 last_run_reported_trap_pre_rip;
U64 last_run_reported_trap_post_rip;
} thread;
struct{
HANDLE handle;
U64 address_of_name_pointer;
B32 is_main;
B32 name_is_unicode;
} module;
};
//- helpers
typedef struct DEMON_W32_InjectedBreak DEMON_W32_InjectedBreak;
struct DEMON_W32_InjectedBreak
{
U64 code;
U64 user_data;
};
#define DEMON_W32_INJECTED_CODE_SIZE 32
typedef struct DEMON_W32_ImageInfo DEMON_W32_ImageInfo;
struct DEMON_W32_ImageInfo
{
Architecture arch;
U32 size;
};
typedef struct DEMON_W32_EntityNode DEMON_W32_EntityNode;
struct DEMON_W32_EntityNode
{
DEMON_W32_EntityNode *next;
DEMON_Entity *entity;
};
typedef HRESULT GetThreadDescriptionFunctionType(HANDLE hThread, WCHAR **ppszThreadDescription);
////////////////////////////////
//~ NOTE(allen): Win32 Demon Exceptions
#define DEMON_W32_EXCEPTION_BREAKPOINT 0x80000003u
#define DEMON_W32_EXCEPTION_SINGLE_STEP 0x80000004u
#define DEMON_W32_EXCEPTION_LONG_JUMP 0x80000026u
#define DEMON_W32_EXCEPTION_ACCESS_VIOLATION 0xC0000005u
#define DEMON_W32_EXCEPTION_ARRAY_BOUNDS_EXCEEDED 0xC000008Cu
#define DEMON_W32_EXCEPTION_DATA_TYPE_MISALIGNMENT 0x80000002u
#define DEMON_W32_EXCEPTION_GUARD_PAGE_VIOLATION 0x80000001u
#define DEMON_W32_EXCEPTION_FLT_DENORMAL_OPERAND 0xC000008Du
#define DEMON_W32_EXCEPTION_FLT_DEVIDE_BY_ZERO 0xC000008Eu
#define DEMON_W32_EXCEPTION_FLT_INEXACT_RESULT 0xC000008Fu
#define DEMON_W32_EXCEPTION_FLT_INVALID_OPERATION 0xC0000090u
#define DEMON_W32_EXCEPTION_FLT_OVERFLOW 0xC0000091u
#define DEMON_W32_EXCEPTION_FLT_STACK_CHECK 0xC0000092u
#define DEMON_W32_EXCEPTION_FLT_UNDERFLOW 0xC0000093u
#define DEMON_W32_EXCEPTION_INT_DIVIDE_BY_ZERO 0xC0000094u
#define DEMON_W32_EXCEPTION_INT_OVERFLOW 0xC0000095u
#define DEMON_W32_EXCEPTION_PRIVILEGED_INSTRUCTION 0xC0000096u
#define DEMON_W32_EXCEPTION_ILLEGAL_INSTRUCTION 0xC000001Du
#define DEMON_W32_EXCEPTION_IN_PAGE_ERROR 0xC0000006u
#define DEMON_W32_EXCEPTION_INVALID_DISPOSITION 0xC0000026u
#define DEMON_W32_EXCEPTION_NONCONTINUABLE 0xC0000025u
#define DEMON_W32_EXCEPTION_STACK_OVERFLOW 0xC00000FDu
#define DEMON_W32_EXCEPTION_INVALID_HANDLE 0xC0000008u
#define DEMON_W32_EXCEPTION_UNWIND_CONSOLIDATE 0x80000029u
#define DEMON_W32_EXCEPTION_DLL_NOT_FOUND 0xC0000135u
#define DEMON_W32_EXCEPTION_ORDINAL_NOT_FOUND 0xC0000138u
#define DEMON_W32_EXCEPTION_ENTRY_POINT_NOT_FOUND 0xC0000139u
#define DEMON_W32_EXCEPTION_DLL_INIT_FAILED 0xC0000142u
#define DEMON_W32_EXCEPTION_CONTROL_C_EXIT 0xC000013Au
#define DEMON_W32_EXCEPTION_FLT_MULTIPLE_FAULTS 0xC00002B4u
#define DEMON_W32_EXCEPTION_FLT_MULTIPLE_TRAPS 0xC00002B5u
#define DEMON_W32_EXCEPTION_NAT_CONSUMPTION 0xC00002C9u
#define DEMON_W32_EXCEPTION_HEAP_CORRUPTION 0xC0000374u
#define DEMON_W32_EXCEPTION_STACK_BUFFER_OVERRUN 0xC0000409u
#define DEMON_W32_EXCEPTION_INVALID_CRUNTIME_PARAM 0xC0000417u
#define DEMON_W32_EXCEPTION_ASSERT_FAILURE 0xC0000420u
#define DEMON_W32_EXCEPTION_NO_MEMORY 0xC0000017u
#define DEMON_W32_EXCEPTION_THROW 0xE06D7363u
#define DEMON_W32_EXCEPTION_SET_THREAD_NAME 0x406d1388u
////////////////////////////////
//~ NOTE(allen): Win32 Demon Register API Codes
#define DEMON_W32_CTX_X86 0x00010000
#define DEMON_W32_CTX_X64 0x00100000
#define DEMON_W32_CTX_INTEL_CONTROL 0x0001
#define DEMON_W32_CTX_INTEL_INTEGER 0x0002
#define DEMON_W32_CTX_INTEL_SEGMENTS 0x0004
#define DEMON_W32_CTX_INTEL_FLOATS 0x0008
#define DEMON_W32_CTX_INTEL_DEBUG 0x0010
#define DEMON_W32_CTX_INTEL_EXTENDED 0x0020
#define DEMON_W32_CTX_INTEL_XSTATE 0x0040
#define DEMON_W32_CTX_X86_ALL (DEMON_W32_CTX_X86 | \
DEMON_W32_CTX_INTEL_CONTROL | DEMON_W32_CTX_INTEL_INTEGER | \
DEMON_W32_CTX_INTEL_SEGMENTS | DEMON_W32_CTX_INTEL_DEBUG | \
DEMON_W32_CTX_INTEL_EXTENDED)
#define DEMON_W32_CTX_X64_ALL (DEMON_W32_CTX_X64 | \
DEMON_W32_CTX_INTEL_CONTROL | DEMON_W32_CTX_INTEL_INTEGER | \
DEMON_W32_CTX_INTEL_SEGMENTS | DEMON_W32_CTX_INTEL_FLOATS | \
DEMON_W32_CTX_INTEL_DEBUG)
////////////////////////////////
//~ rjf: DOS Header Types
// this is the "MZ" as a 16-bit short
#define DEMON_DOS_MAGIC 0x5a4d
#pragma pack(push,1)
typedef struct DEMON_DosHeader DEMON_DosHeader;
struct DEMON_DosHeader
{
U16 magic;
U16 last_page_size;
U16 page_count;
U16 reloc_count;
U16 paragraph_header_size;
U16 min_paragraph;
U16 max_paragraph;
U16 init_ss;
U16 init_sp;
U16 checksum;
U16 init_ip;
U16 init_cs;
U16 reloc_table_file_off;
U16 overlay_number;
U16 reserved[4];
U16 oem_id;
U16 oem_info;
U16 reserved2[10];
U32 coff_file_offset;
};
#pragma pack(pop)
////////////////////////////////
//~ rjf: Coff Header Types
#define DEMON_PE_MAGIC 0x00004550u
typedef U16 DEMON_CoffMachineType;
enum{
DEMON_CoffMachineType_UNKNOWN = 0x0,
DEMON_CoffMachineType_X86 = 0x14c,
DEMON_CoffMachineType_X64 = 0x8664,
DEMON_CoffMachineType_ARM33 = 0x1d3,
DEMON_CoffMachineType_ARM = 0x1c0,
DEMON_CoffMachineType_ARM64 = 0xaa64,
DEMON_CoffMachineType_ARMNT = 0x1c4,
DEMON_CoffMachineType_EBC = 0xebc,
DEMON_CoffMachineType_IA64 = 0x200,
DEMON_CoffMachineType_M32R = 0x9041,
DEMON_CoffMachineType_MIPS16 = 0x266,
DEMON_CoffMachineType_MIPSFPU = 0x366,
DEMON_CoffMachineType_MIPSFPU16 = 0x466,
DEMON_CoffMachineType_POWERPC = 0x1f0,
DEMON_CoffMachineType_POWERPCFP = 0x1f1,
DEMON_CoffMachineType_R4000 = 0x166,
DEMON_CoffMachineType_RISCV32 = 0x5032,
DEMON_CoffMachineType_RISCV64 = 0x5064,
DEMON_CoffMachineType_RISCV128 = 0x5128,
DEMON_CoffMachineType_SH3 = 0x1a2,
DEMON_CoffMachineType_SH3DSP = 0x1a3,
DEMON_CoffMachineType_SH4 = 0x1a6,
DEMON_CoffMachineType_SH5 = 0x1a8,
DEMON_CoffMachineType_THUMB = 0x1c2,
DEMON_CoffMachineType_WCEMIPSV2 = 0x169,
DEMON_CoffMachineType_COUNT = 25
};
typedef U16 DEMON_CoffFlags;
enum{
DEMON_CoffFlag_RELOC_STRIPPED = (1 << 0),
DEMON_CoffFlag_EXECUTABLE_IMAGE = (1 << 1),
DEMON_CoffFlag_LINE_NUMS_STRIPPED = (1 << 2),
DEMON_CoffFlag_SYM_STRIPPED = (1 << 3),
DEMON_CoffFlag_RESERVED_0 = (1 << 4),
DEMON_CoffFlag_LARGE_ADDRESS_AWARE = (1 << 5),
DEMON_CoffFlag_RESERVED_1 = (1 << 6),
DEMON_CoffFlag_RESERVED_2 = (1 << 7),
DEMON_CoffFlag_32BIT_MACHINE = (1 << 8),
DEMON_CoffFlag_DEBUG_STRIPPED = (1 << 9),
DEMON_CoffFlag_REMOVABLE_RUN_FROM_SWAP = (1 << 10),
DEMON_CoffFlag_NET_RUN_FROM_SWAP = (1 << 11),
DEMON_CoffFlag_SYSTEM = (1 << 12),
DEMON_CoffFlag_DLL = (1 << 13),
DEMON_CoffFlag_UP_SYSTEM_ONLY = (1 << 14),
DEMON_CoffFlag_BYTES_RESERVED_HI = (1 << 15),
};
#pragma pack(push,1)
typedef struct DEMON_CoffHeader DEMON_CoffHeader;
struct DEMON_CoffHeader
{
DEMON_CoffMachineType machine;
U16 section_count;
U32 time_date_stamp;
// TODO: rename to "unix_timestamp"
U32 pointer_to_symbol_table;
U32 number_of_symbols;
// TODO: rename to "symbol_count"
U16 size_of_optional_header;
// TODO: rename to "optional_header_size"
DEMON_CoffFlags flags;
};
#pragma pack(pop)
////////////////////////////////
//~ rjf: PE Header Types
#pragma pack(push, 1)
typedef U16 DEMON_PeWindowsSubsystem;
enum{
DEMON_PeWindowsSubsystem_UNKNOWN = 0,
DEMON_PeWindowsSubsystem_NATIVE = 1,
DEMON_PeWindowsSubsystem_WINDOWS_GUI = 2,
DEMON_PeWindowsSubsystem_WINDOWS_CUI = 3,
DEMON_PeWindowsSubsystem_OS2_CUI = 5,
DEMON_PeWindowsSubsystem_POSIX_CUI = 7,
DEMON_PeWindowsSubsystem_NATIVE_WINDOWS = 8,
DEMON_PeWindowsSubsystem_WINDOWS_CE_GUI = 9,
DEMON_PeWindowsSubsystem_EFI_APPLICATION = 10,
DEMON_PeWindowsSubsystem_EFI_BOOT_SERVICE_DRIVER = 11,
DEMON_PeWindowsSubsystem_EFI_RUNTIME_DRIVER = 12,
DEMON_PeWindowsSubsystem_EFI_ROM = 13,
DEMON_PeWindowsSubsystem_XBOX = 14,
DEMON_PeWindowsSubsystem_WINDOWS_BOOT_APPLICATION = 16,
DEMON_PeWindowsSubsystem_COUNT = 14
};
typedef U16 DEMON_DllCharacteristics;
enum{
DEMON_DllCharacteristic_HIGH_ENTROPY_VA = (1 << 5),
DEMON_DllCharacteristic_DYNAMIC_BASE = (1 << 6),
DEMON_DllCharacteristic_FORCE_INTEGRITY = (1 << 7),
DEMON_DllCharacteristic_NX_COMPAT = (1 << 8),
DEMON_DllCharacteristic_NO_ISOLATION = (1 << 9),
DEMON_DllCharacteristic_NO_SEH = (1 << 10),
DEMON_DllCharacteristic_NO_BIND = (1 << 11),
DEMON_DllCharacteristic_APPCONTAINER = (1 << 12),
DEMON_DllCharacteristic_WDM_DRIVER = (1 << 13),
DEMON_DllCharacteristic_GUARD_CF = (1 << 14),
DEMON_DllCharacteristic_TERMINAL_SERVER_AWARE = (1 << 15),
};
typedef struct DEMON_PeOptionalHeader32 DEMON_PeOptionalHeader32;
struct DEMON_PeOptionalHeader32
{
U16 magic;
U8 major_linker_version;
U8 minor_linker_version;
U32 sizeof_code;
U32 sizeof_inited_data;
U32 sizeof_uninited_data;
U32 entry_point_va;
U32 code_base;
U32 data_base;
U32 image_base;
U32 section_alignment;
U32 file_alignment;
U16 major_os_ver;
U16 minor_os_ver;
U16 major_img_ver;
U16 minor_img_ver;
U16 major_subsystem_ver;
U16 minor_subsystem_ver;
U32 win32_version_value;
U32 sizeof_image;
U32 sizeof_headers;
U32 check_sum;
DEMON_PeWindowsSubsystem subsystem;
DEMON_DllCharacteristics dll_characteristics;
U32 sizeof_stack_reserve;
U32 sizeof_stack_commit;
U32 sizeof_heap_reserve;
U32 sizeof_heap_commit;
U32 loader_flags;
U32 data_dir_count;
};
typedef struct DEMON_PeOptionalHeader32Plus DEMON_PeOptionalHeader32Plus;
struct DEMON_PeOptionalHeader32Plus
{
U16 magic;
U8 major_linker_version;
U8 minor_linker_version;
U32 sizeof_code;
U32 sizeof_inited_data;
U32 sizeof_uninited_data;
U32 entry_point_va;
U32 code_base;
U64 image_base;
U32 section_alignment;
U32 file_alignment;
U16 major_os_ver;
U16 minor_os_ver;
U16 major_img_ver;
U16 minor_img_ver;
U16 major_subsystem_ver;
U16 minor_subsystem_ver;
U32 win32_version_value;
U32 sizeof_image;
U32 sizeof_headers;
U32 check_sum;
DEMON_PeWindowsSubsystem subsystem;
DEMON_DllCharacteristics dll_characteristics;
U64 sizeof_stack_reserve;
U64 sizeof_stack_commit;
U64 sizeof_heap_reserve;
U64 sizeof_heap_commit;
U32 loader_flags;
U32 data_dir_count;
};
#pragma pack(pop)
////////////////////////////////
//~ rjf: Helpers
internal U64 demon_w32_hash_from_string(String8 string);
internal DEMON_W32_Ext* demon_w32_ext_alloc(void);
internal DEMON_W32_Ext* demon_w32_ext(DEMON_Entity *entity);
internal U64 demon_w32_read_memory(HANDLE process_handle, void *dst, U64 src_address, U64 size);
internal B32 demon_w32_write_memory(HANDLE process_handle, U64 dst_address, void *src, U64 size);
internal String8 demon_w32_read_memory_str(Arena *arena, HANDLE process_handle, U64 address);
internal String16 demon_w32_read_memory_str16(Arena *arena, HANDLE process_handle, U64 address);
#define demon_w32_read_struct(h,dst,src) demon_w32_read_memory((h), (dst), (src), sizeof(*(dst)))
internal DEMON_W32_ImageInfo demon_w32_image_info_from_base(HANDLE process_handle, U64 base);
internal DWORD demon_w32_inject_thread(DEMON_Entity *process, U64 start_address);
internal U16 demon_w32_real_tag_word_from_xsave(XSAVE_FORMAT *fxsave);
internal U16 demon_w32_xsave_tag_word_from_real_tag_word(U16 ftw);
internal DWORD demon_w32_win32_from_memory_protect_flags(DEMON_MemoryProtectFlags flags);
////////////////////////////////
//~ rjf: Experiments
internal void demon_w32_peak_at_tls(DEMON_Handle handle);
#endif //DEMON_OS_WIN32_H
+481 -458
View File
File diff suppressed because it is too large Load Diff
+26 -39
View File
@@ -430,6 +430,7 @@ struct DF_Entity
DF_EntityFlags flags;
DF_EntityID id;
U64 generation;
U64 alloc_time_us;
B32 deleted;
F32 alive_t;
@@ -446,7 +447,7 @@ struct DF_Entity
// rjf: ctrl entity equipment
CTRL_MachineID ctrl_machine_id;
CTRL_Handle ctrl_handle;
DMN_Handle ctrl_handle;
Architecture arch;
U32 ctrl_id;
U64 stack_base;
@@ -510,20 +511,7 @@ struct DF_EntityFuzzyItemArray
};
////////////////////////////////
//~ rjf: Text Slices (output type from data which can be used to produce readable text)
//- rjf: text slice construction flags
typedef U32 DF_TextSliceFlags;
enum
{
DF_TextSliceFlag_CodeBytes = (1<<0),
DF_TextSliceFlag_Addresses = (1<<1),
DF_TextSliceFlag_Tokens = (1<<2),
DF_TextSliceFlag_Src2Dasm = (1<<3),
DF_TextSliceFlag_Dasm2Src = (1<<4),
DF_TextSliceFlag_VirtualOff= (1<<5),
};
//~ rjf: Source <-> Disasm Types
//- rjf: debug info for mapping src -> disasm
@@ -939,7 +927,6 @@ struct DF_RunUnwindCacheNode
DF_RunUnwindCacheNode *hash_next;
DF_Handle thread;
CTRL_Unwind unwind;
U64 tls_base_vaddr;
};
typedef struct DF_RunUnwindCacheSlot DF_RunUnwindCacheSlot;
@@ -953,8 +940,8 @@ typedef struct DF_RunUnwindCache DF_RunUnwindCache;
struct DF_RunUnwindCache
{
Arena *arena;
U64 table_size;
DF_RunUnwindCacheSlot *table;
U64 slots_count;
DF_RunUnwindCacheSlot *slots;
};
//- rjf: per-run tls-base-vaddr cache
@@ -1135,14 +1122,18 @@ struct DF_State
// rjf: per-run caches
U64 unwind_cache_reggen_idx;
U64 unwind_cache_memgen_idx;
DF_RunUnwindCache unwind_cache;
DF_RunUnwindCache unwind_caches[2];
U64 unwind_cache_gen;
U64 tls_base_cache_reggen_idx;
U64 tls_base_cache_memgen_idx;
DF_RunTLSBaseCache tls_base_cache;
DF_RunTLSBaseCache tls_base_caches[2];
U64 tls_base_cache_gen;
U64 locals_cache_reggen_idx;
DF_RunLocalsCache locals_cache;
DF_RunLocalsCache locals_caches[2];
U64 locals_cache_gen;
U64 member_cache_reggen_idx;
DF_RunLocalsCache member_cache;
DF_RunLocalsCache member_caches[2];
U64 member_cache_gen;
// rjf: eval view cache
DF_EvalViewCache eval_view_cache;
@@ -1168,6 +1159,7 @@ struct DF_State
DF_RunKind ctrl_last_run_kind;
U64 ctrl_last_run_frame_idx;
DF_Handle ctrl_last_run_thread;
CTRL_RunFlags ctrl_last_run_flags;
CTRL_TrapList ctrl_last_run_traps;
U64 ctrl_run_gen;
B32 ctrl_is_running;
@@ -1178,6 +1170,7 @@ struct DF_State
B32 ctrl_solo_stepping_mode;
// rjf: control thread ctrl -> user reading state
CTRL_EntityStore *ctrl_entity_store;
Arena *ctrl_stop_arena;
CTRL_Event ctrl_last_stop_event;
@@ -1226,6 +1219,7 @@ read_only global DF_Entity df_g_nil_entity =
0,
0,
0,
0,
// rjf: allocationless, simple equipment
{0},
@@ -1396,9 +1390,6 @@ internal DF_EntityFuzzyItemArray df_entity_fuzzy_item_array_from_entity_array_ne
//- rjf: entity -> text info
internal TXTI_Handle df_txti_handle_from_entity(DF_Entity *entity);
//- rjf: entity -> disasm info
internal DASM_Handle df_dasm_handle_from_process_vaddr(DF_Entity *process, U64 vaddr);
//- rjf: full path building, from file/folder entities
internal String8 df_full_path_from_entity(Arena *arena, DF_Entity *entity);
@@ -1445,7 +1436,7 @@ internal void df_entity_equip_cfg_src(DF_Entity *entity, DF_CfgSrc cfg_src);
//- rjf: control layer correllation equipment
internal void df_entity_equip_ctrl_machine_id(DF_Entity *entity, CTRL_MachineID machine_id);
internal void df_entity_equip_ctrl_handle(DF_Entity *entity, CTRL_Handle handle);
internal void df_entity_equip_ctrl_handle(DF_Entity *entity, DMN_Handle handle);
internal void df_entity_equip_arch(DF_Entity *entity, Architecture arch);
internal void df_entity_equip_ctrl_id(DF_Entity *entity, U32 id);
internal void df_entity_equip_stack_base(DF_Entity *entity, U64 stack_base);
@@ -1466,7 +1457,7 @@ internal DF_Entity *df_entity_root(void);
internal DF_EntityList df_push_entity_list_with_kind(Arena *arena, DF_EntityKind kind);
internal DF_Entity *df_entity_from_id(DF_EntityID id);
internal DF_Entity *df_machine_entity_from_machine_id(CTRL_MachineID machine_id);
internal DF_Entity *df_entity_from_ctrl_handle(CTRL_MachineID machine_id, CTRL_Handle handle);
internal DF_Entity *df_entity_from_ctrl_handle(CTRL_MachineID machine_id, DMN_Handle handle);
internal DF_Entity *df_entity_from_ctrl_id(CTRL_MachineID machine_id, U32 id);
internal DF_Entity *df_entity_from_name_and_kind(String8 string, DF_EntityKind kind);
internal DF_Entity *df_entity_from_u64_and_kind(U64 u64, DF_EntityKind kind);
@@ -1531,7 +1522,6 @@ internal DF_TextLineSrc2DasmInfoListArray df_text_line_src2dasm_info_list_array_
//- rjf: voff -> src lookups
internal DF_TextLineDasm2SrcInfo df_text_line_dasm2src_info_from_binary_voff(DF_Entity *binary, U64 voff);
internal DF_TextLineDasm2SrcInfoList df_text_line_dasm2src_info_from_voff(Arena *arena, U64 voff);
//- rjf: symbol -> voff lookups
internal U64 df_voff_from_binary_symbol_name(DF_Entity *binary, String8 symbol_name);
@@ -1545,9 +1535,6 @@ 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 CTRL_Unwind df_push_unwind_from_thread(Arena *arena, DF_Entity *thread);
internal U64 df_rip_from_thread(DF_Entity *thread);
internal U64 df_rip_from_thread_unwind(DF_Entity *thread, U64 unwind_count);
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 B32 df_set_thread_rip(DF_Entity *thread, U64 vaddr);
@@ -1565,7 +1552,7 @@ internal DF_Entity *df_log_from_entity(DF_Entity *entity);
internal void df_push_ctrl_msg(CTRL_Msg *msg);
//- rjf: control thread running
internal void df_ctrl_run(DF_RunKind run, DF_Entity *run_thread, CTRL_TrapList *run_traps);
internal void df_ctrl_run(DF_RunKind run, DF_Entity *target, DF_Entity *run_thread, CTRL_RunFlags flags, CTRL_TrapList *run_traps);
//- rjf: stopped info from the control thread
internal CTRL_Event df_ctrl_last_stop_event(void);
@@ -1577,8 +1564,8 @@ 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 DF_Eval df_value_mode_eval_from_eval(TG_Graph *graph, RADDBG_Parsed *rdbg, DF_CtrlCtx *ctrl_ctx, DF_Eval eval);
internal DF_Eval df_dynamically_typed_eval_from_eval(TG_Graph *graph, RADDBG_Parsed *rdbg, DF_CtrlCtx *ctrl_ctx, DF_Eval eval);
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);
////////////////////////////////
@@ -1602,14 +1589,14 @@ internal String8 df_eval_view_rule_from_key(DF_EvalView *eval_view, DF_ExpandKey
//- rjf: evaluation value string builder helpers
internal String8 df_string_from_ascii_value(Arena *arena, U8 val);
internal String8 df_string_from_simple_typed_eval(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, DF_EvalVizStringFlags flags, U32 radix, DF_Eval eval);
internal String8 df_string_from_simple_typed_eval(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, DF_EvalVizStringFlags flags, U32 radix, DF_Eval eval);
//- rjf: writing values back to child processes
internal B32 df_commit_eval_value(TG_Graph *graph, RADDBG_Parsed *rdbg, DF_CtrlCtx *ctrl_ctx, DF_Eval dst_eval, DF_Eval src_eval);
internal B32 df_commit_eval_value(TG_Graph *graph, RDI_Parsed *rdi, DF_CtrlCtx *ctrl_ctx, DF_Eval dst_eval, DF_Eval src_eval);
//- rjf: type helpers
internal TG_MemberArray df_filtered_data_members_from_members_cfg_table(Arena *arena, TG_MemberArray members, DF_CfgTable *cfg);
internal DF_EvalLinkBaseChunkList df_eval_link_base_chunk_list_from_eval(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key link_member_type_key, U64 link_member_off, DF_CtrlCtx *ctrl_ctx, DF_Eval eval, U64 cap);
internal DF_EvalLinkBaseChunkList df_eval_link_base_chunk_list_from_eval(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, TG_Key link_member_type_key, U64 link_member_off, DF_CtrlCtx *ctrl_ctx, DF_Eval eval, U64 cap);
internal DF_EvalLinkBase df_eval_link_base_from_chunk_list_index(DF_EvalLinkBaseChunkList *list, U64 idx);
internal DF_EvalLinkBaseArray df_eval_link_base_array_from_chunk_list(Arena *arena, DF_EvalLinkBaseChunkList *chunks);
@@ -1618,7 +1605,7 @@ internal DF_EvalVizBlock *df_eval_viz_block_begin(Arena *arena, DF_EvalVizBlockK
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_num(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_EvalView *eval_view, String8 expr, U64 num);
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_eval_viz_block_list_concat__in_place(DF_EvalVizBlockList *dst, DF_EvalVizBlockList *to_push);
//- rjf: viz block list <-> table coordinates
@@ -1688,7 +1675,7 @@ internal void df_push_cmd__root(DF_CmdParams *params, DF_CmdSpec *spec);
////////////////////////////////
//~ rjf: Main Layer Top-Level Calls
internal void df_core_init(String8 user_path, String8 profile_path, DF_StateDeltaHistory *hist);
internal void df_core_init(CmdLine *cmdln, DF_StateDeltaHistory *hist);
internal DF_CmdList df_core_gather_root_cmds(Arena *arena);
internal void df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt);
internal void df_core_end_frame(void);
+82 -123
View File
@@ -16,14 +16,6 @@ DF_CfgSrcTable:
////////////////////////////////
//~ rjf: Entity Kind Tables
@table(name)
DF_NameKindTable:
{
{Null}
{EntityName}
{EntityKindName}
}
@table(name name_lower op_delete op_freeze op_edit op_rename op_enable op_cond op_dup lf_mut_user_cfg tr_mut_user_cfg lf_mut_prof_cfg tr_mut_prof_cfg lf_mut_halt lf_mut_dbg tr_mut_halt tr_mut_dbg name_is_code user_lifetime name_label icon_kind display_string)
DF_EntityKindTable:
{
@@ -61,7 +53,6 @@ DF_EntityKindTable:
{Dest dest 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "Path" Null "Destination" }
//- rjf: control system entities
{CtrlRequest ctrl_request 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 "Label" Null "Control Request" }
{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" }
@@ -82,24 +73,24 @@ DF_EntityKindTable:
@table(name, name_lower, c_type)
DF_CmdParamSlotTable:
{
{Window, window, `DF_Handle`}
{Panel, panel, `DF_Handle`}
{DestPanel, dest_panel, `DF_Handle`}
{PrevView, prev_view, `DF_Handle`}
{View, view, `DF_Handle`}
{Entity, entity, `DF_Handle`}
{EntityList, entity_list, `DF_HandleList`}
{String, string, `String8`}
{FilePath, file_path, `String8`}
{TextPoint, text_point, `TxtPt`}
{CmdSpec, cmd_spec, `struct DF_CmdSpec *`}
{ViewSpec, view_spec, `struct DF_ViewSpec *`}
{VirtualAddr, vaddr, `U64`}
{VirtualOff, voff, `U64`}
{Index, index, `U64`}
{ID, id, `U64`}
{PreferDisassembly, prefer_dasm, `B32`}
{ForceConfirm, force_confirm,`B32`}
{Window window `DF_Handle`}
{Panel panel `DF_Handle`}
{DestPanel dest_panel `DF_Handle`}
{PrevView prev_view `DF_Handle`}
{View view `DF_Handle`}
{Entity entity `DF_Handle`}
{EntityList entity_list `DF_HandleList`}
{String string `String8`}
{FilePath file_path `String8`}
{TextPoint text_point `TxtPt`}
{CmdSpec cmd_spec `struct DF_CmdSpec *`}
{ViewSpec view_spec `struct DF_ViewSpec *`}
{VirtualAddr vaddr `U64`}
{VirtualOff voff `U64`}
{Index index `U64`}
{ID id `U64`}
{PreferDisassembly prefer_dasm `B32`}
{ForceConfirm force_confirm `B32`}
}
@table(name lister_omit q_slot q_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_required canonical_icon string display_name desc search_tags )
@@ -463,6 +454,13 @@ DF_CoreCmdTable:// | | |
// rows, this stage offers the ability to build a ui
// stretching over all of the rows.
//
// whole ui build, "wu" -> sometimes, more sophisticated interfaces need to be
// provided for a view rule, that stretch beyond the
// limits of what could be offered inside a watch
// window block. in such cases, the eval/view-rule
// combo will be granted its own tab for example, and
// this stage is used to fill such a ui.
//
// A few other bits are included for various ways in which a view rule may be
// applied throughout the eval visualization pipeline. A list follows:
//
@@ -487,6 +485,7 @@ DF_CoreViewRuleTable:
{
{Null null "" - - - - "" - "" }
{Array array "array" - - x - "Array" x "Specifies that a pointer points to N elements, rather than only 1." }
{Slice slice "slice" - - x - "Slice" x "Specifies that a struct to be rendered as a slice." }
{List list "list" - - - x "List" x "Specifies that some struct, union, or class forms the top of a linked list, and the member which points at the following element in the list." }
{ByteSwap bswap "bswap" x - x - "Byte Swap" x "Specifies that all integer primitives should be byte-swapped, such that their endianness is reversed." }
{BaseDec base_dec "dec" x - - - "Decimal Base (Base 10)" x "Specifies that all integral evaluations should appear in base-10 form." }
@@ -501,8 +500,7 @@ DF_CoreViewRuleTable:
{Disasm disasm "disasm" - x - x "Disassembly" x "Displays as disassembled instructions, interpreting the data as raw machine code." }
{Bitmap bitmap "bitmap" - x - x "Bitmap" x "Displays as a bitmap, interpreting the data as raw pixel data." }
{Geo geo "geo" - x - x "Geometry" x "Displays as geometry, interpreting the data as vertex data." }
{Slice slice "slice" - - x - "Slice" x "Specifies that some struct is to be rendered as a slice." }
{OdinMap odin_map "odin_map" - - x - "Odin Map" x "Specifies that a struct to be rendered as an Odin map." }
{OdinMap odin_map "odin_map" - - x - "Odin map" x "Specifies that a struct to be rendered as an Odin map type." }
}
////////////////////////////////
@@ -1690,179 +1688,140 @@ DF_DevToggleTable:
//- rjf: enums
@table_gen_enum
DF_CfgSrc:
@enum DF_CfgSrc:
{
@expand(DF_CfgSrcTable a) `DF_CfgSrc_$(a.name),`;
`DF_CfgSrc_COUNT`;
@expand(DF_CfgSrcTable a) `$(a.name)`,
COUNT,
}
@table_gen_enum
DF_EntityKind:
@enum DF_EntityKind:
{
@expand(DF_EntityKindTable a) `DF_EntityKind_$(a.name),`;
`DF_EntityKind_COUNT`;
@expand(DF_EntityKindTable a) `$(a.name)`,
COUNT,
}
@table_gen_enum
DF_NameKind:
@enum DF_CoreCmdKind:
{
@expand(DF_NameKindTable, a) `DF_NameKind_$(a.name),`;
`DF_NameKind_COUNT`;
@expand(DF_CoreCmdTable, a) `$(a.name)`,
COUNT,
}
@table_gen_enum
DF_CoreCmdKind:
@enum DF_IconKind:
{
@expand(DF_CoreCmdTable, a)
`DF_CoreCmdKind_$(a.name),`,
`DF_CoreCmdKind_COUNT`,
@expand(DF_IconTable a) `$(a.name)`,
COUNT,
}
@table_gen_enum
DF_IconKind:
@enum DF_CoreViewRuleKind:
{
@expand(DF_IconTable a)
`DF_IconKind_$(a.name),`;
`DF_IconKind_COUNT`;
}
@table_gen_enum
DF_CoreViewRuleKind:
{
@expand(DF_CoreViewRuleTable a) `DF_CoreViewRuleKind_$(a.name),`;
`DF_CoreViewRuleKind_COUNT`;
@expand(DF_CoreViewRuleTable a) `$(a.name)`,
COUNT,
}
//- rjf: command params
@table_gen_enum
DF_CmdParamSlot:
@enum DF_CmdParamSlot:
{
`DF_CmdParamSlot_Null,`;
@expand(DF_CmdParamSlotTable a)
`DF_CmdParamSlot_$(a.name),`;
`DF_CmdParamSlot_COUNT`;
Null,
@expand(DF_CmdParamSlotTable a) `$(a.name)`,
COUNT,
}
@table_gen
@struct DF_CmdParams:
{
`typedef struct DF_CmdParams DF_CmdParams;`;
`struct DF_CmdParams`;
`{`;
`U64 slot_props[(DF_CmdParamSlot_COUNT + 63) / 64];`;
@expand(DF_CmdParamSlotTable a)
`$(a.c_type) $(a.name_lower);`;
`};`;
`U64 slot_props[(DF_CmdParamSlot_COUNT + 63) / 64]`;
@expand(DF_CmdParamSlotTable a) `$(a.c_type) $(a.name_lower)`;
}
@table_gen_data(type:Rng1U64, fallback:0)
df_g_cmd_param_slot_range_table:
@data(Rng1U64) df_g_cmd_param_slot_range_table:
{
`{0},`
@expand(DF_CmdParamSlotTable a)
`{OffsetOf(DF_CmdParams, $(a.name_lower)), OffsetOf(DF_CmdParams, $(a.name_lower)) + sizeof($(a.c_type))},`
`{0}`,
@expand(DF_CmdParamSlotTable a) `{OffsetOf(DF_CmdParams, $(a.name_lower)), OffsetOf(DF_CmdParams, $(a.name_lower)) + sizeof($(a.c_type))}`,
}
//- rjf: entity kind tables
@table_gen_data(type: DF_IconKind, fallback: `DF_IconKind_Null`)
df_g_entity_kind_icon_kind_table:
@data(DF_IconKind) df_g_entity_kind_icon_kind_table:
{
@expand(DF_EntityKindTable a) `DF_IconKind_$(a.icon_kind),`;
@expand(DF_EntityKindTable a) `DF_IconKind_$(a.icon_kind)`,
}
@table_gen_data(type: String8, fallback: `{0}`)
df_g_entity_kind_display_string_table:
@data(String8) df_g_entity_kind_display_string_table:
{
@expand(DF_EntityKindTable a) `str8_lit_comp("$(a.display_string)"),`;
@expand(DF_EntityKindTable a) `str8_lit_comp("$(a.display_string)")`,
}
@table_gen_data(type: String8, fallback: `{0}`)
df_g_entity_kind_name_label_table:
@data(String8) df_g_entity_kind_name_label_table:
{
@expand(DF_EntityKindTable a) `str8_lit_comp("$(a.name_label)"),`;
@expand(DF_EntityKindTable a) `str8_lit_comp("$(a.name_label)")`,
}
@table_gen_data(type:DF_EntityKindFlags, fallback: `0`)
df_g_entity_kind_flags_table:
@data(DF_EntityKindFlags) df_g_entity_kind_flags_table:
{
@expand(DF_EntityKindTable a) `($(a.lf_mut_user_cfg)*DF_EntityKindFlag_LeafMutationUserConfig | $(a.lf_mut_prof_cfg)*DF_EntityKindFlag_LeafMutationProfileConfig | $(a.lf_mut_halt)*DF_EntityKindFlag_LeafMutationSoftHalt | $(a.lf_mut_dbg)*DF_EntityKindFlag_LeafMutationDebugInfoMap | $(a.tr_mut_user_cfg)*DF_EntityKindFlag_TreeMutationUserConfig | $(a.tr_mut_prof_cfg)*DF_EntityKindFlag_TreeMutationProfileConfig | $(a.tr_mut_halt)*DF_EntityKindFlag_TreeMutationSoftHalt | $(a.tr_mut_dbg)*DF_EntityKindFlag_TreeMutationDebugInfoMap | $(a.name_is_code)*DF_EntityKindFlag_NameIsCode | $(a.user_lifetime)*DF_EntityKindFlag_UserDefinedLifetime),`;
@expand(DF_EntityKindTable a) `($(a.lf_mut_user_cfg)*DF_EntityKindFlag_LeafMutationUserConfig | $(a.lf_mut_prof_cfg)*DF_EntityKindFlag_LeafMutationProfileConfig | $(a.lf_mut_halt)*DF_EntityKindFlag_LeafMutationSoftHalt | $(a.lf_mut_dbg)*DF_EntityKindFlag_LeafMutationDebugInfoMap | $(a.tr_mut_user_cfg)*DF_EntityKindFlag_TreeMutationUserConfig | $(a.tr_mut_prof_cfg)*DF_EntityKindFlag_TreeMutationProfileConfig | $(a.tr_mut_halt)*DF_EntityKindFlag_TreeMutationSoftHalt | $(a.tr_mut_dbg)*DF_EntityKindFlag_TreeMutationDebugInfoMap | $(a.name_is_code)*DF_EntityKindFlag_NameIsCode | $(a.user_lifetime)*DF_EntityKindFlag_UserDefinedLifetime)`,
}
@table_gen_data(type: DF_EntityOpFlags, fallback: `0`)
df_g_entity_kind_op_flags_table:
@data(DF_EntityOpFlags) df_g_entity_kind_op_flags_table:
{
@expand(DF_EntityKindTable a) `($(a.op_delete)*DF_EntityOpFlag_Delete) | ($(a.op_freeze)*DF_EntityOpFlag_Freeze) | ($(a.op_edit)*DF_EntityOpFlag_Edit) | ($(a.op_rename)*DF_EntityOpFlag_Rename) | ($(a.op_enable)*DF_EntityOpFlag_Enable) | ($(a.op_cond)*DF_EntityOpFlag_Condition) | ($(a.op_dup)*DF_EntityOpFlag_Duplicate),`;
@expand(DF_EntityKindTable a) `($(a.op_delete)*DF_EntityOpFlag_Delete) | ($(a.op_freeze)*DF_EntityOpFlag_Freeze) | ($(a.op_edit)*DF_EntityOpFlag_Edit) | ($(a.op_rename)*DF_EntityOpFlag_Rename) | ($(a.op_enable)*DF_EntityOpFlag_Enable) | ($(a.op_cond)*DF_EntityOpFlag_Condition) | ($(a.op_dup)*DF_EntityOpFlag_Duplicate)`,
}
//- rjf: config source tables
@table_gen_data(type: String8, fallback: DF_CoreCmdKind_Null)
df_g_cfg_src_string_table:
@data(String8) df_g_cfg_src_string_table:
{
@expand(DF_CfgSrcTable a) `str8_lit_comp("$(a.string)"),`;
@expand(DF_CfgSrcTable a) `str8_lit_comp("$(a.string)")`,
}
@table_gen_data(type: DF_CoreCmdKind, fallback: DF_CoreCmdKind_Null)
df_g_cfg_src_load_cmd_kind_table:
@data(DF_CoreCmdKind) df_g_cfg_src_load_cmd_kind_table:
{
@expand(DF_CfgSrcTable a) `DF_CoreCmdKind_$(a.load_cmd),`;
@expand(DF_CfgSrcTable a) `DF_CoreCmdKind_$(a.load_cmd)`,
}
@table_gen_data(type: DF_CoreCmdKind, fallback: DF_CoreCmdKind_Null)
df_g_cfg_src_write_cmd_kind_table:
@data(DF_CoreCmdKind) df_g_cfg_src_write_cmd_kind_table:
{
@expand(DF_CfgSrcTable a) `DF_CoreCmdKind_$(a.write_cmd),`;
@expand(DF_CfgSrcTable a) `DF_CoreCmdKind_$(a.write_cmd)`,
}
@table_gen_data(type: DF_CoreCmdKind, fallback: DF_CoreCmdKind_Null)
df_g_cfg_src_apply_cmd_kind_table:
@data(DF_CoreCmdKind) df_g_cfg_src_apply_cmd_kind_table:
{
@expand(DF_CfgSrcTable a) `DF_CoreCmdKind_$(a.apply_cmd),`;
@expand(DF_CfgSrcTable a) `DF_CoreCmdKind_$(a.apply_cmd)`;
}
//- rjf: core view rule function prototypes
@table_gen
@gen
{
``;
@expand(DF_CoreViewRuleTable a)
`$(a.er == "x" -> "DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(" .. a.name_lower .. ");")`;
@expand(DF_CoreViewRuleTable a)
`$(a.vb == "x" -> "DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(" .. a.name_lower .. ");")`;
@expand(DF_CoreViewRuleTable a) `$(a.er == "x" -> "DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(" .. a.name_lower .. ");")`;
@expand(DF_CoreViewRuleTable a) `$(a.vb == "x" -> "DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(" .. a.name_lower .. ");")`;
}
//- rjf: core command kind tables
@table_gen_data(type: DF_CmdSpecInfo, fallback: `{0}`) @c_file
df_g_core_cmd_kind_spec_info_table:
@data(DF_CmdSpecInfo) @c_file df_g_core_cmd_kind_spec_info_table:
{
@expand(DF_CoreCmdTable, a)
```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.display_name)"), (DF_CmdSpecFlag_OmitFromLists*$(a.lister_omit)), {DF_CmdParamSlot_$(a.q_slot), DF_EntityKind_$(a.q_ent_kind), (DF_CmdQueryFlag_AllowFiles*$(a.q_allow_files))|(DF_CmdQueryFlag_AllowFolders*$(a.q_allow_folders))|(DF_CmdQueryFlag_CodeInput*$(a.q_is_code))|(DF_CmdQueryFlag_KeepOldInput*$(a.q_keep_oi))|(DF_CmdQueryFlag_SelectOldInput*$(a.q_select_oi))|(DF_CmdQueryFlag_Required*$(a.q_required))}, DF_IconKind_$(a.canonical_icon)},```;
```{ str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.desc)"), str8_lit_comp("$(a.search_tags)"), str8_lit_comp("$(a.display_name)"), (DF_CmdSpecFlag_OmitFromLists*$(a.lister_omit)), {DF_CmdParamSlot_$(a.q_slot), DF_EntityKind_$(a.q_ent_kind), (DF_CmdQueryFlag_AllowFiles*$(a.q_allow_files))|(DF_CmdQueryFlag_AllowFolders*$(a.q_allow_folders))|(DF_CmdQueryFlag_CodeInput*$(a.q_is_code))|(DF_CmdQueryFlag_KeepOldInput*$(a.q_keep_oi))|(DF_CmdQueryFlag_SelectOldInput*$(a.q_select_oi))|(DF_CmdQueryFlag_Required*$(a.q_required))}, DF_IconKind_$(a.canonical_icon)}```;
}
//- rjf: core view rule tables
@table_gen_data(type: DF_CoreViewRuleSpecInfo, fallback: `{0}`) @c_file
df_g_core_view_rule_spec_info_table:
@data(DF_CoreViewRuleSpecInfo) @c_file df_g_core_view_rule_spec_info_table:
{
@expand(DF_CoreViewRuleTable a)
```{str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.description)"), (DF_CoreViewRuleSpecInfoFlag_Inherited*$(a.ih == "x"))|(DF_CoreViewRuleSpecInfoFlag_Expandable*$(a.ex == "x"))|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*$(a.er == "x"))|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*$(a.vb == "x")), $(a.er == "x" -> "DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME("..a.name_lower..")") $(a.er != "x" -> 0), $(a.vb == "x" -> "DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME("..a.name_lower..")") $(a.vb != "x" -> 0), },```;
```{str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.description)"), (DF_CoreViewRuleSpecInfoFlag_Inherited*$(a.ih == "x"))|(DF_CoreViewRuleSpecInfoFlag_Expandable*$(a.ex == "x"))|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*$(a.er == "x"))|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*$(a.vb == "x")), $(a.er == "x" -> "DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME("..a.name_lower..")") $(a.er != "x" -> 0), $(a.vb == "x" -> "DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME("..a.name_lower..")") $(a.vb != "x" -> 0), }```;
}
//- rjf: icon kinds
@table_gen_data(type: String8, fallback: `{0}`)
df_g_icon_kind_text_table:
@data(String8) df_g_icon_kind_text_table:
{
@expand(DF_IconTable a)
`str8_lit_comp("$(a.text)"),`;
@expand(DF_IconTable a) `str8_lit_comp("$(a.text)")`;
}
//- rjf: instruction metadata table
@table_gen
@gen
{
``;
`struct{String8 mnemonic; String8 summary;} df_g_inst_table_x64[] =`;
@@ -1874,12 +1833,12 @@ df_g_icon_kind_text_table:
//- rjf: developer toggles
@table_gen
@gen
{
@expand(DF_DevToggleTable a) `global B32 DEV_$(a.name) = 0;`
}
@table_gen
@gen
{
`struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] =`;
`{`;
+285 -4
View File
@@ -3,7 +3,213 @@
//- GENERATED CODE
DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[] =
C_LINKAGE_BEGIN
Rng1U64 df_g_cmd_param_slot_range_table[19] =
{
{0},
{OffsetOf(DF_CmdParams, window), OffsetOf(DF_CmdParams, window) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, panel), OffsetOf(DF_CmdParams, panel) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, dest_panel), OffsetOf(DF_CmdParams, dest_panel) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, prev_view), OffsetOf(DF_CmdParams, prev_view) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, view), OffsetOf(DF_CmdParams, view) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, entity), OffsetOf(DF_CmdParams, entity) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, entity_list), OffsetOf(DF_CmdParams, entity_list) + sizeof(DF_HandleList)},
{OffsetOf(DF_CmdParams, string), OffsetOf(DF_CmdParams, string) + sizeof(String8)},
{OffsetOf(DF_CmdParams, file_path), OffsetOf(DF_CmdParams, file_path) + sizeof(String8)},
{OffsetOf(DF_CmdParams, text_point), OffsetOf(DF_CmdParams, text_point) + sizeof(TxtPt)},
{OffsetOf(DF_CmdParams, cmd_spec), OffsetOf(DF_CmdParams, cmd_spec) + sizeof(struct DF_CmdSpec *)},
{OffsetOf(DF_CmdParams, view_spec), OffsetOf(DF_CmdParams, view_spec) + sizeof(struct DF_ViewSpec *)},
{OffsetOf(DF_CmdParams, vaddr), OffsetOf(DF_CmdParams, vaddr) + sizeof(U64)},
{OffsetOf(DF_CmdParams, voff), OffsetOf(DF_CmdParams, voff) + sizeof(U64)},
{OffsetOf(DF_CmdParams, index), OffsetOf(DF_CmdParams, index) + sizeof(U64)},
{OffsetOf(DF_CmdParams, id), OffsetOf(DF_CmdParams, id) + sizeof(U64)},
{OffsetOf(DF_CmdParams, prefer_dasm), OffsetOf(DF_CmdParams, prefer_dasm) + sizeof(B32)},
{OffsetOf(DF_CmdParams, force_confirm), OffsetOf(DF_CmdParams, force_confirm) + sizeof(B32)},
};
DF_IconKind df_g_entity_kind_icon_kind_table[26] =
{
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Machine,
DF_IconKind_FileOutline,
DF_IconKind_FileOutline,
DF_IconKind_FileOutline,
DF_IconKind_FileOutline,
DF_IconKind_Null,
DF_IconKind_Pin,
DF_IconKind_CircleFilled,
DF_IconKind_CircleFilled,
DF_IconKind_Target,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Threads,
DF_IconKind_Thread,
DF_IconKind_Module,
DF_IconKind_Null,
DF_IconKind_Threads,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Null,
};
String8 df_g_entity_kind_display_string_table[26] =
{
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("Diagnostics Log"),
str8_lit_comp("Flash Marker"),
str8_lit_comp("Watch Pin"),
str8_lit_comp("Breakpoint"),
str8_lit_comp("Condition"),
str8_lit_comp("Target"),
str8_lit_comp("Executable"),
str8_lit_comp("Arguments"),
str8_lit_comp("Execution Path"),
str8_lit_comp("Entry Point Name"),
str8_lit_comp("Source"),
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("Conversion Task"),
str8_lit_comp("Conversion Failure"),
str8_lit_comp("EndedProcess"),
};
String8 df_g_entity_kind_name_label_table[26] =
{
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("Label"),
str8_lit_comp("Label"),
str8_lit_comp("Expression"),
str8_lit_comp("Label"),
str8_lit_comp("Expression"),
str8_lit_comp("Label"),
str8_lit_comp("Executable"),
str8_lit_comp("Arguments"),
str8_lit_comp("Execution Path"),
str8_lit_comp("Symbol Name"),
str8_lit_comp("Path"),
str8_lit_comp("Path"),
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("Label"),
str8_lit_comp("Label"),
};
DF_EntityKindFlags df_g_entity_kind_flags_table[26] =
{
(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 | 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),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*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 | 1*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 | 1*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 | 1*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 | 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 | 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),
(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),
};
DF_EntityOpFlags df_g_entity_kind_op_flags_table[26] =
{
(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) | (1*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*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),
(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),
(1*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (1*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (1*DF_EntityOpFlag_Enable) | (0*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),
(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),
(0*DF_EntityOpFlag_Delete) | (1*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (1*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*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) | (1*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) | (1*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) | (0*DF_EntityOpFlag_Duplicate),
};
String8 df_g_cfg_src_string_table[4] =
{
str8_lit_comp("user"),
str8_lit_comp("profile"),
str8_lit_comp("command_line"),
str8_lit_comp("transient"),
};
DF_CoreCmdKind df_g_cfg_src_load_cmd_kind_table[4] =
{
DF_CoreCmdKind_OpenUser,
DF_CoreCmdKind_OpenProfile,
DF_CoreCmdKind_Null,
DF_CoreCmdKind_Null,
};
DF_CoreCmdKind df_g_cfg_src_write_cmd_kind_table[4] =
{
DF_CoreCmdKind_WriteUserData,
DF_CoreCmdKind_WriteProfileData,
DF_CoreCmdKind_Null,
DF_CoreCmdKind_Null,
};
DF_CoreCmdKind df_g_cfg_src_apply_cmd_kind_table[4] =
{
DF_CoreCmdKind_ApplyUserData,
DF_CoreCmdKind_ApplyProfileData,
DF_CoreCmdKind_Null,
DF_CoreCmdKind_Null,
};
DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[206] =
{
{ str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp("Exit"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_X},
@@ -213,10 +419,11 @@ DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[] =
{ str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp("Toggle Developer Menu"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
};
DF_CoreViewRuleSpecInfo df_g_core_view_rule_spec_info_table[] =
DF_CoreViewRuleSpecInfo df_g_core_view_rule_spec_info_table[18] =
{
{str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, },
{str8_lit_comp("array"), str8_lit_comp("Array"), str8_lit_comp("Specifies that a pointer points to N elements, rather than only 1."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*1)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(array) , 0, },
{str8_lit_comp("slice"), str8_lit_comp("Slice"), str8_lit_comp("Specifies that a struct to be rendered as a slice."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*1)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(slice) , 0, },
{str8_lit_comp("list"), str8_lit_comp("List"), str8_lit_comp("Specifies that some struct, union, or class forms the top of a linked list, and the member which points at the following element in the list."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(list) , },
{str8_lit_comp("bswap"), str8_lit_comp("Byte Swap"), str8_lit_comp("Specifies that all integer primitives should be byte-swapped, such that their endianness is reversed."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*1)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(bswap) , 0, },
{str8_lit_comp("dec"), str8_lit_comp("Decimal Base (Base 10)"), str8_lit_comp("Specifies that all integral evaluations should appear in base-10 form."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, },
@@ -231,7 +438,81 @@ DF_CoreViewRuleSpecInfo df_g_core_view_rule_spec_info_table[] =
{str8_lit_comp("disasm"), str8_lit_comp("Disassembly"), str8_lit_comp("Displays as disassembled instructions, interpreting the data as raw machine code."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(disasm) , },
{str8_lit_comp("bitmap"), str8_lit_comp("Bitmap"), str8_lit_comp("Displays as a bitmap, interpreting the data as raw pixel data."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(bitmap) , },
{str8_lit_comp("geo"), str8_lit_comp("Geometry"), str8_lit_comp("Displays as geometry, interpreting the data as vertex data."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(geo) , },
{str8_lit_comp("slice"), str8_lit_comp("Slice"), str8_lit_comp("Specifies that some struct is to be rendered as a slice."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*1)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(slice) , 0, },
{str8_lit_comp("odin_map"), str8_lit_comp("Odin Map"), str8_lit_comp("Specifies that a struct to be rendered as an Odin map."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*1)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(odin_map) , 0, },
{str8_lit_comp("odin_map"), str8_lit_comp("Odin map"), str8_lit_comp("Specifies that a struct to be rendered as an Odin map type."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*1)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(odin_map) , 0, },
};
String8 df_g_icon_kind_text_table[69] =
{
str8_lit_comp(""),
str8_lit_comp("b"),
str8_lit_comp("c"),
str8_lit_comp("B"),
str8_lit_comp("C"),
str8_lit_comp("f"),
str8_lit_comp("F"),
str8_lit_comp("g"),
str8_lit_comp("h"),
str8_lit_comp("r"),
str8_lit_comp("s"),
str8_lit_comp("i"),
str8_lit_comp("w"),
str8_lit_comp("W"),
str8_lit_comp("k"),
str8_lit_comp("K"),
str8_lit_comp("L"),
str8_lit_comp("R"),
str8_lit_comp("U"),
str8_lit_comp("D"),
str8_lit_comp("G"),
str8_lit_comp("P"),
str8_lit_comp("3"),
str8_lit_comp("p"),
str8_lit_comp("O"),
str8_lit_comp("o"),
str8_lit_comp("!"),
str8_lit_comp("1"),
str8_lit_comp("<"),
str8_lit_comp(">"),
str8_lit_comp("^"),
str8_lit_comp("v"),
str8_lit_comp("9"),
str8_lit_comp("0"),
str8_lit_comp("7"),
str8_lit_comp("8"),
str8_lit_comp("+"),
str8_lit_comp("-"),
str8_lit_comp("'"),
str8_lit_comp("\""),
str8_lit_comp("M"),
str8_lit_comp("."),
str8_lit_comp("x"),
str8_lit_comp("q"),
str8_lit_comp("j"),
str8_lit_comp("u"),
str8_lit_comp("m"),
str8_lit_comp("n"),
str8_lit_comp("l"),
str8_lit_comp("a"),
str8_lit_comp("z"),
str8_lit_comp("y"),
str8_lit_comp("X"),
str8_lit_comp("Y"),
str8_lit_comp("S"),
str8_lit_comp("T"),
str8_lit_comp("Z"),
str8_lit_comp("d"),
str8_lit_comp("N"),
str8_lit_comp("E"),
str8_lit_comp("H"),
str8_lit_comp("e"),
str8_lit_comp("I"),
str8_lit_comp("J"),
str8_lit_comp("A"),
str8_lit_comp("?"),
str8_lit_comp("4"),
str8_lit_comp("5"),
str8_lit_comp("c"),
};
C_LINKAGE_END
+21 -300
View File
@@ -12,7 +12,7 @@ DF_CfgSrc_User,
DF_CfgSrc_Profile,
DF_CfgSrc_CommandLine,
DF_CfgSrc_Transient,
DF_CfgSrc_COUNT
DF_CfgSrc_COUNT,
} DF_CfgSrc;
typedef enum DF_EntityKind
@@ -35,7 +35,6 @@ DF_EntityKind_ExecutionPath,
DF_EntityKind_EntryPointName,
DF_EntityKind_Source,
DF_EntityKind_Dest,
DF_EntityKind_CtrlRequest,
DF_EntityKind_Process,
DF_EntityKind_Thread,
DF_EntityKind_Module,
@@ -44,17 +43,9 @@ DF_EntityKind_PendingThreadName,
DF_EntityKind_ConversionTask,
DF_EntityKind_ConversionFail,
DF_EntityKind_EndedProcess,
DF_EntityKind_COUNT
DF_EntityKind_COUNT,
} DF_EntityKind;
typedef enum DF_NameKind
{
DF_NameKind_Null,
DF_NameKind_EntityName,
DF_NameKind_EntityKindName,
DF_NameKind_COUNT
} DF_NameKind;
typedef enum DF_CoreCmdKind
{
DF_CoreCmdKind_Null,
@@ -263,7 +254,7 @@ DF_CoreCmdKind_PickFileOrFolder,
DF_CoreCmdKind_CompleteQuery,
DF_CoreCmdKind_CancelQuery,
DF_CoreCmdKind_ToggleDevMenu,
DF_CoreCmdKind_COUNT
DF_CoreCmdKind_COUNT,
} DF_CoreCmdKind;
typedef enum DF_IconKind
@@ -337,13 +328,14 @@ DF_IconKind_QuestionMark,
DF_IconKind_Person,
DF_IconKind_Briefcase,
DF_IconKind_Dot,
DF_IconKind_COUNT
DF_IconKind_COUNT,
} DF_IconKind;
typedef enum DF_CoreViewRuleKind
{
DF_CoreViewRuleKind_Null,
DF_CoreViewRuleKind_Array,
DF_CoreViewRuleKind_Slice,
DF_CoreViewRuleKind_List,
DF_CoreViewRuleKind_ByteSwap,
DF_CoreViewRuleKind_BaseDec,
@@ -358,9 +350,8 @@ DF_CoreViewRuleKind_Text,
DF_CoreViewRuleKind_Disasm,
DF_CoreViewRuleKind_Bitmap,
DF_CoreViewRuleKind_Geo,
DF_CoreViewRuleKind_Slice,
DF_CoreViewRuleKind_OdinMap,
DF_CoreViewRuleKind_COUNT
DF_CoreViewRuleKind_COUNT,
} DF_CoreViewRuleKind;
typedef enum DF_CmdParamSlot
@@ -384,7 +375,7 @@ DF_CmdParamSlot_Index,
DF_CmdParamSlot_ID,
DF_CmdParamSlot_PreferDisassembly,
DF_CmdParamSlot_ForceConfirm,
DF_CmdParamSlot_COUNT
DF_CmdParamSlot_COUNT,
} DF_CmdParamSlot;
typedef struct DF_CmdParams DF_CmdParams;
@@ -412,8 +403,8 @@ B32 force_confirm;
};
DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(array);
DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(bswap);
DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(slice);
DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(bswap);
DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(odin_map);
DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(list);
DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(only);
@@ -1519,288 +1510,18 @@ struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] =
{&DEV_scratch_mouse_draw, str8_lit_comp("scratch_mouse_draw")},
{&DEV_updating_indicator, str8_lit_comp("updating_indicator")},
};
Rng1U64 df_g_cmd_param_slot_range_table[] =
{
{0},
{OffsetOf(DF_CmdParams, window), OffsetOf(DF_CmdParams, window) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, panel), OffsetOf(DF_CmdParams, panel) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, dest_panel), OffsetOf(DF_CmdParams, dest_panel) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, prev_view), OffsetOf(DF_CmdParams, prev_view) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, view), OffsetOf(DF_CmdParams, view) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, entity), OffsetOf(DF_CmdParams, entity) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, entity_list), OffsetOf(DF_CmdParams, entity_list) + sizeof(DF_HandleList)},
{OffsetOf(DF_CmdParams, string), OffsetOf(DF_CmdParams, string) + sizeof(String8)},
{OffsetOf(DF_CmdParams, file_path), OffsetOf(DF_CmdParams, file_path) + sizeof(String8)},
{OffsetOf(DF_CmdParams, text_point), OffsetOf(DF_CmdParams, text_point) + sizeof(TxtPt)},
{OffsetOf(DF_CmdParams, cmd_spec), OffsetOf(DF_CmdParams, cmd_spec) + sizeof(struct DF_CmdSpec *)},
{OffsetOf(DF_CmdParams, view_spec), OffsetOf(DF_CmdParams, view_spec) + sizeof(struct DF_ViewSpec *)},
{OffsetOf(DF_CmdParams, vaddr), OffsetOf(DF_CmdParams, vaddr) + sizeof(U64)},
{OffsetOf(DF_CmdParams, voff), OffsetOf(DF_CmdParams, voff) + sizeof(U64)},
{OffsetOf(DF_CmdParams, index), OffsetOf(DF_CmdParams, index) + sizeof(U64)},
{OffsetOf(DF_CmdParams, id), OffsetOf(DF_CmdParams, id) + sizeof(U64)},
{OffsetOf(DF_CmdParams, prefer_dasm), OffsetOf(DF_CmdParams, prefer_dasm) + sizeof(B32)},
{OffsetOf(DF_CmdParams, force_confirm), OffsetOf(DF_CmdParams, force_confirm) + sizeof(B32)},
};
DF_IconKind df_g_entity_kind_icon_kind_table[] =
{
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Machine,
DF_IconKind_FileOutline,
DF_IconKind_FileOutline,
DF_IconKind_FileOutline,
DF_IconKind_FileOutline,
DF_IconKind_Null,
DF_IconKind_Pin,
DF_IconKind_CircleFilled,
DF_IconKind_CircleFilled,
DF_IconKind_Target,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Threads,
DF_IconKind_Thread,
DF_IconKind_Module,
DF_IconKind_Null,
DF_IconKind_Threads,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Null,
};
String8 df_g_entity_kind_display_string_table[] =
{
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("Diagnostics Log"),
str8_lit_comp("Flash Marker"),
str8_lit_comp("Watch Pin"),
str8_lit_comp("Breakpoint"),
str8_lit_comp("Condition"),
str8_lit_comp("Target"),
str8_lit_comp("Executable"),
str8_lit_comp("Arguments"),
str8_lit_comp("Execution Path"),
str8_lit_comp("Entry Point Name"),
str8_lit_comp("Source"),
str8_lit_comp("Destination"),
str8_lit_comp("Control Request"),
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("Conversion Task"),
str8_lit_comp("Conversion Failure"),
str8_lit_comp("EndedProcess"),
};
String8 df_g_entity_kind_name_label_table[] =
{
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("Label"),
str8_lit_comp("Label"),
str8_lit_comp("Expression"),
str8_lit_comp("Label"),
str8_lit_comp("Expression"),
str8_lit_comp("Label"),
str8_lit_comp("Executable"),
str8_lit_comp("Arguments"),
str8_lit_comp("Execution Path"),
str8_lit_comp("Symbol Name"),
str8_lit_comp("Path"),
str8_lit_comp("Path"),
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("Label"),
str8_lit_comp("Label"),
str8_lit_comp("Label"),
};
DF_EntityKindFlags df_g_entity_kind_flags_table[] =
{
(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 | 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),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*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 | 1*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 | 1*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 | 1*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 | 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 | 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),
(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),
};
DF_EntityOpFlags df_g_entity_kind_op_flags_table[] =
{
(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) | (1*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*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),
(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),
(1*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (1*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (1*DF_EntityOpFlag_Enable) | (0*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),
(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),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (1*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (1*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*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) | (1*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) | (1*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) | (0*DF_EntityOpFlag_Duplicate),
};
String8 df_g_cfg_src_string_table[] =
{
str8_lit_comp("user"),
str8_lit_comp("profile"),
str8_lit_comp("command_line"),
str8_lit_comp("transient"),
};
DF_CoreCmdKind df_g_cfg_src_load_cmd_kind_table[] =
{
DF_CoreCmdKind_OpenUser,
DF_CoreCmdKind_OpenProfile,
DF_CoreCmdKind_Null,
DF_CoreCmdKind_Null,
};
DF_CoreCmdKind df_g_cfg_src_write_cmd_kind_table[] =
{
DF_CoreCmdKind_WriteUserData,
DF_CoreCmdKind_WriteProfileData,
DF_CoreCmdKind_Null,
DF_CoreCmdKind_Null,
};
DF_CoreCmdKind df_g_cfg_src_apply_cmd_kind_table[] =
{
DF_CoreCmdKind_ApplyUserData,
DF_CoreCmdKind_ApplyProfileData,
DF_CoreCmdKind_Null,
DF_CoreCmdKind_Null,
};
String8 df_g_icon_kind_text_table[] =
{
str8_lit_comp(""),
str8_lit_comp("b"),
str8_lit_comp("c"),
str8_lit_comp("B"),
str8_lit_comp("C"),
str8_lit_comp("f"),
str8_lit_comp("F"),
str8_lit_comp("g"),
str8_lit_comp("h"),
str8_lit_comp("r"),
str8_lit_comp("s"),
str8_lit_comp("i"),
str8_lit_comp("w"),
str8_lit_comp("W"),
str8_lit_comp("k"),
str8_lit_comp("K"),
str8_lit_comp("L"),
str8_lit_comp("R"),
str8_lit_comp("U"),
str8_lit_comp("D"),
str8_lit_comp("G"),
str8_lit_comp("P"),
str8_lit_comp("3"),
str8_lit_comp("p"),
str8_lit_comp("O"),
str8_lit_comp("o"),
str8_lit_comp("!"),
str8_lit_comp("1"),
str8_lit_comp("<"),
str8_lit_comp(">"),
str8_lit_comp("^"),
str8_lit_comp("v"),
str8_lit_comp("9"),
str8_lit_comp("0"),
str8_lit_comp("7"),
str8_lit_comp("8"),
str8_lit_comp("+"),
str8_lit_comp("-"),
str8_lit_comp("'"),
str8_lit_comp("\""),
str8_lit_comp("M"),
str8_lit_comp("."),
str8_lit_comp("x"),
str8_lit_comp("q"),
str8_lit_comp("j"),
str8_lit_comp("u"),
str8_lit_comp("m"),
str8_lit_comp("n"),
str8_lit_comp("l"),
str8_lit_comp("a"),
str8_lit_comp("z"),
str8_lit_comp("y"),
str8_lit_comp("X"),
str8_lit_comp("Y"),
str8_lit_comp("S"),
str8_lit_comp("T"),
str8_lit_comp("Z"),
str8_lit_comp("d"),
str8_lit_comp("N"),
str8_lit_comp("E"),
str8_lit_comp("H"),
str8_lit_comp("e"),
str8_lit_comp("I"),
str8_lit_comp("J"),
str8_lit_comp("A"),
str8_lit_comp("?"),
str8_lit_comp("4"),
str8_lit_comp("5"),
str8_lit_comp("c"),
};
C_LINKAGE_BEGIN
extern Rng1U64 df_g_cmd_param_slot_range_table[19];
extern DF_IconKind df_g_entity_kind_icon_kind_table[26];
extern String8 df_g_entity_kind_display_string_table[26];
extern String8 df_g_entity_kind_name_label_table[26];
extern DF_EntityKindFlags df_g_entity_kind_flags_table[26];
extern DF_EntityOpFlags df_g_entity_kind_op_flags_table[26];
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];
extern DF_CoreCmdKind df_g_cfg_src_apply_cmd_kind_table[4];
extern String8 df_g_icon_kind_text_table[69];
C_LINKAGE_END
#endif // DF_CORE_META_H
+791 -665
View File
File diff suppressed because it is too large Load Diff
+21 -83
View File
@@ -47,71 +47,6 @@ struct DF_StringBindingPair
DF_Binding binding;
};
////////////////////////////////
//~ rjf: Text Searching Types
typedef struct DF_TextSearchMatch DF_TextSearchMatch;
struct DF_TextSearchMatch
{
TxtPt pt;
};
typedef struct DF_TextSearchMatchChunkNode DF_TextSearchMatchChunkNode;
struct DF_TextSearchMatchChunkNode
{
DF_TextSearchMatchChunkNode *next;
DF_TextSearchMatch *v;
U64 count;
U64 cap;
};
typedef struct DF_TextSearchMatchChunkList DF_TextSearchMatchChunkList;
struct DF_TextSearchMatchChunkList
{
DF_TextSearchMatchChunkNode *first;
DF_TextSearchMatchChunkNode *last;
U64 node_count;
U64 total_count;
};
typedef struct DF_TextSearchMatchArray DF_TextSearchMatchArray;
struct DF_TextSearchMatchArray
{
DF_TextSearchMatch *v;
U64 count;
};
typedef struct DF_TextSearchCacheNode DF_TextSearchCacheNode;
struct DF_TextSearchCacheNode
{
// rjf: links
DF_TextSearchCacheNode *next;
DF_TextSearchCacheNode *prev;
// rjf: allocation
Arena *arena;
// rjf: search parameters
U128 hash;
String8 needle;
DF_TextSliceFlags flags;
TxtPt start_pt;
// rjf: search results
B32 good;
DF_TextSearchMatchChunkList search_matches;
// rjf: last time touched
U64 last_time_touched_us;
};
typedef struct DF_TextSearchCacheSlot DF_TextSearchCacheSlot;
struct DF_TextSearchCacheSlot
{
DF_TextSearchCacheNode *first;
DF_TextSearchCacheNode *last;
};
////////////////////////////////
//~ rjf: Key Map Types
@@ -178,7 +113,7 @@ struct DF_ViewSpecInfo
DF_ViewSpecFlags flags;
String8 name;
String8 display_string;
DF_NameKind name_kind;
enum DF_NameKind name_kind;
DF_IconKind icon_kind;
DF_ViewSetupFunctionType *setup_hook;
DF_ViewStringFromStateFunctionType *string_from_state_hook;
@@ -346,6 +281,7 @@ enum
DF_GfxViewRuleSpecInfoFlag_LineStringize = (1<<1),
DF_GfxViewRuleSpecInfoFlag_RowUI = (1<<2),
DF_GfxViewRuleSpecInfoFlag_BlockUI = (1<<3),
DF_GfxViewRuleSpecInfoFlag_WholeUI = (1<<4),
};
#define DF_GFX_VIEW_RULE_VIZ_ROW_PROD_FUNCTION_SIG(name) void name(void)
@@ -364,10 +300,15 @@ enum
#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))
#define DF_GFX_VIEW_RULE_WHOLE_UI_FUNCTION_SIG(name) void name(struct DF_Window *ws, struct DF_Panel *panel, struct DF_View *view, Rng2F32 rect, DBGI_Scope *dbgi_scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, struct DF_CfgNode *cfg)
#define DF_GFX_VIEW_RULE_WHOLE_UI_FUNCTION_NAME(name) df_gfx_view_rule_whole_ui__##name
#define DF_GFX_VIEW_RULE_WHOLE_UI_FUNCTION_DEF(name) DF_GFX_VIEW_RULE_WHOLE_UI_FUNCTION_SIG(DF_GFX_VIEW_RULE_WHOLE_UI_FUNCTION_NAME(name))
typedef DF_GFX_VIEW_RULE_VIZ_ROW_PROD_FUNCTION_SIG(DF_GfxViewRuleVizRowProdHookFunctionType);
typedef DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_SIG(DF_GfxViewRuleLineStringizeHookFunctionType);
typedef DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_SIG(DF_GfxViewRuleRowUIFunctionType);
typedef DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_SIG(DF_GfxViewRuleBlockUIFunctionType);
typedef DF_GFX_VIEW_RULE_WHOLE_UI_FUNCTION_SIG(DF_GfxViewRuleWholeUIFunctionType);
typedef struct DF_GfxViewRuleSpecInfo DF_GfxViewRuleSpecInfo;
struct DF_GfxViewRuleSpecInfo
@@ -378,6 +319,7 @@ struct DF_GfxViewRuleSpecInfo
DF_GfxViewRuleLineStringizeHookFunctionType *line_stringize;
DF_GfxViewRuleRowUIFunctionType *row_ui;
DF_GfxViewRuleBlockUIFunctionType *block_ui;
DF_GfxViewRuleWholeUIFunctionType *whole_ui;
};
typedef struct DF_GfxViewRuleSpecInfoArray DF_GfxViewRuleSpecInfoArray;
@@ -441,8 +383,9 @@ enum
typedef U32 DF_CodeSliceFlags;
enum
{
DF_CodeSliceFlag_Margin = (1<<0),
DF_CodeSliceFlag_LineNums = (1<<1),
DF_CodeSliceFlag_Clickable = (1<<0),
DF_CodeSliceFlag_Margin = (1<<1),
DF_CodeSliceFlag_LineNums = (1<<2),
};
typedef struct DF_CodeSliceParams DF_CodeSliceParams;
@@ -453,7 +396,7 @@ struct DF_CodeSliceParams
Rng1S64 line_num_range;
String8 *line_text;
Rng1U64 *line_ranges;
TXTI_TokenArray *line_tokens;
TXT_TokenArray *line_tokens;
DF_EntityList *line_bps;
DF_EntityList *line_ips;
DF_EntityList *line_pins;
@@ -961,7 +904,7 @@ internal void df_window_update_and_render(Arena *arena, OS_EventList *events, DF
//~ rjf: Eval Viz
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, RADDBG_Parsed *rdbg, 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 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);
////////////////////////////////
@@ -985,17 +928,6 @@ internal void df_set_autocomp_lister_query(DF_Window *ws, UI_Key root_key, DF_Ct
internal void df_set_search_string(String8 string);
internal String8 df_push_search_string(Arena *arena);
////////////////////////////////
//~ rjf: Text Searching
internal void df_text_search_match_chunk_list_push(Arena *arena, DF_TextSearchMatchChunkList *list, U64 cap, DF_TextSearchMatch *match);
internal DF_TextSearchMatchArray df_text_search_match_array_from_chunk_list(Arena *arena, DF_TextSearchMatchChunkList *chunks);
internal U64 df_text_search_little_hash_from_hash(U128 hash);
internal void df_text_search_thread_entry_point(void *p);
internal int df_text_search_match_array_qsort_compare(TxtPt *a, TxtPt *b);
internal void df_text_search_match_array_sort_in_place(DF_TextSearchMatchArray *array);
internal DF_TextSearchMatch df_text_search_match_array_find_nearest__linear_scan(DF_TextSearchMatchArray *array, TxtPt pt, Side side);
////////////////////////////////
//~ rjf: Colors, Fonts, Config
@@ -1010,7 +942,7 @@ internal DF_CmdSpecList df_cmd_spec_list_from_event_flags(Arena *arena, OS_Event
//- rjf: colors
internal Vec4F32 df_rgba_from_theme_color(DF_ThemeColor color);
internal DF_ThemeColor df_theme_color_from_txti_token_kind(TXTI_TokenKind kind);
internal DF_ThemeColor df_theme_color_from_txt_token_kind(TXT_TokenKind kind);
//- rjf: fonts/sizes
internal F_Tag df_font_from_slot(DF_FontSlot slot);
@@ -1019,6 +951,12 @@ internal F32 df_font_size_from_slot(DF_Window *ws, DF_FontSlot slot);
//- rjf: config serialization
internal String8List df_cfg_strings_from_gfx(Arena *arena, String8 root_path, DF_CfgSrc source);
////////////////////////////////
//~ rjf: Process Control Info Stringification
internal String8 df_string_from_exception_code(U32 code);
internal String8 df_stop_explanation_string_icon_from_ctrl_event(Arena *arena, CTRL_Event *event, DF_IconKind *icon_out);
////////////////////////////////
//~ rjf: UI Widgets: Fancy Buttons
@@ -1040,8 +978,8 @@ internal UI_BOX_CUSTOM_DRAW(df_bp_box_draw_extensions);
internal DF_CodeSliceSignal df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *preferred_column, String8 string);
internal DF_CodeSliceSignal df_code_slicef(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *preferred_column, char *fmt, ...);
internal B32 df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, TxtPt *cursor, TxtPt *mark, S64 *preferred_column);
internal B32 df_do_txti_controls(TXTI_Handle handle, U64 line_count_per_page, TxtPt *cursor, TxtPt *mark, S64 *preferred_column);
internal B32 df_do_dasm_controls(DASM_Handle handle, U64 line_count_per_page, TxtPt *cursor, TxtPt *mark, S64 *preferred_column);
////////////////////////////////
//~ rjf: UI Widgets: Fancy Labels
+89 -98
View File
@@ -177,6 +177,14 @@ DF_BindingVersionRemapTable:
////////////////////////////////
//~ rjf: Gfx Layer View Kinds
@table(name)
DF_NameKindTable:
{
{Null}
{EntityName}
{EntityKindName}
}
@table(name, name_lower, display_string, name_kind, icon, parameterized_by_entity, can_serialize, can_serialize_entity_path, can_filter, filter_is_code, typing_automatically_filters, inc_in_docs, docs_desc)
DF_GfxViewTable:
{
@@ -196,6 +204,7 @@ DF_GfxViewTable:
{ PendingEntity "pending_entity" "Pending Entity" EntityName FileOutline 1 0 0 0 0 0 0 "" }
{ Code "code" "Code" EntityName FileOutline 1 1 1 0 0 0 0 "" }
{ Disassembly "disassembly" "Disassembly" Null Glasses 0 1 0 0 0 0 1 "Displays disassembled instructions in a textual form from the selected thread's containing process virtual address space." }
{ EvalViewer "eval_viewer" "Evaluation Viewer" Null Binoculars 0 1 0 0 0 0 0 "." }
{ Watch "watch" "Watch" Null Binoculars 0 1 0 1 1 1 1 "The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section." }
{ Locals "locals" "Locals" Null Binoculars 0 1 0 1 1 1 1 "Nearly identical to `Watch`, but automatically filled with local variables found within the selected call stack frame of the selected thread, according to the associated debug info. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." }
{ Registers "registers" "Registers" Null Binoculars 0 1 0 1 1 1 1 "Nearly identical to `Watch`, but automatically filled with all register names according to the selected thread's architecture. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." }
@@ -231,23 +240,23 @@ DF_CmdParamSlot2ViewSpecMap:
//
// NOTE(rjf): see @view_rule_info
@table(string vr ls ru bu)
@table(string vr ls ru bu wu)
DF_GfxViewRuleTable:
{
{"array" - - - -}
{"list" x - - -}
{"dec" - x - -}
{"bin" - x - -}
{"oct" - x - -}
{"hex" - x - -}
{"only" x x - -}
{"omit" x x - -}
{"no_addr" - x - -}
{"rgba" - - x x}
{"text" - - - x}
{"disasm" - - - x}
{"bitmap" - - x x}
{"geo" - - x x}
{"array" - - - - - }
{"list" x - - - - }
{"dec" - x - - - }
{"bin" - x - - - }
{"oct" - x - - - }
{"hex" - x - - - }
{"only" x x - - - }
{"omit" x x - - - }
{"no_addr" - x - - - }
{"rgba" - - x x - }
{"text" - - - x - }
{"disasm" - - - x - }
{"bitmap" - - x x x }
{"geo" - - x x - }
}
////////////////////////////////
@@ -265,6 +274,7 @@ DF_ThemeTable:
{CodeFunction "Code (Function)" code_function }
{CodeType "Code (Type)" code_type }
{CodeLocal "Code (Local)" code_local }
{CodeRegister "Code (Register)" code_register }
{CodeKeyword "Code (Keyword)" code_keyword }
{CodeSymbol "Code (Symbol)" code_symbol }
{CodeNumeric "Code (Numeric)" code_numeric }
@@ -349,6 +359,7 @@ DF_ThemePresetColorTable:
(code_function 0x7fcc99ff 0x2a7a45ff 0xdcdcaaff 0x74531fff 0x1c7dd1ff 0xc39d36ff 0xcc5735ff 0x7fcc99ff 0x49b2ffff )
(code_type 0x66b2e5ff 0x2c688fff 0x4ec9b0ff 0x2b91afff 0x1c7dd1ff 0x66b2e5ff 0xd8a51dff 0x66b2e5ff 0x49b2ffff )
(code_local 0xfe9548ff 0xfe9548ff 0xfe9548ff 0xfe9548ff 0xfe9548ff 0xfe9548ff 0xfe9548ff 0xfe9548ff 0xfe9548ff )
(code_register 0xd45d90ff 0xd45d90ff 0xd45d90ff 0xd45d90ff 0xd45d90ff 0xd45d90ff 0xd45d90ff 0xd45d90ff 0xd45d90ff )
(code_keyword 0xf7bf5eff 0xa47729ff 0x569cd6ff 0x0000ffff 0x63980fff 0xc39d36ff 0xac7b0bff 0xd08f20ff 0xff0000ff )
(code_symbol 0x994c32ff 0x6c2d18ff 0xb4b4b4ff 0x000000ff 0x839496ff 0x2e5256ff 0x994c32ff 0x994c32ff 0xffffffff )
(code_numeric 0x4ce54cff 0x2c7d2cff 0xb5cea8ff 0x000000ff 0xcb4b20ff 0x657b83ff 0x6b8e23ff 0x50ff30ff 0x2cff50ff )
@@ -400,149 +411,131 @@ DF_ThemePresetColorTable:
//- rjf: enums
@table_gen_enum
DF_GfxViewKind:
@enum DF_NameKind:
{
@expand(DF_GfxViewTable a)
`DF_GfxViewKind_$(a.name),`
`DF_GfxViewKind_COUNT`;
@expand(DF_NameKindTable, a) `$(a.name)`,
COUNT,
}
@table_gen_enum
DF_ThemeColor:
@enum DF_GfxViewKind:
{
@expand(DF_ThemeTable, a)
`DF_ThemeColor_$(a.name),`;
`DF_ThemeColor_COUNT`;
@expand(DF_GfxViewTable a) `$(a.name)`,
COUNT,
}
@table_gen_enum
DF_ThemePreset:
@enum DF_ThemeColor:
{
@expand(DF_ThemePresetTable a)
`DF_ThemePreset_$(a.name),`;
`DF_ThemePreset_COUNT`;
@expand(DF_ThemeTable a) `$(a.name)`,
COUNT,
}
@enum DF_ThemePreset:
{
@expand(DF_ThemePresetTable a) `$(a.name)`,
COUNT,
}
//- rjf: theme preset color tables
@table_gen_data(type: String8, fallback: `{0}`)
df_g_theme_preset_display_string_table:
@data(String8) df_g_theme_preset_display_string_table:
{
@expand(DF_ThemePresetTable a) `str8_lit_comp("$(a.display_string)"),`;
@expand(DF_ThemePresetTable a) `str8_lit_comp("$(a.display_string)")`,
}
@table_gen_data(type: String8, fallback: `{0}`)
df_g_theme_preset_code_string_table:
@data(String8) df_g_theme_preset_code_string_table:
{
@expand(DF_ThemePresetTable a) `str8_lit_comp("$(a.name_lower)"),`;
@expand(DF_ThemePresetTable a) `str8_lit_comp("$(a.name_lower)")`,
}
@table_gen_data(type: Vec4F32, fallback: `{1, 0, 1, 1}`)
df_g_theme_preset_colors__default_dark:
@data(Vec4F32) df_g_theme_preset_colors__default_dark:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.default_dark)),`;
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.default_dark))`,
}
@table_gen_data(type: Vec4F32, fallback: `{1, 0, 1, 1}`)
df_g_theme_preset_colors__default_light:
@data(Vec4F32) df_g_theme_preset_colors__default_light:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.default_light)),`;
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.default_light))`,
}
@table_gen_data(type: Vec4F32, fallback: `{1, 0, 1, 1}`)
df_g_theme_preset_colors__vs_dark:
@data(Vec4F32) df_g_theme_preset_colors__vs_dark:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.vs_dark)),`;
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.vs_dark))`,
}
@table_gen_data(type: Vec4F32, fallback: `{1, 0, 1, 1}`)
df_g_theme_preset_colors__vs_light:
@data(Vec4F32) df_g_theme_preset_colors__vs_light:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.vs_light)),`;
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.vs_light))`,
}
@table_gen_data(type: Vec4F32, fallback: `{1, 0, 1, 1}`)
df_g_theme_preset_colors__solarized_dark:
@data(Vec4F32) df_g_theme_preset_colors__solarized_dark:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.solarized_dark)),`;
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.solarized_dark))`,
}
@table_gen_data(type: Vec4F32, fallback: `{1, 0, 1, 1}`)
df_g_theme_preset_colors__solarized_light:
@data(Vec4F32) df_g_theme_preset_colors__solarized_light:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.solarized_light)),`;
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.solarized_light))`,
}
@table_gen_data(type: Vec4F32, fallback: `{1, 0, 1, 1}`)
df_g_theme_preset_colors__handmade_hero:
@data(Vec4F32) df_g_theme_preset_colors__handmade_hero:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.handmade_hero)),`;
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.handmade_hero))`,
}
@table_gen_data(type: Vec4F32, fallback: `{1, 0, 1, 1}`)
df_g_theme_preset_colors__four_coder:
@data(Vec4F32) df_g_theme_preset_colors__four_coder:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.four_coder)),`;
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.four_coder))`,
}
@table_gen_data(type: Vec4F32, fallback: `{1, 0, 1, 1}`)
df_g_theme_preset_colors__far_manager:
@data(Vec4F32) df_g_theme_preset_colors__far_manager:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.far_manager)),`;
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.far_manager))`;
}
@table_gen_data(type: `Vec4F32 *`, fallback: `0`)
df_g_theme_preset_colors_table:
@data(`Vec4F32*`) df_g_theme_preset_colors_table:
{
@expand(DF_ThemePresetTable a) `df_g_theme_preset_colors__$(a.name_lower),`;
@expand(DF_ThemePresetTable a) `df_g_theme_preset_colors__$(a.name_lower)`,
}
//- rjf: cmd param slot -> view spec tables
@table_gen_data(type: DF_CmdParamSlot, fallback:`DF_CmdParamSlot_Null`)
df_g_cmd_param_slot_2_view_spec_src_map:
@data(DF_CmdParamSlot) df_g_cmd_param_slot_2_view_spec_src_map:
{
@expand(DF_CmdParamSlot2ViewSpecMap a) `DF_CmdParamSlot_$(a.slot),`
@expand(DF_CmdParamSlot2ViewSpecMap a) `DF_CmdParamSlot_$(a.slot)`
}
@table_gen_data(type: String8, fallback:`{0}`)
df_g_cmd_param_slot_2_view_spec_dst_map:
@data(String8) df_g_cmd_param_slot_2_view_spec_dst_map:
{
@expand(DF_CmdParamSlot2ViewSpecMap a) `str8_lit_comp("$(a.view_spec)"),`
@expand(DF_CmdParamSlot2ViewSpecMap a) `str8_lit_comp("$(a.view_spec)")`
}
@table_gen_data(type: String8, fallback:`{0}`)
df_g_cmd_param_slot_2_view_spec_cmd_map:
@data(String8) df_g_cmd_param_slot_2_view_spec_cmd_map:
{
@expand(DF_CmdParamSlot2ViewSpecMap a) `str8_lit_comp("$(a.opt_cmd_spec)"),`
@expand(DF_CmdParamSlot2ViewSpecMap a) `str8_lit_comp("$(a.opt_cmd_spec)")`
}
//- rjf: default bindings table
@table_gen_data(type: DF_StringBindingPair, fallback: `{0}`)
df_g_default_binding_table:
@data(DF_StringBindingPair) df_g_default_binding_table:
{
@expand(DF_DefaultBindingTable a) ```{str8_lit_comp("$(a.name)"), {OS_Key_$(a.key), 0 $(a.ctrl != 0 -> `|OS_EventFlag_Ctrl`) $(a.shift != 0 -> `|OS_EventFlag_Shift`) $(a.alt != 0 -> `|OS_EventFlag_Alt`)}},```;
@expand(DF_DefaultBindingTable a) ```{str8_lit_comp("$(a.name)"), {OS_Key_$(a.key), 0 $(a.ctrl != 0 -> `|OS_EventFlag_Ctrl`) $(a.shift != 0 -> `|OS_EventFlag_Shift`) $(a.alt != 0 -> `|OS_EventFlag_Alt`)}}```;
}
//- rjf: binding version remap tables
@table_gen_data(type: String8, fallback: `{0}`)
df_g_binding_version_remap_old_name_table:
@data(String8) df_g_binding_version_remap_old_name_table:
{
@expand(DF_BindingVersionRemapTable a) `str8_lit_comp("$(a.old_name)"),`
@expand(DF_BindingVersionRemapTable a) `str8_lit_comp("$(a.old_name)")`
}
@table_gen_data(type: String8, fallback: `{0}`)
df_g_binding_version_remap_new_name_table:
@data(String8) df_g_binding_version_remap_new_name_table:
{
@expand(DF_BindingVersionRemapTable a) `str8_lit_comp("$(a.new_name)"),`
@expand(DF_BindingVersionRemapTable a) `str8_lit_comp("$(a.new_name)")`
}
//- rjf: view hook forward declares
@table_gen
@gen
{
@expand(DF_GfxViewTable a) `DF_VIEW_SETUP_FUNCTION_DEF($(a.name));`;
@expand(DF_GfxViewTable a) `DF_VIEW_STRING_FROM_STATE_FUNCTION_DEF($(a.name));`;
@@ -552,7 +545,7 @@ df_g_binding_version_remap_new_name_table:
//- rjf: gfx view rule function forward declares
@table_gen
@gen
{
``;
@expand(DF_GfxViewRuleTable a)
@@ -563,37 +556,35 @@ df_g_binding_version_remap_new_name_table:
`$(a.ru == "x" -> "DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_DEF(" .. a.name_lower .. ");")`;
@expand(DF_GfxViewRuleTable a)
`$(a.bu == "x" -> "DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(" .. a.name_lower .. ");")`;
@expand(DF_GfxViewRuleTable a)
`$(a.wu == "x" -> "DF_GFX_VIEW_RULE_WHOLE_UI_FUNCTION_DEF(" .. a.name_lower .. ");")`;
}
//- rjf: gfx view rule tables
@table_gen_data(type: DF_GfxViewRuleSpecInfo, fallback: `{0}`) @c_file
df_g_gfx_view_rule_spec_info_table:
@data(DF_GfxViewRuleSpecInfo) @c_file df_g_gfx_view_rule_spec_info_table:
{
@expand(DF_GfxViewRuleTable a)
```{ str8_lit_comp("$(a.string)"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*$(a.vr == "x"))|(DF_GfxViewRuleSpecInfoFlag_LineStringize*$(a.ls == "x"))|(DF_GfxViewRuleSpecInfoFlag_RowUI*$(a.ru == "x"))|(DF_GfxViewRuleSpecInfoFlag_BlockUI*$(a.bu == "x")), $(a.vr == "x" -> "DF_GFX_VIEW_RULE_VIZ_ROW_PROD_FUNCTION_NAME("..a.name_lower..")") $(a.vr != "x" -> 0), $(a.ls == "x" -> "DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME("..a.name_lower..")") $(a.ls != "x" -> 0), $(a.ru == "x" -> "DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_NAME("..a.name_lower..")") $(a.ru != "x" -> 0), $(a.bu == "x" -> "DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME("..a.name_lower..")") $(a.bu != "x" -> 0), },```;
```{ str8_lit_comp("$(a.string)"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*$(a.vr == "x"))|(DF_GfxViewRuleSpecInfoFlag_LineStringize*$(a.ls == "x"))|(DF_GfxViewRuleSpecInfoFlag_RowUI*$(a.ru == "x"))|(DF_GfxViewRuleSpecInfoFlag_BlockUI*$(a.bu == "x")), $(a.vr == "x" -> "DF_GFX_VIEW_RULE_VIZ_ROW_PROD_FUNCTION_NAME("..a.name_lower..")") $(a.vr != "x" -> 0), $(a.ls == "x" -> "DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME("..a.name_lower..")") $(a.ls != "x" -> 0), $(a.ru == "x" -> "DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_NAME("..a.name_lower..")") $(a.ru != "x" -> 0), $(a.bu == "x" -> "DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME("..a.name_lower..")") $(a.bu != "x" -> 0), $(a.wu == "x" -> "DF_GFX_VIEW_RULE_WHOLE_UI_FUNCTION_NAME("..a.name_lower..")") $(a.wu != "x" -> 0) }```;
}
//- rjf: default view spec info table
@table_gen_data(type: DF_ViewSpecInfo, fallback: `{0}`)
df_g_gfx_view_kind_spec_info_table:
@data(DF_ViewSpecInfo) df_g_gfx_view_kind_spec_info_table:
{
@expand(DF_GfxViewTable a) ```{(0|$(a.parameterized_by_entity)*DF_ViewSpecFlag_ParameterizedByEntity|$(a.can_serialize)*DF_ViewSpecFlag_CanSerialize|$(a.can_serialize_entity_path)*DF_ViewSpecFlag_CanSerializeEntityPath|$(a.can_filter)*DF_ViewSpecFlag_CanFilter|$(a.filter_is_code)*DF_ViewSpecFlag_FilterIsCode|$(a.typing_automatically_filters)*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("$(a.name_lower)"), str8_lit_comp("$(a.display_string)"), DF_NameKind_$(a.name_kind), DF_IconKind_$(a.icon), DF_VIEW_SETUP_FUNCTION_NAME($(a.name)), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME($(a.name)), DF_VIEW_CMD_FUNCTION_NAME($(a.name)), DF_VIEW_UI_FUNCTION_NAME($(a.name))},```;
@expand(DF_GfxViewTable a) ```{(0|$(a.parameterized_by_entity)*DF_ViewSpecFlag_ParameterizedByEntity|$(a.can_serialize)*DF_ViewSpecFlag_CanSerialize|$(a.can_serialize_entity_path)*DF_ViewSpecFlag_CanSerializeEntityPath|$(a.can_filter)*DF_ViewSpecFlag_CanFilter|$(a.filter_is_code)*DF_ViewSpecFlag_FilterIsCode|$(a.typing_automatically_filters)*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("$(a.name_lower)"), str8_lit_comp("$(a.display_string)"), DF_NameKind_$(a.name_kind), DF_IconKind_$(a.icon), DF_VIEW_SETUP_FUNCTION_NAME($(a.name)), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME($(a.name)), DF_VIEW_CMD_FUNCTION_NAME($(a.name)), DF_VIEW_UI_FUNCTION_NAME($(a.name))}```;
}
//- rjf: theme color tables
@table_gen_data(type: String8, fallback: `str8_lit_comp("")`)
df_g_theme_color_display_string_table:
@data(String8) df_g_theme_color_display_string_table:
{
@expand(DF_ThemeTable a) `str8_lit_comp("$(a.display_name)"),`;
@expand(DF_ThemeTable a) `str8_lit_comp("$(a.display_name)")`
}
@table_gen_data(type: String8, fallback: `str8_lit_comp("")`)
df_g_theme_color_cfg_string_table:
@data(String8) df_g_theme_color_cfg_string_table:
{
@expand(DF_ThemeTable a) `str8_lit_comp("$(a.name_lower)"),`;
@expand(DF_ThemeTable a) `str8_lit_comp("$(a.name_lower)")`
}
////////////////////////////////
+433 -205
View File
@@ -5,7 +5,7 @@
//~ rjf: Helpers
internal Vec4F32
df_view_rule_hooks__rgba_from_eval(DF_Eval eval, TG_Graph *graph, RADDBG_Parsed *raddbg, DF_Entity *process)
df_view_rule_hooks__rgba_from_eval(DF_Eval eval, TG_Graph *graph, RDI_Parsed *raddbg, DF_Entity *process)
{
Vec4F32 rgba = {0};
Temp scratch = scratch_begin(0, 0);
@@ -27,14 +27,14 @@ df_view_rule_hooks__rgba_from_eval(DF_Eval eval, TG_Graph *graph, RADDBG_Parsed
case TG_Kind_Array:
if(eval.mode == EVAL_EvalMode_Addr)
{
U64 array_total_size = tg_byte_size_from_graph_raddbg_key(graph, raddbg, type_key);
U64 array_total_size = tg_byte_size_from_graph_rdi_key(graph, raddbg, type_key);
U64 array_total_size_capped = ClampTop(array_total_size, 64);
Rng1U64 array_memory_vaddr_rng = r1u64(eval.offset, eval.offset + array_total_size_capped);
CTRL_ProcessMemorySlice array_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->ctrl_machine_id, process->ctrl_handle, array_memory_vaddr_rng, 0);
String8 array_memory = array_slice.data;
TG_Key element_type_key = tg_unwrapped_direct_from_graph_raddbg_key(graph, raddbg, type_key);
TG_Key element_type_key = tg_unwrapped_direct_from_graph_rdi_key(graph, raddbg, type_key);
TG_Kind element_type_kind = tg_kind_from_key(element_type_key);
U64 element_type_size = tg_byte_size_from_graph_raddbg_key(graph, raddbg, element_type_key);
U64 element_type_size = tg_byte_size_from_graph_rdi_key(graph, raddbg, element_type_key);
for(U64 element_idx = 0; element_idx < 4; element_idx += 1)
{
U64 offset = element_idx*element_type_size;
@@ -64,12 +64,12 @@ df_view_rule_hooks__rgba_from_eval(DF_Eval eval, TG_Graph *graph, RADDBG_Parsed
case TG_Kind_Union:
if(eval.mode == EVAL_EvalMode_Addr)
{
U64 struct_total_size = tg_byte_size_from_graph_raddbg_key(graph, raddbg, type_key);
U64 struct_total_size = tg_byte_size_from_graph_rdi_key(graph, raddbg, type_key);
U64 struct_total_size_capped = ClampTop(struct_total_size, 64);
Rng1U64 struct_memory_vaddr_rng = r1u64(eval.offset, eval.offset + struct_total_size_capped);
CTRL_ProcessMemorySlice struct_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->ctrl_machine_id, process->ctrl_handle, struct_memory_vaddr_rng, 0);
String8 struct_memory = struct_slice.data;
TG_Type *type = tg_type_from_graph_raddbg_key(scratch.arena, graph, raddbg, type_key);
TG_Type *type = tg_type_from_graph_rdi_key(scratch.arena, graph, raddbg, type_key);
for(U64 element_idx = 0, member_idx = 0;
element_idx < 4 && member_idx < type->count;
member_idx += 1)
@@ -102,7 +102,7 @@ df_view_rule_hooks__rgba_from_eval(DF_Eval eval, TG_Graph *graph, RADDBG_Parsed
}
internal void
df_view_rule_hooks__eval_commit_rgba(DF_Eval eval, TG_Graph *graph, RADDBG_Parsed *raddbg, DF_CtrlCtx *ctrl_ctx, Vec4F32 rgba)
df_view_rule_hooks__eval_commit_rgba(DF_Eval eval, TG_Graph *graph, RDI_Parsed *raddbg, DF_CtrlCtx *ctrl_ctx, Vec4F32 rgba)
{
TG_Key type_key = eval.type_key;
TG_Kind type_kind = tg_kind_from_key(type_key);
@@ -126,13 +126,13 @@ df_view_rule_hooks__eval_commit_rgba(DF_Eval eval, TG_Graph *graph, RADDBG_Parse
case TG_Kind_Array:
if(eval.mode == EVAL_EvalMode_Addr)
{
U64 array_total_size = tg_byte_size_from_graph_raddbg_key(graph, raddbg, type_key);
U64 array_total_size = tg_byte_size_from_graph_rdi_key(graph, raddbg, type_key);
U64 array_total_size_capped = ClampTop(array_total_size, 64);
Rng1U64 array_memory_vaddr_rng = r1u64(eval.offset, eval.offset + array_total_size_capped);
String8 array_memory = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->ctrl_machine_id, process->ctrl_handle, array_memory_vaddr_rng);
TG_Key element_type_key = tg_unwrapped_direct_from_graph_raddbg_key(graph, raddbg, type_key);
TG_Key element_type_key = tg_unwrapped_direct_from_graph_rdi_key(graph, raddbg, type_key);
TG_Kind element_type_kind = tg_kind_from_key(element_type_key);
U64 element_type_size = tg_byte_size_from_graph_raddbg_key(graph, raddbg, element_type_key);
U64 element_type_size = tg_byte_size_from_graph_rdi_key(graph, raddbg, element_type_key);
for(U64 element_idx = 0; element_idx < 4; element_idx += 1)
{
U64 offset = element_idx*element_type_size;
@@ -162,11 +162,11 @@ df_view_rule_hooks__eval_commit_rgba(DF_Eval eval, TG_Graph *graph, RADDBG_Parse
case TG_Kind_Union:
if(eval.mode == EVAL_EvalMode_Addr)
{
U64 struct_total_size = tg_byte_size_from_graph_raddbg_key(graph, raddbg, type_key);
U64 struct_total_size = tg_byte_size_from_graph_rdi_key(graph, raddbg, type_key);
U64 struct_total_size_capped = ClampTop(struct_total_size, 64);
Rng1U64 struct_memory_vaddr_rng = r1u64(eval.offset, eval.offset + struct_total_size_capped);
String8 struct_memory = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->ctrl_machine_id, process->ctrl_handle, struct_memory_vaddr_rng);
TG_Type *type = tg_type_from_graph_raddbg_key(scratch.arena, graph, raddbg, type_key);
TG_Type *type = tg_type_from_graph_rdi_key(scratch.arena, graph, raddbg, type_key);
for(U64 element_idx = 0, member_idx = 0;
element_idx < 4 && member_idx < type->count;
member_idx += 1)
@@ -223,10 +223,10 @@ df_view_rule_hooks__bitmap_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx
String8 height_expr = str8_list_join(scratch.arena, &height_expr_strs, 0);
String8 fmt_string = fmt_cfg->first->string;
DF_Eval width_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, macro_map, width_expr);
DF_Eval width_eval_value = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, width_eval);
DF_Eval width_eval_value = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdi, ctrl_ctx, width_eval);
info.width = width_eval_value.imm_u64;
DF_Eval height_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, macro_map, height_expr);
DF_Eval height_eval_value = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, height_eval);
DF_Eval height_eval_value = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdi, ctrl_ctx, height_eval);
info.height = height_eval_value.imm_u64;
if(fmt_string.size != 0)
{
@@ -276,9 +276,9 @@ df_view_rule_hooks__geo_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ct
DF_Eval count_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, macro_map, count_expr);
DF_Eval vertices_base_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, macro_map, vertices_base_expr);
DF_Eval vertices_size_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, macro_map, vertices_size_expr);
DF_Eval count_val_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, count_eval);
DF_Eval vertices_base_val_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, vertices_base_eval);
DF_Eval vertices_size_val_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, vertices_size_eval);
DF_Eval count_val_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdi, ctrl_ctx, count_eval);
DF_Eval vertices_base_val_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdi, ctrl_ctx, vertices_base_eval);
DF_Eval vertices_size_val_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdi, ctrl_ctx, vertices_size_eval);
U64 vertices_base_vaddr = vertices_base_val_eval.imm_u64 ? vertices_base_val_eval.imm_u64 : vertices_base_val_eval.offset;
result.index_count = count_val_eval.imm_u64;
result.vertices_vaddr_range = r1u64(vertices_base_vaddr, vertices_base_vaddr+vertices_size_val_eval.imm_u64);
@@ -306,7 +306,7 @@ df_view_rule_hooks__txt_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ct
lang_string = lang_cfg->first->string;
String8 size_expr = str8_list_join(scratch.arena, &size_expr_strs, &join);
DF_Eval size_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, macro_map, size_expr);
DF_Eval size_val_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, size_eval);
DF_Eval size_val_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdi, ctrl_ctx, size_eval);
result.lang = txt_lang_kind_from_extension(lang_string);
result.size_cap = size_val_eval.imm_u64;
}
@@ -314,6 +314,36 @@ df_view_rule_hooks__txt_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ct
return result;
}
internal DF_DisasmTopologyInfo
df_view_rule_hooks__disasm_topology_info_from_cfg(DBGI_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;
{
StringJoin join = {0};
join.sep = str8_lit(" ");
DF_CfgNode *size_cfg = df_cfg_node_child_from_string(cfg, str8_lit("size"), 0);
DF_CfgNode *arch_cfg = df_cfg_node_child_from_string(cfg, str8_lit("arch"), 0);
String8List size_expr_strs = {0};
String8 arch_string = {0};
for(DF_CfgNode *child = size_cfg->first; child != &df_g_nil_cfg_node; child = child->next)
{
str8_list_push(scratch.arena, &size_expr_strs, child->string);
}
arch_string = arch_cfg->first->string;
String8 size_expr = str8_list_join(scratch.arena, &size_expr_strs, &join);
DF_Eval size_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, macro_map, size_expr);
DF_Eval size_val_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdi, ctrl_ctx, size_eval);
if(str8_match(arch_string, str8_lit("x64"), StringMatchFlag_CaseInsensitive))
{
result.arch = Architecture_x64;
}
result.size_cap = size_val_eval.imm_u64;
}
scratch_end(scratch);
return result;
}
////////////////////////////////
//~ rjf: "array"
@@ -337,13 +367,13 @@ DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(array)
}
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_value = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, array_size_eval);
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;
}
// rjf: apply array size to type
TG_Key pointee = tg_ptee_from_graph_raddbg_key(parse_ctx->type_graph, parse_ctx->rdbg, type_key);
TG_Key pointee = tg_ptee_from_graph_rdi_key(parse_ctx->type_graph, parse_ctx->rdi, type_key);
TG_Key array_type = tg_cons_type_make(parse_ctx->type_graph, TG_Kind_Array, pointee, array_size);
eval.type_key = tg_cons_type_make(parse_ctx->type_graph, TG_Kind_Ptr, array_type, 0);
}
@@ -353,17 +383,8 @@ DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(array)
}
////////////////////////////////
//~ bill: utility procedures
//~ bill: "slice"
internal void dbg_printf(char const *fmt, ...)
{
va_list argp;
va_start(argp, fmt);
char buf[4096] = {};
vsnprintf_s(buf, 4095, fmt, argp);
va_end(argp);
OutputDebugStringA(buf);
}
internal TG_Member *tg_member_from_name(TG_MemberArray array, String8 name, StringMatchFlags flags)
{
@@ -378,17 +399,13 @@ internal TG_Member *tg_member_from_name(TG_MemberArray array, String8 name, Stri
return NULL;
}
////////////////////////////////
//~ bill: "slice"
internal U64 df_evaluate_integer_from_eval(EVAL_ParseCtx *parse_ctx, DF_CtrlCtx *ctrl_ctx, DF_Eval eval, TG_Member *member)
{
DF_Eval res = zero_struct;
res.mode = EVAL_EvalMode_Addr;
res.offset = eval.offset + member->off;
res.type_key = member->type_key;
res = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, res);
res = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdi, ctrl_ctx, res);
if (res.mode == EVAL_EvalMode_Value)
{
return res.imm_u64;
@@ -403,29 +420,28 @@ DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(slice)
if (type_kind == TG_Kind_Struct)
{
Temp scratch = scratch_begin(&arena, 1);
DF_CfgNode *struct_node = val->last;
if (struct_node != &df_g_nil_cfg_node)
{
Temp scratch = scratch_begin(&arena, 1);
TG_MemberArray data_members = tg_data_members_from_graph_raddbg_key(arena, parse_ctx->type_graph, parse_ctx->rdbg, type_key);
TG_MemberArray data_members = tg_data_members_from_graph_rdi_key(scratch.arena, parse_ctx->type_graph, parse_ctx->rdi, type_key);
TG_Member *member_ptr = NULL;
TG_Member *member_len = NULL;
member_ptr = member_ptr ? member_ptr : tg_member_from_name(data_members, str8_lit("data"), StringMatchFlag_CaseInsensitive);
member_ptr = member_ptr ? member_ptr : tg_member_from_name(data_members, str8_lit("str"), StringMatchFlag_CaseInsensitive);
member_ptr = member_ptr ? member_ptr : tg_member_from_name(data_members, str8_lit("ptr"), StringMatchFlag_CaseInsensitive);
member_len = member_len ? member_len : tg_member_from_name(data_members, str8_lit("len"), StringMatchFlag_CaseInsensitive);
member_len = member_len ? member_len : tg_member_from_name(data_members, str8_lit("size"), StringMatchFlag_CaseInsensitive);
member_len = member_len ? member_len : tg_member_from_name(data_members, str8_lit("count"), StringMatchFlag_CaseInsensitive);
member_ptr = member_ptr ? member_ptr : tg_member_from_name(data_members, str8_lit("data"), StringMatchFlag_CaseInsensitive);
member_ptr = member_ptr ? member_ptr : tg_member_from_name(data_members, str8_lit("str"), StringMatchFlag_CaseInsensitive);
member_ptr = member_ptr ? member_ptr : tg_member_from_name(data_members, str8_lit("ptr"), StringMatchFlag_CaseInsensitive);
member_len = member_len ? member_len : tg_member_from_name(data_members, str8_lit("len"), StringMatchFlag_CaseInsensitive);
member_len = member_len ? member_len : tg_member_from_name(data_members, str8_lit("length"), StringMatchFlag_CaseInsensitive);
member_len = member_len ? member_len : tg_member_from_name(data_members, str8_lit("count"), StringMatchFlag_CaseInsensitive);
member_len = member_len ? member_len : tg_member_from_name(data_members, str8_lit("size"), StringMatchFlag_CaseInsensitive);
if (member_ptr && member_len)
{
// NOTE(bill): this assumes little-endian format
U64 slice_len = df_evaluate_integer_from_eval(parse_ctx, ctrl_ctx, eval, member_len);
TG_Key pointee = tg_ptee_from_graph_raddbg_key(parse_ctx->type_graph, parse_ctx->rdbg, member_ptr->type_key);
TG_Key pointee = tg_ptee_from_graph_rdi_key(parse_ctx->type_graph, parse_ctx->rdi, member_ptr->type_key);
TG_Key array_type = tg_cons_type_make(parse_ctx->type_graph, TG_Kind_Array, pointee, slice_len);
// TODO(bill): How do you make this render with the original name, if possible?
@@ -436,15 +452,119 @@ DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(slice)
eval = new_eval;
}
scratch_end(scratch);
}
scratch_end(scratch);
}
return eval;
}
////////////////////////////////
//~ bill: "odin_map"
typedef struct DF_OdinMapCellInfo DF_OdinMapCellInfo;
struct DF_OdinMapCellInfo {
U64 size_of_type;
U64 size_of_cell;
U64 elements_per_cell;
};
internal DF_OdinMapCellInfo df_odin_map_cell_info(Arena *arena, EVAL_ParseCtx *parse_ctx, TG_Key type, TG_Key cell_type)
{
DF_OdinMapCellInfo info = zero_struct;
info.size_of_type = tg_byte_size_from_graph_rdi_key(parse_ctx->type_graph, parse_ctx->rdi, type);
info.size_of_cell = tg_byte_size_from_graph_rdi_key(parse_ctx->type_graph, parse_ctx->rdi, cell_type);
if (info.size_of_type != info.size_of_cell) {
Temp scratch = scratch_begin(&arena, 1);
TG_Kind kind = tg_kind_from_key(cell_type);
Assert(kind == TG_Kind_Struct);
TG_MemberArray data_members = tg_data_members_from_graph_rdi_key(scratch.arena, parse_ctx->type_graph, parse_ctx->rdi, cell_type);
Assert(data_members.count >= 1);
TG_Key array_type = data_members.v[0].type_key;
U64 size_of_array = tg_byte_size_from_graph_rdi_key(parse_ctx->type_graph, parse_ctx->rdi, array_type);
if (size_of_array > 0 && info.size_of_type > 0) {
info.elements_per_cell = size_of_array / info.size_of_type;
}
scratch_end(scratch);
}
if (info.elements_per_cell == 0) {
info.elements_per_cell = 1;
}
return info;
}
internal U64 df_odin_map_cell_index(U64 base, DF_OdinMapCellInfo const *info, U64 index)
{
U64 elements_per_cell = info->elements_per_cell;
U64 size_of_cell = info->size_of_cell;
U64 size_of_type = info->size_of_type;
U64 cell_index = 0;
U64 data_index = 0;
switch (elements_per_cell) {
case 1:
return base + (index * size_of_cell);
case 2:
cell_index = index >> 1;
data_index = index & 1;
break;
case 4:
cell_index = index >> 2;
data_index = index & 3;
break;
case 8:
cell_index = index >> 3;
data_index = index & 7;
break;
case 16:
cell_index = index >> 4;
data_index = index & 15;
break;
case 32:
cell_index = index >> 5;
data_index = index & 31;
break;
default:
cell_index = index / elements_per_cell;
data_index = index % elements_per_cell;
break;
}
return base + (cell_index * size_of_cell) + (data_index * size_of_type);
}
// internal void dbg_printf(char const *fmt, ...) {
// va_list argp;
// va_start(argp, fmt);
// char buf[4096] = {};
// vsnprintf_s(buf, 4095, fmt, argp);
// va_end(argp);
// OutputDebugStringA(buf);
// }
internal U64 df_evaluate_hash_from_offset(EVAL_ParseCtx *parse_ctx, DF_CtrlCtx *ctrl_ctx, U64 offset, TG_Key hash_type)
{
DF_Eval res = zero_struct;
res.mode = EVAL_EvalMode_Addr;
res.offset = offset;
res.type_key = hash_type;
res = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdi, ctrl_ctx, res);
if (res.mode == EVAL_EvalMode_Value)
{
return res.imm_u64;
}
return 0;
}
DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(odin_map)
{
TG_Key type_key = eval.type_key;
@@ -455,63 +575,102 @@ DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(odin_map)
DF_CfgNode *struct_node = val->last;
if (struct_node != &df_g_nil_cfg_node)
{
TG_MemberArray data_members = tg_data_members_from_graph_raddbg_key(arena, parse_ctx->type_graph, parse_ctx->rdbg, type_key);
TG_Member *member_data = tg_member_from_name(data_members, str8_lit("data"), 0);
TG_Member *member_len = tg_member_from_name(data_members, str8_lit("len"), 0);
TG_Member *member_metadata = tg_member_from_name(data_members, str8_lit("__metadata"), 0);
TG_MemberArray data_members = tg_data_members_from_graph_rdi_key(arena, parse_ctx->type_graph, parse_ctx->rdi, type_key);
if (member_data && member_len && member_metadata)
TG_Member *member_data = tg_member_from_name(data_members, str8_lit("data"), 0);
TG_Member *member_len = tg_member_from_name(data_members, str8_lit("len"), 0);
if (member_data && member_len)
{
TG_Key metadata = member_metadata->type_key;
metadata = tg_direct_from_graph_raddbg_key(parse_ctx->type_graph, parse_ctx->rdbg, metadata);
metadata = tg_ptee_from_graph_raddbg_key(parse_ctx->type_graph, parse_ctx->rdbg, metadata);
Assert(tg_kind_from_key(metadata) == TG_Kind_Struct);
TG_Key metadata = member_data->type_key;
metadata = tg_ptee_from_graph_rdi_key(parse_ctx->type_graph, parse_ctx->rdi, metadata);
if (tg_kind_from_key(metadata) != TG_Kind_Struct)
{
return eval;
}
TG_MemberArray md_members = tg_data_members_from_graph_raddbg_key(arena, parse_ctx->type_graph, parse_ctx->rdbg, metadata);
TG_MemberArray md_members = tg_data_members_from_graph_rdi_key(arena, parse_ctx->type_graph, parse_ctx->rdi, metadata);
TG_Member *m_key = tg_member_from_name(md_members, str8_lit("key"), 0);
TG_Member *m_value = tg_member_from_name(md_members, str8_lit("value"), 0);
TG_Member *m_hash = tg_member_from_name(md_members, str8_lit("hash"), 0);
TG_Member *m_key_cell = tg_member_from_name(md_members, str8_lit("key_cell"), 0);
TG_Member *m_value_cell = tg_member_from_name(md_members, str8_lit("value_cell"), 0);
if (m_key == NULL) {
if (m_key == NULL ||
m_value == NULL ||
m_hash == NULL ||
m_key_cell == NULL ||
m_value_cell == NULL)
{
return eval;
}
Assert(m_key && m_value && m_hash && m_key_cell && m_value_cell);
TG_Key key = m_key->type_key;
TG_Key value = m_value->type_key;
TG_Key hash = m_hash->type_key;
TG_Key key_cell = m_key_cell->type_key;
TG_Key value_cell = m_value_cell->type_key;
U64 raw_data = df_evaluate_integer_from_eval(parse_ctx, ctrl_ctx, eval, member_data);
U64 ptr = raw_data & ~(U64)63;
U64 len = df_evaluate_integer_from_eval(parse_ctx, ctrl_ctx, eval, member_len);
U64 cap_log2 = raw_data & 63;
U64 cap = cap_log2 ? ((U64)1)<<cap_log2 : 0;
// NOTE(bill): this assumes little-endian format
U64 len = df_evaluate_integer_from_eval(parse_ctx, ctrl_ctx, eval, member_len);
U64 data = df_evaluate_integer_from_eval(parse_ctx, ctrl_ctx, eval, member_data);
U64 cap = data & (U64)63;
if (cap)
TG_Key array_type = zero_struct;
DF_OdinMapCellInfo key_cell_info = df_odin_map_cell_info(arena, parse_ctx, key, key_cell);
DF_OdinMapCellInfo value_cell_info = df_odin_map_cell_info(arena, parse_ctx, value, value_cell);
U64 size_of_hash = tg_byte_size_from_graph_rdi_key(parse_ctx->type_graph, parse_ctx->rdi, hash);
U64 key_ptr = ptr;
U64 value_ptr = df_odin_map_cell_index(key_ptr, &key_cell_info, cap);
U64 hash_ptr = df_odin_map_cell_index(value_ptr, &value_cell_info, cap);
(void)value_ptr;
(void)hash_ptr;
U64 TOMBSTONE_MASK = ((U64)1u)<<(size_of_hash*8 - 1);
for (U64 i = 0; i < cap; i += 1)
{
cap = ((U64)1)<<cap;
U64 offset_hash = hash_ptr + i*size_of_hash;
U64 h = df_evaluate_hash_from_offset(parse_ctx, ctrl_ctx, offset_hash, hash);
if (h != 0 && (h & TOMBSTONE_MASK) == 0)
{
U64 offset_key = df_odin_map_cell_index(key_ptr, &key_cell_info, i);
U64 offset_value = df_odin_map_cell_index(value_ptr, &value_cell_info, i);
DF_Eval addr_key = zero_struct;
addr_key.mode = EVAL_EvalMode_Addr;
addr_key.offset = offset_key;
addr_key.type_key = key;
DF_Eval addr_value = zero_struct;
addr_value.mode = EVAL_EvalMode_Addr;
addr_value.offset = offset_value;
addr_value.type_key = value;
// render element
}
}
data = data &~ (U64)63;
TG_Key array_type = tg_cons_type_make(parse_ctx->type_graph, TG_Kind_Array, key, cap);
// TODO(bill): How do you make this render with the original name, if possible?
TG_Key key_array_type = tg_cons_type_make(parse_ctx->type_graph, TG_Kind_Array, key_cell, cap/key_cell_info.elements_per_cell);
DF_Eval new_eval = zero_struct;
new_eval.mode = EVAL_EvalMode_Value;
new_eval.imm_u64 = data;
new_eval.type_key = tg_cons_type_make(parse_ctx->type_graph, TG_Kind_Ptr, array_type, 0);
new_eval.imm_u64 = key_ptr;
new_eval.type_key = tg_cons_type_make(parse_ctx->type_graph, TG_Kind_Ptr, key_array_type, 0);
eval = new_eval;
}
}
}
return eval;
}
////////////////////////////////
//~ rjf: "list"
@@ -533,13 +692,13 @@ DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(bswap)
Temp scratch = scratch_begin(&arena, 1);
TG_Key type_key = eval.type_key;
TG_Kind type_kind = tg_kind_from_key(type_key);
U64 type_size_bytes = tg_byte_size_from_graph_raddbg_key(parse_ctx->type_graph, parse_ctx->rdbg, type_key);
U64 type_size_bytes = tg_byte_size_from_graph_rdi_key(parse_ctx->type_graph, parse_ctx->rdi, type_key);
if(TG_Kind_Char8 <= type_kind && type_kind <= TG_Kind_S256 &&
(type_size_bytes == 2 ||
type_size_bytes == 4 ||
type_size_bytes == 8))
{
DF_Eval value_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, eval);
DF_Eval value_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdi, ctrl_ctx, eval);
if(value_eval.mode == EVAL_EvalMode_Value)
{
switch(type_size_bytes)
@@ -658,8 +817,8 @@ DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_DEF(rgba)
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
//- rjf: grab hsva
DF_Eval value_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, eval);
Vec4F32 rgba = df_view_rule_hooks__rgba_from_eval(value_eval, parse_ctx->type_graph, parse_ctx->rdbg, process);
DF_Eval value_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdi, ctrl_ctx, eval);
Vec4F32 rgba = df_view_rule_hooks__rgba_from_eval(value_eval, parse_ctx->type_graph, parse_ctx->rdi, process);
Vec4F32 hsva = hsva_from_rgba(rgba);
//- rjf: build text box
@@ -706,7 +865,7 @@ DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_DEF(rgba)
//- rjf: hover color box -> show components
UI_Signal sig = ui_signal_from_box(color_box);
if(sig.hovering)
if(ui_hovering(sig))
{
ui_do_color_tooltip_hsva(hsva);
}
@@ -725,17 +884,17 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(rgba)
Vec4F32 rgba = {0};
Vec4F32 hsva = {0};
{
if(state->memgen_idx >= ctrl_memgen_idx())
if(state->memgen_idx >= ctrl_mem_gen())
{
hsva = state->hsva;
rgba = rgba_from_hsva(hsva);
}
else
{
DF_Eval value_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, eval);
rgba = df_view_rule_hooks__rgba_from_eval(value_eval, parse_ctx->type_graph, parse_ctx->rdbg, process);
DF_Eval value_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdi, ctrl_ctx, eval);
rgba = df_view_rule_hooks__rgba_from_eval(value_eval, parse_ctx->type_graph, parse_ctx->rdi, process);
state->hsva = hsva = hsva_from_rgba(rgba);
state->memgen_idx = ctrl_memgen_idx();
state->memgen_idx = ctrl_mem_gen();
}
}
Vec4F32 initial_hsva = hsva;
@@ -747,12 +906,12 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(rgba)
UI_PrefWidth(ui_px(dim.y, 1.f))
{
UI_Signal sv_sig = ui_sat_val_pickerf(hsva.x, &hsva.y, &hsva.z, "sat_val_picker");
commit = commit || sv_sig.released;
commit = commit || ui_released(sv_sig);
}
UI_PrefWidth(ui_em(3.f, 1.f))
{
UI_Signal h_sig = ui_hue_pickerf(&hsva.x, hsva.y, hsva.z, "hue_picker");
commit = commit || h_sig.released;
commit = commit || ui_released(h_sig);
}
UI_PrefWidth(ui_children_sum(1)) UI_Column UI_PrefWidth(ui_text_dim(10, 1)) UI_Font(df_font_from_slot(DF_FontSlot_Code)) UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_WeakText))
{
@@ -783,8 +942,8 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(rgba)
if(commit)
{
Vec4F32 rgba = rgba_from_hsva(hsva);
df_view_rule_hooks__eval_commit_rgba(eval, parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, rgba);
state->memgen_idx = ctrl_memgen_idx();
df_view_rule_hooks__eval_commit_rgba(eval, parse_ctx->type_graph, parse_ctx->rdi, ctrl_ctx, rgba);
state->memgen_idx = ctrl_mem_gen();
}
//- rjf: commit possible edited value to state
@@ -822,84 +981,89 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(text)
Temp scratch = scratch_begin(0, 0);
HS_Scope *hs_scope = hs_scope_open();
TXT_Scope *txt_scope = txt_scope_open();
//////////////////////////////
//- rjf: get & initialize state
//
DF_ViewRuleHooks_TextState *state = df_view_rule_block_user_state(key, DF_ViewRuleHooks_TextState);
if(!state->initialized)
{
state->initialized = 1;
state->cursor = state->mark = txt_pt(1, 1);
}
if(state->last_open_frame_idx+1 < df_frame_index())
//////////////////////////////
//- rjf: unpack evaluation / view rule params
//
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_view_rule_hooks__txt_topology_info_from_cfg(dbgi_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));
//////////////////////////////
//- rjf: evaluation info -> text visualization info
//
String8 data = {0};
TXT_TextInfo info = {0};
TXT_LineTokensSlice line_tokens_slice = {0};
{
state->loaded_t = 0;
U128 text_hash = {0};
U128 text_key = ctrl_hash_store_key_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, vaddr_range, 1);
info = txt_text_info_from_key_lang(txt_scope, text_key, top.lang, &text_hash);
data = hs_data_from_hash(hs_scope, text_hash);
line_tokens_slice = txt_line_tokens_slice_from_info_data_line_range(scratch.arena, &info, data, r1s64(1, info.lines_count));
}
state->last_open_frame_idx = df_frame_index();
//////////////////////////////
//- rjf: info -> code slice info
//
DF_CodeSliceParams code_slice_params = {0};
{
//- rjf: unpack params
DF_TxtTopologyInfo top = df_view_rule_hooks__txt_topology_info_from_cfg(dbgi_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->rdbg, 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));
//- rjf: unpack thread/process of eval
DF_Entity *thread = df_entity_from_handle(ctrl_ctx->thread);
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
//- rjf: unique identifying info about this address -> unique key
U128 text_key = {0};
code_slice_params.flags = DF_CodeSliceFlag_LineNums;
code_slice_params.line_num_range = r1s64(1, info.lines_count);
code_slice_params.line_text = push_array(scratch.arena, String8, info.lines_count);
code_slice_params.line_ranges = push_array(scratch.arena, Rng1U64, info.lines_count);
code_slice_params.line_tokens = push_array(scratch.arena, TXT_TokenArray, info.lines_count);
code_slice_params.line_bps = push_array(scratch.arena, DF_EntityList, info.lines_count);
code_slice_params.line_ips = push_array(scratch.arena, DF_EntityList, info.lines_count);
code_slice_params.line_pins = push_array(scratch.arena, DF_EntityList, info.lines_count);
code_slice_params.line_dasm2src = push_array(scratch.arena, DF_TextLineDasm2SrcInfoList, info.lines_count);
code_slice_params.line_src2dasm = push_array(scratch.arena, DF_TextLineSrc2DasmInfoList, info.lines_count);
for(U64 line_idx = 0; line_idx < info.lines_count; line_idx += 1)
{
U64 data[] =
{
(U64)process->ctrl_machine_id,
(U64)process->ctrl_handle.u64[0],
vaddr_range.min,
vaddr_range.max,
};
text_key = hs_hash_from_data(str8((U8 *)data, sizeof(data)));
code_slice_params.line_text[line_idx] = str8_substr(data, info.lines_ranges[line_idx]);
code_slice_params.line_ranges[line_idx] = info.lines_ranges[line_idx];
code_slice_params.line_tokens[line_idx] = line_tokens_slice.line_tokens[line_idx];
}
//- rjf: address range -> hash
U128 hash = ctrl_stored_hash_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, vaddr_range, 1, 0);
//- rjf: hash -> data
String8 data = hs_data_from_hash(hs_scope, hash);
//- rjf: key * hash -> parsed text info
TXT_TextInfo info = txt_text_info_from_key_hash_lang(txt_scope, text_key, hash, top.lang);
//- rjf: info -> code slice info
DF_CodeSliceParams code_slice_params = {0};
code_slice_params.font = df_font_from_slot(DF_FontSlot_Code);
code_slice_params.font_size = ui_top_font_size();
code_slice_params.line_height_px = ui_top_font_size()*1.5f;
code_slice_params.margin_width_px = 0;
code_slice_params.line_num_width_px = ui_top_font_size()*5.f;
code_slice_params.line_text_max_width_px = ui_top_font_size()*2.f*info.lines_max_size;
}
//////////////////////////////
//- rjf: build UI
//
if(info.lines_count != 0)
{
//- rjf: build top-level container
UI_Box *container = &ui_g_nil_box;
UI_PrefWidth(ui_px(dim.x, 1.f)) UI_PrefHeight(ui_px(dim.y, 1.f))
{
code_slice_params.flags = DF_CodeSliceFlag_LineNums;
code_slice_params.line_num_range = r1s64(1, info.lines_count);
code_slice_params.line_text = push_array(scratch.arena, String8, info.lines_count);
code_slice_params.line_ranges = push_array(scratch.arena, Rng1U64, info.lines_count);
code_slice_params.line_tokens = push_array(scratch.arena, TXTI_TokenArray, info.lines_count);
code_slice_params.line_bps = push_array(scratch.arena, DF_EntityList, info.lines_count);
code_slice_params.line_ips = push_array(scratch.arena, DF_EntityList, info.lines_count);
code_slice_params.line_pins = push_array(scratch.arena, DF_EntityList, info.lines_count);
code_slice_params.line_dasm2src = push_array(scratch.arena, DF_TextLineDasm2SrcInfoList, info.lines_count);
code_slice_params.line_src2dasm = push_array(scratch.arena, DF_TextLineSrc2DasmInfoList, info.lines_count);
for(U64 line_idx = 0; line_idx < info.lines_count; line_idx += 1)
{
code_slice_params.line_text[line_idx] = str8_substr(data, info.lines_ranges[line_idx]);
code_slice_params.line_ranges[line_idx] = info.lines_ranges[line_idx];
}
code_slice_params.font = df_font_from_slot(DF_FontSlot_Code);
code_slice_params.font_size = ui_top_font_size();
code_slice_params.line_height_px = ui_top_font_size()*1.5f;
code_slice_params.margin_width_px = 0;
code_slice_params.line_num_width_px = ui_top_font_size()*5.f;
code_slice_params.line_text_max_width_px = ui_top_font_size()*2.f*info.lines_max_size;
container = ui_build_box_from_stringf(UI_BoxFlag_AllowOverflow|UI_BoxFlag_Clip, "###text_container");
}
//- rjf: build code slice
if(info.lines_count != 0) UI_Padding(ui_pct(1, 0)) UI_PrefWidth(ui_px(info.lines_max_size*ui_top_font_size()*1.2f, 1.f)) UI_Column UI_Padding(ui_pct(1, 0))
UI_WidthFill UI_HeightFill UI_Parent(container)
{
DF_CodeSliceSignal sig = df_code_slice(ws, ctrl_ctx, parse_ctx, &code_slice_params, &state->cursor, &state->mark, &state->preferred_column, str8_lit("###code_slice"));
DF_CodeSliceSignal slice_sig = df_code_slice(ws, ctrl_ctx, parse_ctx, &code_slice_params, &state->cursor, &state->mark, &state->preferred_column, str8_lit("###slice"));
}
}
txt_scope_close(txt_scope);
hs_scope_close(hs_scope);
scratch_end(scratch);
@@ -908,6 +1072,17 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(text)
////////////////////////////////
//~ rjf: "disasm"
typedef struct DF_ViewRuleHooks_DisasmState DF_ViewRuleHooks_DisasmState;
struct DF_ViewRuleHooks_DisasmState
{
B32 initialized;
TxtPt cursor;
TxtPt mark;
S64 preferred_column;
U64 last_open_frame_idx;
F32 loaded_t;
};
DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(disasm)
{
DF_EvalVizBlock *vb = df_eval_viz_block_begin(arena, DF_EvalVizBlockKind_Canvas, key, df_expand_key_make(df_hash_from_expand_key(key), 1), depth);
@@ -920,7 +1095,92 @@ DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(disasm)
DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(disasm)
{
Temp scratch = scratch_begin(0, 0);
HS_Scope *hs_scope = hs_scope_open();
TXT_Scope *txt_scope = txt_scope_open();
DASM_Scope *dasm_scope = dasm_scope_open();
DF_ViewRuleHooks_DisasmState *state = df_view_rule_block_user_state(key, DF_ViewRuleHooks_DisasmState);
if(!state->initialized)
{
state->initialized = 1;
state->cursor = state->mark = txt_pt(1, 1);
}
if(state->last_open_frame_idx+1 < df_frame_index())
{
state->loaded_t = 0;
}
state->last_open_frame_idx = df_frame_index();
{
//- rjf: unpack params
DF_DisasmTopologyInfo top = df_view_rule_hooks__disasm_topology_info_from_cfg(dbgi_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);
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));
//- rjf: unpack thread/process of eval
DF_Entity *thread = df_entity_from_handle(ctrl_ctx->thread);
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
//- rjf: unpack key for this region in memory
U128 dasm_key = ctrl_hash_store_key_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, vaddr_range, 0);
//- rjf: key -> parsed text info
U128 data_hash = {0};
DASM_Info dasm_info = dasm_info_from_key_addr_arch_style(dasm_scope, dasm_key, vaddr_range.min, top.arch, 0, DASM_Syntax_Intel, &data_hash);
String8 dasm_text_data = {0};
TXT_TextInfo dasm_text_info = {0};
for(U64 rewind_idx = 0; rewind_idx < 2; rewind_idx += 1)
{
U128 dasm_text_hash = hs_hash_from_key(dasm_info.text_key, rewind_idx);
dasm_text_data = hs_data_from_hash(hs_scope, dasm_text_hash);
dasm_text_info = txt_text_info_from_hash_lang(txt_scope, dasm_text_hash, TXT_LangKind_DisasmX64Intel);
if(dasm_text_info.lines_count != 0)
{
break;
}
}
TXT_LineTokensSlice line_tokens_slice = txt_line_tokens_slice_from_info_data_line_range(scratch.arena, &dasm_text_info, dasm_text_data, r1s64(1, dasm_info.insts.count));
//- rjf: info -> code slice info
DF_CodeSliceParams code_slice_params = {0};
{
code_slice_params.flags = DF_CodeSliceFlag_LineNums;
code_slice_params.line_num_range = r1s64(1, dasm_text_info.lines_count);
code_slice_params.line_text = push_array(scratch.arena, String8, dasm_text_info.lines_count);
code_slice_params.line_ranges = push_array(scratch.arena, Rng1U64, dasm_text_info.lines_count);
code_slice_params.line_tokens = push_array(scratch.arena, TXT_TokenArray, dasm_text_info.lines_count);
code_slice_params.line_bps = push_array(scratch.arena, DF_EntityList, dasm_text_info.lines_count);
code_slice_params.line_ips = push_array(scratch.arena, DF_EntityList, dasm_text_info.lines_count);
code_slice_params.line_pins = push_array(scratch.arena, DF_EntityList, dasm_text_info.lines_count);
code_slice_params.line_dasm2src = push_array(scratch.arena, DF_TextLineDasm2SrcInfoList, dasm_text_info.lines_count);
code_slice_params.line_src2dasm = push_array(scratch.arena, DF_TextLineSrc2DasmInfoList, dasm_text_info.lines_count);
for(U64 line_idx = 0; line_idx < dasm_text_info.lines_count; line_idx += 1)
{
code_slice_params.line_text[line_idx] = str8_substr(dasm_text_data, dasm_info.insts.v[line_idx].text_range);
code_slice_params.line_ranges[line_idx] = dasm_info.insts.v[line_idx].text_range;
code_slice_params.line_tokens[line_idx] = line_tokens_slice.line_tokens[line_idx];
}
code_slice_params.font = df_font_from_slot(DF_FontSlot_Code);
code_slice_params.font_size = ui_top_font_size();
code_slice_params.line_height_px = ui_top_font_size()*1.5f;
code_slice_params.margin_width_px = 0;
code_slice_params.line_num_width_px = ui_top_font_size()*5.f;
code_slice_params.line_text_max_width_px = ui_top_font_size()*2.f*dasm_text_info.lines_max_size;
}
//- rjf: build code slice
if(dasm_info.insts.count != 0 && dasm_text_info.lines_count != 0)
UI_Padding(ui_pct(1, 0)) UI_PrefWidth(ui_px(dasm_text_info.lines_max_size*ui_top_font_size()*1.2f, 1.f)) UI_Column UI_Padding(ui_pct(1, 0))
{
DF_CodeSliceSignal sig = df_code_slice(ws, ctrl_ctx, parse_ctx, &code_slice_params, &state->cursor, &state->mark, &state->preferred_column, str8_lit("###code_slice"));
}
}
dasm_scope_close(dasm_scope);
txt_scope_close(txt_scope);
hs_scope_close(hs_scope);
scratch_end(scratch);
}
////////////////////////////////
@@ -1004,7 +1264,7 @@ DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(bitmap)
DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_DEF(bitmap)
{
DF_Eval value_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, eval);
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 = df_view_rule_hooks__bitmap_topology_info_from_cfg(scope, ctrl_ctx, parse_ctx, macro_map, cfg);
U64 expected_size = topology.width*topology.height*r_tex2d_format_bytes_per_pixel_table[topology.fmt];
@@ -1025,7 +1285,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(bitmap)
state->last_open_frame_idx = df_frame_index();
//- rjf: resolve to address value
DF_Eval value_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, eval);
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;
//- rjf: unpack thread/process of eval
@@ -1037,34 +1297,22 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(bitmap)
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);
//- rjf: unique identifying info about this address -> unique key
U128 texture_key = {0};
{
U64 data[] =
{
(U64)process->ctrl_machine_id,
(U64)process->ctrl_handle.u64[0],
vaddr_range.min,
vaddr_range.max,
};
texture_key = hs_hash_from_data(str8((U8 *)data, sizeof(data)));
}
//- rjf: address range -> hash
U128 hash = ctrl_stored_hash_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, vaddr_range, 0, 0);
//- rjf: obtain key for this data range
U128 texture_key = ctrl_hash_store_key_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, vaddr_range, 0);
//- rjf: hash & topology -> texture
TEX_Topology topology = tex_topology_make(v2s32((S32)topology_info.width, (S32)topology_info.height), topology_info.fmt);
R_Handle texture = tex_texture_from_key_hash_topology(tex_scope, texture_key, hash, topology);
R_Handle texture = tex_texture_from_key_topology(tex_scope, texture_key, topology);
//- rjf: build preview
F32 rate = 1 - pow_f32(2, (-15.f * df_dt()));
if(expected_size != 0)
{
F32 img_dim = dim.y - ui_top_font_size()*2.f;
UI_Padding(ui_pct(1.f, 0.f))
UI_PrefWidth(ui_px(dim.y*((F32)topology_info.width/(F32)topology_info.height), 1.f))
UI_PrefWidth(ui_px(img_dim*((F32)topology_info.width/(F32)topology_info.height), 1.f))
UI_Column UI_Padding(ui_pct(1.f, 0.f))
UI_PrefHeight(ui_px(dim.y, 1.f))
UI_PrefHeight(ui_px(img_dim, 1.f))
{
ui_set_next_hover_cursor(OS_Cursor_HandPoint);
UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable|UI_BoxFlag_DrawHotEffects, "image_box");
@@ -1076,7 +1324,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(bitmap)
draw_data->texture = texture;
draw_data->src = r2f32(v2f32(0, 0), v2f32((F32)topology_info.width, (F32)topology_info.height));
draw_data->loaded_t = state->loaded_t;
draw_data->hovered = sig.hovering;
draw_data->hovered = ui_hovering(sig);
draw_data->mouse_px = mouse_bitmap_px_off;
draw_data->ui_per_bmp_px = ui_per_bmp_px;
ui_box_equip_custom_draw(box, df_view_rule_hooks__bitmap_box_draw, draw_data);
@@ -1093,14 +1341,15 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(bitmap)
df_gfx_request_frame();
}
}
if(sig.hovering && r_handle_match(texture, r_handle_zero())) UI_Tooltip
if(ui_hovering(sig) && r_handle_match(texture, r_handle_zero())) UI_Tooltip
{
ui_labelf("Texture not loaded.");
}
if(sig.hovering && !r_handle_match(texture, r_handle_zero()))
if(ui_hovering(sig) && !r_handle_match(texture, r_handle_zero()))
{
if(dim.y > (F32)topology_info.height)
{
U128 hash = hs_hash_from_key(texture_key, 0);
String8 data = hs_data_from_hash(hs_scope, hash);
U64 bytes_per_pixel = r_tex2d_format_bytes_per_pixel_table[topology.fmt];
U64 mouse_pixel_off = mouse_bitmap_px_off.y*topology_info.width + mouse_bitmap_px_off.x;
@@ -1172,6 +1421,11 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(bitmap)
scratch_end(scratch);
}
DF_GFX_VIEW_RULE_WHOLE_UI_FUNCTION_DEF(bitmap)
{
}
////////////////////////////////
//~ rjf: "geo"
@@ -1247,7 +1501,7 @@ DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(geo)
DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_DEF(geo)
{
DF_Eval value_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, eval);
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;
UI_Font(df_font_from_slot(DF_FontSlot_Code)) UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_WeakText))
ui_labelf("0x%I64x -> Geometry", base_vaddr);
@@ -1272,7 +1526,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(geo)
state->last_open_frame_idx = df_frame_index();
//- rjf: resolve to address value
DF_Eval value_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, eval);
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;
//- rjf: extract extra geo topology info from view rule
@@ -1284,39 +1538,13 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(geo)
DF_Entity *thread = df_entity_from_handle(ctrl_ctx->thread);
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
//- rjf: produce unique keys for index buffer
U128 index_buffer_key = {0};
{
U64 data[] =
{
(U64)process->ctrl_machine_id,
(U64)process->ctrl_handle.u64[0],
index_buffer_vaddr_range.min,
index_buffer_vaddr_range.max,
};
index_buffer_key = hs_hash_from_data(str8((U8 *)data, sizeof(data)));
}
//- rjf: produce unique keys for vertex buffer
U128 vertex_buffer_key = {0};
{
U64 data[] =
{
(U64)process->ctrl_machine_id,
(U64)process->ctrl_handle.u64[0],
vertex_buffer_vaddr_range.min,
vertex_buffer_vaddr_range.max,
};
vertex_buffer_key = hs_hash_from_data(str8((U8 *)data, sizeof(data)));
}
//- rjf: address range -> hash
U128 index_buffer_hash = ctrl_stored_hash_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, index_buffer_vaddr_range, 0, 0);
U128 vertex_buffer_hash = ctrl_stored_hash_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, vertex_buffer_vaddr_range, 0, 0);
//- rjf: obtain keys for index buffer & vertex buffer memory
U128 index_buffer_key = ctrl_hash_store_key_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, index_buffer_vaddr_range, 0);
U128 vertex_buffer_key = ctrl_hash_store_key_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, vertex_buffer_vaddr_range, 0);
//- rjf: get gpu buffers
R_Handle index_buffer = geo_buffer_from_key_hash(geo_scope, index_buffer_key, index_buffer_hash);
R_Handle vertex_buffer = geo_buffer_from_key_hash(geo_scope, vertex_buffer_key, vertex_buffer_hash);
R_Handle index_buffer = geo_buffer_from_key(geo_scope, index_buffer_key);
R_Handle vertex_buffer = geo_buffer_from_key(geo_scope, vertex_buffer_key);
//- rjf: build preview
F32 rate = 1 - pow_f32(2, (-15.f * df_dt()));
@@ -1329,9 +1557,9 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(geo)
{
UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground|UI_BoxFlag_Clickable, "geo_box");
UI_Signal sig = ui_signal_from_box(box);
if(sig.dragging)
if(ui_dragging(sig))
{
if(sig.pressed)
if(ui_pressed(sig))
{
Vec2F32 data = v2f32(state->yaw_target, state->pitch_target);
ui_store_drag_struct(&data);
+10 -2
View File
@@ -29,13 +29,21 @@ struct DF_TxtTopologyInfo
U64 size_cap;
};
typedef struct DF_DisasmTopologyInfo DF_DisasmTopologyInfo;
struct DF_DisasmTopologyInfo
{
Architecture arch;
U64 size_cap;
};
////////////////////////////////
//~ rjf: Helpers
internal Vec4F32 df_view_rule_hooks__rgba_from_eval(DF_Eval eval, TG_Graph *graph, RADDBG_Parsed *raddbg, DF_Entity *process);
internal void df_view_rule_hooks__eval_commit_rgba(DF_Eval eval, TG_Graph *graph, RADDBG_Parsed *raddbg, DF_CtrlCtx *ctrl_ctx, Vec4F32 rgba);
internal Vec4F32 df_view_rule_hooks__rgba_from_eval(DF_Eval eval, TG_Graph *graph, RDI_Parsed *raddbg, DF_Entity *process);
internal void df_view_rule_hooks__eval_commit_rgba(DF_Eval eval, TG_Graph *graph, RDI_Parsed *raddbg, DF_CtrlCtx *ctrl_ctx, Vec4F32 rgba);
internal DF_BitmapTopologyInfo df_view_rule_hooks__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_GeoTopologyInfo df_view_rule_hooks__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_TxtTopologyInfo df_view_rule_hooks__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_DisasmTopologyInfo df_view_rule_hooks__disasm_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg);
#endif //DF_VIEW_RULE_HOOKS_H
+507 -628
View File
File diff suppressed because it is too large Load Diff
+4 -6
View File
@@ -144,7 +144,7 @@ struct DF_EntityListerItemArray
typedef struct DF_ProcessInfo DF_ProcessInfo;
struct DF_ProcessInfo
{
DEMON_ProcessInfo info;
DMN_ProcessInfo info;
B32 is_attached;
FuzzyMatchRangeList attached_match_ranges;
FuzzyMatchRangeList name_match_ranges;
@@ -364,6 +364,7 @@ struct DF_DisasmViewState
TxtPt mark;
S64 preferred_column;
B32 drifted_for_search;
DASM_StyleFlags style_flags;
// rjf: per-frame command info
S64 goto_line_num;
@@ -435,11 +436,6 @@ internal DF_EntityListerItemList df_entity_lister_item_list_from_needle(Arena *a
internal DF_EntityListerItemArray df_entity_lister_item_array_from_list(Arena *arena, DF_EntityListerItemList list);
internal void df_entity_lister_item_array_sort_by_strength__in_place(DF_EntityListerItemArray array);
////////////////////////////////
//~ rjf: Disassembly View
internal TXTI_TokenArray df_txti_token_array_from_dasm_arch_string(Arena *arena, Architecture arch, String8 string);
////////////////////////////////
//~ rjf: Eval/Watch Views
@@ -453,6 +449,8 @@ internal void df_eval_root_equip_string(DF_EvalRoot *root, String8 str
internal DF_EvalRoot * df_eval_root_from_string(DF_EvalWatchViewState *ews, String8 string);
internal DF_EvalRoot * df_eval_root_from_expand_key(DF_EvalWatchViewState *ews, DF_EvalView *eval_view, DF_ExpandKey expand_key);
internal String8 df_string_from_eval_root(DF_EvalRoot *root);
internal DF_ExpandKey df_parent_expand_key_from_eval_root(DF_EvalRoot *root);
internal DF_ExpandKey df_expand_key_from_eval_root(DF_EvalRoot *root);
//- 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_EvalWatchViewState *ews);
+877 -15
View File
@@ -3,21 +3,883 @@
//- GENERATED CODE
DF_GfxViewRuleSpecInfo df_g_gfx_view_rule_spec_info_table[] =
C_LINKAGE_BEGIN
String8 df_g_theme_preset_display_string_table[9] =
{
{ str8_lit_comp("array"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, 0, 0, 0, },
{ str8_lit_comp("list"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*1)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), DF_GFX_VIEW_RULE_VIZ_ROW_PROD_FUNCTION_NAME(list) , 0, 0, 0, },
{ str8_lit_comp("dec"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(dec) , 0, 0, },
{ str8_lit_comp("bin"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(bin) , 0, 0, },
{ str8_lit_comp("oct"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(oct) , 0, 0, },
{ str8_lit_comp("hex"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(hex) , 0, 0, },
{ str8_lit_comp("only"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*1)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), DF_GFX_VIEW_RULE_VIZ_ROW_PROD_FUNCTION_NAME(only) , DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(only) , 0, 0, },
{ str8_lit_comp("omit"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*1)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), DF_GFX_VIEW_RULE_VIZ_ROW_PROD_FUNCTION_NAME(omit) , DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(omit) , 0, 0, },
{ str8_lit_comp("no_addr"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(no_addr) , 0, 0, },
{ str8_lit_comp("rgba"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*1)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*1), 0, 0, DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_NAME(rgba) , DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(rgba) , },
{ str8_lit_comp("text"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*1), 0, 0, 0, DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(text) , },
{ str8_lit_comp("disasm"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*1), 0, 0, 0, DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(disasm) , },
{ str8_lit_comp("bitmap"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*1)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*1), 0, 0, DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_NAME(bitmap) , DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(bitmap) , },
{ str8_lit_comp("geo"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*1)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*1), 0, 0, DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_NAME(geo) , DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(geo) , },
str8_lit_comp("Default (Dark)"),
str8_lit_comp("Default (Light)"),
str8_lit_comp("VS (Dark)"),
str8_lit_comp("VS (Light)"),
str8_lit_comp("Solarized (Dark)"),
str8_lit_comp("Solarized (Light)"),
str8_lit_comp("Handmade Hero"),
str8_lit_comp("4coder"),
str8_lit_comp("Far Manager"),
};
String8 df_g_theme_preset_code_string_table[9] =
{
str8_lit_comp("default_dark"),
str8_lit_comp("default_light"),
str8_lit_comp("vs_dark"),
str8_lit_comp("vs_light"),
str8_lit_comp("solarized_dark"),
str8_lit_comp("solarized_light"),
str8_lit_comp("handmade_hero"),
str8_lit_comp("four_coder"),
str8_lit_comp("far_manager"),
};
Vec4F32 df_g_theme_preset_colors__default_dark[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x3333337f),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x7fcc99ff),
rgba_from_u32_lit_comp(0x66b2e5ff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0xf7bf5eff),
rgba_from_u32_lit_comp(0x994c32ff),
rgba_from_u32_lit_comp(0x4ce54cff),
rgba_from_u32_lit_comp(0xe5cc66ff),
rgba_from_u32_lit_comp(0xe54c4cff),
rgba_from_u32_lit_comp(0x7f7f7fff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xa87a4c99),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0xffffff7f),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32 df_g_theme_preset_colors__default_light[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0x383838ff),
rgba_from_u32_lit_comp(0xedededfe),
rgba_from_u32_lit_comp(0x0000001d),
rgba_from_u32_lit_comp(0x00000033),
rgba_from_u32_lit_comp(0x282828ff),
rgba_from_u32_lit_comp(0x2a7a45ff),
rgba_from_u32_lit_comp(0x2c688fff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0xa47729ff),
rgba_from_u32_lit_comp(0x6c2d18ff),
rgba_from_u32_lit_comp(0x2c7d2cff),
rgba_from_u32_lit_comp(0xcc5a0fff),
rgba_from_u32_lit_comp(0x8a0c0cff),
rgba_from_u32_lit_comp(0x7f7f7fff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0x535353ff),
rgba_from_u32_lit_comp(0xfefefebc),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xc7a27dff),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0xd76489cc),
rgba_from_u32_lit_comp(0x0000007f),
rgba_from_u32_lit_comp(0x7d98b34c),
rgba_from_u32_lit_comp(0x101010ff),
rgba_from_u32_lit_comp(0xb272189b),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x75db61ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xf27961ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xad7c34ff),
rgba_from_u32_lit_comp(0x639b2aff),
rgba_from_u32_lit_comp(0xa94c91ff),
rgba_from_u32_lit_comp(0x305398ff),
rgba_from_u32_lit_comp(0x339574ff),
rgba_from_u32_lit_comp(0xbf7416ff),
rgba_from_u32_lit_comp(0x57238bff),
rgba_from_u32_lit_comp(0x2a7e1cff),
rgba_from_u32_lit_comp(0x236481ff),
rgba_from_u32_lit_comp(0x0000000d),
rgba_from_u32_lit_comp(0x0000003b),
};
Vec4F32 df_g_theme_preset_colors__vs_dark[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x1e1e1eff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xd4d4d4ff),
rgba_from_u32_lit_comp(0xdcdcaaff),
rgba_from_u32_lit_comp(0x4ec9b0ff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0x569cd6ff),
rgba_from_u32_lit_comp(0xb4b4b4ff),
rgba_from_u32_lit_comp(0xb5cea8ff),
rgba_from_u32_lit_comp(0xd69d85ff),
rgba_from_u32_lit_comp(0x9b9b9bff),
rgba_from_u32_lit_comp(0x6a9955ff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0xf1f1f1ff),
rgba_from_u32_lit_comp(0x1b1b1cff),
rgba_from_u32_lit_comp(0x333337ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0x007accff),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0xffffff7f),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32 df_g_theme_preset_colors__vs_light[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0x1e1e1eff),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0xcccedb1d),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x000000ff),
rgba_from_u32_lit_comp(0x74531fff),
rgba_from_u32_lit_comp(0x2b91afff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0x0000ffff),
rgba_from_u32_lit_comp(0x000000ff),
rgba_from_u32_lit_comp(0x000000ff),
rgba_from_u32_lit_comp(0xc11515ff),
rgba_from_u32_lit_comp(0x808080ff),
rgba_from_u32_lit_comp(0x008000ff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0x535353ff),
rgba_from_u32_lit_comp(0xfefefebc),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0x007accff),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0x0000007f),
rgba_from_u32_lit_comp(0x7d98b34c),
rgba_from_u32_lit_comp(0x101010ff),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xad7c34ff),
rgba_from_u32_lit_comp(0x639b2aff),
rgba_from_u32_lit_comp(0xa94c91ff),
rgba_from_u32_lit_comp(0x305398ff),
rgba_from_u32_lit_comp(0x339574ff),
rgba_from_u32_lit_comp(0xbf7416ff),
rgba_from_u32_lit_comp(0x57238bff),
rgba_from_u32_lit_comp(0x2a7e1cff),
rgba_from_u32_lit_comp(0x236481ff),
rgba_from_u32_lit_comp(0x0000000d),
rgba_from_u32_lit_comp(0x0000003b),
};
Vec4F32 df_g_theme_preset_colors__solarized_dark[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x002b36ff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x839496ff),
rgba_from_u32_lit_comp(0x1c7dd1ff),
rgba_from_u32_lit_comp(0x1c7dd1ff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0x63980fff),
rgba_from_u32_lit_comp(0x839496ff),
rgba_from_u32_lit_comp(0xcb4b20ff),
rgba_from_u32_lit_comp(0x2aa198ff),
rgba_from_u32_lit_comp(0xe54c4cff),
rgba_from_u32_lit_comp(0x7f7f7fff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x002b36ff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0x28515eff),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0xffffff7f),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32 df_g_theme_preset_colors__solarized_light[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0x1e1e1eff),
rgba_from_u32_lit_comp(0xfcf6e2ff),
rgba_from_u32_lit_comp(0xcccedb1d),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x74878cff),
rgba_from_u32_lit_comp(0xc39d36ff),
rgba_from_u32_lit_comp(0x66b2e5ff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0xc39d36ff),
rgba_from_u32_lit_comp(0x2e5256ff),
rgba_from_u32_lit_comp(0x657b83ff),
rgba_from_u32_lit_comp(0x5ab4a9ff),
rgba_from_u32_lit_comp(0xe54c4cff),
rgba_from_u32_lit_comp(0xadafb2ff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0x535353ff),
rgba_from_u32_lit_comp(0xfcf6e2ff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xa87a4c99),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0x0000007f),
rgba_from_u32_lit_comp(0x7d98b34c),
rgba_from_u32_lit_comp(0x101010ff),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xad7c34ff),
rgba_from_u32_lit_comp(0x639b2aff),
rgba_from_u32_lit_comp(0xa94c91ff),
rgba_from_u32_lit_comp(0x305398ff),
rgba_from_u32_lit_comp(0x339574ff),
rgba_from_u32_lit_comp(0xbf7416ff),
rgba_from_u32_lit_comp(0x57238bff),
rgba_from_u32_lit_comp(0x2a7e1cff),
rgba_from_u32_lit_comp(0x236481ff),
rgba_from_u32_lit_comp(0x0000000d),
rgba_from_u32_lit_comp(0x0000003b),
};
Vec4F32 df_g_theme_preset_colors__handmade_hero[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0xa08563ff),
rgba_from_u32_lit_comp(0x0c0c0cff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xa08563ff),
rgba_from_u32_lit_comp(0xcc5735ff),
rgba_from_u32_lit_comp(0xd8a51dff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0xac7b0bff),
rgba_from_u32_lit_comp(0x994c32ff),
rgba_from_u32_lit_comp(0x6b8e23ff),
rgba_from_u32_lit_comp(0x6b8e23ff),
rgba_from_u32_lit_comp(0xdab98fff),
rgba_from_u32_lit_comp(0x686868ff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0xa08563ff),
rgba_from_u32_lit_comp(0x0c0c0cff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xa87a4c99),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0xa08563af),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32 df_g_theme_preset_colors__four_coder[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0x90b080ff),
rgba_from_u32_lit_comp(0x0c0c0cff),
rgba_from_u32_lit_comp(0x181818a0),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x90b080ff),
rgba_from_u32_lit_comp(0x7fcc99ff),
rgba_from_u32_lit_comp(0x66b2e5ff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0xd08f20ff),
rgba_from_u32_lit_comp(0x994c32ff),
rgba_from_u32_lit_comp(0x50ff30ff),
rgba_from_u32_lit_comp(0x50ff30ff),
rgba_from_u32_lit_comp(0x50ff30ff),
rgba_from_u32_lit_comp(0x2090f0ff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0x90b080ff),
rgba_from_u32_lit_comp(0x0c0c0cff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xa87a4c99),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0x90b080af),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32 df_g_theme_preset_colors__far_manager[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0x00ffffff),
rgba_from_u32_lit_comp(0x000082ff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x00ffffff),
rgba_from_u32_lit_comp(0x49b2ffff),
rgba_from_u32_lit_comp(0x49b2ffff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0xff0000ff),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x2cff50ff),
rgba_from_u32_lit_comp(0xe5cc66ff),
rgba_from_u32_lit_comp(0xffff00ff),
rgba_from_u32_lit_comp(0x7f7f7fff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0x000000ff),
rgba_from_u32_lit_comp(0x008184ff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xa87a4c99),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0xffffff7f),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32* df_g_theme_preset_colors_table[9] =
{
df_g_theme_preset_colors__default_dark,
df_g_theme_preset_colors__default_light,
df_g_theme_preset_colors__vs_dark,
df_g_theme_preset_colors__vs_light,
df_g_theme_preset_colors__solarized_dark,
df_g_theme_preset_colors__solarized_light,
df_g_theme_preset_colors__handmade_hero,
df_g_theme_preset_colors__four_coder,
df_g_theme_preset_colors__far_manager,
};
DF_CmdParamSlot df_g_cmd_param_slot_2_view_spec_src_map[7] =
{
DF_CmdParamSlot_Entity,
DF_CmdParamSlot_EntityList,
DF_CmdParamSlot_FilePath,
DF_CmdParamSlot_CmdSpec,
DF_CmdParamSlot_ID,
DF_CmdParamSlot_String,
DF_CmdParamSlot_String,
};
String8 df_g_cmd_param_slot_2_view_spec_dst_map[7] =
{
str8_lit_comp("entity_lister"),
str8_lit_comp("entity_lister"),
str8_lit_comp("file_system"),
str8_lit_comp("commands"),
str8_lit_comp("system_processes"),
str8_lit_comp("symbol_lister"),
str8_lit_comp("symbol_lister"),
};
String8 df_g_cmd_param_slot_2_view_spec_cmd_map[7] =
{
str8_lit_comp(""),
str8_lit_comp(""),
str8_lit_comp(""),
str8_lit_comp(""),
str8_lit_comp(""),
str8_lit_comp("goto_name"),
str8_lit_comp("function_breakpoint"),
};
DF_StringBindingPair df_g_default_binding_table[97] =
{
{str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("step_over_inst"), {OS_Key_F10, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("step_out"), {OS_Key_F11, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("halt"), {OS_Key_X, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("halt"), {OS_Key_Pause, 0 }},
{str8_lit_comp("soft_halt_refresh"), {OS_Key_R, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("run"), {OS_Key_F5, 0 }},
{str8_lit_comp("restart"), {OS_Key_F5, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("step_into"), {OS_Key_F11, 0 }},
{str8_lit_comp("step_over"), {OS_Key_F10, 0 }},
{str8_lit_comp("run_to_cursor"), {OS_Key_F10, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("set_next_statement"), {OS_Key_F10, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("inc_ui_font_scale"), {OS_Key_Equal, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("dec_ui_font_scale"), {OS_Key_Minus, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("inc_code_font_scale"), {OS_Key_Equal, 0 |OS_EventFlag_Shift |OS_EventFlag_Alt}},
{str8_lit_comp("dec_code_font_scale"), {OS_Key_Minus, 0 |OS_EventFlag_Shift |OS_EventFlag_Alt}},
{str8_lit_comp("window"), {OS_Key_N, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("toggle_fullscreen"), {OS_Key_Return, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("new_panel_right"), {OS_Key_P, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("new_panel_down"), {OS_Key_Minus, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("rotate_panel_columns"), {OS_Key_2, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("next_panel"), {OS_Key_Comma, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("prev_panel"), {OS_Key_Comma, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("focus_panel_right"), {OS_Key_Right, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
{str8_lit_comp("focus_panel_left"), {OS_Key_Left, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
{str8_lit_comp("focus_panel_up"), {OS_Key_Up, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
{str8_lit_comp("focus_panel_down"), {OS_Key_Down, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
{str8_lit_comp("close_panel"), {OS_Key_P, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("next_tab"), {OS_Key_PageDown, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("prev_tab"), {OS_Key_PageUp, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("next_tab"), {OS_Key_Tab, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("prev_tab"), {OS_Key_Tab, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_tab_right"), {OS_Key_PageDown, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_tab_left"), {OS_Key_PageUp, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("close_tab"), {OS_Key_W, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("tab_bar_top"), {OS_Key_Up, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}},
{str8_lit_comp("tab_bar_bottom"), {OS_Key_Down, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}},
{str8_lit_comp("open"), {OS_Key_O, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("reload_active"), {OS_Key_R, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("switch"), {OS_Key_I, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("switch_to_partner_file"), {OS_Key_O, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("load_user"), {OS_Key_O, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}},
{str8_lit_comp("load_profile"), {OS_Key_O, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
{str8_lit_comp("move_left"), {OS_Key_Left, 0 }},
{str8_lit_comp("move_right"), {OS_Key_Right, 0 }},
{str8_lit_comp("move_up"), {OS_Key_Up, 0 }},
{str8_lit_comp("move_down"), {OS_Key_Down, 0 }},
{str8_lit_comp("move_left_select"), {OS_Key_Left, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_right_select"), {OS_Key_Right, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_up_select"), {OS_Key_Up, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_down_select"), {OS_Key_Down, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_left_chunk"), {OS_Key_Left, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_right_chunk"), {OS_Key_Right, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_up_chunk"), {OS_Key_Up, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_down_chunk"), {OS_Key_Down, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_up_page"), {OS_Key_PageUp, 0 }},
{str8_lit_comp("move_down_page"), {OS_Key_PageDown, 0 }},
{str8_lit_comp("move_up_whole"), {OS_Key_Home, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_down_whole"), {OS_Key_End, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_left_chunk_select"), {OS_Key_Left, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_right_chunk_select"), {OS_Key_Right, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_up_chunk_select"), {OS_Key_Up, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_down_chunk_select"), {OS_Key_Down, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_up_page_select"), {OS_Key_PageUp, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_down_page_select"), {OS_Key_PageDown, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_up_whole_select"), {OS_Key_Home, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_down_whole_select"), {OS_Key_End, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_home"), {OS_Key_Home, 0 }},
{str8_lit_comp("move_end"), {OS_Key_End, 0 }},
{str8_lit_comp("move_home_select"), {OS_Key_Home, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_end_select"), {OS_Key_End, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("select_all"), {OS_Key_A, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("delete_single"), {OS_Key_Delete, 0 }},
{str8_lit_comp("delete_chunk"), {OS_Key_Delete, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("backspace_single"), {OS_Key_Backspace, 0 }},
{str8_lit_comp("backspace_chunk"), {OS_Key_Backspace, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("copy"), {OS_Key_C, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("cut"), {OS_Key_X, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("paste"), {OS_Key_V, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("insert_text"), {OS_Key_Null, 0 }},
{str8_lit_comp("goto_line"), {OS_Key_G, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("goto_address"), {OS_Key_G, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("find_text_forward"), {OS_Key_F, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("find_text_backward"), {OS_Key_R, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("find_next"), {OS_Key_F3, 0 }},
{str8_lit_comp("find_prev"), {OS_Key_F3, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("find_selected_thread"), {OS_Key_F4, 0 }},
{str8_lit_comp("goto_name"), {OS_Key_J, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("goto_name_at_cursor"), {OS_Key_F12, 0 }},
{str8_lit_comp("toggle_watch_expr_at_cursor"), {OS_Key_W, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("toggle_watch_pin_at_cursor"), {OS_Key_F9, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("toggle_breakpoint_cursor"), {OS_Key_F9, 0 }},
{str8_lit_comp("add_target"), {OS_Key_T, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("attach"), {OS_Key_F6, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("filter"), {OS_Key_Slash, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("run_command"), {OS_Key_F1, 0 }},
};
String8 df_g_binding_version_remap_old_name_table[3] =
{
str8_lit_comp("commands"),
str8_lit_comp("load_user"),
str8_lit_comp("load_profile"),
};
String8 df_g_binding_version_remap_new_name_table[3] =
{
str8_lit_comp("run_command"),
str8_lit_comp("open_user"),
str8_lit_comp("open_profile"),
};
DF_GfxViewRuleSpecInfo df_g_gfx_view_rule_spec_info_table[14] =
{
{ str8_lit_comp("array"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, 0, 0, 0, 0 },
{ str8_lit_comp("list"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*1)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), DF_GFX_VIEW_RULE_VIZ_ROW_PROD_FUNCTION_NAME(list) , 0, 0, 0, 0 },
{ str8_lit_comp("dec"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(dec) , 0, 0, 0 },
{ str8_lit_comp("bin"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(bin) , 0, 0, 0 },
{ str8_lit_comp("oct"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(oct) , 0, 0, 0 },
{ str8_lit_comp("hex"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(hex) , 0, 0, 0 },
{ str8_lit_comp("only"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*1)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), DF_GFX_VIEW_RULE_VIZ_ROW_PROD_FUNCTION_NAME(only) , DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(only) , 0, 0, 0 },
{ str8_lit_comp("omit"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*1)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), DF_GFX_VIEW_RULE_VIZ_ROW_PROD_FUNCTION_NAME(omit) , DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(omit) , 0, 0, 0 },
{ str8_lit_comp("no_addr"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(no_addr) , 0, 0, 0 },
{ str8_lit_comp("rgba"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*1)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*1), 0, 0, DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_NAME(rgba) , DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(rgba) , 0 },
{ str8_lit_comp("text"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*1), 0, 0, 0, DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(text) , 0 },
{ str8_lit_comp("disasm"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*1), 0, 0, 0, DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(disasm) , 0 },
{ str8_lit_comp("bitmap"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*1)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*1), 0, 0, DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_NAME(bitmap) , DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(bitmap) , DF_GFX_VIEW_RULE_WHOLE_UI_FUNCTION_NAME(bitmap) },
{ str8_lit_comp("geo"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*1)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*1), 0, 0, DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_NAME(geo) , DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(geo) , 0 },
};
DF_ViewSpecInfo df_g_gfx_view_kind_spec_info_table[30] =
{
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("null"), str8_lit_comp(""), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(Null), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Null), DF_VIEW_CMD_FUNCTION_NAME(Null), DF_VIEW_UI_FUNCTION_NAME(Null)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("empty"), str8_lit_comp(""), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(Empty), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Empty), DF_VIEW_CMD_FUNCTION_NAME(Empty), DF_VIEW_UI_FUNCTION_NAME(Empty)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("commands"), str8_lit_comp("Commands"), DF_NameKind_Null, DF_IconKind_List, DF_VIEW_SETUP_FUNCTION_NAME(Commands), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Commands), DF_VIEW_CMD_FUNCTION_NAME(Commands), DF_VIEW_UI_FUNCTION_NAME(Commands)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("file_system"), str8_lit_comp("File System"), DF_NameKind_Null, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(FileSystem), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(FileSystem), DF_VIEW_CMD_FUNCTION_NAME(FileSystem), DF_VIEW_UI_FUNCTION_NAME(FileSystem)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("system_processes"), str8_lit_comp("System Processes"), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(SystemProcesses), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(SystemProcesses), DF_VIEW_CMD_FUNCTION_NAME(SystemProcesses), DF_VIEW_UI_FUNCTION_NAME(SystemProcesses)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("entity_lister"), str8_lit_comp("Entity List"), DF_NameKind_EntityKindName, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(EntityLister), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(EntityLister), DF_VIEW_CMD_FUNCTION_NAME(EntityLister), DF_VIEW_UI_FUNCTION_NAME(EntityLister)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("symbol_lister"), str8_lit_comp("Symbols"), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(SymbolLister), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(SymbolLister), DF_VIEW_CMD_FUNCTION_NAME(SymbolLister), DF_VIEW_UI_FUNCTION_NAME(SymbolLister)},
{(0|1*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("target"), str8_lit_comp("Target"), DF_NameKind_EntityName, DF_IconKind_Target, DF_VIEW_SETUP_FUNCTION_NAME(Target), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Target), DF_VIEW_CMD_FUNCTION_NAME(Target), DF_VIEW_UI_FUNCTION_NAME(Target)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("targets"), str8_lit_comp("Targets"), DF_NameKind_Null, DF_IconKind_Target, DF_VIEW_SETUP_FUNCTION_NAME(Targets), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Targets), DF_VIEW_CMD_FUNCTION_NAME(Targets), DF_VIEW_UI_FUNCTION_NAME(Targets)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("file_path_map"), str8_lit_comp("File Path Map"), DF_NameKind_Null, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(FilePathMap), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(FilePathMap), DF_VIEW_CMD_FUNCTION_NAME(FilePathMap), DF_VIEW_UI_FUNCTION_NAME(FilePathMap)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("scheduler"), str8_lit_comp("Scheduler"), DF_NameKind_Null, DF_IconKind_Scheduler, DF_VIEW_SETUP_FUNCTION_NAME(Scheduler), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Scheduler), DF_VIEW_CMD_FUNCTION_NAME(Scheduler), DF_VIEW_UI_FUNCTION_NAME(Scheduler)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("call_stack"), str8_lit_comp("Call Stack"), DF_NameKind_Null, DF_IconKind_Thread, DF_VIEW_SETUP_FUNCTION_NAME(CallStack), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(CallStack), DF_VIEW_CMD_FUNCTION_NAME(CallStack), DF_VIEW_UI_FUNCTION_NAME(CallStack)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("modules"), str8_lit_comp("Modules"), DF_NameKind_Null, DF_IconKind_Module, DF_VIEW_SETUP_FUNCTION_NAME(Modules), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Modules), DF_VIEW_CMD_FUNCTION_NAME(Modules), DF_VIEW_UI_FUNCTION_NAME(Modules)},
{(0|1*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("pending_entity"), str8_lit_comp("Pending Entity"), DF_NameKind_EntityName, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(PendingEntity), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(PendingEntity), DF_VIEW_CMD_FUNCTION_NAME(PendingEntity), DF_VIEW_UI_FUNCTION_NAME(PendingEntity)},
{(0|1*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|1*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("code"), str8_lit_comp("Code"), DF_NameKind_EntityName, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(Code), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Code), DF_VIEW_CMD_FUNCTION_NAME(Code), DF_VIEW_UI_FUNCTION_NAME(Code)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("disassembly"), str8_lit_comp("Disassembly"), DF_NameKind_Null, DF_IconKind_Glasses, DF_VIEW_SETUP_FUNCTION_NAME(Disassembly), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Disassembly), DF_VIEW_CMD_FUNCTION_NAME(Disassembly), DF_VIEW_UI_FUNCTION_NAME(Disassembly)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("eval_viewer"), str8_lit_comp("Evaluation Viewer"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(EvalViewer), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(EvalViewer), DF_VIEW_CMD_FUNCTION_NAME(EvalViewer), DF_VIEW_UI_FUNCTION_NAME(EvalViewer)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("watch"), str8_lit_comp("Watch"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Watch), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Watch), DF_VIEW_CMD_FUNCTION_NAME(Watch), DF_VIEW_UI_FUNCTION_NAME(Watch)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("locals"), str8_lit_comp("Locals"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Locals), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Locals), DF_VIEW_CMD_FUNCTION_NAME(Locals), DF_VIEW_UI_FUNCTION_NAME(Locals)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("registers"), str8_lit_comp("Registers"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Registers), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Registers), DF_VIEW_CMD_FUNCTION_NAME(Registers), DF_VIEW_UI_FUNCTION_NAME(Registers)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("globals"), str8_lit_comp("Globals"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Globals), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Globals), DF_VIEW_CMD_FUNCTION_NAME(Globals), DF_VIEW_UI_FUNCTION_NAME(Globals)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("thread_locals"), str8_lit_comp("Thread Locals"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(ThreadLocals), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(ThreadLocals), DF_VIEW_CMD_FUNCTION_NAME(ThreadLocals), DF_VIEW_UI_FUNCTION_NAME(ThreadLocals)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("types"), str8_lit_comp("Types"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Types), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Types), DF_VIEW_CMD_FUNCTION_NAME(Types), DF_VIEW_UI_FUNCTION_NAME(Types)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("procedures"), str8_lit_comp("Procedures"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Procedures), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Procedures), DF_VIEW_CMD_FUNCTION_NAME(Procedures), DF_VIEW_UI_FUNCTION_NAME(Procedures)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("output"), str8_lit_comp("Output"), DF_NameKind_Null, DF_IconKind_List, DF_VIEW_SETUP_FUNCTION_NAME(Output), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Output), DF_VIEW_CMD_FUNCTION_NAME(Output), DF_VIEW_UI_FUNCTION_NAME(Output)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|1*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("memory"), str8_lit_comp("Memory"), DF_NameKind_Null, DF_IconKind_Grid, DF_VIEW_SETUP_FUNCTION_NAME(Memory), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Memory), DF_VIEW_CMD_FUNCTION_NAME(Memory), DF_VIEW_UI_FUNCTION_NAME(Memory)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("breakpoints"), str8_lit_comp("Breakpoints"), DF_NameKind_Null, DF_IconKind_CircleFilled, DF_VIEW_SETUP_FUNCTION_NAME(Breakpoints), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Breakpoints), DF_VIEW_CMD_FUNCTION_NAME(Breakpoints), DF_VIEW_UI_FUNCTION_NAME(Breakpoints)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("watch_pins"), str8_lit_comp("Watch Pins"), DF_NameKind_Null, DF_IconKind_Pin, DF_VIEW_SETUP_FUNCTION_NAME(WatchPins), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(WatchPins), DF_VIEW_CMD_FUNCTION_NAME(WatchPins), DF_VIEW_UI_FUNCTION_NAME(WatchPins)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("exception_filters"), str8_lit_comp("Exception Filters"), DF_NameKind_Null, DF_IconKind_Gear, DF_VIEW_SETUP_FUNCTION_NAME(ExceptionFilters), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(ExceptionFilters), DF_VIEW_CMD_FUNCTION_NAME(ExceptionFilters), DF_VIEW_UI_FUNCTION_NAME(ExceptionFilters)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("theme"), str8_lit_comp("Theme"), DF_NameKind_Null, DF_IconKind_Palette, DF_VIEW_SETUP_FUNCTION_NAME(Theme), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Theme), DF_VIEW_CMD_FUNCTION_NAME(Theme), DF_VIEW_UI_FUNCTION_NAME(Theme)},
};
String8 df_g_theme_color_display_string_table[54] =
{
str8_lit_comp("Null"),
str8_lit_comp("Plain Text"),
str8_lit_comp("Plain Background"),
str8_lit_comp("Plain Border"),
str8_lit_comp("Plain Overlay"),
str8_lit_comp("Code (Default)"),
str8_lit_comp("Code (Function)"),
str8_lit_comp("Code (Type)"),
str8_lit_comp("Code (Local)"),
str8_lit_comp("Code (Register)"),
str8_lit_comp("Code (Keyword)"),
str8_lit_comp("Code (Symbol)"),
str8_lit_comp("Code (Numeric)"),
str8_lit_comp("Code (String)"),
str8_lit_comp("Code (Meta)"),
str8_lit_comp("Code (Comment)"),
str8_lit_comp("Line Info (0)"),
str8_lit_comp("Line Info (1)"),
str8_lit_comp("Line Info (2)"),
str8_lit_comp("Line Info (3)"),
str8_lit_comp("Alt Text"),
str8_lit_comp("Alt Background"),
str8_lit_comp("Alt Border"),
str8_lit_comp("Alt Overlay"),
str8_lit_comp("Inactive Tab"),
str8_lit_comp("Active Tab"),
str8_lit_comp("Entity Background"),
str8_lit_comp("Query Bar"),
str8_lit_comp("Weak Text"),
str8_lit_comp("Text Selection"),
str8_lit_comp("Cursor"),
str8_lit_comp("Highlight (0)"),
str8_lit_comp("Highlight (1)"),
str8_lit_comp("Success Text"),
str8_lit_comp("Success Background"),
str8_lit_comp("Success Border"),
str8_lit_comp("Failure Text"),
str8_lit_comp("Failure Background"),
str8_lit_comp("Failure Border"),
str8_lit_comp("Action Text"),
str8_lit_comp("Action Background"),
str8_lit_comp("Action Border"),
str8_lit_comp("Drop Site Overlay"),
str8_lit_comp("Thread (0)"),
str8_lit_comp("Thread (1)"),
str8_lit_comp("Thread (2)"),
str8_lit_comp("Thread (3)"),
str8_lit_comp("Thread (4)"),
str8_lit_comp("Thread (5)"),
str8_lit_comp("Thread (6)"),
str8_lit_comp("Thread (7)"),
str8_lit_comp("Thread (Unwound)"),
str8_lit_comp("Inactive Panel Overlay"),
str8_lit_comp("Drop Shadow"),
};
String8 df_g_theme_color_cfg_string_table[54] =
{
str8_lit_comp("null"),
str8_lit_comp("plain_text"),
str8_lit_comp("plain_background"),
str8_lit_comp("plain_border"),
str8_lit_comp("plain_overlay"),
str8_lit_comp("code_default"),
str8_lit_comp("code_function"),
str8_lit_comp("code_type"),
str8_lit_comp("code_local"),
str8_lit_comp("code_register"),
str8_lit_comp("code_keyword"),
str8_lit_comp("code_symbol"),
str8_lit_comp("code_numeric"),
str8_lit_comp("code_string"),
str8_lit_comp("code_meta"),
str8_lit_comp("code_comment"),
str8_lit_comp("line_info_0"),
str8_lit_comp("line_info_1"),
str8_lit_comp("line_info_2"),
str8_lit_comp("line_info_3"),
str8_lit_comp("alt_text"),
str8_lit_comp("alt_background"),
str8_lit_comp("alt_border"),
str8_lit_comp("alt_overlay"),
str8_lit_comp("tab_inactive"),
str8_lit_comp("tab_active"),
str8_lit_comp("entity_background"),
str8_lit_comp("query_bar"),
str8_lit_comp("weak_text"),
str8_lit_comp("text_selection"),
str8_lit_comp("cursor"),
str8_lit_comp("highlight_0"),
str8_lit_comp("highlight_1"),
str8_lit_comp("success_text"),
str8_lit_comp("success_background"),
str8_lit_comp("success_border"),
str8_lit_comp("failure_text"),
str8_lit_comp("failure_background"),
str8_lit_comp("failure_border"),
str8_lit_comp("action_text"),
str8_lit_comp("action_background"),
str8_lit_comp("action_border"),
str8_lit_comp("drop_site_overlay"),
str8_lit_comp("thread_0"),
str8_lit_comp("thread_1"),
str8_lit_comp("thread_2"),
str8_lit_comp("thread_3"),
str8_lit_comp("thread_4"),
str8_lit_comp("thread_5"),
str8_lit_comp("thread_6"),
str8_lit_comp("thread_7"),
str8_lit_comp("thread_unwound"),
str8_lit_comp("inactive_panel_overlay"),
str8_lit_comp("drop_shadow"),
};
C_LINKAGE_END
+41 -850
View File
@@ -6,6 +6,14 @@
#ifndef DF_GFX_META_H
#define DF_GFX_META_H
typedef enum DF_NameKind
{
DF_NameKind_Null,
DF_NameKind_EntityName,
DF_NameKind_EntityKindName,
DF_NameKind_COUNT,
} DF_NameKind;
typedef enum DF_GfxViewKind
{
DF_GfxViewKind_Null,
@@ -24,6 +32,7 @@ DF_GfxViewKind_Modules,
DF_GfxViewKind_PendingEntity,
DF_GfxViewKind_Code,
DF_GfxViewKind_Disassembly,
DF_GfxViewKind_EvalViewer,
DF_GfxViewKind_Watch,
DF_GfxViewKind_Locals,
DF_GfxViewKind_Registers,
@@ -37,7 +46,7 @@ DF_GfxViewKind_Breakpoints,
DF_GfxViewKind_WatchPins,
DF_GfxViewKind_ExceptionFilters,
DF_GfxViewKind_Theme,
DF_GfxViewKind_COUNT
DF_GfxViewKind_COUNT,
} DF_GfxViewKind;
typedef enum DF_ThemeColor
@@ -51,6 +60,7 @@ DF_ThemeColor_CodeDefault,
DF_ThemeColor_CodeFunction,
DF_ThemeColor_CodeType,
DF_ThemeColor_CodeLocal,
DF_ThemeColor_CodeRegister,
DF_ThemeColor_CodeKeyword,
DF_ThemeColor_CodeSymbol,
DF_ThemeColor_CodeNumeric,
@@ -95,7 +105,7 @@ DF_ThemeColor_Thread7,
DF_ThemeColor_ThreadUnwound,
DF_ThemeColor_InactivePanelOverlay,
DF_ThemeColor_DropShadow,
DF_ThemeColor_COUNT
DF_ThemeColor_COUNT,
} DF_ThemeColor;
typedef enum DF_ThemePreset
@@ -109,7 +119,7 @@ DF_ThemePreset_SolarizedLight,
DF_ThemePreset_HandmadeHero,
DF_ThemePreset_FourCoder,
DF_ThemePreset_FarManager,
DF_ThemePreset_COUNT
DF_ThemePreset_COUNT,
} DF_ThemePreset;
DF_VIEW_SETUP_FUNCTION_DEF(Null);
@@ -128,6 +138,7 @@ DF_VIEW_SETUP_FUNCTION_DEF(Modules);
DF_VIEW_SETUP_FUNCTION_DEF(PendingEntity);
DF_VIEW_SETUP_FUNCTION_DEF(Code);
DF_VIEW_SETUP_FUNCTION_DEF(Disassembly);
DF_VIEW_SETUP_FUNCTION_DEF(EvalViewer);
DF_VIEW_SETUP_FUNCTION_DEF(Watch);
DF_VIEW_SETUP_FUNCTION_DEF(Locals);
DF_VIEW_SETUP_FUNCTION_DEF(Registers);
@@ -157,6 +168,7 @@ DF_VIEW_STRING_FROM_STATE_FUNCTION_DEF(Modules);
DF_VIEW_STRING_FROM_STATE_FUNCTION_DEF(PendingEntity);
DF_VIEW_STRING_FROM_STATE_FUNCTION_DEF(Code);
DF_VIEW_STRING_FROM_STATE_FUNCTION_DEF(Disassembly);
DF_VIEW_STRING_FROM_STATE_FUNCTION_DEF(EvalViewer);
DF_VIEW_STRING_FROM_STATE_FUNCTION_DEF(Watch);
DF_VIEW_STRING_FROM_STATE_FUNCTION_DEF(Locals);
DF_VIEW_STRING_FROM_STATE_FUNCTION_DEF(Registers);
@@ -186,6 +198,7 @@ DF_VIEW_CMD_FUNCTION_DEF(Modules);
DF_VIEW_CMD_FUNCTION_DEF(PendingEntity);
DF_VIEW_CMD_FUNCTION_DEF(Code);
DF_VIEW_CMD_FUNCTION_DEF(Disassembly);
DF_VIEW_CMD_FUNCTION_DEF(EvalViewer);
DF_VIEW_CMD_FUNCTION_DEF(Watch);
DF_VIEW_CMD_FUNCTION_DEF(Locals);
DF_VIEW_CMD_FUNCTION_DEF(Registers);
@@ -215,6 +228,7 @@ DF_VIEW_UI_FUNCTION_DEF(Modules);
DF_VIEW_UI_FUNCTION_DEF(PendingEntity);
DF_VIEW_UI_FUNCTION_DEF(Code);
DF_VIEW_UI_FUNCTION_DEF(Disassembly);
DF_VIEW_UI_FUNCTION_DEF(EvalViewer);
DF_VIEW_UI_FUNCTION_DEF(Watch);
DF_VIEW_UI_FUNCTION_DEF(Locals);
DF_VIEW_UI_FUNCTION_DEF(Registers);
@@ -247,853 +261,29 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(text);
DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(disasm);
DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(bitmap);
DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(geo);
String8 df_g_theme_preset_display_string_table[] =
{
str8_lit_comp("Default (Dark)"),
str8_lit_comp("Default (Light)"),
str8_lit_comp("VS (Dark)"),
str8_lit_comp("VS (Light)"),
str8_lit_comp("Solarized (Dark)"),
str8_lit_comp("Solarized (Light)"),
str8_lit_comp("Handmade Hero"),
str8_lit_comp("4coder"),
str8_lit_comp("Far Manager"),
};
String8 df_g_theme_preset_code_string_table[] =
{
str8_lit_comp("default_dark"),
str8_lit_comp("default_light"),
str8_lit_comp("vs_dark"),
str8_lit_comp("vs_light"),
str8_lit_comp("solarized_dark"),
str8_lit_comp("solarized_light"),
str8_lit_comp("handmade_hero"),
str8_lit_comp("four_coder"),
str8_lit_comp("far_manager"),
};
Vec4F32 df_g_theme_preset_colors__default_dark[] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x3333337f),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x7fcc99ff),
rgba_from_u32_lit_comp(0x66b2e5ff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xf7bf5eff),
rgba_from_u32_lit_comp(0x994c32ff),
rgba_from_u32_lit_comp(0x4ce54cff),
rgba_from_u32_lit_comp(0xe5cc66ff),
rgba_from_u32_lit_comp(0xe54c4cff),
rgba_from_u32_lit_comp(0x7f7f7fff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xa87a4c99),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0xffffff7f),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32 df_g_theme_preset_colors__default_light[] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0x383838ff),
rgba_from_u32_lit_comp(0xedededfe),
rgba_from_u32_lit_comp(0x0000001d),
rgba_from_u32_lit_comp(0x00000033),
rgba_from_u32_lit_comp(0x282828ff),
rgba_from_u32_lit_comp(0x2a7a45ff),
rgba_from_u32_lit_comp(0x2c688fff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xa47729ff),
rgba_from_u32_lit_comp(0x6c2d18ff),
rgba_from_u32_lit_comp(0x2c7d2cff),
rgba_from_u32_lit_comp(0xcc5a0fff),
rgba_from_u32_lit_comp(0x8a0c0cff),
rgba_from_u32_lit_comp(0x7f7f7fff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0x535353ff),
rgba_from_u32_lit_comp(0xfefefebc),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xc7a27dff),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0xd76489cc),
rgba_from_u32_lit_comp(0x0000007f),
rgba_from_u32_lit_comp(0x7d98b34c),
rgba_from_u32_lit_comp(0x101010ff),
rgba_from_u32_lit_comp(0xb272189b),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x75db61ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xf27961ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xad7c34ff),
rgba_from_u32_lit_comp(0x639b2aff),
rgba_from_u32_lit_comp(0xa94c91ff),
rgba_from_u32_lit_comp(0x305398ff),
rgba_from_u32_lit_comp(0x339574ff),
rgba_from_u32_lit_comp(0xbf7416ff),
rgba_from_u32_lit_comp(0x57238bff),
rgba_from_u32_lit_comp(0x2a7e1cff),
rgba_from_u32_lit_comp(0x236481ff),
rgba_from_u32_lit_comp(0x0000000d),
rgba_from_u32_lit_comp(0x0000003b),
};
Vec4F32 df_g_theme_preset_colors__vs_dark[] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x1e1e1eff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xd4d4d4ff),
rgba_from_u32_lit_comp(0xdcdcaaff),
rgba_from_u32_lit_comp(0x4ec9b0ff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0x569cd6ff),
rgba_from_u32_lit_comp(0xb4b4b4ff),
rgba_from_u32_lit_comp(0xb5cea8ff),
rgba_from_u32_lit_comp(0xd69d85ff),
rgba_from_u32_lit_comp(0x9b9b9bff),
rgba_from_u32_lit_comp(0x6a9955ff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0xf1f1f1ff),
rgba_from_u32_lit_comp(0x1b1b1cff),
rgba_from_u32_lit_comp(0x333337ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0x007accff),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0xffffff7f),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32 df_g_theme_preset_colors__vs_light[] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0x1e1e1eff),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0xcccedb1d),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x000000ff),
rgba_from_u32_lit_comp(0x74531fff),
rgba_from_u32_lit_comp(0x2b91afff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0x0000ffff),
rgba_from_u32_lit_comp(0x000000ff),
rgba_from_u32_lit_comp(0x000000ff),
rgba_from_u32_lit_comp(0xc11515ff),
rgba_from_u32_lit_comp(0x808080ff),
rgba_from_u32_lit_comp(0x008000ff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0x535353ff),
rgba_from_u32_lit_comp(0xfefefebc),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0x007accff),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0x0000007f),
rgba_from_u32_lit_comp(0x7d98b34c),
rgba_from_u32_lit_comp(0x101010ff),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xad7c34ff),
rgba_from_u32_lit_comp(0x639b2aff),
rgba_from_u32_lit_comp(0xa94c91ff),
rgba_from_u32_lit_comp(0x305398ff),
rgba_from_u32_lit_comp(0x339574ff),
rgba_from_u32_lit_comp(0xbf7416ff),
rgba_from_u32_lit_comp(0x57238bff),
rgba_from_u32_lit_comp(0x2a7e1cff),
rgba_from_u32_lit_comp(0x236481ff),
rgba_from_u32_lit_comp(0x0000000d),
rgba_from_u32_lit_comp(0x0000003b),
};
Vec4F32 df_g_theme_preset_colors__solarized_dark[] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x002b36ff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x839496ff),
rgba_from_u32_lit_comp(0x1c7dd1ff),
rgba_from_u32_lit_comp(0x1c7dd1ff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0x63980fff),
rgba_from_u32_lit_comp(0x839496ff),
rgba_from_u32_lit_comp(0xcb4b20ff),
rgba_from_u32_lit_comp(0x2aa198ff),
rgba_from_u32_lit_comp(0xe54c4cff),
rgba_from_u32_lit_comp(0x7f7f7fff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x002b36ff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0x28515eff),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0xffffff7f),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32 df_g_theme_preset_colors__solarized_light[] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0x1e1e1eff),
rgba_from_u32_lit_comp(0xfcf6e2ff),
rgba_from_u32_lit_comp(0xcccedb1d),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x74878cff),
rgba_from_u32_lit_comp(0xc39d36ff),
rgba_from_u32_lit_comp(0x66b2e5ff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xc39d36ff),
rgba_from_u32_lit_comp(0x2e5256ff),
rgba_from_u32_lit_comp(0x657b83ff),
rgba_from_u32_lit_comp(0x5ab4a9ff),
rgba_from_u32_lit_comp(0xe54c4cff),
rgba_from_u32_lit_comp(0xadafb2ff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0x535353ff),
rgba_from_u32_lit_comp(0xfcf6e2ff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xa87a4c99),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0x0000007f),
rgba_from_u32_lit_comp(0x7d98b34c),
rgba_from_u32_lit_comp(0x101010ff),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xad7c34ff),
rgba_from_u32_lit_comp(0x639b2aff),
rgba_from_u32_lit_comp(0xa94c91ff),
rgba_from_u32_lit_comp(0x305398ff),
rgba_from_u32_lit_comp(0x339574ff),
rgba_from_u32_lit_comp(0xbf7416ff),
rgba_from_u32_lit_comp(0x57238bff),
rgba_from_u32_lit_comp(0x2a7e1cff),
rgba_from_u32_lit_comp(0x236481ff),
rgba_from_u32_lit_comp(0x0000000d),
rgba_from_u32_lit_comp(0x0000003b),
};
Vec4F32 df_g_theme_preset_colors__handmade_hero[] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0xa08563ff),
rgba_from_u32_lit_comp(0x0c0c0cff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xa08563ff),
rgba_from_u32_lit_comp(0xcc5735ff),
rgba_from_u32_lit_comp(0xd8a51dff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xac7b0bff),
rgba_from_u32_lit_comp(0x994c32ff),
rgba_from_u32_lit_comp(0x6b8e23ff),
rgba_from_u32_lit_comp(0x6b8e23ff),
rgba_from_u32_lit_comp(0xdab98fff),
rgba_from_u32_lit_comp(0x686868ff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0xa08563ff),
rgba_from_u32_lit_comp(0x0c0c0cff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xa87a4c99),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0xa08563af),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32 df_g_theme_preset_colors__four_coder[] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0x90b080ff),
rgba_from_u32_lit_comp(0x0c0c0cff),
rgba_from_u32_lit_comp(0x181818a0),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x90b080ff),
rgba_from_u32_lit_comp(0x7fcc99ff),
rgba_from_u32_lit_comp(0x66b2e5ff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd08f20ff),
rgba_from_u32_lit_comp(0x994c32ff),
rgba_from_u32_lit_comp(0x50ff30ff),
rgba_from_u32_lit_comp(0x50ff30ff),
rgba_from_u32_lit_comp(0x50ff30ff),
rgba_from_u32_lit_comp(0x2090f0ff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0x90b080ff),
rgba_from_u32_lit_comp(0x0c0c0cff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xa87a4c99),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0x90b080af),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32 df_g_theme_preset_colors__far_manager[] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0x00ffffff),
rgba_from_u32_lit_comp(0x000082ff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x00ffffff),
rgba_from_u32_lit_comp(0x49b2ffff),
rgba_from_u32_lit_comp(0x49b2ffff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xff0000ff),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x2cff50ff),
rgba_from_u32_lit_comp(0xe5cc66ff),
rgba_from_u32_lit_comp(0xffff00ff),
rgba_from_u32_lit_comp(0x7f7f7fff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0x000000ff),
rgba_from_u32_lit_comp(0x008184ff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xa87a4c99),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0xffffff7f),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32 * df_g_theme_preset_colors_table[] =
{
df_g_theme_preset_colors__default_dark,
df_g_theme_preset_colors__default_light,
df_g_theme_preset_colors__vs_dark,
df_g_theme_preset_colors__vs_light,
df_g_theme_preset_colors__solarized_dark,
df_g_theme_preset_colors__solarized_light,
df_g_theme_preset_colors__handmade_hero,
df_g_theme_preset_colors__four_coder,
df_g_theme_preset_colors__far_manager,
};
DF_CmdParamSlot df_g_cmd_param_slot_2_view_spec_src_map[] =
{
DF_CmdParamSlot_Entity,
DF_CmdParamSlot_EntityList,
DF_CmdParamSlot_FilePath,
DF_CmdParamSlot_CmdSpec,
DF_CmdParamSlot_ID,
DF_CmdParamSlot_String,
DF_CmdParamSlot_String,
};
String8 df_g_cmd_param_slot_2_view_spec_dst_map[] =
{
str8_lit_comp("entity_lister"),
str8_lit_comp("entity_lister"),
str8_lit_comp("file_system"),
str8_lit_comp("commands"),
str8_lit_comp("system_processes"),
str8_lit_comp("symbol_lister"),
str8_lit_comp("symbol_lister"),
};
String8 df_g_cmd_param_slot_2_view_spec_cmd_map[] =
{
str8_lit_comp(""),
str8_lit_comp(""),
str8_lit_comp(""),
str8_lit_comp(""),
str8_lit_comp(""),
str8_lit_comp("goto_name"),
str8_lit_comp("function_breakpoint"),
};
DF_StringBindingPair df_g_default_binding_table[] =
{
{str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("step_over_inst"), {OS_Key_F10, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("step_out"), {OS_Key_F11, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("halt"), {OS_Key_X, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("halt"), {OS_Key_Pause, 0 }},
{str8_lit_comp("soft_halt_refresh"), {OS_Key_R, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("run"), {OS_Key_F5, 0 }},
{str8_lit_comp("restart"), {OS_Key_F5, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("step_into"), {OS_Key_F11, 0 }},
{str8_lit_comp("step_over"), {OS_Key_F10, 0 }},
{str8_lit_comp("run_to_cursor"), {OS_Key_F10, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("set_next_statement"), {OS_Key_F10, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("inc_ui_font_scale"), {OS_Key_Equal, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("dec_ui_font_scale"), {OS_Key_Minus, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("inc_code_font_scale"), {OS_Key_Equal, 0 |OS_EventFlag_Shift |OS_EventFlag_Alt}},
{str8_lit_comp("dec_code_font_scale"), {OS_Key_Minus, 0 |OS_EventFlag_Shift |OS_EventFlag_Alt}},
{str8_lit_comp("window"), {OS_Key_N, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("toggle_fullscreen"), {OS_Key_Return, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("new_panel_right"), {OS_Key_P, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("new_panel_down"), {OS_Key_Minus, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("rotate_panel_columns"), {OS_Key_2, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("next_panel"), {OS_Key_Comma, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("prev_panel"), {OS_Key_Comma, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("focus_panel_right"), {OS_Key_Right, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
{str8_lit_comp("focus_panel_left"), {OS_Key_Left, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
{str8_lit_comp("focus_panel_up"), {OS_Key_Up, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
{str8_lit_comp("focus_panel_down"), {OS_Key_Down, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
{str8_lit_comp("close_panel"), {OS_Key_P, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("next_tab"), {OS_Key_PageDown, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("prev_tab"), {OS_Key_PageUp, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("next_tab"), {OS_Key_Tab, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("prev_tab"), {OS_Key_Tab, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_tab_right"), {OS_Key_PageDown, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_tab_left"), {OS_Key_PageUp, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("close_tab"), {OS_Key_W, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("tab_bar_top"), {OS_Key_Up, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}},
{str8_lit_comp("tab_bar_bottom"), {OS_Key_Down, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}},
{str8_lit_comp("open"), {OS_Key_O, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("reload_active"), {OS_Key_R, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("switch"), {OS_Key_I, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("switch_to_partner_file"), {OS_Key_O, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("load_user"), {OS_Key_O, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}},
{str8_lit_comp("load_profile"), {OS_Key_O, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
{str8_lit_comp("move_left"), {OS_Key_Left, 0 }},
{str8_lit_comp("move_right"), {OS_Key_Right, 0 }},
{str8_lit_comp("move_up"), {OS_Key_Up, 0 }},
{str8_lit_comp("move_down"), {OS_Key_Down, 0 }},
{str8_lit_comp("move_left_select"), {OS_Key_Left, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_right_select"), {OS_Key_Right, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_up_select"), {OS_Key_Up, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_down_select"), {OS_Key_Down, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_left_chunk"), {OS_Key_Left, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_right_chunk"), {OS_Key_Right, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_up_chunk"), {OS_Key_Up, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_down_chunk"), {OS_Key_Down, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_up_page"), {OS_Key_PageUp, 0 }},
{str8_lit_comp("move_down_page"), {OS_Key_PageDown, 0 }},
{str8_lit_comp("move_up_whole"), {OS_Key_Home, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_down_whole"), {OS_Key_End, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_left_chunk_select"), {OS_Key_Left, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_right_chunk_select"), {OS_Key_Right, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_up_chunk_select"), {OS_Key_Up, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_down_chunk_select"), {OS_Key_Down, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_up_page_select"), {OS_Key_PageUp, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_down_page_select"), {OS_Key_PageDown, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_up_whole_select"), {OS_Key_Home, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_down_whole_select"), {OS_Key_End, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_home"), {OS_Key_Home, 0 }},
{str8_lit_comp("move_end"), {OS_Key_End, 0 }},
{str8_lit_comp("move_home_select"), {OS_Key_Home, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_end_select"), {OS_Key_End, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("select_all"), {OS_Key_A, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("delete_single"), {OS_Key_Delete, 0 }},
{str8_lit_comp("delete_chunk"), {OS_Key_Delete, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("backspace_single"), {OS_Key_Backspace, 0 }},
{str8_lit_comp("backspace_chunk"), {OS_Key_Backspace, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("copy"), {OS_Key_C, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("cut"), {OS_Key_X, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("paste"), {OS_Key_V, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("insert_text"), {OS_Key_Null, 0 }},
{str8_lit_comp("goto_line"), {OS_Key_G, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("goto_address"), {OS_Key_G, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("find_text_forward"), {OS_Key_F, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("find_text_backward"), {OS_Key_R, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("find_next"), {OS_Key_F3, 0 }},
{str8_lit_comp("find_prev"), {OS_Key_F3, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("find_selected_thread"), {OS_Key_F4, 0 }},
{str8_lit_comp("goto_name"), {OS_Key_J, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("goto_name_at_cursor"), {OS_Key_F12, 0 }},
{str8_lit_comp("toggle_watch_expr_at_cursor"), {OS_Key_W, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("toggle_watch_pin_at_cursor"), {OS_Key_F9, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("toggle_breakpoint_cursor"), {OS_Key_F9, 0 }},
{str8_lit_comp("add_target"), {OS_Key_T, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("attach"), {OS_Key_F6, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("filter"), {OS_Key_Slash, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("run_command"), {OS_Key_F1, 0 }},
};
String8 df_g_binding_version_remap_old_name_table[] =
{
str8_lit_comp("commands"),
str8_lit_comp("load_user"),
str8_lit_comp("load_profile"),
};
String8 df_g_binding_version_remap_new_name_table[] =
{
str8_lit_comp("run_command"),
str8_lit_comp("open_user"),
str8_lit_comp("open_profile"),
};
DF_ViewSpecInfo df_g_gfx_view_kind_spec_info_table[] =
{
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("null"), str8_lit_comp(""), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(Null), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Null), DF_VIEW_CMD_FUNCTION_NAME(Null), DF_VIEW_UI_FUNCTION_NAME(Null)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("empty"), str8_lit_comp(""), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(Empty), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Empty), DF_VIEW_CMD_FUNCTION_NAME(Empty), DF_VIEW_UI_FUNCTION_NAME(Empty)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("commands"), str8_lit_comp("Commands"), DF_NameKind_Null, DF_IconKind_List, DF_VIEW_SETUP_FUNCTION_NAME(Commands), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Commands), DF_VIEW_CMD_FUNCTION_NAME(Commands), DF_VIEW_UI_FUNCTION_NAME(Commands)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("file_system"), str8_lit_comp("File System"), DF_NameKind_Null, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(FileSystem), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(FileSystem), DF_VIEW_CMD_FUNCTION_NAME(FileSystem), DF_VIEW_UI_FUNCTION_NAME(FileSystem)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("system_processes"), str8_lit_comp("System Processes"), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(SystemProcesses), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(SystemProcesses), DF_VIEW_CMD_FUNCTION_NAME(SystemProcesses), DF_VIEW_UI_FUNCTION_NAME(SystemProcesses)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("entity_lister"), str8_lit_comp("Entity List"), DF_NameKind_EntityKindName, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(EntityLister), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(EntityLister), DF_VIEW_CMD_FUNCTION_NAME(EntityLister), DF_VIEW_UI_FUNCTION_NAME(EntityLister)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("symbol_lister"), str8_lit_comp("Symbols"), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(SymbolLister), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(SymbolLister), DF_VIEW_CMD_FUNCTION_NAME(SymbolLister), DF_VIEW_UI_FUNCTION_NAME(SymbolLister)},
{(0|1*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("target"), str8_lit_comp("Target"), DF_NameKind_EntityName, DF_IconKind_Target, DF_VIEW_SETUP_FUNCTION_NAME(Target), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Target), DF_VIEW_CMD_FUNCTION_NAME(Target), DF_VIEW_UI_FUNCTION_NAME(Target)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("targets"), str8_lit_comp("Targets"), DF_NameKind_Null, DF_IconKind_Target, DF_VIEW_SETUP_FUNCTION_NAME(Targets), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Targets), DF_VIEW_CMD_FUNCTION_NAME(Targets), DF_VIEW_UI_FUNCTION_NAME(Targets)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("file_path_map"), str8_lit_comp("File Path Map"), DF_NameKind_Null, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(FilePathMap), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(FilePathMap), DF_VIEW_CMD_FUNCTION_NAME(FilePathMap), DF_VIEW_UI_FUNCTION_NAME(FilePathMap)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("scheduler"), str8_lit_comp("Scheduler"), DF_NameKind_Null, DF_IconKind_Scheduler, DF_VIEW_SETUP_FUNCTION_NAME(Scheduler), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Scheduler), DF_VIEW_CMD_FUNCTION_NAME(Scheduler), DF_VIEW_UI_FUNCTION_NAME(Scheduler)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("call_stack"), str8_lit_comp("Call Stack"), DF_NameKind_Null, DF_IconKind_Thread, DF_VIEW_SETUP_FUNCTION_NAME(CallStack), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(CallStack), DF_VIEW_CMD_FUNCTION_NAME(CallStack), DF_VIEW_UI_FUNCTION_NAME(CallStack)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("modules"), str8_lit_comp("Modules"), DF_NameKind_Null, DF_IconKind_Module, DF_VIEW_SETUP_FUNCTION_NAME(Modules), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Modules), DF_VIEW_CMD_FUNCTION_NAME(Modules), DF_VIEW_UI_FUNCTION_NAME(Modules)},
{(0|1*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("pending_entity"), str8_lit_comp("Pending Entity"), DF_NameKind_EntityName, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(PendingEntity), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(PendingEntity), DF_VIEW_CMD_FUNCTION_NAME(PendingEntity), DF_VIEW_UI_FUNCTION_NAME(PendingEntity)},
{(0|1*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|1*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("code"), str8_lit_comp("Code"), DF_NameKind_EntityName, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(Code), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Code), DF_VIEW_CMD_FUNCTION_NAME(Code), DF_VIEW_UI_FUNCTION_NAME(Code)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("disassembly"), str8_lit_comp("Disassembly"), DF_NameKind_Null, DF_IconKind_Glasses, DF_VIEW_SETUP_FUNCTION_NAME(Disassembly), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Disassembly), DF_VIEW_CMD_FUNCTION_NAME(Disassembly), DF_VIEW_UI_FUNCTION_NAME(Disassembly)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("watch"), str8_lit_comp("Watch"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Watch), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Watch), DF_VIEW_CMD_FUNCTION_NAME(Watch), DF_VIEW_UI_FUNCTION_NAME(Watch)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("locals"), str8_lit_comp("Locals"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Locals), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Locals), DF_VIEW_CMD_FUNCTION_NAME(Locals), DF_VIEW_UI_FUNCTION_NAME(Locals)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("registers"), str8_lit_comp("Registers"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Registers), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Registers), DF_VIEW_CMD_FUNCTION_NAME(Registers), DF_VIEW_UI_FUNCTION_NAME(Registers)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("globals"), str8_lit_comp("Globals"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Globals), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Globals), DF_VIEW_CMD_FUNCTION_NAME(Globals), DF_VIEW_UI_FUNCTION_NAME(Globals)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("thread_locals"), str8_lit_comp("Thread Locals"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(ThreadLocals), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(ThreadLocals), DF_VIEW_CMD_FUNCTION_NAME(ThreadLocals), DF_VIEW_UI_FUNCTION_NAME(ThreadLocals)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("types"), str8_lit_comp("Types"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Types), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Types), DF_VIEW_CMD_FUNCTION_NAME(Types), DF_VIEW_UI_FUNCTION_NAME(Types)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("procedures"), str8_lit_comp("Procedures"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Procedures), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Procedures), DF_VIEW_CMD_FUNCTION_NAME(Procedures), DF_VIEW_UI_FUNCTION_NAME(Procedures)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("output"), str8_lit_comp("Output"), DF_NameKind_Null, DF_IconKind_List, DF_VIEW_SETUP_FUNCTION_NAME(Output), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Output), DF_VIEW_CMD_FUNCTION_NAME(Output), DF_VIEW_UI_FUNCTION_NAME(Output)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|1*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("memory"), str8_lit_comp("Memory"), DF_NameKind_Null, DF_IconKind_Grid, DF_VIEW_SETUP_FUNCTION_NAME(Memory), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Memory), DF_VIEW_CMD_FUNCTION_NAME(Memory), DF_VIEW_UI_FUNCTION_NAME(Memory)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("breakpoints"), str8_lit_comp("Breakpoints"), DF_NameKind_Null, DF_IconKind_CircleFilled, DF_VIEW_SETUP_FUNCTION_NAME(Breakpoints), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Breakpoints), DF_VIEW_CMD_FUNCTION_NAME(Breakpoints), DF_VIEW_UI_FUNCTION_NAME(Breakpoints)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("watch_pins"), str8_lit_comp("Watch Pins"), DF_NameKind_Null, DF_IconKind_Pin, DF_VIEW_SETUP_FUNCTION_NAME(WatchPins), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(WatchPins), DF_VIEW_CMD_FUNCTION_NAME(WatchPins), DF_VIEW_UI_FUNCTION_NAME(WatchPins)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("exception_filters"), str8_lit_comp("Exception Filters"), DF_NameKind_Null, DF_IconKind_Gear, DF_VIEW_SETUP_FUNCTION_NAME(ExceptionFilters), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(ExceptionFilters), DF_VIEW_CMD_FUNCTION_NAME(ExceptionFilters), DF_VIEW_UI_FUNCTION_NAME(ExceptionFilters)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("theme"), str8_lit_comp("Theme"), DF_NameKind_Null, DF_IconKind_Palette, DF_VIEW_SETUP_FUNCTION_NAME(Theme), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Theme), DF_VIEW_CMD_FUNCTION_NAME(Theme), DF_VIEW_UI_FUNCTION_NAME(Theme)},
};
String8 df_g_theme_color_display_string_table[] =
{
str8_lit_comp("Null"),
str8_lit_comp("Plain Text"),
str8_lit_comp("Plain Background"),
str8_lit_comp("Plain Border"),
str8_lit_comp("Plain Overlay"),
str8_lit_comp("Code (Default)"),
str8_lit_comp("Code (Function)"),
str8_lit_comp("Code (Type)"),
str8_lit_comp("Code (Local)"),
str8_lit_comp("Code (Keyword)"),
str8_lit_comp("Code (Symbol)"),
str8_lit_comp("Code (Numeric)"),
str8_lit_comp("Code (String)"),
str8_lit_comp("Code (Meta)"),
str8_lit_comp("Code (Comment)"),
str8_lit_comp("Line Info (0)"),
str8_lit_comp("Line Info (1)"),
str8_lit_comp("Line Info (2)"),
str8_lit_comp("Line Info (3)"),
str8_lit_comp("Alt Text"),
str8_lit_comp("Alt Background"),
str8_lit_comp("Alt Border"),
str8_lit_comp("Alt Overlay"),
str8_lit_comp("Inactive Tab"),
str8_lit_comp("Active Tab"),
str8_lit_comp("Entity Background"),
str8_lit_comp("Query Bar"),
str8_lit_comp("Weak Text"),
str8_lit_comp("Text Selection"),
str8_lit_comp("Cursor"),
str8_lit_comp("Highlight (0)"),
str8_lit_comp("Highlight (1)"),
str8_lit_comp("Success Text"),
str8_lit_comp("Success Background"),
str8_lit_comp("Success Border"),
str8_lit_comp("Failure Text"),
str8_lit_comp("Failure Background"),
str8_lit_comp("Failure Border"),
str8_lit_comp("Action Text"),
str8_lit_comp("Action Background"),
str8_lit_comp("Action Border"),
str8_lit_comp("Drop Site Overlay"),
str8_lit_comp("Thread (0)"),
str8_lit_comp("Thread (1)"),
str8_lit_comp("Thread (2)"),
str8_lit_comp("Thread (3)"),
str8_lit_comp("Thread (4)"),
str8_lit_comp("Thread (5)"),
str8_lit_comp("Thread (6)"),
str8_lit_comp("Thread (7)"),
str8_lit_comp("Thread (Unwound)"),
str8_lit_comp("Inactive Panel Overlay"),
str8_lit_comp("Drop Shadow"),
};
String8 df_g_theme_color_cfg_string_table[] =
{
str8_lit_comp("null"),
str8_lit_comp("plain_text"),
str8_lit_comp("plain_background"),
str8_lit_comp("plain_border"),
str8_lit_comp("plain_overlay"),
str8_lit_comp("code_default"),
str8_lit_comp("code_function"),
str8_lit_comp("code_type"),
str8_lit_comp("code_local"),
str8_lit_comp("code_keyword"),
str8_lit_comp("code_symbol"),
str8_lit_comp("code_numeric"),
str8_lit_comp("code_string"),
str8_lit_comp("code_meta"),
str8_lit_comp("code_comment"),
str8_lit_comp("line_info_0"),
str8_lit_comp("line_info_1"),
str8_lit_comp("line_info_2"),
str8_lit_comp("line_info_3"),
str8_lit_comp("alt_text"),
str8_lit_comp("alt_background"),
str8_lit_comp("alt_border"),
str8_lit_comp("alt_overlay"),
str8_lit_comp("tab_inactive"),
str8_lit_comp("tab_active"),
str8_lit_comp("entity_background"),
str8_lit_comp("query_bar"),
str8_lit_comp("weak_text"),
str8_lit_comp("text_selection"),
str8_lit_comp("cursor"),
str8_lit_comp("highlight_0"),
str8_lit_comp("highlight_1"),
str8_lit_comp("success_text"),
str8_lit_comp("success_background"),
str8_lit_comp("success_border"),
str8_lit_comp("failure_text"),
str8_lit_comp("failure_background"),
str8_lit_comp("failure_border"),
str8_lit_comp("action_text"),
str8_lit_comp("action_background"),
str8_lit_comp("action_border"),
str8_lit_comp("drop_site_overlay"),
str8_lit_comp("thread_0"),
str8_lit_comp("thread_1"),
str8_lit_comp("thread_2"),
str8_lit_comp("thread_3"),
str8_lit_comp("thread_4"),
str8_lit_comp("thread_5"),
str8_lit_comp("thread_6"),
str8_lit_comp("thread_7"),
str8_lit_comp("thread_unwound"),
str8_lit_comp("inactive_panel_overlay"),
str8_lit_comp("drop_shadow"),
};
DF_GFX_VIEW_RULE_WHOLE_UI_FUNCTION_DEF(bitmap);
C_LINKAGE_BEGIN
extern String8 df_g_theme_preset_display_string_table[9];
extern String8 df_g_theme_preset_code_string_table[9];
extern Vec4F32 df_g_theme_preset_colors__default_dark[54];
extern Vec4F32 df_g_theme_preset_colors__default_light[54];
extern Vec4F32 df_g_theme_preset_colors__vs_dark[54];
extern Vec4F32 df_g_theme_preset_colors__vs_light[54];
extern Vec4F32 df_g_theme_preset_colors__solarized_dark[54];
extern Vec4F32 df_g_theme_preset_colors__solarized_light[54];
extern Vec4F32 df_g_theme_preset_colors__handmade_hero[54];
extern Vec4F32 df_g_theme_preset_colors__four_coder[54];
extern Vec4F32 df_g_theme_preset_colors__far_manager[54];
extern Vec4F32* df_g_theme_preset_colors_table[9];
extern DF_CmdParamSlot df_g_cmd_param_slot_2_view_spec_src_map[7];
extern String8 df_g_cmd_param_slot_2_view_spec_dst_map[7];
extern String8 df_g_cmd_param_slot_2_view_spec_cmd_map[7];
extern DF_StringBindingPair df_g_default_binding_table[97];
extern String8 df_g_binding_version_remap_old_name_table[3];
extern String8 df_g_binding_version_remap_new_name_table[3];
extern DF_ViewSpecInfo df_g_gfx_view_kind_spec_info_table[30];
extern String8 df_g_theme_color_display_string_table[54];
extern String8 df_g_theme_color_cfg_string_table[54];
read_only global U8 df_g_icon_font_bytes__data[] =
{
0x00,0x01,0x00,0x00,0x00,0x0f,0x00,0x80,0x00,0x03,0x00,0x70,0x47,0x53,0x55,0x42,0x20,0x8b,0x25,0x7a,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x54,0x4f,0x53,0x2f,0x32,0x56,0x44,0x49,0xa0,0x00,0x00,0x01,0x50,0x00,0x00,0x00,0x60,0x63,0x6d,0x61,0x70,0x2a,0x09,0xe2,0xc2,0x00,0x00,0x01,0xb0,0x00,0x00,0x05,0xec,0x63,0x76,0x74,0x20,
@@ -5674,5 +4864,6 @@ read_only global U8 df_g_default_code_font_bytes__data[] =
};
read_only global String8 df_g_default_code_font_bytes = {df_g_default_code_font_bytes__data, sizeof(df_g_default_code_font_bytes__data)};
C_LINKAGE_END
#endif // DF_GFX_META_H
+7 -7
View File
@@ -10,31 +10,31 @@ D_StackTable:
{Transparency transparency F32 `0` }
}
@table_gen
@gen
{
@expand(D_StackTable a) `typedef struct D_$(a.name)Node D_$(a.name)Node; struct D_$(a.name)Node {D_$(a.name)Node *next; $(a.type) v;};`;
}
@table_gen
@gen
{
`#define D_BucketStackDecls struct{\\`;
@expand(D_StackTable a) `D_$(a.name)Node *top_$(a.name_lower);\\`;
`}`;
}
@table_gen
@gen
{
@expand(D_StackTable a) `read_only global D_$(a.name)Node d_nil_$(a.name_lower) = {0, $(a.default_init)};`;
}
@table_gen
@gen
{
`#define D_BucketStackInits(b) do{\\`;
@expand(D_StackTable a) `(b)->top_$(a.name_lower) = &d_nil_$(a.name_lower);\\`;
`}while(0)`;
}
@table_gen
@gen
{
`#if 0`;
@expand(D_StackTable a) `internal $(a.type) $(=>35) d_push_$(a.name_lower)($(a.type) v);`;
@@ -43,14 +43,14 @@ D_StackTable:
`#endif`;
}
@table_gen @c_file
@gen @c_file
{
@expand(D_StackTable a) `internal $(a.type) $(=>35) d_push_$(a.name_lower)($(a.type) v) {D_StackPushImpl($(a.name), $(a.name_lower), $(a.type), v);}`;
@expand(D_StackTable a) `internal $(a.type) $(=>35) d_pop_$(a.name_lower)(void) {D_StackPopImpl($(a.name), $(a.name_lower), $(a.type));}`;
@expand(D_StackTable a) `internal $(a.type) $(=>35) d_top_$(a.name_lower)(void) {D_StackTopImpl($(a.name), $(a.name_lower), $(a.type));}`;
}
@table_gen
@gen
{
`#if 0`;
@expand(D_StackTable a) `#define D_$(a.name)Scope(v) $(=>35) DeferLoop(d_push_$(a.name_lower)(v), d_pop_$(a.name_lower)())`;
+3
View File
@@ -15,3 +15,6 @@ internal R_Tex2DSampleKind d_top_tex2d_sample_kind(void) {D_StackTopImp
internal Mat3x3F32 d_top_xform2d(void) {D_StackTopImpl(XForm2D, xform2d, Mat3x3F32);}
internal Rng2F32 d_top_clip(void) {D_StackTopImpl(Clip, clip, Rng2F32);}
internal F32 d_top_transparency(void) {D_StackTopImpl(Transparency, transparency, F32);}
C_LINKAGE_BEGIN
C_LINKAGE_END
+2
View File
@@ -46,5 +46,7 @@ internal F32 d_top_transparency(void);
#define D_ClipScope(v) DeferLoop(d_push_clip(v), d_pop_clip())
#define D_TransparencyScope(v) DeferLoop(d_push_transparency(v), d_pop_transparency())
#endif
C_LINKAGE_BEGIN
C_LINKAGE_END
#endif // DRAW_META_H
+38 -16
View File
@@ -6,6 +6,8 @@
// op_string - string for quick display of the operator
EVAL_ExprKindTable:
{
{ Nil 0 "" }
{ ArrayIndex 2 "[]" }
{ MemberAccess 2 "." }
{ Deref 1 "*" }
@@ -54,31 +56,51 @@ EVAL_ExprKindTable:
{ LeafIdent 0 "leaf_ident" }
}
@table_gen
@table(name display_string)
EVAL_ResultCodeTable:
{
`typedef U32 EVAL_ExprKind;`;
`enum`;
`{`;
@expand(EVAL_ExprKindTable a) `EVAL_ExprKind_$(a.name),`;
`EVAL_ExprKind_COUNT`;
`};`;
``;
{ Good "" }
{ DivideByZero "Cannot divide by zero." }
{ BadOp "Invalid operation." }
{ BadOpTypes "Invalid operation types." }
{ BadMemRead "Failed memory read." }
{ BadRegRead "Failed register read." }
{ BadFrameBase "Invalid frame base address." }
{ BadModuleBase "Invalid module base address." }
{ BadTLSBase "Invalid thread-local storage base address." }
{ InsufficientStackSpace "Insufficient evaluation machine stack space." }
{ MalformedBytecode "Malformed bytecode." }
}
@table_gen_data(type:U8, fallback:0)
eval_expr_kind_child_counts:
@enum(U32) EVAL_ExprKind:
{
@expand(EVAL_ExprKindTable a) `$(a.num_children),`;
@expand(EVAL_ExprKindTable a) `$(a.name)`,
COUNT,
}
@table_gen_data(type:String8, fallback:`{0}`)
@enum EVAL_ResultCode:
{
@expand(EVAL_ResultCodeTable a) `$(a.name)`,
COUNT,
}
@data(U8) eval_expr_kind_child_counts:
{
@expand(EVAL_ExprKindTable a) `$(a.num_children)`
}
@data(String8)
eval_expr_kind_strings:
{
@expand(EVAL_ExprKindTable a) `str8_lit_comp("$(a.name)"),`;
@expand(EVAL_ExprKindTable a) `str8_lit_comp("$(a.name)")`
}
@table_gen_data(type:String8, fallback:`{0}`)
eval_expr_op_strings:
@data(String8) eval_result_code_display_strings:
{
@expand(EVAL_ExprKindTable a) `str8_lit_comp("$(a.op_string)"),`;
@expand(EVAL_ResultCodeTable a) `str8_lit_comp("$(a.display_string)")`
}
@data(String8) eval_expr_op_strings:
{
@expand(EVAL_ExprKindTable a) `str8_lit_comp("$(a.op_string)")`
}
+209 -209
View File
@@ -23,8 +23,8 @@ eval_bytecode_from_oplist(Arena *arena, EVAL_OpList *list){
default:
{
// compute bytecode advance
U8 ctrlbits = raddbg_eval_opcode_ctrlbits[opcode];
U64 extra_byte_count = RADDBG_DECODEN_FROM_CTRLBITS(ctrlbits);
U8 ctrlbits = rdi_eval_opcode_ctrlbits[opcode];
U64 extra_byte_count = RDI_DECODEN_FROM_CTRLBITS(ctrlbits);
U8 *next_ptr = ptr + 1 + extra_byte_count;
Assert(next_ptr <= opl);
@@ -62,9 +62,9 @@ eval_bytecode_from_oplist(Arena *arena, EVAL_OpList *list){
}
internal void
eval_oplist_push_op(Arena *arena, EVAL_OpList *list, RADDBG_EvalOp opcode, U64 p){
U8 ctrlbits = raddbg_eval_opcode_ctrlbits[opcode];
U32 p_size = RADDBG_DECODEN_FROM_CTRLBITS(ctrlbits);
eval_oplist_push_op(Arena *arena, EVAL_OpList *list, RDI_EvalOp opcode, U64 p){
U8 ctrlbits = rdi_eval_opcode_ctrlbits[opcode];
U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits);
EVAL_Op *node = push_array_no_zero(arena, EVAL_Op, 1);
node->opcode = opcode;
@@ -78,35 +78,35 @@ eval_oplist_push_op(Arena *arena, EVAL_OpList *list, RADDBG_EvalOp opcode, U64 p
internal void
eval_oplist_push_uconst(Arena *arena, EVAL_OpList *list, U64 x){
if (x <= 0xFF){
eval_oplist_push_op(arena, list, RADDBG_EvalOp_ConstU8, x);
eval_oplist_push_op(arena, list, RDI_EvalOp_ConstU8, x);
}
else if (x <= 0xFFFF){
eval_oplist_push_op(arena, list, RADDBG_EvalOp_ConstU16, x);
eval_oplist_push_op(arena, list, RDI_EvalOp_ConstU16, x);
}
else if (x <= 0xFFFFFFFF){
eval_oplist_push_op(arena, list, RADDBG_EvalOp_ConstU32, x);
eval_oplist_push_op(arena, list, RDI_EvalOp_ConstU32, x);
}
else{
eval_oplist_push_op(arena, list, RADDBG_EvalOp_ConstU64, x);
eval_oplist_push_op(arena, list, RDI_EvalOp_ConstU64, x);
}
}
internal void
eval_oplist_push_sconst(Arena *arena, EVAL_OpList *list, S64 x){
if (-0x80 <= x && x <= 0x7F){
eval_oplist_push_op(arena, list, RADDBG_EvalOp_ConstU8, (U64)x);
eval_oplist_push_op(arena, list, RADDBG_EvalOp_TruncSigned, 8);
eval_oplist_push_op(arena, list, RDI_EvalOp_ConstU8, (U64)x);
eval_oplist_push_op(arena, list, RDI_EvalOp_TruncSigned, 8);
}
else if (-0x8000 <= x && x <= 0x7FFF){
eval_oplist_push_op(arena, list, RADDBG_EvalOp_ConstU16, (U64)x);
eval_oplist_push_op(arena, list, RADDBG_EvalOp_TruncSigned, 16);
eval_oplist_push_op(arena, list, RDI_EvalOp_ConstU16, (U64)x);
eval_oplist_push_op(arena, list, RDI_EvalOp_TruncSigned, 16);
}
else if (-0x80000000ll <= x && x <= 0x7FFFFFFFll){
eval_oplist_push_op(arena, list, RADDBG_EvalOp_ConstU32, (U64)x);
eval_oplist_push_op(arena, list, RADDBG_EvalOp_TruncSigned, 32);
eval_oplist_push_op(arena, list, RDI_EvalOp_ConstU32, (U64)x);
eval_oplist_push_op(arena, list, RDI_EvalOp_TruncSigned, 32);
}
else{
eval_oplist_push_op(arena, list, RADDBG_EvalOp_ConstU64, (U64)x);
eval_oplist_push_op(arena, list, RDI_EvalOp_ConstU64, (U64)x);
}
}
@@ -138,31 +138,31 @@ eval_oplist_concat_in_place(EVAL_OpList *left_dst, EVAL_OpList *right_destroyed)
////////////////////////////////
//~ allen: EVAL Expression Info Functions
internal RADDBG_EvalOp
internal RDI_EvalOp
eval_opcode_from_expr_kind(EVAL_ExprKind kind){
RADDBG_EvalOp result = RADDBG_EvalOp_Stop;
RDI_EvalOp result = RDI_EvalOp_Stop;
switch (kind){
case EVAL_ExprKind_Neg: result = RADDBG_EvalOp_Neg; break;
case EVAL_ExprKind_LogNot: result = RADDBG_EvalOp_LogNot; break;
case EVAL_ExprKind_BitNot: result = RADDBG_EvalOp_BitNot; break;
case EVAL_ExprKind_Mul: result = RADDBG_EvalOp_Mul; break;
case EVAL_ExprKind_Div: result = RADDBG_EvalOp_Div; break;
case EVAL_ExprKind_Mod: result = RADDBG_EvalOp_Mod; break;
case EVAL_ExprKind_Add: result = RADDBG_EvalOp_Add; break;
case EVAL_ExprKind_Sub: result = RADDBG_EvalOp_Sub; break;
case EVAL_ExprKind_LShift: result = RADDBG_EvalOp_LShift; break;
case EVAL_ExprKind_RShift: result = RADDBG_EvalOp_RShift; break;
case EVAL_ExprKind_Less: result = RADDBG_EvalOp_Less; break;
case EVAL_ExprKind_LsEq: result = RADDBG_EvalOp_LsEq; break;
case EVAL_ExprKind_Grtr: result = RADDBG_EvalOp_Grtr; break;
case EVAL_ExprKind_GrEq: result = RADDBG_EvalOp_GrEq; break;
case EVAL_ExprKind_EqEq: result = RADDBG_EvalOp_EqEq; break;
case EVAL_ExprKind_NtEq: result = RADDBG_EvalOp_NtEq; break;
case EVAL_ExprKind_BitAnd: result = RADDBG_EvalOp_BitAnd; break;
case EVAL_ExprKind_BitXor: result = RADDBG_EvalOp_BitXor; break;
case EVAL_ExprKind_BitOr: result = RADDBG_EvalOp_BitOr; break;
case EVAL_ExprKind_LogAnd: result = RADDBG_EvalOp_LogAnd; break;
case EVAL_ExprKind_LogOr: result = RADDBG_EvalOp_LogOr; break;
case EVAL_ExprKind_Neg: result = RDI_EvalOp_Neg; break;
case EVAL_ExprKind_LogNot: result = RDI_EvalOp_LogNot; break;
case EVAL_ExprKind_BitNot: result = RDI_EvalOp_BitNot; break;
case EVAL_ExprKind_Mul: result = RDI_EvalOp_Mul; break;
case EVAL_ExprKind_Div: result = RDI_EvalOp_Div; break;
case EVAL_ExprKind_Mod: result = RDI_EvalOp_Mod; break;
case EVAL_ExprKind_Add: result = RDI_EvalOp_Add; break;
case EVAL_ExprKind_Sub: result = RDI_EvalOp_Sub; break;
case EVAL_ExprKind_LShift: result = RDI_EvalOp_LShift; break;
case EVAL_ExprKind_RShift: result = RDI_EvalOp_RShift; break;
case EVAL_ExprKind_Less: result = RDI_EvalOp_Less; break;
case EVAL_ExprKind_LsEq: result = RDI_EvalOp_LsEq; break;
case EVAL_ExprKind_Grtr: result = RDI_EvalOp_Grtr; break;
case EVAL_ExprKind_GrEq: result = RDI_EvalOp_GrEq; break;
case EVAL_ExprKind_EqEq: result = RDI_EvalOp_EqEq; break;
case EVAL_ExprKind_NtEq: result = RDI_EvalOp_NtEq; break;
case EVAL_ExprKind_BitAnd: result = RDI_EvalOp_BitAnd; break;
case EVAL_ExprKind_BitXor: result = RDI_EvalOp_BitXor; break;
case EVAL_ExprKind_BitOr: result = RDI_EvalOp_BitOr; break;
case EVAL_ExprKind_LogAnd: result = RDI_EvalOp_LogAnd; break;
case EVAL_ExprKind_LogOr: result = RDI_EvalOp_LogOr; break;
}
return(result);
}
@@ -286,9 +286,9 @@ eval_expr_leaf_type(Arena *arena, void *location, TG_Key type_key){
////////////////////////////////
//~ allen: EVAL Type Information Transformers
internal RADDBG_EvalTypeGroup
internal RDI_EvalTypeGroup
eval_type_group_from_kind(TG_Kind kind){
RADDBG_EvalTypeGroup result = 0;
RDI_EvalTypeGroup result = 0;
switch (kind){
default:{}break;
@@ -303,7 +303,7 @@ eval_type_group_from_kind(TG_Kind kind){
case TG_Kind_IncompleteStruct: case TG_Kind_IncompleteClass:
case TG_Kind_IncompleteUnion: case TG_Kind_IncompleteEnum:
case TG_Kind_Bitfield: case TG_Kind_Variadic:
result = RADDBG_EvalTypeGroup_Other; break;
result = RDI_EvalTypeGroup_Other; break;
case TG_Kind_Handle:
case TG_Kind_UChar8: case TG_Kind_UChar16: case TG_Kind_UChar32:
@@ -312,26 +312,26 @@ eval_type_group_from_kind(TG_Kind kind){
case TG_Kind_U512:
case TG_Kind_Ptr: case TG_Kind_LRef: case TG_Kind_RRef:
case TG_Kind_Function: case TG_Kind_Method: case TG_Kind_MemberPtr:
result = RADDBG_EvalTypeGroup_U; break;
result = RDI_EvalTypeGroup_U; break;
case TG_Kind_Char8: case TG_Kind_Char16: case TG_Kind_Char32:
case TG_Kind_S8: case TG_Kind_S16: case TG_Kind_S32:
case TG_Kind_S64: case TG_Kind_S128: case TG_Kind_S256:
case TG_Kind_S512:
case TG_Kind_Bool:
result = RADDBG_EvalTypeGroup_S; break;
result = RDI_EvalTypeGroup_S; break;
case TG_Kind_F32:
result = RADDBG_EvalTypeGroup_F32; break;
result = RDI_EvalTypeGroup_F32; break;
case TG_Kind_F64:
result = RADDBG_EvalTypeGroup_F64; break;
result = RDI_EvalTypeGroup_F64; break;
}
return(result);
}
internal TG_Key
eval_type_unwrap_enum(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key key)
eval_type_unwrap_enum(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key)
{
TG_Key result = key;
for(B32 good = 1; good;)
@@ -339,7 +339,7 @@ eval_type_unwrap_enum(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key key)
TG_Kind kind = tg_kind_from_key(key);
if(kind == TG_Kind_Enum)
{
result = tg_direct_from_graph_raddbg_key(graph, rdbg, result);
result = tg_direct_from_graph_rdi_key(graph, rdi, result);
}
else
{
@@ -350,7 +350,7 @@ eval_type_unwrap_enum(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key key)
}
internal TG_Key
eval_type_promote(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key key){
eval_type_promote(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key){
TG_Key result = key;
TG_Kind kind = tg_kind_from_key(key);
if(kind == TG_Kind_Bool ||
@@ -365,17 +365,17 @@ eval_type_promote(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key key){
}
internal TG_Key
eval_type_coerce(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key l, TG_Key r){
eval_type_coerce(TG_Graph *graph, RDI_Parsed *rdi, TG_Key l, TG_Key r){
Assert(eval_kind_is_basic_or_enum(tg_kind_from_key(l)) &&
eval_kind_is_basic_or_enum(tg_kind_from_key(r)));
// replace enums with corresponding ints
TG_Key lt = eval_type_unwrap_enum(graph, rdbg, l);
TG_Key rt = eval_type_unwrap_enum(graph, rdbg, r);
TG_Key lt = eval_type_unwrap_enum(graph, rdi, l);
TG_Key rt = eval_type_unwrap_enum(graph, rdi, r);
// first promote each
TG_Key lp = eval_type_promote(graph, rdbg, lt);
TG_Key rp = eval_type_promote(graph, rdbg, rt);
TG_Key lp = eval_type_promote(graph, rdi, lt);
TG_Key rp = eval_type_promote(graph, rdi, rt);
TG_Kind lk = tg_kind_from_key(lp);
TG_Kind rk = tg_kind_from_key(rp);
@@ -384,12 +384,12 @@ eval_type_coerce(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key l, TG_Key r){
}
internal B32
eval_type_match(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key l, TG_Key r){
eval_type_match(TG_Graph *graph, RDI_Parsed *rdi, TG_Key l, TG_Key r){
B32 result = 0;
// unwrap
TG_Key lu = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, l);
TG_Key ru = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, r);
TG_Key lu = tg_unwrapped_from_graph_rdi_key(graph, rdi, l);
TG_Key ru = tg_unwrapped_from_graph_rdi_key(graph, rdi, r);
if (tg_key_match(lu, ru)){
result = 1;
@@ -408,21 +408,21 @@ eval_type_match(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key l, TG_Key r){
case TG_Kind_LRef:
case TG_Kind_RRef:
{
TG_Key lud = tg_direct_from_graph_raddbg_key(graph, rdbg, lu);
TG_Key rud = tg_direct_from_graph_raddbg_key(graph, rdbg, ru);
if (eval_type_match(graph, rdbg, lud, rud)){
TG_Key lud = tg_direct_from_graph_rdi_key(graph, rdi, lu);
TG_Key rud = tg_direct_from_graph_rdi_key(graph, rdi, ru);
if (eval_type_match(graph, rdi, lud, rud)){
result = 1;
}
}break;
case TG_Kind_MemberPtr:
{
TG_Key lud = tg_direct_from_graph_raddbg_key(graph, rdbg, lu);
TG_Key rud = tg_direct_from_graph_raddbg_key(graph, rdbg, ru);
TG_Key luo = tg_owner_from_graph_raddbg_key(graph, rdbg, lu);
TG_Key ruo = tg_owner_from_graph_raddbg_key(graph, rdbg, ru);
if (eval_type_match(graph, rdbg, lud, rud) &&
eval_type_match(graph, rdbg, luo, ruo)){
TG_Key lud = tg_direct_from_graph_rdi_key(graph, rdi, lu);
TG_Key rud = tg_direct_from_graph_rdi_key(graph, rdi, ru);
TG_Key luo = tg_owner_from_graph_rdi_key(graph, rdi, lu);
TG_Key ruo = tg_owner_from_graph_rdi_key(graph, rdi, ru);
if (eval_type_match(graph, rdi, lud, rud) &&
eval_type_match(graph, rdi, luo, ruo)){
result = 1;
}
}break;
@@ -430,9 +430,9 @@ eval_type_match(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key l, TG_Key r){
case TG_Kind_Array:
{
Temp scratch = scratch_begin(0, 0);
TG_Type *lt = tg_type_from_graph_raddbg_key(scratch.arena, graph, rdbg, l);
TG_Type *rt = tg_type_from_graph_raddbg_key(scratch.arena, graph, rdbg, r);
if(lt->count == rt->count && eval_type_match(graph, rdbg, lt->direct_type_key, rt->direct_type_key))
TG_Type *lt = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, l);
TG_Type *rt = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, r);
if(lt->count == rt->count && eval_type_match(graph, rdi, lt->direct_type_key, rt->direct_type_key))
{
result = 1;
}
@@ -442,9 +442,9 @@ eval_type_match(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key l, TG_Key r){
case TG_Kind_Function:
{
Temp scratch = scratch_begin(0, 0);
TG_Type *lt = tg_type_from_graph_raddbg_key(scratch.arena, graph, rdbg, l);
TG_Type *rt = tg_type_from_graph_raddbg_key(scratch.arena, graph, rdbg, r);
if (lt->count == rt->count && eval_type_match(graph, rdbg, lt->direct_type_key, rt->direct_type_key))
TG_Type *lt = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, l);
TG_Type *rt = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, r);
if (lt->count == rt->count && eval_type_match(graph, rdi, lt->direct_type_key, rt->direct_type_key))
{
B32 params_match = 1;
TG_Key *lp = lt->param_type_keys;
@@ -452,7 +452,7 @@ eval_type_match(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key l, TG_Key r){
U64 count = lt->count;
for(U64 i = 0; i < count; i += 1, lp += 1, rp += 1)
{
if(!eval_type_match(graph, rdbg, *lp, *rp))
if(!eval_type_match(graph, rdi, *lp, *rp))
{
params_match = 0;
break;
@@ -466,11 +466,11 @@ eval_type_match(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key l, TG_Key r){
case TG_Kind_Method:
{
Temp scratch = scratch_begin(0, 0);
TG_Type *lt = tg_type_from_graph_raddbg_key(scratch.arena, graph, rdbg, l);
TG_Type *rt = tg_type_from_graph_raddbg_key(scratch.arena, graph, rdbg, r);
TG_Type *lt = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, l);
TG_Type *rt = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, r);
if (lt->count == rt->count &&
eval_type_match(graph, rdbg, lt->direct_type_key, rt->direct_type_key) &&
eval_type_match(graph, rdbg, lt->owner_type_key, rt->owner_type_key))
eval_type_match(graph, rdi, lt->direct_type_key, rt->direct_type_key) &&
eval_type_match(graph, rdi, lt->owner_type_key, rt->owner_type_key))
{
B32 params_match = 1;
TG_Key *lp = lt->param_type_keys;
@@ -478,7 +478,7 @@ eval_type_match(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key l, TG_Key r){
U64 count = lt->count;
for(U64 i = 0; i < count; i += 1, lp += 1, rp += 1)
{
if(!eval_type_match(graph, rdbg, *lp, *rp))
if(!eval_type_match(graph, rdi, *lp, *rp))
{
params_match = 0;
break;
@@ -522,15 +522,15 @@ eval_kind_is_basic_or_enum(TG_Kind kind){
internal EVAL_IRTree*
eval_irtree_const_u(Arena *arena, U64 v){
// choose encoding op
RADDBG_EvalOp op = RADDBG_EvalOp_ConstU64;
RDI_EvalOp op = RDI_EvalOp_ConstU64;
if (v < 0x100){
op = RADDBG_EvalOp_ConstU8;
op = RDI_EvalOp_ConstU8;
}
else if (v < 0x10000){
op = RADDBG_EvalOp_ConstU16;
op = RDI_EvalOp_ConstU16;
}
else if (v < 0x100000000){
op = RADDBG_EvalOp_ConstU32;
op = RDI_EvalOp_ConstU32;
}
// make the tree node
@@ -541,8 +541,8 @@ eval_irtree_const_u(Arena *arena, U64 v){
}
internal EVAL_IRTree*
eval_irtree_unary_op(Arena *arena, RADDBG_EvalOp op,
RADDBG_EvalTypeGroup group, EVAL_IRTree *c){
eval_irtree_unary_op(Arena *arena, RDI_EvalOp op,
RDI_EvalTypeGroup group, EVAL_IRTree *c){
EVAL_IRTree *result = push_array(arena, EVAL_IRTree, 1);
result->op = op;
result->p = group;
@@ -551,7 +551,7 @@ eval_irtree_unary_op(Arena *arena, RADDBG_EvalOp op,
}
internal EVAL_IRTree*
eval_irtree_binary_op(Arena *arena, RADDBG_EvalOp op, RADDBG_EvalTypeGroup group,
eval_irtree_binary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group,
EVAL_IRTree *l, EVAL_IRTree *r){
EVAL_IRTree *result = push_array(arena, EVAL_IRTree, 1);
result->op = op;
@@ -562,15 +562,15 @@ eval_irtree_binary_op(Arena *arena, RADDBG_EvalOp op, RADDBG_EvalTypeGroup group
}
internal EVAL_IRTree*
eval_irtree_binary_op_u(Arena *arena, RADDBG_EvalOp op, EVAL_IRTree *l, EVAL_IRTree *r){
EVAL_IRTree *result = eval_irtree_binary_op(arena, op, RADDBG_EvalTypeGroup_U, l, r);
eval_irtree_binary_op_u(Arena *arena, RDI_EvalOp op, EVAL_IRTree *l, EVAL_IRTree *r){
EVAL_IRTree *result = eval_irtree_binary_op(arena, op, RDI_EvalTypeGroup_U, l, r);
return(result);
}
internal EVAL_IRTree*
eval_irtree_conditional(Arena *arena, EVAL_IRTree *c, EVAL_IRTree *l, EVAL_IRTree *r){
EVAL_IRTree *result = push_array(arena, EVAL_IRTree, 1);
result->op = RADDBG_EvalOp_Cond;
result->op = RDI_EvalOp_Cond;
result->children[0] = c;
result->children[1] = l;
result->children[2] = r;
@@ -589,13 +589,13 @@ eval_irtree_bytecode_no_copy(Arena *arena, String8 bytecode){
//~ allen: EVAL IR-Tree High Level Helpers
internal EVAL_IRTree*
eval_irtree_mem_read_type(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_IRTree *c, TG_Key type_key){
U64 byte_size = tg_byte_size_from_graph_raddbg_key(graph, rdbg, type_key);
eval_irtree_mem_read_type(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_IRTree *c, TG_Key type_key){
U64 byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, type_key);
EVAL_IRTree *result = &eval_irtree_nil;
if (0 < byte_size && byte_size <= 8){
// build the read node
EVAL_IRTree *read_node = push_array(arena, EVAL_IRTree, 1);
read_node->op = RADDBG_EvalOp_MemRead;
read_node->op = RDI_EvalOp_MemRead;
read_node->p = byte_size;
read_node->children[0] = c;
@@ -605,7 +605,7 @@ eval_irtree_mem_read_type(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EV
TG_Kind kind = tg_kind_from_key(type_key);
if (bit_size < 64 && eval_kind_is_signed(kind)){
with_trunc = push_array(arena, EVAL_IRTree, 1);
with_trunc->op = RADDBG_EvalOp_TruncSigned;
with_trunc->op = RDI_EvalOp_TruncSigned;
with_trunc->p = bit_size;
with_trunc->children[0] = read_node;
}
@@ -620,23 +620,23 @@ eval_irtree_mem_read_type(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EV
}
internal EVAL_IRTree*
eval_irtree_convert_lo(Arena *arena, EVAL_IRTree *c, RADDBG_EvalTypeGroup out, RADDBG_EvalTypeGroup in){
eval_irtree_convert_lo(Arena *arena, EVAL_IRTree *c, RDI_EvalTypeGroup out, RDI_EvalTypeGroup in){
EVAL_IRTree *result = push_array(arena, EVAL_IRTree, 1);
result->op = RADDBG_EvalOp_Convert;
result->op = RDI_EvalOp_Convert;
result->p = in | (out << 8);
result->children[0] = c;
return(result);
}
internal EVAL_IRTree*
eval_irtree_trunc(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_IRTree *c, TG_Key type_key){
eval_irtree_trunc(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_IRTree *c, TG_Key type_key){
EVAL_IRTree *result = c;
U64 byte_size = tg_byte_size_from_graph_raddbg_key(graph, rdbg, type_key);
U64 byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, type_key);
if (byte_size < 64){
RADDBG_EvalOp op = RADDBG_EvalOp_Trunc;
RDI_EvalOp op = RDI_EvalOp_Trunc;
TG_Kind kind = tg_kind_from_key(type_key);
if (eval_kind_is_signed(kind)){
op = RADDBG_EvalOp_TruncSigned;
op = RDI_EvalOp_TruncSigned;
}
U64 bit_size = byte_size << 3;
result = push_array(arena, EVAL_IRTree, 1);
@@ -648,39 +648,39 @@ eval_irtree_trunc(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_IRTre
}
internal EVAL_IRTree*
eval_irtree_convert_hi(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_IRTree *c, TG_Key out, TG_Key in){
eval_irtree_convert_hi(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_IRTree *c, TG_Key out, TG_Key in){
EVAL_IRTree *result = c;
TG_Kind in_kind = tg_kind_from_key(in);
TG_Kind out_kind = tg_kind_from_key(out);
U8 in_group = eval_type_group_from_kind(in_kind);
U8 out_group = eval_type_group_from_kind(out_kind);
U32 conversion_rule = raddbg_eval_conversion_rule(in_group, out_group);
if(conversion_rule == RADDBG_EvalConversionKind_Legal)
U32 conversion_rule = rdi_eval_conversion_rule(in_group, out_group);
if(conversion_rule == RDI_EvalConversionKind_Legal)
{
result = eval_irtree_convert_lo(arena, result, out_group, in_group);
}
U64 in_byte_size = tg_byte_size_from_graph_raddbg_key(graph, rdbg, in);
U64 out_byte_size = tg_byte_size_from_graph_raddbg_key(graph, rdbg, out);
U64 in_byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, in);
U64 out_byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, out);
if(out_byte_size < in_byte_size && eval_kind_is_integer(out_kind))
{
result = eval_irtree_trunc(arena, graph, rdbg, result, out);
result = eval_irtree_trunc(arena, graph, rdi, result, out);
}
return(result);
}
internal EVAL_IRTree*
eval_irtree_resolve_to_value(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_EvalMode from_mode,
eval_irtree_resolve_to_value(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_EvalMode from_mode,
EVAL_IRTree *tree, TG_Key type_key){
EVAL_IRTree *result = tree;
switch (from_mode){
default:{}break;
case EVAL_EvalMode_Addr:
{
result = eval_irtree_mem_read_type(arena, graph, rdbg, tree, type_key);
result = eval_irtree_mem_read_type(arena, graph, rdi, tree, type_key);
}break;
case EVAL_EvalMode_Reg:
{
result = eval_irtree_unary_op(arena, RADDBG_EvalOp_RegReadDyn, RADDBG_EvalTypeGroup_U, tree);
result = eval_irtree_unary_op(arena, RDI_EvalOp_RegReadDyn, RDI_EvalTypeGroup_U, tree);
}break;
}
return(result);
@@ -715,7 +715,7 @@ eval_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, EVAL_String2ExprMap
}
internal TG_Key
eval_type_from_type_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_Expr *expr, EVAL_ErrorList *eout){
eval_type_from_type_expr(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_Expr *expr, EVAL_ErrorList *eout){
TG_Key result = zero_struct;
EVAL_ExprKind kind = expr->kind;
@@ -732,14 +732,14 @@ eval_type_from_type_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVA
case EVAL_ExprKind_Ptr:
{
TG_Key direct_type_key = eval_type_from_type_expr(arena, graph, rdbg, expr->children[0], eout);
TG_Key direct_type_key = eval_type_from_type_expr(arena, graph, rdi, expr->children[0], eout);
result = tg_cons_type_make(graph, TG_Kind_Ptr, direct_type_key, 0);
}break;
case EVAL_ExprKind_Array:
{
EVAL_Expr *child_expr = expr->child_and_constant.child;
TG_Key direct_type_key = eval_type_from_type_expr(arena, graph, rdbg, child_expr, eout);
TG_Key direct_type_key = eval_type_from_type_expr(arena, graph, rdi, child_expr, eout);
result = tg_cons_type_make(graph, TG_Kind_Array, direct_type_key, expr->child_and_constant.u64);
}break;
@@ -758,7 +758,7 @@ eval_type_from_type_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVA
}
internal EVAL_IRTreeAndType
eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_String2ExprMap *leaf_ident_expr_map, EVAL_Expr *expr, EVAL_ErrorList *eout)
eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_String2ExprMap *leaf_ident_expr_map, EVAL_Expr *expr, EVAL_ErrorList *eout)
{
ProfBeginFunction();
EVAL_IRTreeAndType result = {0};
@@ -777,12 +777,12 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
EVAL_Expr *exprl = expr->children[0];
EVAL_Expr *exprr = expr->children[1];
EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprl, eout);
EVAL_IRTreeAndType r = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprr, eout);
EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprl, eout);
EVAL_IRTreeAndType r = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprr, eout);
if (l.tree->op != 0 && r.tree->op != 0){
TG_Key l_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, l.type_key);
TG_Key r_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, r.type_key);
TG_Key l_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, l.type_key);
TG_Key r_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, r.type_key);
TG_Kind l_restype_kind = tg_kind_from_key(l_restype);
TG_Kind r_restype_kind = tg_kind_from_key(r_restype);
@@ -795,8 +795,8 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, exprr->location, "Cannot index with this type.");
}
else{
direct_type = tg_unwrapped_direct_from_graph_raddbg_key(graph, rdbg, l_restype);
direct_type_size = tg_byte_size_from_graph_raddbg_key(graph, rdbg, direct_type);
direct_type = tg_unwrapped_direct_from_graph_rdi_key(graph, rdi, l_restype);
direct_type_size = tg_byte_size_from_graph_rdi_key(graph, rdi, direct_type);
if (l_restype_kind == TG_Kind_Ptr){
if (direct_type_size == 0){
eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, exprr->location, "Cannot index into pointers of zero-sized types.");
@@ -829,20 +829,20 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
// generate ir tree
if (can_generate){
// how to compute the index
EVAL_IRTree *index_tree = eval_irtree_resolve_to_value(arena, graph, rdbg, r.mode, r.tree, r_restype);
EVAL_IRTree *index_tree = eval_irtree_resolve_to_value(arena, graph, rdi, r.mode, r.tree, r_restype);
if (direct_type_size > 1){
EVAL_IRTree *const_tree = eval_irtree_const_u(arena, direct_type_size);
index_tree = eval_irtree_binary_op_u(arena, RADDBG_EvalOp_Mul, index_tree, const_tree);
index_tree = eval_irtree_binary_op_u(arena, RDI_EvalOp_Mul, index_tree, const_tree);
}
// how to compute the base address
EVAL_IRTree *base_tree = l.tree;
if (l_resolve){
base_tree = eval_irtree_resolve_to_value(arena, graph, rdbg, l.mode, base_tree, l_restype);
base_tree = eval_irtree_resolve_to_value(arena, graph, rdi, l.mode, base_tree, l_restype);
}
// how to compute the final address
EVAL_IRTree *new_tree = eval_irtree_binary_op_u(arena, RADDBG_EvalOp_Add, index_tree, base_tree);
EVAL_IRTree *new_tree = eval_irtree_binary_op_u(arena, RDI_EvalOp_Add, index_tree, base_tree);
// fill result
result.tree = new_tree;
@@ -857,17 +857,17 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
EVAL_Expr *exprl = expr->children[0];
EVAL_Expr *exprr = expr->children[1];
EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprl, eout);
EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprl, eout);
if (l.tree->op != 0 && !tg_key_match(tg_key_zero(), l.type_key)){
TG_Key l_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, l.type_key);
TG_Key l_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, l.type_key);
TG_Kind l_restype_kind = tg_kind_from_key(l_restype);
// determine which type to use
TG_Key check_type_key = l_restype;
TG_Kind check_type_kind = l_restype_kind;
if (l_restype_kind == TG_Kind_Ptr || l_restype_kind == TG_Kind_LRef || l_restype_kind == TG_Kind_RRef){
check_type_key = tg_unwrapped_direct_from_graph_raddbg_key(graph, rdbg, l_restype);
check_type_key = tg_unwrapped_direct_from_graph_rdi_key(graph, rdi, l_restype);
check_type_kind = tg_kind_from_key(check_type_key);
}
@@ -921,7 +921,7 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
if (l_good && r_good){
Temp scratch = scratch_begin(&arena, 1);
TG_MemberArray check_type_members = tg_data_members_from_graph_raddbg_key(scratch.arena, graph, rdbg, check_type_key);
TG_MemberArray check_type_members = tg_data_members_from_graph_rdi_key(scratch.arena, graph, rdi, check_type_key);
// lookup member
String8 member_name = exprr->name;
@@ -953,11 +953,11 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
if (can_generate){
EVAL_IRTree *new_tree = l.tree;
if (l_resolve){
new_tree = eval_irtree_resolve_to_value(arena, graph, rdbg, l.mode, new_tree, l_restype);
new_tree = eval_irtree_resolve_to_value(arena, graph, rdi, l.mode, new_tree, l_restype);
}
if (r_off != 0){
EVAL_IRTree *const_tree = eval_irtree_const_u(arena, r_off);
new_tree = eval_irtree_binary_op_u(arena, RADDBG_EvalOp_Add, new_tree, const_tree);
new_tree = eval_irtree_binary_op_u(arena, RDI_EvalOp_Add, new_tree, const_tree);
}
// fill result
@@ -975,13 +975,13 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
{
EVAL_Expr *exprc = expr->children[0];
EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprc, eout);
EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprc, eout);
if (c.tree->op != 0){
TG_Key c_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, c.type_key);
TG_Key c_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, c.type_key);
TG_Kind c_restype_kind = tg_kind_from_key(c_restype);
TG_Key c_restype_direct = tg_unwrapped_direct_from_graph_raddbg_key(graph, rdbg, c_restype);
U64 c_restype_direct_size = tg_byte_size_from_graph_raddbg_key(graph, rdbg, c_restype_direct);
TG_Key c_restype_direct = tg_unwrapped_direct_from_graph_rdi_key(graph, rdi, c_restype);
U64 c_restype_direct_size = tg_byte_size_from_graph_rdi_key(graph, rdi, c_restype_direct);
// analyze situation
B32 can_generate = 0;
@@ -1018,7 +1018,7 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
if (can_generate){
EVAL_IRTree *new_tree = c.tree;
if (c_resolve){
new_tree = eval_irtree_resolve_to_value(arena, graph, rdbg, c.mode, c.tree, c_restype);
new_tree = eval_irtree_resolve_to_value(arena, graph, rdi, c.mode, c.tree, c_restype);
}
// fill result
@@ -1032,10 +1032,10 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
case EVAL_ExprKind_Address:
{
EVAL_Expr *exprc = expr->children[0];
EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprc, eout);
EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprc, eout);
if(c.tree->op != 0 && !tg_key_match(c.type_key, tg_key_zero()))
{
TG_Key c_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, c.type_key);
TG_Key c_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, c.type_key);
TG_Kind c_restype_kind = tg_kind_from_key(c_restype);
// analyze situation
@@ -1064,36 +1064,36 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
EVAL_Expr *exprl = expr->children[0];
EVAL_Expr *exprr = expr->children[1];
TG_Key cast_type_key = eval_type_from_type_expr(arena, graph, rdbg, exprl, eout);
TG_Key cast_type_key = eval_type_from_type_expr(arena, graph, rdi, exprl, eout);
TG_Kind cast_type_kind = tg_kind_from_key(cast_type_key);
EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprr, eout);
EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprr, eout);
if(cast_type_kind != TG_Kind_Null && c.tree->op != 0)
{
TG_Key c_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, c.type_key);
TG_Key c_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, c.type_key);
TG_Kind c_restype_kind = tg_kind_from_key(c_restype);
U64 c_restype_byte_size = tg_byte_size_from_graph_raddbg_key(graph, rdbg, c_restype);
U64 cast_type_byte_size = tg_byte_size_from_graph_raddbg_key(graph, rdbg, cast_type_key);
U64 c_restype_byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, c_restype);
U64 cast_type_byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, cast_type_key);
// analyze situation
U8 in_group = eval_type_group_from_kind(c_restype_kind);
U8 out_group = eval_type_group_from_kind(cast_type_kind);
RADDBG_EvalConversionKind conversion_rule = raddbg_eval_conversion_rule(in_group, out_group);
RDI_EvalConversionKind conversion_rule = rdi_eval_conversion_rule(in_group, out_group);
// generate tree
switch(conversion_rule)
{
case RADDBG_EvalConversionKind_Noop:
case RADDBG_EvalConversionKind_Legal:
case RDI_EvalConversionKind_Noop:
case RDI_EvalConversionKind_Legal:
{
EVAL_IRTree *in_tree = eval_irtree_resolve_to_value(arena, graph, rdbg, c.mode, c.tree, c_restype);
EVAL_IRTree *in_tree = eval_irtree_resolve_to_value(arena, graph, rdi, c.mode, c.tree, c_restype);
EVAL_IRTree *new_tree = in_tree;
if (conversion_rule == RADDBG_EvalConversionKind_Legal){
if (conversion_rule == RDI_EvalConversionKind_Legal){
new_tree = eval_irtree_convert_lo(arena, in_tree, out_group, in_group);
}
if (cast_type_byte_size < c_restype_byte_size && eval_kind_is_integer(cast_type_kind)){
new_tree = eval_irtree_trunc(arena, graph, rdbg, in_tree, cast_type_key);
new_tree = eval_irtree_trunc(arena, graph, rdi, in_tree, cast_type_key);
}
result.tree = new_tree;
@@ -1104,8 +1104,8 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
default:
{
String8 text = str8_lit("(internal) unknown conversion rule");
if (conversion_rule < RADDBG_EvalConversionKind_COUNT){
text.str = raddbg_eval_conversion_message(conversion_rule, &text.size);
if (conversion_rule < RDI_EvalConversionKind_COUNT){
text.str = rdi_eval_conversion_message(conversion_rule, &text.size);
}
eval_error(arena, eout, EVAL_ErrorKind_MalformedInput, expr->location, text);
}break;
@@ -1126,13 +1126,13 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
case EVAL_ExprKind_Array:
case EVAL_ExprKind_Func:
{
type_key = eval_type_from_type_expr(arena, graph, rdbg, exprc, eout);
type_key = eval_type_from_type_expr(arena, graph, rdi, exprc, eout);
}break;
// size of value expression
default:
{
EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprc, eout);
EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprc, eout);
type_key = c.type_key;
}break;
}
@@ -1141,7 +1141,7 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
TG_Kind type_kind = tg_kind_from_key(type_key);
if (type_kind != TG_Kind_Null){
can_generate = 1;
size = tg_byte_size_from_graph_raddbg_key(graph, rdbg, type_key);
size = tg_byte_size_from_graph_rdi_key(graph, rdi, type_key);
}
// generate ir tree
@@ -1160,17 +1160,17 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
{
EVAL_Expr *exprc = expr->children[0];
EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprc, eout);
EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprc, eout);
if (c.tree->op != 0){
TG_Key c_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, c.type_key);
TG_Key p_type = eval_type_promote(graph, rdbg, c_restype);
TG_Key c_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, c.type_key);
TG_Key p_type = eval_type_promote(graph, rdi, c_restype);
TG_Kind c_restype_kind = tg_kind_from_key(c_restype);
// analyze situation
B32 can_generate = 0;
RADDBG_EvalOp op = eval_opcode_from_expr_kind(kind);
RDI_EvalOp op = eval_opcode_from_expr_kind(kind);
U8 c_group = eval_type_group_from_kind(c_restype_kind);
if (!raddbg_eval_opcode_type_compatible(op, c_group)){
if (!rdi_eval_opcode_type_compatible(op, c_group)){
eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, expr->location, "Cannot use this operator on this type.");
}
else{
@@ -1179,8 +1179,8 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
// generate ir tree
if (can_generate){
EVAL_IRTree *in_tree = eval_irtree_resolve_to_value(arena, graph, rdbg, c.mode, c.tree, c_restype);
in_tree = eval_irtree_convert_hi(arena, graph, rdbg, in_tree, p_type, c_restype);
EVAL_IRTree *in_tree = eval_irtree_resolve_to_value(arena, graph, rdi, c.mode, c.tree, c_restype);
in_tree = eval_irtree_convert_hi(arena, graph, rdi, in_tree, p_type, c_restype);
EVAL_IRTree *new_tree = eval_irtree_unary_op(arena, op, c_group, in_tree);
@@ -1214,12 +1214,12 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
EVAL_Expr *exprl = expr->children[0];
EVAL_Expr *exprr = expr->children[1];
EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprl, eout);
EVAL_IRTreeAndType r = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprr, eout);
EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprl, eout);
EVAL_IRTreeAndType r = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprr, eout);
if (l.tree->op != 0 && r.tree->op != 0){
TG_Key l_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, l.type_key);
TG_Key r_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, r.type_key);
TG_Key l_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, l.type_key);
TG_Key r_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, r.type_key);
TG_Kind l_restype_kind = tg_kind_from_key(l_restype);
TG_Kind r_restype_kind = tg_kind_from_key(r_restype);
@@ -1235,7 +1235,7 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
r_restype_kind = tg_kind_from_key(r_restype);
}
RADDBG_EvalOp op = eval_opcode_from_expr_kind(kind);
RDI_EvalOp op = eval_opcode_from_expr_kind(kind);
//- pointer decay
B32 l_is_pointer = (l_restype_kind == TG_Kind_Ptr);
@@ -1267,10 +1267,10 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
arith_path = EVAL_ArithPath_PtrAdd;
}
if (l_is_pointer_like && r_is_pointer_like){
TG_Key l_restype_direct = tg_unwrapped_direct_from_graph_raddbg_key(graph, rdbg, l_restype);
TG_Key r_restype_direct = tg_unwrapped_direct_from_graph_raddbg_key(graph, rdbg, r_restype);
U64 l_restype_direct_byte_size = tg_byte_size_from_graph_raddbg_key(graph, rdbg, l_restype_direct);
U64 r_restype_direct_byte_size = tg_byte_size_from_graph_raddbg_key(graph, rdbg, r_restype_direct);
TG_Key l_restype_direct = tg_unwrapped_direct_from_graph_rdi_key(graph, rdi, l_restype);
TG_Key r_restype_direct = tg_unwrapped_direct_from_graph_rdi_key(graph, rdi, r_restype);
U64 l_restype_direct_byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, l_restype_direct);
U64 r_restype_direct_byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, r_restype_direct);
if (l_restype_direct_byte_size == r_restype_direct_byte_size){
arith_path = EVAL_ArithPath_PtrSub;
}
@@ -1289,9 +1289,9 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
TG_Key cv_type_key = zero_struct;
if (both_basic){
cv_type_key = eval_type_coerce(graph, rdbg, l_restype, r_restype);
cv_type_key = eval_type_coerce(graph, rdi, l_restype, r_restype);
}
else if (is_comparison && eval_type_match(graph, rdbg, l_restype, r_restype)){
else if (is_comparison && eval_type_match(graph, rdi, l_restype, r_restype)){
cv_type_key = l_restype;
}
@@ -1299,7 +1299,7 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
U8 cv_group = eval_type_group_from_kind(cv_type_kind);
B32 can_generate = 0;
if (raddbg_eval_opcode_type_compatible(op, cv_group)){
if (rdi_eval_opcode_type_compatible(op, cv_group)){
can_generate = 1;
}
else{
@@ -1313,11 +1313,11 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
final_type_key = tg_key_basic(TG_Kind_Bool);
}
EVAL_IRTree *l_tree = eval_irtree_resolve_to_value(arena, graph, rdbg, l.mode, l.tree, l_restype);
l_tree = eval_irtree_convert_hi(arena, graph, rdbg, l_tree, cv_type_key, l_restype);
EVAL_IRTree *l_tree = eval_irtree_resolve_to_value(arena, graph, rdi, l.mode, l.tree, l_restype);
l_tree = eval_irtree_convert_hi(arena, graph, rdi, l_tree, cv_type_key, l_restype);
EVAL_IRTree *r_tree = eval_irtree_resolve_to_value(arena, graph, rdbg, r.mode, r.tree, r_restype);
r_tree = eval_irtree_convert_hi(arena, graph, rdbg, r_tree, cv_type_key, r_restype);
EVAL_IRTree *r_tree = eval_irtree_resolve_to_value(arena, graph, rdi, r.mode, r.tree, r_restype);
r_tree = eval_irtree_convert_hi(arena, graph, rdi, r_tree, cv_type_key, r_restype);
EVAL_IRTree *new_tree = eval_irtree_binary_op(arena, op, cv_group, l_tree, r_tree);
@@ -1339,19 +1339,19 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
ptr_is_decay = r_is_decay;
}
TG_Key direct = tg_unwrapped_direct_from_graph_raddbg_key(graph, rdbg, ptr->type_key);
U64 direct_type_size = tg_byte_size_from_graph_raddbg_key(graph, rdbg, direct);
TG_Key direct = tg_unwrapped_direct_from_graph_rdi_key(graph, rdi, ptr->type_key);
U64 direct_type_size = tg_byte_size_from_graph_rdi_key(graph, rdi, direct);
// generate ir tree
EVAL_IRTree *ptr_tree = ptr->tree;
if (!ptr_is_decay){
ptr_tree = eval_irtree_resolve_to_value(arena, graph, rdbg, ptr->mode, ptr_tree, ptr->type_key);
ptr_tree = eval_irtree_resolve_to_value(arena, graph, rdi, ptr->mode, ptr_tree, ptr->type_key);
}
EVAL_IRTree *integer_tree = eval_irtree_resolve_to_value(arena, graph, rdbg, integer->mode, integer->tree, integer->type_key);
EVAL_IRTree *integer_tree = eval_irtree_resolve_to_value(arena, graph, rdi, integer->mode, integer->tree, integer->type_key);
if (direct_type_size > 1){
EVAL_IRTree *const_tree = eval_irtree_const_u(arena, direct_type_size);
integer_tree = eval_irtree_binary_op_u(arena, RADDBG_EvalOp_Mul, integer_tree, const_tree);
integer_tree = eval_irtree_binary_op_u(arena, RDI_EvalOp_Mul, integer_tree, const_tree);
}
TG_Key ptr_type = ptr->type_key;
@@ -1359,7 +1359,7 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
ptr_type = tg_cons_type_make(graph, TG_Kind_Ptr, direct, 0);
}
EVAL_IRTree *new_tree = eval_irtree_binary_op(arena, op, RADDBG_EvalTypeGroup_U, ptr_tree, integer_tree);
EVAL_IRTree *new_tree = eval_irtree_binary_op(arena, op, RDI_EvalTypeGroup_U, ptr_tree, integer_tree);
result.tree = new_tree;
result.type_key = ptr_type;
@@ -1368,26 +1368,26 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
case EVAL_ArithPath_PtrSub:
{
TG_Key direct = tg_unwrapped_direct_from_graph_raddbg_key(graph, rdbg, l_restype);
U64 direct_type_size = tg_byte_size_from_graph_raddbg_key(graph, rdbg, direct);
TG_Key direct = tg_unwrapped_direct_from_graph_rdi_key(graph, rdi, l_restype);
U64 direct_type_size = tg_byte_size_from_graph_rdi_key(graph, rdi, direct);
// generate ir tree
EVAL_IRTree *l_tree = l.tree;
if (!l_is_decay){
l_tree = eval_irtree_resolve_to_value(arena, graph, rdbg, l.mode, l.tree, l_restype);
l_tree = eval_irtree_resolve_to_value(arena, graph, rdi, l.mode, l.tree, l_restype);
}
EVAL_IRTree *r_tree = r.tree;
if (!r_is_decay){
r_tree = eval_irtree_resolve_to_value(arena, graph, rdbg, r.mode, r.tree, r_restype);
r_tree = eval_irtree_resolve_to_value(arena, graph, rdi, r.mode, r.tree, r_restype);
}
EVAL_IRTree *op_tree = eval_irtree_binary_op(arena, op, RADDBG_EvalTypeGroup_U, l_tree, r_tree);
EVAL_IRTree *op_tree = eval_irtree_binary_op(arena, op, RDI_EvalTypeGroup_U, l_tree, r_tree);
EVAL_IRTree *new_tree = op_tree;
if (direct_type_size > 1){
EVAL_IRTree *const_tree = eval_irtree_const_u(arena, direct_type_size);
new_tree = eval_irtree_binary_op(arena, RADDBG_EvalOp_Div, RADDBG_EvalTypeGroup_U, new_tree, const_tree);
new_tree = eval_irtree_binary_op(arena, RDI_EvalOp_Div, RDI_EvalTypeGroup_U, new_tree, const_tree);
}
result.tree = new_tree;
@@ -1404,15 +1404,15 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
EVAL_Expr *exprl = expr->children[1];
EVAL_Expr *exprr = expr->children[2];
EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprc, eout);
EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprl, eout);
EVAL_IRTreeAndType r = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprr, eout);
EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprc, eout);
EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprl, eout);
EVAL_IRTreeAndType r = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprr, eout);
if (l.tree->op != 0 && r.tree->op != 0 && c.tree->op != 0){
TG_Key c_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, c.type_key);
TG_Key l_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, l.type_key);
TG_Key r_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, r.type_key);
TG_Key c_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, c.type_key);
TG_Key l_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, l.type_key);
TG_Key r_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, r.type_key);
TG_Kind c_restype_kind = tg_kind_from_key(c_restype);
TG_Kind l_restype_kind = tg_kind_from_key(l_restype);
TG_Kind r_restype_kind = tg_kind_from_key(r_restype);
@@ -1427,10 +1427,10 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
if (eval_kind_is_basic_or_enum(l_restype_kind) &&
eval_kind_is_basic_or_enum(r_restype_kind)){
can_generate = 1;
final_type = eval_type_coerce(graph, rdbg, l_restype, r_restype);
final_type = eval_type_coerce(graph, rdi, l_restype, r_restype);
}
else{
if (eval_type_match(graph, rdbg, l_restype, r_restype)){
if (eval_type_match(graph, rdi, l_restype, r_restype)){
if (l_restype_kind == TG_Kind_Ptr){
can_generate = 1;
final_type = l_restype;
@@ -1447,13 +1447,13 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
// generate ir tree
if (can_generate){
EVAL_IRTree *c_tree = eval_irtree_resolve_to_value(arena, graph, rdbg, c.mode, c.tree, c_restype);
EVAL_IRTree *c_tree = eval_irtree_resolve_to_value(arena, graph, rdi, c.mode, c.tree, c_restype);
EVAL_IRTree *l_tree = eval_irtree_resolve_to_value(arena, graph, rdbg, l.mode, l.tree, l_restype);
l_tree = eval_irtree_convert_hi(arena, graph, rdbg, l_tree, final_type, l_restype);
EVAL_IRTree *l_tree = eval_irtree_resolve_to_value(arena, graph, rdi, l.mode, l.tree, l_restype);
l_tree = eval_irtree_convert_hi(arena, graph, rdi, l_tree, final_type, l_restype);
EVAL_IRTree *r_tree = eval_irtree_resolve_to_value(arena, graph, rdbg, r.mode, r.tree, r_restype);
r_tree = eval_irtree_convert_hi(arena, graph, rdbg, r_tree, final_type, r_restype);
EVAL_IRTree *r_tree = eval_irtree_resolve_to_value(arena, graph, rdi, r.mode, r.tree, r_restype);
r_tree = eval_irtree_convert_hi(arena, graph, rdi, r_tree, final_type, r_restype);
EVAL_IRTree *new_tree = eval_irtree_conditional(arena, c_tree, l_tree, r_tree);
@@ -1540,7 +1540,7 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
{
eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, expr->location, "Left side of assignment must be an identifier.");
}
result = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, expr->children[1], eout);
result = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, expr->children[1], eout);
}break;
case EVAL_ExprKind_LeafIdent:
{
@@ -1553,7 +1553,7 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb
else
{
eval_string2expr_map_inc_poison(leaf_ident_expr_map, name);
result = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, leaf_ident_expr, eout);
result = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, leaf_ident_expr, eout);
eval_string2expr_map_dec_poison(leaf_ident_expr_map, name);
}
}break;
@@ -1568,8 +1568,8 @@ eval_oplist_from_irtree(Arena *arena, EVAL_IRTree *tree, EVAL_OpList *out){
ProfBeginFunction();
U32 op = tree->op;
switch (op){
case RADDBG_EvalOp_Stop:
case RADDBG_EvalOp_Skip:
case RDI_EvalOp_Stop:
case RDI_EvalOp_Skip:
{
// TODO: error - invalid ir-tree op
}break;
@@ -1579,7 +1579,7 @@ eval_oplist_from_irtree(Arena *arena, EVAL_IRTree *tree, EVAL_OpList *out){
eval_oplist_push_bytecode(arena, out, tree->bytecode);
}break;
case RADDBG_EvalOp_Cond:
case RDI_EvalOp_Cond:
{
// split out each of the children
EVAL_OpList prt_cond = {0};
@@ -1598,11 +1598,11 @@ eval_oplist_from_irtree(Arena *arena, EVAL_IRTree *tree, EVAL_OpList *out){
// 4.
// modify prt_right in place to create step 2
eval_oplist_push_op(arena, &prt_right, RADDBG_EvalOp_Skip, prt_left.encoded_size);
eval_oplist_push_op(arena, &prt_right, RDI_EvalOp_Skip, prt_left.encoded_size);
// merge 1 into out
eval_oplist_concat_in_place(out, &prt_cond);
eval_oplist_push_op(arena, out, RADDBG_EvalOp_Cond, prt_right.encoded_size);
eval_oplist_push_op(arena, out, RDI_EvalOp_Cond, prt_right.encoded_size);
// merge 2 into out
eval_oplist_concat_in_place(out, &prt_right);
@@ -1613,20 +1613,20 @@ eval_oplist_from_irtree(Arena *arena, EVAL_IRTree *tree, EVAL_OpList *out){
default:
{
if (op >= RADDBG_EvalOp_COUNT){
if (op >= RDI_EvalOp_COUNT){
// TODO: error - invalid ir-tree op
}
else{
// handle all children
U8 ctrlbits = raddbg_eval_opcode_ctrlbits[op];
U64 child_count = RADDBG_POPN_FROM_CTRLBITS(ctrlbits);
U8 ctrlbits = rdi_eval_opcode_ctrlbits[op];
U64 child_count = RDI_POPN_FROM_CTRLBITS(ctrlbits);
EVAL_IRTree**child = tree->children;
for (U64 i = 0; i < child_count; i += 1, child += 1){
eval_oplist_from_irtree(arena, *child, out);
}
// emit op to compute this node
eval_oplist_push_op(arena, out, (RADDBG_EvalOp)tree->op, tree->p);
eval_oplist_push_op(arena, out, (RDI_EvalOp)tree->op, tree->p);
}
}break;
}
+18 -18
View File
@@ -9,7 +9,7 @@
internal String8 eval_bytecode_from_oplist(Arena *arena, EVAL_OpList *list);
internal void eval_oplist_push_op(Arena *arena, EVAL_OpList *list, RADDBG_EvalOp op, U64 p);
internal void eval_oplist_push_op(Arena *arena, EVAL_OpList *list, RDI_EvalOp op, U64 p);
internal void eval_oplist_push_uconst(Arena *arena, EVAL_OpList *list, U64 x);
internal void eval_oplist_push_sconst(Arena *arena, EVAL_OpList *list, S64 x);
@@ -20,8 +20,8 @@ internal void eval_oplist_concat_in_place(EVAL_OpList *left_dst, EVAL_OpList *ri
////////////////////////////////
//~ allen: EVAL Expression Info Functions
internal RADDBG_EvalOp eval_opcode_from_expr_kind(EVAL_ExprKind kind);
internal B32 eval_expr_kind_is_comparison(EVAL_ExprKind kind);
internal RDI_EvalOp eval_opcode_from_expr_kind(EVAL_ExprKind kind);
internal B32 eval_expr_kind_is_comparison(EVAL_ExprKind kind);
////////////////////////////////
//~ allen: EVAL Expression Constructors
@@ -40,13 +40,13 @@ internal EVAL_Expr* eval_expr_leaf_type(Arena *arena, void *location, TG_Key typ
////////////////////////////////
//~ allen: EVAL Type Information Transformers
internal RADDBG_EvalTypeGroup eval_type_group_from_kind(TG_Kind kind);
internal RDI_EvalTypeGroup eval_type_group_from_kind(TG_Kind kind);
internal TG_Key eval_type_unwrap_enum(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key key);
internal TG_Key eval_type_promote(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key key);
internal TG_Key eval_type_coerce(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key l, TG_Key r);
internal TG_Key eval_type_unwrap_enum(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key);
internal TG_Key eval_type_promote(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key);
internal TG_Key eval_type_coerce(TG_Graph *graph, RDI_Parsed *rdi, TG_Key l, TG_Key r);
internal B32 eval_type_match(TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key l, TG_Key r);
internal B32 eval_type_match(TG_Graph *graph, RDI_Parsed *rdi, TG_Key l, TG_Key r);
internal B32 eval_kind_is_integer(TG_Kind kind);
internal B32 eval_kind_is_signed(TG_Kind kind);
@@ -56,27 +56,27 @@ internal B32 eval_kind_is_basic_or_enum(TG_Kind kind);
//~ allen: EVAL IR-Tree Constructors
internal EVAL_IRTree* eval_irtree_const_u(Arena *arena, U64 v);
internal EVAL_IRTree* eval_irtree_unary_op(Arena *arena, RADDBG_EvalOp op, RADDBG_EvalTypeGroup group, EVAL_IRTree *c);
internal EVAL_IRTree* eval_irtree_binary_op(Arena *arena, RADDBG_EvalOp op, RADDBG_EvalTypeGroup group, EVAL_IRTree *l, EVAL_IRTree *r);
internal EVAL_IRTree* eval_irtree_binary_op_u(Arena *arena, RADDBG_EvalOp op, EVAL_IRTree *l, EVAL_IRTree *r);
internal EVAL_IRTree* eval_irtree_unary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, EVAL_IRTree *c);
internal EVAL_IRTree* eval_irtree_binary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, EVAL_IRTree *l, EVAL_IRTree *r);
internal EVAL_IRTree* eval_irtree_binary_op_u(Arena *arena, RDI_EvalOp op, EVAL_IRTree *l, EVAL_IRTree *r);
internal EVAL_IRTree* eval_irtree_conditional(Arena *arena, EVAL_IRTree *c, EVAL_IRTree *l, EVAL_IRTree *r);
internal EVAL_IRTree* eval_irtree_bytecode_no_copy(Arena *arena, String8 bytecode);
////////////////////////////////
//~ allen: EVAL IR-Tree High Level Helpers
internal EVAL_IRTree* eval_irtree_mem_read_type(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_IRTree *c, TG_Key type_key);
internal EVAL_IRTree* eval_irtree_convert_lo(Arena *arena, EVAL_IRTree *c, RADDBG_EvalTypeGroup out, RADDBG_EvalTypeGroup in);
internal EVAL_IRTree* eval_irtree_trunc(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_IRTree *c, TG_Key type_key);
internal EVAL_IRTree* eval_irtree_convert_hi(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_IRTree *c, TG_Key out, TG_Key in);
internal EVAL_IRTree* eval_irtree_resolve_to_value(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_EvalMode from_mode, EVAL_IRTree *tree, TG_Key type_key);
internal EVAL_IRTree* eval_irtree_mem_read_type(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_IRTree *c, TG_Key type_key);
internal EVAL_IRTree* eval_irtree_convert_lo(Arena *arena, EVAL_IRTree *c, RDI_EvalTypeGroup out, RDI_EvalTypeGroup in);
internal EVAL_IRTree* eval_irtree_trunc(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_IRTree *c, TG_Key type_key);
internal EVAL_IRTree* eval_irtree_convert_hi(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_IRTree *c, TG_Key out, TG_Key in);
internal EVAL_IRTree* eval_irtree_resolve_to_value(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_EvalMode from_mode, EVAL_IRTree *tree, TG_Key type_key);
////////////////////////////////
//~ allen: EVAL Compiler Phases
internal void eval_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, EVAL_String2ExprMap *map, EVAL_Expr *expr, EVAL_ErrorList *eout);
internal TG_Key eval_type_from_type_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_Expr *expr, EVAL_ErrorList *eout);
internal EVAL_IRTreeAndType eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_String2ExprMap *leaf_ident_expr_map, EVAL_Expr *expr, EVAL_ErrorList *eout);
internal TG_Key eval_type_from_type_expr(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_Expr *expr, EVAL_ErrorList *eout);
internal EVAL_IRTreeAndType eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_String2ExprMap *leaf_ident_expr_map, EVAL_Expr *expr, EVAL_ErrorList *eout);
internal void eval_oplist_from_irtree(Arena *arena, EVAL_IRTree *tree, EVAL_OpList *out);
#endif //EVAL_COMPILER_H
+5
View File
@@ -1,6 +1,11 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Generated Code
#include "generated/eval.meta.c"
////////////////////////////////
//~ rjf: Basic Functions
+5 -4
View File
@@ -13,6 +13,7 @@ typedef enum EVAL_ErrorKind
EVAL_ErrorKind_MalformedInput,
EVAL_ErrorKind_MissingInfo,
EVAL_ErrorKind_ResolutionFailure,
EVAL_ErrorKind_InterpretationError,
EVAL_ErrorKind_COUNT
}
EVAL_ErrorKind;
@@ -40,7 +41,7 @@ struct EVAL_ErrorList
enum
{
EVAL_IRExtKind_Bytecode = RADDBG_EvalOp_COUNT,
EVAL_IRExtKind_Bytecode = RDI_EvalOp_COUNT,
EVAL_IRExtKind_COUNT
};
@@ -48,7 +49,7 @@ typedef struct EVAL_Op EVAL_Op;
struct EVAL_Op
{
EVAL_Op *next;
RADDBG_EvalOp opcode;
RDI_EvalOp opcode;
union
{
U64 p;
@@ -114,7 +115,7 @@ struct EVAL_Expr
typedef struct EVAL_IRTree EVAL_IRTree;
struct EVAL_IRTree{
RADDBG_EvalOp op;
RDI_EvalOp op;
EVAL_IRTree *children[3];
union{
U64 p;
@@ -212,7 +213,7 @@ internal U64 eval_num_from_string(EVAL_String2NumMap *map, String8 string);
//- rjf: string -> expr
internal EVAL_String2ExprMap eval_string2expr_map_make(Arena *arena, U64 slot_count);
internal void eval_string2expr_map_insert(Arena *arena, EVAL_String2NumMap *map, String8 string, EVAL_Expr *expr);
internal void eval_string2expr_map_insert(Arena *arena, EVAL_String2ExprMap *map, String8 string, EVAL_Expr *expr);
internal void eval_string2expr_map_inc_poison(EVAL_String2ExprMap *map, String8 string);
internal void eval_string2expr_map_dec_poison(EVAL_String2ExprMap *map, String8 string);
internal EVAL_Expr *eval_expr_from_string(EVAL_String2ExprMap *map, String8 string);
+159 -143
View File
@@ -5,7 +5,8 @@
//~ allen: Eval Machine Functions
internal EVAL_Result
eval_interpret(EVAL_Machine *machine, String8 bytecode){
eval_interpret(EVAL_Machine *machine, String8 bytecode)
{
ProfBeginFunction();
EVAL_Result result = {0};
@@ -21,21 +22,21 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){
for (;ptr < opl;){
// consume opcode
RADDBG_EvalOp op = (RADDBG_EvalOp)*ptr;
if (op >= RADDBG_EvalOp_COUNT){
result.bad_eval = 1;
RDI_EvalOp op = (RDI_EvalOp)*ptr;
if (op >= RDI_EvalOp_COUNT){
result.code = EVAL_ResultCode_BadOp;
goto done;
}
U8 ctrlbits = raddbg_eval_opcode_ctrlbits[op];
U8 ctrlbits = rdi_eval_opcode_ctrlbits[op];
ptr += 1;
// decode
U64 imm = 0;
{
U32 decode_size = RADDBG_DECODEN_FROM_CTRLBITS(ctrlbits);
U32 decode_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits);
U8 *next_ptr = ptr + decode_size;
if (next_ptr > opl){
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOp;
goto done;
}
// TODO(allen): to improve this:
@@ -53,9 +54,9 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){
// pop
EVAL_Slot *svals = 0;
{
U32 pop_count = RADDBG_POPN_FROM_CTRLBITS(ctrlbits);
U32 pop_count = RDI_POPN_FROM_CTRLBITS(ctrlbits);
if (pop_count > stack_count){
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOp;
goto done;
}
if (pop_count <= stack_count){
@@ -67,29 +68,29 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){
// interpret
EVAL_Slot nval = {0};
switch (op){
case RADDBG_EvalOp_Stop:
case RDI_EvalOp_Stop:
{
goto done;
}break;
case RADDBG_EvalOp_Noop:
case RDI_EvalOp_Noop:
{
// do nothing
}break;
case RADDBG_EvalOp_Cond:
case RDI_EvalOp_Cond:
{
if (svals[0].u64){
ptr += imm;
}
}break;
case RADDBG_EvalOp_Skip:
case RDI_EvalOp_Skip:
{
ptr += imm;
}break;
case RADDBG_EvalOp_MemRead:
case RDI_EvalOp_MemRead:
{
U64 addr = svals[0].u64;
U64 size = imm;
@@ -99,17 +100,17 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){
good_read = 1;
}
if (!good_read){
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadMemRead;
goto done;
}
}break;
case RADDBG_EvalOp_RegRead:
case RDI_EvalOp_RegRead:
{
U8 raddbg_reg_code = (imm&0x0000FF)>>0;
U8 byte_size = (imm&0x00FF00)>>8;
U8 byte_off = (imm&0xFF0000)>>16;
REGS_RegCode base_reg_code = regs_reg_code_from_arch_raddbg_code(machine->arch, raddbg_reg_code);
U8 rdi_reg_code = (imm&0x0000FF)>>0;
U8 byte_size = (imm&0x00FF00)>>8;
U8 byte_off = (imm&0xFF0000)>>16;
REGS_RegCode base_reg_code = regs_reg_code_from_arch_rdi_code(machine->arch, rdi_reg_code);
REGS_Rng rng = regs_reg_code_rng_table_from_architecture(machine->arch)[base_reg_code];
U64 off = (U64)rng.byte_off + byte_off;
U64 size = (U64)byte_size;
@@ -117,12 +118,12 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){
MemoryCopy(&nval, (U8*)machine->reg_data + off, size);
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadRegRead;
goto done;
}
}break;
case RADDBG_EvalOp_RegReadDyn:
case RDI_EvalOp_RegReadDyn:
{
U64 off = svals[0].u64;
U64 size = bit_size_from_arch(machine->arch)/8;
@@ -130,61 +131,61 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){
MemoryCopy(&nval, (U8*)machine->reg_data + off, size);
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadRegRead;
goto done;
}
}break;
case RADDBG_EvalOp_FrameOff:
case RDI_EvalOp_FrameOff:
{
if (machine->frame_base != 0){
nval.u64 = *machine->frame_base + imm;
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadFrameBase;
goto done;
}
}break;
case RADDBG_EvalOp_ModuleOff:
case RDI_EvalOp_ModuleOff:
{
if (machine->module_base != 0){
nval.u64 = *machine->module_base + imm;
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadModuleBase;
goto done;
}
}break;
case RADDBG_EvalOp_TLSOff:
case RDI_EvalOp_TLSOff:
{
if (machine->tls_base != 0){
nval.u64 = *machine->tls_base + imm;
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadTLSBase;
goto done;
}
}break;
case RADDBG_EvalOp_ConstU8:
case RADDBG_EvalOp_ConstU16:
case RADDBG_EvalOp_ConstU32:
case RADDBG_EvalOp_ConstU64:
case RDI_EvalOp_ConstU8:
case RDI_EvalOp_ConstU16:
case RDI_EvalOp_ConstU32:
case RDI_EvalOp_ConstU64:
{
nval.u64 = imm;
}break;
case RADDBG_EvalOp_Abs:
case RDI_EvalOp_Abs:
{
if (imm == RADDBG_EvalTypeGroup_F32){
if (imm == RDI_EvalTypeGroup_F32){
nval.f32 = svals[0].f32;
if (svals[0].f32 < 0){
nval.f32 = -svals[0].f32;
}
}
else if (imm == RADDBG_EvalTypeGroup_F64){
else if (imm == RDI_EvalTypeGroup_F64){
nval.f64 = svals[0].f64;
if (svals[0].f64 < 0){
nval.f64 = -svals[0].f64;
@@ -198,12 +199,12 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){
}
}break;
case RADDBG_EvalOp_Neg:
case RDI_EvalOp_Neg:
{
if (imm == RADDBG_EvalTypeGroup_F32){
if (imm == RDI_EvalTypeGroup_F32){
nval.f32 = -svals[0].f32;
}
else if (imm == RADDBG_EvalTypeGroup_F64){
else if (imm == RDI_EvalTypeGroup_F64){
nval.f64 = -svals[0].f64;
}
else{
@@ -211,12 +212,12 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){
}
}break;
case RADDBG_EvalOp_Add:
case RDI_EvalOp_Add:
{
if (imm == RADDBG_EvalTypeGroup_F32){
if (imm == RDI_EvalTypeGroup_F32){
nval.f32 = svals[0].f32 + svals[1].f32;
}
else if (imm == RADDBG_EvalTypeGroup_F64){
else if (imm == RDI_EvalTypeGroup_F64){
nval.f64 = svals[0].f64 + svals[1].f64;
}
else{
@@ -224,12 +225,12 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){
}
}break;
case RADDBG_EvalOp_Sub:
case RDI_EvalOp_Sub:
{
if (imm == RADDBG_EvalTypeGroup_F32){
if (imm == RDI_EvalTypeGroup_F32){
nval.f32 = svals[0].f32 - svals[1].f32;
}
else if (imm == RADDBG_EvalTypeGroup_F64){
else if (imm == RDI_EvalTypeGroup_F64){
nval.f64 = svals[0].f64 - svals[1].f64;
}
else{
@@ -237,12 +238,12 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){
}
}break;
case RADDBG_EvalOp_Mul:
case RDI_EvalOp_Mul:
{
if (imm == RADDBG_EvalTypeGroup_F32){
if (imm == RDI_EvalTypeGroup_F32){
nval.f32 = svals[0].f32*svals[1].f32;
}
else if (imm == RADDBG_EvalTypeGroup_F64){
else if (imm == RDI_EvalTypeGroup_F64){
nval.f64 = svals[0].f64*svals[1].f64;
}
else{
@@ -250,245 +251,260 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){
}
}break;
case RADDBG_EvalOp_Div:
case RDI_EvalOp_Div:
{
if (imm == RADDBG_EvalTypeGroup_F32){
if (imm == RDI_EvalTypeGroup_F32){
if (svals[1].f32 != 0.f){
nval.f32 = svals[0].f32/svals[1].f32;
}
else
{
result.code = EVAL_ResultCode_DivideByZero;
goto done;
}
}
else if (imm == RADDBG_EvalTypeGroup_F64){
else if (imm == RDI_EvalTypeGroup_F64){
if (svals[1].f64 != 0.){
nval.f64 = svals[0].f64/svals[1].f64;
}
else
{
result.code = EVAL_ResultCode_DivideByZero;
goto done;
}
}
else if (imm == RADDBG_EvalTypeGroup_U ||
imm == RADDBG_EvalTypeGroup_S){
else if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
if (svals[1].u64 != 0){
nval.u64 = svals[0].u64/svals[1].u64;
}
else
{
result.code = EVAL_ResultCode_DivideByZero;
goto done;
}
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RADDBG_EvalOp_Mod:
case RDI_EvalOp_Mod:
{
if (imm == RADDBG_EvalTypeGroup_U ||
imm == RADDBG_EvalTypeGroup_S){
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
if (svals[1].u64 != 0){
nval.u64 = svals[0].u64%svals[1].u64;
}
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RADDBG_EvalOp_LShift:
case RDI_EvalOp_LShift:
{
if (imm == RADDBG_EvalTypeGroup_U ||
imm == RADDBG_EvalTypeGroup_S){
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
nval.u64 = svals[0].u64 << svals[1].u64;
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RADDBG_EvalOp_RShift:
case RDI_EvalOp_RShift:
{
if (imm == RADDBG_EvalTypeGroup_U){
if (imm == RDI_EvalTypeGroup_U){
nval.u64 = svals[0].u64 >> svals[1].u64;
}
else if (imm == RADDBG_EvalTypeGroup_S){
else if (imm == RDI_EvalTypeGroup_S){
nval.u64 = svals[0].s64 >> svals[1].u64;
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RADDBG_EvalOp_BitAnd:
case RDI_EvalOp_BitAnd:
{
if (imm == RADDBG_EvalTypeGroup_U ||
imm == RADDBG_EvalTypeGroup_S){
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
nval.u64 = svals[0].u64&svals[1].u64;
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RADDBG_EvalOp_BitOr:
case RDI_EvalOp_BitOr:
{
if (imm == RADDBG_EvalTypeGroup_U ||
imm == RADDBG_EvalTypeGroup_S){
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
nval.u64 = svals[0].u64|svals[1].u64;
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RADDBG_EvalOp_BitXor:
case RDI_EvalOp_BitXor:
{
if (imm == RADDBG_EvalTypeGroup_U ||
imm == RADDBG_EvalTypeGroup_S){
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
nval.u64 = svals[0].u64^svals[1].u64;
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RADDBG_EvalOp_BitNot:
case RDI_EvalOp_BitNot:
{
if (imm == RADDBG_EvalTypeGroup_U ||
imm == RADDBG_EvalTypeGroup_S){
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
nval.u64 = ~svals[0].u64;
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RADDBG_EvalOp_LogAnd:
case RDI_EvalOp_LogAnd:
{
if (imm == RADDBG_EvalTypeGroup_U ||
imm == RADDBG_EvalTypeGroup_S){
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
nval.u64 = (svals[0].u64 && svals[1].u64);
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RADDBG_EvalOp_LogOr:
case RDI_EvalOp_LogOr:
{
if (imm == RADDBG_EvalTypeGroup_U ||
imm == RADDBG_EvalTypeGroup_S){
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
nval.u64 = (svals[0].u64 || svals[1].u64);
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RADDBG_EvalOp_LogNot:
case RDI_EvalOp_LogNot:
{
if (imm == RADDBG_EvalTypeGroup_U ||
imm == RADDBG_EvalTypeGroup_S){
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
nval.u64 = (!svals[0].u64);
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RADDBG_EvalOp_EqEq:
case RDI_EvalOp_EqEq:
{
nval.u64 = (svals[0].u64 == svals[1].u64);
}break;
case RADDBG_EvalOp_NtEq:
case RDI_EvalOp_NtEq:
{
nval.u64 = (svals[0].u64 != svals[1].u64);
}break;
case RADDBG_EvalOp_LsEq:
case RDI_EvalOp_LsEq:
{
if (imm == RADDBG_EvalTypeGroup_F32){
if (imm == RDI_EvalTypeGroup_F32){
nval.u64 = (svals[0].f32 <= svals[1].f32);
}
else if (imm == RADDBG_EvalTypeGroup_F64){
else if (imm == RDI_EvalTypeGroup_F64){
nval.u64 = (svals[0].f64 <= svals[1].f64);
}
else if (imm == RADDBG_EvalTypeGroup_U){
else if (imm == RDI_EvalTypeGroup_U){
nval.u64 = (svals[0].u64 <= svals[1].u64);
}
else if (imm == RADDBG_EvalTypeGroup_S){
else if (imm == RDI_EvalTypeGroup_S){
nval.u64 = (svals[0].s64 <= svals[1].s64);
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RADDBG_EvalOp_GrEq:
case RDI_EvalOp_GrEq:
{
if (imm == RADDBG_EvalTypeGroup_F32){
if (imm == RDI_EvalTypeGroup_F32){
nval.u64 = (svals[0].f32 >= svals[1].f32);
}
else if (imm == RADDBG_EvalTypeGroup_F64){
else if (imm == RDI_EvalTypeGroup_F64){
nval.u64 = (svals[0].f64 >= svals[1].f64);
}
else if (imm == RADDBG_EvalTypeGroup_U){
else if (imm == RDI_EvalTypeGroup_U){
nval.u64 = (svals[0].u64 >= svals[1].u64);
}
else if (imm == RADDBG_EvalTypeGroup_S){
else if (imm == RDI_EvalTypeGroup_S){
nval.u64 = (svals[0].s64 >= svals[1].s64);
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RADDBG_EvalOp_Less:
case RDI_EvalOp_Less:
{
if (imm == RADDBG_EvalTypeGroup_F32){
if (imm == RDI_EvalTypeGroup_F32){
nval.u64 = (svals[0].f32 < svals[1].f32);
}
else if (imm == RADDBG_EvalTypeGroup_F64){
else if (imm == RDI_EvalTypeGroup_F64){
nval.u64 = (svals[0].f64 < svals[1].f64);
}
else if (imm == RADDBG_EvalTypeGroup_U){
else if (imm == RDI_EvalTypeGroup_U){
nval.u64 = (svals[0].u64 < svals[1].u64);
}
else if (imm == RADDBG_EvalTypeGroup_S){
else if (imm == RDI_EvalTypeGroup_S){
nval.u64 = (svals[0].s64 < svals[1].s64);
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RADDBG_EvalOp_Grtr:
case RDI_EvalOp_Grtr:
{
if (imm == RADDBG_EvalTypeGroup_F32){
if (imm == RDI_EvalTypeGroup_F32){
nval.u64 = (svals[0].f32 > svals[1].f32);
}
else if (imm == RADDBG_EvalTypeGroup_F64){
else if (imm == RDI_EvalTypeGroup_F64){
nval.u64 = (svals[0].f64 > svals[1].f64);
}
else if (imm == RADDBG_EvalTypeGroup_U){
else if (imm == RDI_EvalTypeGroup_U){
nval.u64 = (svals[0].u64 > svals[1].u64);
}
else if (imm == RADDBG_EvalTypeGroup_S){
else if (imm == RDI_EvalTypeGroup_S){
nval.u64 = (svals[0].s64 > svals[1].s64);
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RADDBG_EvalOp_Trunc:
case RDI_EvalOp_Trunc:
{
if (0 < imm){
U64 mask = 0;
@@ -499,7 +515,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){
}
}break;
case RADDBG_EvalOp_TruncSigned:
case RDI_EvalOp_TruncSigned:
{
if (0 < imm){
U64 mask = 0;
@@ -514,52 +530,52 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){
}
}break;
case RADDBG_EvalOp_Convert:
case RDI_EvalOp_Convert:
{
U32 in = imm&0xFF;
U32 out = (imm >> 8)&0xFF;
if (in != out){
switch (in + out*RADDBG_EvalTypeGroup_COUNT){
case RADDBG_EvalTypeGroup_F32 + RADDBG_EvalTypeGroup_U*RADDBG_EvalTypeGroup_COUNT:
switch (in + out*RDI_EvalTypeGroup_COUNT){
case RDI_EvalTypeGroup_F32 + RDI_EvalTypeGroup_U*RDI_EvalTypeGroup_COUNT:
{
nval.u64 = (U64)svals[0].f32;
}break;
case RADDBG_EvalTypeGroup_F64 + RADDBG_EvalTypeGroup_U*RADDBG_EvalTypeGroup_COUNT:
case RDI_EvalTypeGroup_F64 + RDI_EvalTypeGroup_U*RDI_EvalTypeGroup_COUNT:
{
nval.u64 = (U64)svals[0].f64;
}break;
case RADDBG_EvalTypeGroup_F32 + RADDBG_EvalTypeGroup_S*RADDBG_EvalTypeGroup_COUNT:
case RDI_EvalTypeGroup_F32 + RDI_EvalTypeGroup_S*RDI_EvalTypeGroup_COUNT:
{
nval.s64 = (S64)svals[0].f32;
}break;
case RADDBG_EvalTypeGroup_F64 + RADDBG_EvalTypeGroup_S*RADDBG_EvalTypeGroup_COUNT:
case RDI_EvalTypeGroup_F64 + RDI_EvalTypeGroup_S*RDI_EvalTypeGroup_COUNT:
{
nval.s64 = (S64)svals[0].f64;
}break;
case RADDBG_EvalTypeGroup_U + RADDBG_EvalTypeGroup_F32*RADDBG_EvalTypeGroup_COUNT:
case RDI_EvalTypeGroup_U + RDI_EvalTypeGroup_F32*RDI_EvalTypeGroup_COUNT:
{
nval.f32 = (F32)svals[0].u64;
}break;
case RADDBG_EvalTypeGroup_S + RADDBG_EvalTypeGroup_F32*RADDBG_EvalTypeGroup_COUNT:
case RDI_EvalTypeGroup_S + RDI_EvalTypeGroup_F32*RDI_EvalTypeGroup_COUNT:
{
nval.f32 = (F32)svals[0].s64;
}break;
case RADDBG_EvalTypeGroup_F64 + RADDBG_EvalTypeGroup_F32*RADDBG_EvalTypeGroup_COUNT:
case RDI_EvalTypeGroup_F64 + RDI_EvalTypeGroup_F32*RDI_EvalTypeGroup_COUNT:
{
nval.f32 = (F32)svals[0].f64;
}break;
case RADDBG_EvalTypeGroup_U + RADDBG_EvalTypeGroup_F64*RADDBG_EvalTypeGroup_COUNT:
case RDI_EvalTypeGroup_U + RDI_EvalTypeGroup_F64*RDI_EvalTypeGroup_COUNT:
{
nval.f64 = (F64)svals[0].u64;
}break;
case RADDBG_EvalTypeGroup_S + RADDBG_EvalTypeGroup_F64*RADDBG_EvalTypeGroup_COUNT:
case RDI_EvalTypeGroup_S + RDI_EvalTypeGroup_F64*RDI_EvalTypeGroup_COUNT:
{
nval.f64 = (F64)svals[0].s64;
}break;
case RADDBG_EvalTypeGroup_F32 + RADDBG_EvalTypeGroup_F64*RADDBG_EvalTypeGroup_COUNT:
case RDI_EvalTypeGroup_F32 + RDI_EvalTypeGroup_F64*RDI_EvalTypeGroup_COUNT:
{
nval.f64 = (F64)svals[0].f32;
}break;
@@ -567,23 +583,23 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){
}
}break;
case RADDBG_EvalOp_Pick:
case RDI_EvalOp_Pick:
{
if (stack_count > imm){
nval = stack[stack_count - imm - 1];
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOp;
goto done;
}
}break;
case RADDBG_EvalOp_Pop:
case RDI_EvalOp_Pop:
{
// do nothing - the pop is handled by the control bits
}break;
case RADDBG_EvalOp_Insert:
case RDI_EvalOp_Insert:
{
if (stack_count > imm){
if (imm > 0){
@@ -595,7 +611,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){
}
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_BadOp;
goto done;
}
}break;
@@ -603,14 +619,14 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){
// push
{
U64 push_count = RADDBG_PUSHN_FROM_CTRLBITS(ctrlbits);
U64 push_count = RDI_PUSHN_FROM_CTRLBITS(ctrlbits);
if (push_count == 1){
if (stack_count < stack_cap){
stack[stack_count] = nval;
stack_count += 1;
}
else{
result.bad_eval = 1;
result.code = EVAL_ResultCode_InsufficientStackSpace;
goto done;
}
}
@@ -622,8 +638,8 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){
if (stack_count == 1){
result.value = stack[0];
}
else{
result.bad_eval = 1;
else if(result.code == EVAL_ResultCode_Good){
result.code = EVAL_ResultCode_MalformedBytecode;
}
scratch_end(scratch);
+7 -4
View File
@@ -10,7 +10,8 @@
typedef B32 EVAL_MemoryRead(void *u, void *out, U64 addr, U64 size);
typedef struct EVAL_Machine EVAL_Machine;
struct EVAL_Machine{
struct EVAL_Machine
{
void *u;
Architecture arch;
EVAL_MemoryRead *memory_read;
@@ -22,7 +23,8 @@ struct EVAL_Machine{
};
typedef union EVAL_Slot EVAL_Slot;
union EVAL_Slot{
union EVAL_Slot
{
U64 u256[4];
U64 u128[2];
U64 u64;
@@ -32,9 +34,10 @@ union EVAL_Slot{
};
typedef struct EVAL_Result EVAL_Result;
struct EVAL_Result{
struct EVAL_Result
{
EVAL_Slot value;
B32 bad_eval;
EVAL_ResultCode code;
};
////////////////////////////////
+163 -131
View File
@@ -57,7 +57,7 @@ global read_only S64 eval_g_max_precedence = 15;
//~ rjf: Map Building Fast Paths
internal EVAL_String2NumMap *
eval_push_locals_map_from_raddbg_voff(Arena *arena, RADDBG_Parsed *rdbg, U64 voff)
eval_push_locals_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff)
{
Temp scratch = scratch_begin(&arena, 1);
@@ -66,17 +66,17 @@ eval_push_locals_map_from_raddbg_voff(Arena *arena, RADDBG_Parsed *rdbg, U64 vof
struct Task
{
Task *next;
RADDBG_Scope *scope;
RDI_Scope *scope;
};
Task *first_task = 0;
Task *last_task = 0;
//- rjf: voff -> tightest scope
RADDBG_Scope *tightest_scope = 0;
if(rdbg->scope_vmap != 0 && rdbg->scopes != 0)
RDI_Scope *tightest_scope = 0;
if(rdi->scope_vmap != 0 && rdi->scopes != 0)
{
U64 scope_idx = raddbg_vmap_idx_from_voff(rdbg->scope_vmap, rdbg->scope_vmap_count, voff);
RADDBG_Scope *scope = &rdbg->scopes[scope_idx];
U64 scope_idx = rdi_vmap_idx_from_voff(rdi->scope_vmap, rdi->scope_vmap_count, voff);
RDI_Scope *scope = &rdi->scopes[scope_idx];
Task *task = push_array(scratch.arena, Task, 1);
task->scope = scope;
SLLQueuePush(first_task, last_task, task);
@@ -84,10 +84,10 @@ eval_push_locals_map_from_raddbg_voff(Arena *arena, RADDBG_Parsed *rdbg, U64 vof
}
//- rjf: voff-1 -> scope
if(voff > 0 && rdbg->scope_vmap != 0 && rdbg->scopes != 0)
if(voff > 0 && rdi->scope_vmap != 0 && rdi->scopes != 0)
{
U64 scope_idx = raddbg_vmap_idx_from_voff(rdbg->scope_vmap, rdbg->scope_vmap_count, voff-1);
RADDBG_Scope *scope = &rdbg->scopes[scope_idx];
U64 scope_idx = rdi_vmap_idx_from_voff(rdi->scope_vmap, rdi->scope_vmap_count, voff-1);
RDI_Scope *scope = &rdi->scopes[scope_idx];
if(scope != tightest_scope)
{
Task *task = push_array(scratch.arena, Task, 1);
@@ -99,9 +99,9 @@ eval_push_locals_map_from_raddbg_voff(Arena *arena, RADDBG_Parsed *rdbg, U64 vof
//- rjf: tightest scope -> walk up the tree & build tasks for each parent scope
if(tightest_scope != 0)
{
for(RADDBG_Scope *scope = &rdbg->scopes[tightest_scope->parent_scope_idx];
scope != 0 && scope != &rdbg->scopes[0];
scope = &rdbg->scopes[scope->parent_scope_idx])
for(RDI_Scope *scope = &rdi->scopes[tightest_scope->parent_scope_idx];
scope != 0 && scope != &rdi->scopes[0];
scope = &rdi->scopes[scope->parent_scope_idx])
{
Task *task = push_array(scratch.arena, Task, 1);
task->scope = scope;
@@ -116,15 +116,15 @@ eval_push_locals_map_from_raddbg_voff(Arena *arena, RADDBG_Parsed *rdbg, U64 vof
//- rjf: accumulate locals for all tasks
for(Task *task = first_task; task != 0; task = task->next)
{
RADDBG_Scope *scope = task->scope;
RDI_Scope *scope = task->scope;
if(scope != 0)
{
U32 local_opl_idx = scope->local_first + scope->local_count;
for(U32 local_idx = scope->local_first; local_idx < local_opl_idx; local_idx += 1)
{
RADDBG_Local *local_var = &rdbg->locals[local_idx];
RDI_Local *local_var = &rdi->locals[local_idx];
U64 local_name_size = 0;
U8 *local_name_str = raddbg_string_from_idx(rdbg, local_var->name_string_idx, &local_name_size);
U8 *local_name_str = rdi_string_from_idx(rdi, local_var->name_string_idx, &local_name_size);
String8 name = push_str8_copy(arena, str8(local_name_str, local_name_size));
eval_string2num_map_insert(arena, map, name, (U64)local_idx+1);
}
@@ -136,35 +136,35 @@ eval_push_locals_map_from_raddbg_voff(Arena *arena, RADDBG_Parsed *rdbg, U64 vof
}
internal EVAL_String2NumMap *
eval_push_member_map_from_raddbg_voff(Arena *arena, RADDBG_Parsed *rdbg, U64 voff)
eval_push_member_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff)
{
//- rjf: voff -> tightest scope
RADDBG_Scope *tightest_scope = 0;
if(rdbg->scope_vmap != 0 && rdbg->scopes != 0)
RDI_Scope *tightest_scope = 0;
if(rdi->scope_vmap != 0 && rdi->scopes != 0)
{
U64 scope_idx = raddbg_vmap_idx_from_voff(rdbg->scope_vmap, rdbg->scope_vmap_count, voff);
tightest_scope = &rdbg->scopes[scope_idx];
U64 scope_idx = rdi_vmap_idx_from_voff(rdi->scope_vmap, rdi->scope_vmap_count, voff);
tightest_scope = &rdi->scopes[scope_idx];
}
//- rjf: tightest scope -> procedure
RADDBG_Procedure *procedure = 0;
if(tightest_scope != 0 && rdbg->procedures != 0)
RDI_Procedure *procedure = 0;
if(tightest_scope != 0 && rdi->procedures != 0)
{
U32 proc_idx = tightest_scope->proc_idx;
if(0 < proc_idx && proc_idx < rdbg->procedures_count)
if(0 < proc_idx && proc_idx < rdi->procedures_count)
{
procedure = &rdbg->procedures[proc_idx];
procedure = &rdi->procedures[proc_idx];
}
}
//- rjf: procedure -> udt
RADDBG_UDT *udt = 0;
if(procedure != 0 && rdbg->udts != 0 && procedure->link_flags & RADDBG_LinkFlag_TypeScoped)
RDI_UDT *udt = 0;
if(procedure != 0 && rdi->udts != 0 && procedure->link_flags & RDI_LinkFlag_TypeScoped)
{
U32 udt_idx = procedure->container_idx;
if(0 < udt_idx && udt_idx < rdbg->udts_count)
if(0 < udt_idx && udt_idx < rdi->udts_count)
{
udt = &rdbg->udts[udt_idx];
udt = &rdi->udts[udt_idx];
}
}
@@ -173,22 +173,22 @@ eval_push_member_map_from_raddbg_voff(Arena *arena, RADDBG_Parsed *rdbg, U64 vof
*map = eval_string2num_map_make(arena, 64);
//- rjf: udt -> fill member map
if(udt != 0 && !(udt->flags & RADDBG_UserDefinedTypeFlag_EnumMembers) && rdbg->members != 0)
if(udt != 0 && !(udt->flags & RDI_UserDefinedTypeFlag_EnumMembers) && rdi->members != 0)
{
U64 data_member_num = 1;
for(U32 member_idx = udt->member_first;
member_idx < udt->member_first+udt->member_count;
member_idx += 1)
{
if(member_idx < 1 || rdbg->members_count <= member_idx)
if(member_idx < 1 || rdi->members_count <= member_idx)
{
break;
}
RADDBG_Member *m = &rdbg->members[member_idx];
if(m->kind == RADDBG_MemberKind_DataField)
RDI_Member *m = &rdi->members[member_idx];
if(m->kind == RDI_MemberKind_DataField)
{
String8 name = {0};
name.str = raddbg_string_from_idx(rdbg, m->name_string_idx, &name.size);
name.str = rdi_string_from_idx(rdi, m->name_string_idx, &name.size);
eval_string2num_map_insert(arena, map, name, data_member_num);
data_member_num += 1;
}
@@ -464,25 +464,25 @@ eval_token_array_make_first_opl(EVAL_Token *first, EVAL_Token *opl)
//~ rjf: Parser Functions
internal TG_Key
eval_leaf_type_from_name(RADDBG_Parsed *rdbg, String8 name)
eval_leaf_type_from_name(RDI_Parsed *rdi, String8 name)
{
TG_Key key = zero_struct;
B32 found = 0;
if(rdbg->type_nodes != 0)
if(rdi->type_nodes != 0)
{
RADDBG_NameMap *name_map = raddbg_name_map_from_kind(rdbg, RADDBG_NameMapKind_Types);
RADDBG_ParsedNameMap parsed_name_map = {0};
raddbg_name_map_parse(rdbg, name_map, &parsed_name_map);
RADDBG_NameMapNode *node = raddbg_name_map_lookup(rdbg, &parsed_name_map, name.str, name.size);
RDI_NameMap *name_map = rdi_name_map_from_kind(rdi, RDI_NameMapKind_Types);
RDI_ParsedNameMap parsed_name_map = {0};
rdi_name_map_parse(rdi, name_map, &parsed_name_map);
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, name.str, name.size);
if(node != 0)
{
U32 match_count = 0;
U32 *matches = raddbg_matches_from_map_node(rdbg, node, &match_count);
U32 *matches = rdi_matches_from_map_node(rdi, node, &match_count);
if(match_count != 0)
{
RADDBG_TypeNode *type_node = raddbg_element_from_idx(rdbg, type_nodes, matches[0]);
found = type_node->kind != RADDBG_TypeKind_NULL;
key = tg_key_ext(tg_kind_from_raddbg_type_kind(type_node->kind), (U64)matches[0]);
RDI_TypeNode *type_node = rdi_element_from_idx(rdi, type_nodes, matches[0]);
found = type_node->kind != RDI_TypeKind_NULL;
key = tg_key_ext(tg_kind_from_rdi_type_kind(type_node->kind), (U64)matches[0]);
}
}
}
@@ -569,7 +569,7 @@ eval_parse_type_from_text_tokens(Arena *arena, EVAL_ParseCtx *ctx, String8 text,
if(token.kind == EVAL_TokenKind_Identifier)
{
String8 token_string = str8_substr(text, token.range);
TG_Key type_key = eval_leaf_type_from_name(ctx->rdbg, token_string);
TG_Key type_key = eval_leaf_type_from_name(ctx->rdi, token_string);
if(!tg_key_match(tg_key_zero(), type_key))
{
token_it += 1;
@@ -680,7 +680,7 @@ eval_parse_expr_from_text_tokens__prec(Arena *arena, EVAL_ParseCtx *ctx, String8
String8 some_type_identifier_maybe_string = str8_substr(text, some_type_identifier_maybe.range);
if(some_type_identifier_maybe.kind == EVAL_TokenKind_Identifier)
{
TG_Key type_key = eval_leaf_type_from_name(ctx->rdbg, some_type_identifier_maybe_string);
TG_Key type_key = eval_leaf_type_from_name(ctx->rdi, some_type_identifier_maybe_string);
if(!tg_key_match(type_key, tg_key_zero()) || str8_match(some_type_identifier_maybe_string, str8_lit("unsigned"), 0))
{
// rjf: move past open paren
@@ -775,6 +775,38 @@ eval_parse_expr_from_text_tokens__prec(Arena *arena, EVAL_ParseCtx *ctx, String8
}
}
//- rjf: descent to assembly-style dereference sub-expression
else if(token.kind == EVAL_TokenKind_Symbol && str8_match(token_string, str8_lit("["), 0))
{
// rjf: skip [
it += 1;
// rjf: parse [] contents
EVAL_TokenArray nested_parse_tokens = eval_token_array_make_first_opl(it, it_opl);
EVAL_ParseResult nested_parse = eval_parse_expr_from_text_tokens__prec(arena, ctx, text, &nested_parse_tokens, eval_g_max_precedence);
eval_error_list_concat_in_place(&result.errors, &nested_parse.errors);
atom = nested_parse.expr;
it = nested_parse.last_token;
// rjf: build cast-to-U64*, and dereference operators
atom = eval_expr(arena, EVAL_ExprKind_Cast, token_string.str, eval_expr_leaf_type(arena, token_string.str, tg_cons_type_make(ctx->type_graph, TG_Kind_Ptr, tg_key_basic(TG_Kind_U64), 0)), atom, 0);
atom = eval_expr(arena, EVAL_ExprKind_Deref, token_string.str, atom, 0, 0);
// rjf: expect ]
EVAL_Token close_paren_maybe = eval_token_at_it(it, tokens);
String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range);
if(close_paren_maybe.kind != EVAL_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit("]"), 0))
{
eval_errorf(arena, &result.errors, EVAL_ErrorKind_MalformedInput, token_string.str, "Missing ].");
}
// rjf: consume )
else
{
it += 1;
}
}
//- rjf: leaf (identifier, literal)
else if(token.kind != EVAL_TokenKind_Symbol)
{
@@ -787,9 +819,9 @@ eval_parse_expr_from_text_tokens__prec(Arena *arena, EVAL_ParseCtx *ctx, String8
B32 mapped_identifier = 0;
B32 identifier_type_is_possibly_dynamically_overridden = 0;
B32 identifier_looks_like_type_expr = 0;
RADDBG_LocationKind loc_kind = RADDBG_LocationKind_NULL;
RADDBG_LocationRegister loc_reg = {0};
RADDBG_LocationRegisterPlusU16 loc_reg_u16 = {0};
RDI_LocationKind loc_kind = RDI_LocationKind_NULL;
RDI_LocationRegister loc_reg = {0};
RDI_LocationRegisterPlusU16 loc_reg_u16 = {0};
String8 loc_bytecode = {0};
REGS_RegCode reg_code = 0;
REGS_AliasCode alias_code = 0;
@@ -798,14 +830,14 @@ eval_parse_expr_from_text_tokens__prec(Arena *arena, EVAL_ParseCtx *ctx, String8
//- rjf: form namespaceified fallback versions of this lookup string
String8List namespaceified_token_strings = {0};
if(ctx->rdbg->procedures != 0 && ctx->rdbg->scopes != 0 && ctx->rdbg->scope_vmap != 0)
if(ctx->rdi->procedures != 0 && ctx->rdi->scopes != 0 && ctx->rdi->scope_vmap != 0)
{
U64 scope_idx = raddbg_vmap_idx_from_voff(ctx->rdbg->scope_vmap, ctx->rdbg->scope_vmap_count, ctx->ip_voff);
RADDBG_Scope *scope = &ctx->rdbg->scopes[scope_idx];
U64 scope_idx = rdi_vmap_idx_from_voff(ctx->rdi->scope_vmap, ctx->rdi->scope_vmap_count, ctx->ip_voff);
RDI_Scope *scope = &ctx->rdi->scopes[scope_idx];
U64 proc_idx = scope->proc_idx;
RADDBG_Procedure *procedure = &ctx->rdbg->procedures[proc_idx];
RDI_Procedure *procedure = &ctx->rdi->procedures[proc_idx];
U64 name_size = 0;
U8 *name_ptr = raddbg_string_from_idx(ctx->rdbg, procedure->name_string_idx, &name_size);
U8 *name_ptr = rdi_string_from_idx(ctx->rdi, procedure->name_string_idx, &name_size);
String8 containing_procedure_name = str8(name_ptr, name_size);
U64 last_past_scope_resolution_pos = 0;
for(;;)
@@ -843,48 +875,48 @@ eval_parse_expr_from_text_tokens__prec(Arena *arena, EVAL_ParseCtx *ctx, String8
{
mapped_identifier = 1;
identifier_type_is_possibly_dynamically_overridden = 1;
RADDBG_Local *local_var = raddbg_element_from_idx(ctx->rdbg, locals, local_num-1);
RADDBG_TypeNode *type_node = raddbg_element_from_idx(ctx->rdbg, type_nodes, local_var->type_idx);
type_key = tg_key_ext(tg_kind_from_raddbg_type_kind(type_node->kind), (U64)local_var->type_idx);
RDI_Local *local_var = rdi_element_from_idx(ctx->rdi, locals, local_num-1);
RDI_TypeNode *type_node = rdi_element_from_idx(ctx->rdi, type_nodes, local_var->type_idx);
type_key = tg_key_ext(tg_kind_from_rdi_type_kind(type_node->kind), (U64)local_var->type_idx);
// rjf: grab location info
for(U32 loc_block_idx = local_var->location_first;
loc_block_idx < local_var->location_opl;
loc_block_idx += 1)
{
RADDBG_LocationBlock *block = &ctx->rdbg->location_blocks[loc_block_idx];
RDI_LocationBlock *block = &ctx->rdi->location_blocks[loc_block_idx];
if(block->scope_off_first <= ctx->ip_voff && ctx->ip_voff < block->scope_off_opl)
{
loc_kind = *((RADDBG_LocationKind *)(ctx->rdbg->location_data + block->location_data_off));
loc_kind = *((RDI_LocationKind *)(ctx->rdi->location_data + block->location_data_off));
switch(loc_kind)
{
default:{mapped_identifier = 0;}break;
case RADDBG_LocationKind_AddrBytecodeStream:
case RADDBG_LocationKind_ValBytecodeStream:
case RDI_LocationKind_AddrBytecodeStream:
case RDI_LocationKind_ValBytecodeStream:
{
U8 *bytecode_base = ctx->rdbg->location_data + block->location_data_off + sizeof(RADDBG_LocationKind);
U8 *bytecode_base = ctx->rdi->location_data + block->location_data_off + sizeof(RDI_LocationKind);
U64 bytecode_size = 0;
for(U64 idx = 0; idx < ctx->rdbg->location_data_size; idx += 1)
for(U64 idx = 0; idx < ctx->rdi->location_data_size; idx += 1)
{
U8 op = bytecode_base[idx];
if(op == 0)
{
break;
}
U8 ctrlbits = raddbg_eval_opcode_ctrlbits[op];
U32 p_size = RADDBG_DECODEN_FROM_CTRLBITS(ctrlbits);
U8 ctrlbits = rdi_eval_opcode_ctrlbits[op];
U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits);
bytecode_size += 1+p_size;
}
loc_bytecode = str8(bytecode_base, bytecode_size);
}break;
case RADDBG_LocationKind_AddrRegisterPlusU16:
case RADDBG_LocationKind_AddrAddrRegisterPlusU16:
case RDI_LocationKind_AddrRegisterPlusU16:
case RDI_LocationKind_AddrAddrRegisterPlusU16:
{
MemoryCopy(&loc_reg_u16, (ctx->rdbg->location_data + block->location_data_off), sizeof(loc_reg_u16));
MemoryCopy(&loc_reg_u16, (ctx->rdi->location_data + block->location_data_off), sizeof(loc_reg_u16));
}break;
case RADDBG_LocationKind_ValRegister:
case RDI_LocationKind_ValRegister:
{
MemoryCopy(&loc_reg, (ctx->rdbg->location_data + block->location_data_off), sizeof(loc_reg));
MemoryCopy(&loc_reg, (ctx->rdi->location_data + block->location_data_off), sizeof(loc_reg));
}break;
}
}
@@ -919,21 +951,21 @@ eval_parse_expr_from_text_tokens__prec(Arena *arena, EVAL_ParseCtx *ctx, String8
//- rjf: try global variables
if(mapped_identifier == 0)
{
RADDBG_NameMap *name_map = raddbg_name_map_from_kind(ctx->rdbg, RADDBG_NameMapKind_GlobalVariables);
if(name_map != 0 && ctx->rdbg->global_variables != 0)
RDI_NameMap *name_map = rdi_name_map_from_kind(ctx->rdi, RDI_NameMapKind_GlobalVariables);
if(name_map != 0 && ctx->rdi->global_variables != 0)
{
RADDBG_ParsedNameMap parsed_name_map = {0};
raddbg_name_map_parse(ctx->rdbg, name_map, &parsed_name_map);
RADDBG_NameMapNode *node = raddbg_name_map_lookup(ctx->rdbg, &parsed_name_map, token_string.str, token_string.size);
RDI_ParsedNameMap parsed_name_map = {0};
rdi_name_map_parse(ctx->rdi, name_map, &parsed_name_map);
RDI_NameMapNode *node = rdi_name_map_lookup(ctx->rdi, &parsed_name_map, token_string.str, token_string.size);
U32 matches_count = 0;
U32 *matches = raddbg_matches_from_map_node(ctx->rdbg, node, &matches_count);
U32 *matches = rdi_matches_from_map_node(ctx->rdi, node, &matches_count);
for(String8Node *n = namespaceified_token_strings.first;
n != 0 && matches_count == 0;
n = n->next)
{
node = raddbg_name_map_lookup(ctx->rdbg, &parsed_name_map, n->string.str, n->string.size);
node = rdi_name_map_lookup(ctx->rdi, &parsed_name_map, n->string.str, n->string.size);
matches_count = 0;
matches = raddbg_matches_from_map_node(ctx->rdbg, node, &matches_count);
matches = rdi_matches_from_map_node(ctx->rdi, node, &matches_count);
}
if(matches_count != 0)
{
@@ -942,16 +974,16 @@ eval_parse_expr_from_text_tokens__prec(Arena *arena, EVAL_ParseCtx *ctx, String8
// don't know of a magic hash table fixup path in PDBs, so
// in this case, I'm going to prefer the latest-added global.
U32 match_idx = matches[matches_count-1];
RADDBG_GlobalVariable *global_var = &ctx->rdbg->global_variables[match_idx];
RDI_GlobalVariable *global_var = &ctx->rdi->global_variables[match_idx];
EVAL_OpList oplist = {0};
eval_oplist_push_op(arena, &oplist, RADDBG_EvalOp_ModuleOff, global_var->voff);
loc_kind = RADDBG_LocationKind_AddrBytecodeStream;
eval_oplist_push_op(arena, &oplist, RDI_EvalOp_ModuleOff, global_var->voff);
loc_kind = RDI_LocationKind_AddrBytecodeStream;
loc_bytecode = eval_bytecode_from_oplist(arena, &oplist);
U32 type_idx = global_var->type_idx;
if(type_idx < ctx->rdbg->type_nodes_count)
if(type_idx < ctx->rdi->type_nodes_count)
{
RADDBG_TypeNode *type_node = &ctx->rdbg->type_nodes[type_idx];
type_key = tg_key_ext(tg_kind_from_raddbg_type_kind(type_node->kind), (U64)type_idx);
RDI_TypeNode *type_node = &ctx->rdi->type_nodes[type_idx];
type_key = tg_key_ext(tg_kind_from_rdi_type_kind(type_node->kind), (U64)type_idx);
}
mapped_identifier = 1;
}
@@ -961,35 +993,35 @@ eval_parse_expr_from_text_tokens__prec(Arena *arena, EVAL_ParseCtx *ctx, String8
//- rjf: try thread variables
if(mapped_identifier == 0)
{
RADDBG_NameMap *name_map = raddbg_name_map_from_kind(ctx->rdbg, RADDBG_NameMapKind_ThreadVariables);
if(name_map != 0 && ctx->rdbg->global_variables != 0)
RDI_NameMap *name_map = rdi_name_map_from_kind(ctx->rdi, RDI_NameMapKind_ThreadVariables);
if(name_map != 0 && ctx->rdi->global_variables != 0)
{
RADDBG_ParsedNameMap parsed_name_map = {0};
raddbg_name_map_parse(ctx->rdbg, name_map, &parsed_name_map);
RADDBG_NameMapNode *node = raddbg_name_map_lookup(ctx->rdbg, &parsed_name_map, token_string.str, token_string.size);
RDI_ParsedNameMap parsed_name_map = {0};
rdi_name_map_parse(ctx->rdi, name_map, &parsed_name_map);
RDI_NameMapNode *node = rdi_name_map_lookup(ctx->rdi, &parsed_name_map, token_string.str, token_string.size);
U32 matches_count = 0;
U32 *matches = raddbg_matches_from_map_node(ctx->rdbg, node, &matches_count);
U32 *matches = rdi_matches_from_map_node(ctx->rdi, node, &matches_count);
for(String8Node *n = namespaceified_token_strings.first;
n != 0 && matches_count == 0;
n = n->next)
{
node = raddbg_name_map_lookup(ctx->rdbg, &parsed_name_map, n->string.str, n->string.size);
node = rdi_name_map_lookup(ctx->rdi, &parsed_name_map, n->string.str, n->string.size);
matches_count = 0;
matches = raddbg_matches_from_map_node(ctx->rdbg, node, &matches_count);
matches = rdi_matches_from_map_node(ctx->rdi, node, &matches_count);
}
if(matches_count != 0)
{
U32 match_idx = matches[0];
RADDBG_ThreadVariable *thread_var = &ctx->rdbg->thread_variables[match_idx];
RDI_ThreadVariable *thread_var = &ctx->rdi->thread_variables[match_idx];
EVAL_OpList oplist = {0};
eval_oplist_push_op(arena, &oplist, RADDBG_EvalOp_TLSOff, thread_var->tls_off);
loc_kind = RADDBG_LocationKind_AddrBytecodeStream;
eval_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, thread_var->tls_off);
loc_kind = RDI_LocationKind_AddrBytecodeStream;
loc_bytecode = eval_bytecode_from_oplist(arena, &oplist);
U32 type_idx = thread_var->type_idx;
if(type_idx < ctx->rdbg->type_nodes_count)
if(type_idx < ctx->rdi->type_nodes_count)
{
RADDBG_TypeNode *type_node = &ctx->rdbg->type_nodes[type_idx];
type_key = tg_key_ext(tg_kind_from_raddbg_type_kind(type_node->kind), (U64)type_idx);
RDI_TypeNode *type_node = &ctx->rdi->type_nodes[type_idx];
type_key = tg_key_ext(tg_kind_from_rdi_type_kind(type_node->kind), (U64)type_idx);
}
mapped_identifier = 1;
}
@@ -999,37 +1031,37 @@ eval_parse_expr_from_text_tokens__prec(Arena *arena, EVAL_ParseCtx *ctx, String8
//- rjf: try procedures
if(mapped_identifier == 0)
{
RADDBG_NameMap *name_map = raddbg_name_map_from_kind(ctx->rdbg, RADDBG_NameMapKind_Procedures);
if(name_map != 0 && ctx->rdbg->procedures != 0 && ctx->rdbg->scopes != 0 && ctx->rdbg->scope_voffs)
RDI_NameMap *name_map = rdi_name_map_from_kind(ctx->rdi, RDI_NameMapKind_Procedures);
if(name_map != 0 && ctx->rdi->procedures != 0 && ctx->rdi->scopes != 0 && ctx->rdi->scope_voffs)
{
RADDBG_ParsedNameMap parsed_name_map = {0};
raddbg_name_map_parse(ctx->rdbg, name_map, &parsed_name_map);
RADDBG_NameMapNode *node = raddbg_name_map_lookup(ctx->rdbg, &parsed_name_map, token_string.str, token_string.size);
RDI_ParsedNameMap parsed_name_map = {0};
rdi_name_map_parse(ctx->rdi, name_map, &parsed_name_map);
RDI_NameMapNode *node = rdi_name_map_lookup(ctx->rdi, &parsed_name_map, token_string.str, token_string.size);
U32 matches_count = 0;
U32 *matches = raddbg_matches_from_map_node(ctx->rdbg, node, &matches_count);
U32 *matches = rdi_matches_from_map_node(ctx->rdi, node, &matches_count);
for(String8Node *n = namespaceified_token_strings.first;
n != 0 && matches_count == 0;
n = n->next)
{
node = raddbg_name_map_lookup(ctx->rdbg, &parsed_name_map, n->string.str, n->string.size);
node = rdi_name_map_lookup(ctx->rdi, &parsed_name_map, n->string.str, n->string.size);
matches_count = 0;
matches = raddbg_matches_from_map_node(ctx->rdbg, node, &matches_count);
matches = rdi_matches_from_map_node(ctx->rdi, node, &matches_count);
}
if(matches_count != 0)
{
U32 match_idx = matches[0];
RADDBG_Procedure *procedure = &ctx->rdbg->procedures[match_idx];
RADDBG_Scope *scope = &ctx->rdbg->scopes[procedure->root_scope_idx];
U64 voff = ctx->rdbg->scope_voffs[scope->voff_range_first];
RDI_Procedure *procedure = &ctx->rdi->procedures[match_idx];
RDI_Scope *scope = &ctx->rdi->scopes[procedure->root_scope_idx];
U64 voff = ctx->rdi->scope_voffs[scope->voff_range_first];
EVAL_OpList oplist = {0};
eval_oplist_push_op(arena, &oplist, RADDBG_EvalOp_ModuleOff, voff);
loc_kind = RADDBG_LocationKind_ValBytecodeStream;
eval_oplist_push_op(arena, &oplist, RDI_EvalOp_ModuleOff, voff);
loc_kind = RDI_LocationKind_ValBytecodeStream;
loc_bytecode = eval_bytecode_from_oplist(arena, &oplist);
U32 type_idx = procedure->type_idx;
if(type_idx < ctx->rdbg->type_nodes_count)
if(type_idx < ctx->rdi->type_nodes_count)
{
RADDBG_TypeNode *type_node = &ctx->rdbg->type_nodes[type_idx];
type_key = tg_key_ext(tg_kind_from_raddbg_type_kind(type_node->kind), (U64)type_idx);
RDI_TypeNode *type_node = &ctx->rdi->type_nodes[type_idx];
type_key = tg_key_ext(tg_kind_from_rdi_type_kind(type_node->kind), (U64)type_idx);
}
mapped_identifier = 1;
}
@@ -1039,7 +1071,7 @@ eval_parse_expr_from_text_tokens__prec(Arena *arena, EVAL_ParseCtx *ctx, String8
//- rjf: try types
if(mapped_identifier == 0)
{
type_key = eval_leaf_type_from_name(ctx->rdbg, token_string);
type_key = eval_leaf_type_from_name(ctx->rdi, token_string);
if(!tg_key_match(tg_key_zero(), type_key))
{
mapped_identifier = 1;
@@ -1086,44 +1118,44 @@ eval_parse_expr_from_text_tokens__prec(Arena *arena, EVAL_ParseCtx *ctx, String8
eval_errorf(arena, &result.errors, EVAL_ErrorKind_MissingInfo, token_string.str, "Missing location information for \"%S\".", token_string);
}
}break;
case RADDBG_LocationKind_AddrBytecodeStream:
case RDI_LocationKind_AddrBytecodeStream:
{
atom = eval_expr_leaf_bytecode(arena, token_string.str, type_key, loc_bytecode, EVAL_EvalMode_Addr);
}break;
case RADDBG_LocationKind_ValBytecodeStream:
case RDI_LocationKind_ValBytecodeStream:
{
atom = eval_expr_leaf_bytecode(arena, token_string.str, type_key, loc_bytecode, EVAL_EvalMode_Value);
}break;
case RADDBG_LocationKind_AddrRegisterPlusU16:
case RDI_LocationKind_AddrRegisterPlusU16:
{
EVAL_OpList oplist = {0};
U64 byte_size = bit_size_from_arch(ctx->arch)/8;
U64 regread_param = RADDBG_EncodeRegReadParam(loc_reg_u16.register_code, byte_size, 0);
eval_oplist_push_op(arena, &oplist, RADDBG_EvalOp_RegRead, regread_param);
eval_oplist_push_op(arena, &oplist, RADDBG_EvalOp_ConstU16, loc_reg_u16.offset);
eval_oplist_push_op(arena, &oplist, RADDBG_EvalOp_Add, 0);
U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.register_code, byte_size, 0);
eval_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, regread_param);
eval_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, loc_reg_u16.offset);
eval_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, 0);
atom = eval_expr_leaf_op_list(arena, token_string.str, type_key, &oplist, EVAL_EvalMode_Addr);
}break;
case RADDBG_LocationKind_AddrAddrRegisterPlusU16:
case RDI_LocationKind_AddrAddrRegisterPlusU16:
{
EVAL_OpList oplist = {0};
U64 byte_size = bit_size_from_arch(ctx->arch)/8;
U64 regread_param = RADDBG_EncodeRegReadParam(loc_reg_u16.register_code, byte_size, 0);
eval_oplist_push_op(arena, &oplist, RADDBG_EvalOp_RegRead, regread_param);
eval_oplist_push_op(arena, &oplist, RADDBG_EvalOp_ConstU16, loc_reg_u16.offset);
eval_oplist_push_op(arena, &oplist, RADDBG_EvalOp_Add, 0);
eval_oplist_push_op(arena, &oplist, RADDBG_EvalOp_MemRead, bit_size_from_arch(ctx->arch)/8);
U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.register_code, byte_size, 0);
eval_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, regread_param);
eval_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, loc_reg_u16.offset);
eval_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, 0);
eval_oplist_push_op(arena, &oplist, RDI_EvalOp_MemRead, bit_size_from_arch(ctx->arch)/8);
atom = eval_expr_leaf_op_list(arena, token_string.str, type_key, &oplist, EVAL_EvalMode_Addr);
}break;
case RADDBG_LocationKind_ValRegister:
case RDI_LocationKind_ValRegister:
{
REGS_RegCode regs_reg_code = regs_reg_code_from_arch_raddbg_code(ctx->arch, loc_reg.register_code);
REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(ctx->arch, loc_reg.register_code);
REGS_Rng reg_rng = regs_reg_code_rng_table_from_architecture(ctx->arch)[regs_reg_code];
EVAL_OpList oplist = {0};
U64 byte_size = (U64)reg_rng.byte_size;
U64 byte_pos = 0;
U64 regread_param = RADDBG_EncodeRegReadParam(loc_reg.register_code, byte_size, byte_pos);
eval_oplist_push_op(arena, &oplist, RADDBG_EvalOp_RegRead, regread_param);
U64 regread_param = RDI_EncodeRegReadParam(loc_reg.register_code, byte_size, byte_pos);
eval_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, regread_param);
atom = eval_expr_leaf_op_list(arena, token_string.str, type_key, &oplist, EVAL_EvalMode_Value);
}break;
}
+4 -4
View File
@@ -67,7 +67,7 @@ struct EVAL_ParseCtx
{
Architecture arch;
U64 ip_voff;
RADDBG_Parsed *rdbg;
RDI_Parsed *rdi;
TG_Graph *type_graph;
EVAL_String2NumMap *regs_map;
EVAL_String2NumMap *reg_alias_map;
@@ -85,8 +85,8 @@ global read_only EVAL_ParseResult eval_parse_result_nil = {0, &eval_expr_nil};
////////////////////////////////
//~ rjf: Debug-Info-Driven Map Building Fast Paths
internal EVAL_String2NumMap *eval_push_locals_map_from_raddbg_voff(Arena *arena, RADDBG_Parsed *rdbg, U64 voff);
internal EVAL_String2NumMap *eval_push_member_map_from_raddbg_voff(Arena *arena, RADDBG_Parsed *rdbg, U64 voff);
internal EVAL_String2NumMap *eval_push_locals_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff);
internal EVAL_String2NumMap *eval_push_member_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff);
////////////////////////////////
//~ rjf: Tokenization Functions
@@ -101,7 +101,7 @@ internal EVAL_TokenArray eval_token_array_make_first_opl(EVAL_Token *first, EVAL
////////////////////////////////
//~ rjf: Parser Functions
internal TG_Key eval_leaf_type_from_name(RADDBG_Parsed *rdbg, String8 name);
internal TG_Key eval_leaf_type_from_name(RDI_Parsed *rdi, String8 name);
internal EVAL_ParseResult eval_parse_type_from_text_tokens(Arena *arena, EVAL_ParseCtx *ctx, String8 text, EVAL_TokenArray *tokens);
internal EVAL_ParseResult eval_parse_expr_from_text_tokens__prec(Arena *arena, EVAL_ParseCtx *ctx, String8 text, EVAL_TokenArray *tokens, S64 max_precedence);
internal EVAL_ParseResult eval_parse_expr_from_text_tokens(Arena *arena, EVAL_ParseCtx *ctx, String8 text, EVAL_TokenArray *tokens);
+150
View File
@@ -3,3 +3,153 @@
//- GENERATED CODE
C_LINKAGE_BEGIN
U8 eval_expr_kind_child_counts[40] =
{
0,
2,
2,
1,
1,
2,
1,
1,
1,
1,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
3,
0,
0,
0,
0,
0,
0,
1,
2,
1,
2,
0,
};
String8 eval_expr_kind_strings[40] =
{
str8_lit_comp("Nil"),
str8_lit_comp("ArrayIndex"),
str8_lit_comp("MemberAccess"),
str8_lit_comp("Deref"),
str8_lit_comp("Address"),
str8_lit_comp("Cast"),
str8_lit_comp("Sizeof"),
str8_lit_comp("Neg"),
str8_lit_comp("LogNot"),
str8_lit_comp("BitNot"),
str8_lit_comp("Mul"),
str8_lit_comp("Div"),
str8_lit_comp("Mod"),
str8_lit_comp("Add"),
str8_lit_comp("Sub"),
str8_lit_comp("LShift"),
str8_lit_comp("RShift"),
str8_lit_comp("Less"),
str8_lit_comp("LsEq"),
str8_lit_comp("Grtr"),
str8_lit_comp("GrEq"),
str8_lit_comp("EqEq"),
str8_lit_comp("NtEq"),
str8_lit_comp("BitAnd"),
str8_lit_comp("BitXor"),
str8_lit_comp("BitOr"),
str8_lit_comp("LogAnd"),
str8_lit_comp("LogOr"),
str8_lit_comp("Ternary"),
str8_lit_comp("LeafBytecode"),
str8_lit_comp("LeafMember"),
str8_lit_comp("LeafU64"),
str8_lit_comp("LeafF64"),
str8_lit_comp("LeafF32"),
str8_lit_comp("TypeIdent"),
str8_lit_comp("Ptr"),
str8_lit_comp("Array"),
str8_lit_comp("Func"),
str8_lit_comp("Define"),
str8_lit_comp("LeafIdent"),
};
String8 eval_result_code_display_strings[11] =
{
str8_lit_comp(""),
str8_lit_comp("Cannot divide by zero."),
str8_lit_comp("Invalid operation."),
str8_lit_comp("Invalid operation types."),
str8_lit_comp("Failed memory read."),
str8_lit_comp("Failed register read."),
str8_lit_comp("Invalid frame base address."),
str8_lit_comp("Invalid module base address."),
str8_lit_comp("Invalid thread-local storage base address."),
str8_lit_comp("Insufficient evaluation machine stack space."),
str8_lit_comp("Malformed bytecode."),
};
String8 eval_expr_op_strings[40] =
{
str8_lit_comp(""),
str8_lit_comp("[]"),
str8_lit_comp("."),
str8_lit_comp("*"),
str8_lit_comp("&"),
str8_lit_comp("cast"),
str8_lit_comp("sizeof"),
str8_lit_comp("-"),
str8_lit_comp("!"),
str8_lit_comp("~"),
str8_lit_comp("*"),
str8_lit_comp("/"),
str8_lit_comp("%"),
str8_lit_comp("+"),
str8_lit_comp("-"),
str8_lit_comp("<<"),
str8_lit_comp(">>"),
str8_lit_comp("<"),
str8_lit_comp("<="),
str8_lit_comp(">"),
str8_lit_comp(">="),
str8_lit_comp("=="),
str8_lit_comp("!="),
str8_lit_comp("&"),
str8_lit_comp("^"),
str8_lit_comp("|"),
str8_lit_comp("&&"),
str8_lit_comp("||"),
str8_lit_comp("? "),
str8_lit_comp("bytecode"),
str8_lit_comp("member"),
str8_lit_comp("U64"),
str8_lit_comp("F64"),
str8_lit_comp("F32"),
str8_lit_comp("type_ident"),
str8_lit_comp("ptr"),
str8_lit_comp("array"),
str8_lit_comp("function"),
str8_lit_comp("="),
str8_lit_comp("leaf_ident"),
};
C_LINKAGE_END
+24 -130
View File
@@ -7,8 +7,9 @@
#define EVAL_META_H
typedef U32 EVAL_ExprKind;
enum
typedef enum EVAL_ExprKindEnum
{
EVAL_ExprKind_Nil,
EVAL_ExprKind_ArrayIndex,
EVAL_ExprKind_MemberAccess,
EVAL_ExprKind_Deref,
@@ -48,137 +49,30 @@ EVAL_ExprKind_Array,
EVAL_ExprKind_Func,
EVAL_ExprKind_Define,
EVAL_ExprKind_LeafIdent,
EVAL_ExprKind_COUNT
};
EVAL_ExprKind_COUNT,
} EVAL_ExprKindEnum;
U8 eval_expr_kind_child_counts[] =
typedef enum EVAL_ResultCode
{
2,
2,
1,
1,
2,
1,
1,
1,
1,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
3,
0,
0,
0,
0,
0,
0,
1,
2,
1,
2,
0,
};
String8 eval_expr_kind_strings[] =
{
str8_lit_comp("ArrayIndex"),
str8_lit_comp("MemberAccess"),
str8_lit_comp("Deref"),
str8_lit_comp("Address"),
str8_lit_comp("Cast"),
str8_lit_comp("Sizeof"),
str8_lit_comp("Neg"),
str8_lit_comp("LogNot"),
str8_lit_comp("BitNot"),
str8_lit_comp("Mul"),
str8_lit_comp("Div"),
str8_lit_comp("Mod"),
str8_lit_comp("Add"),
str8_lit_comp("Sub"),
str8_lit_comp("LShift"),
str8_lit_comp("RShift"),
str8_lit_comp("Less"),
str8_lit_comp("LsEq"),
str8_lit_comp("Grtr"),
str8_lit_comp("GrEq"),
str8_lit_comp("EqEq"),
str8_lit_comp("NtEq"),
str8_lit_comp("BitAnd"),
str8_lit_comp("BitXor"),
str8_lit_comp("BitOr"),
str8_lit_comp("LogAnd"),
str8_lit_comp("LogOr"),
str8_lit_comp("Ternary"),
str8_lit_comp("LeafBytecode"),
str8_lit_comp("LeafMember"),
str8_lit_comp("LeafU64"),
str8_lit_comp("LeafF64"),
str8_lit_comp("LeafF32"),
str8_lit_comp("TypeIdent"),
str8_lit_comp("Ptr"),
str8_lit_comp("Array"),
str8_lit_comp("Func"),
str8_lit_comp("Define"),
str8_lit_comp("LeafIdent"),
};
String8 eval_expr_op_strings[] =
{
str8_lit_comp("[]"),
str8_lit_comp("."),
str8_lit_comp("*"),
str8_lit_comp("&"),
str8_lit_comp("cast"),
str8_lit_comp("sizeof"),
str8_lit_comp("-"),
str8_lit_comp("!"),
str8_lit_comp("~"),
str8_lit_comp("*"),
str8_lit_comp("/"),
str8_lit_comp("%"),
str8_lit_comp("+"),
str8_lit_comp("-"),
str8_lit_comp("<<"),
str8_lit_comp(">>"),
str8_lit_comp("<"),
str8_lit_comp("<="),
str8_lit_comp(">"),
str8_lit_comp(">="),
str8_lit_comp("=="),
str8_lit_comp("!="),
str8_lit_comp("&"),
str8_lit_comp("^"),
str8_lit_comp("|"),
str8_lit_comp("&&"),
str8_lit_comp("||"),
str8_lit_comp("? "),
str8_lit_comp("bytecode"),
str8_lit_comp("member"),
str8_lit_comp("U64"),
str8_lit_comp("F64"),
str8_lit_comp("F32"),
str8_lit_comp("type_ident"),
str8_lit_comp("ptr"),
str8_lit_comp("array"),
str8_lit_comp("function"),
str8_lit_comp("="),
str8_lit_comp("leaf_ident"),
};
EVAL_ResultCode_Good,
EVAL_ResultCode_DivideByZero,
EVAL_ResultCode_BadOp,
EVAL_ResultCode_BadOpTypes,
EVAL_ResultCode_BadMemRead,
EVAL_ResultCode_BadRegRead,
EVAL_ResultCode_BadFrameBase,
EVAL_ResultCode_BadModuleBase,
EVAL_ResultCode_BadTLSBase,
EVAL_ResultCode_InsufficientStackSpace,
EVAL_ResultCode_MalformedBytecode,
EVAL_ResultCode_COUNT,
} EVAL_ResultCode;
C_LINKAGE_BEGIN
extern U8 eval_expr_kind_child_counts[40];
extern String8 eval_expr_kind_strings[40];
extern String8 eval_result_code_display_strings[11];
extern String8 eval_expr_op_strings[40];
C_LINKAGE_END
#endif // EVAL_META_H
+132 -54
View File
@@ -11,7 +11,7 @@ fs_init(void)
fs_shared = push_array(arena, FS_Shared, 1);
fs_shared->arena = arena;
fs_shared->slots_count = 1024;
fs_shared->stripes_count = 64;
fs_shared->stripes_count = os_logical_core_count();
fs_shared->slots = push_array(arena, FS_Slot, fs_shared->slots_count);
fs_shared->stripes = push_array(arena, FS_Stripe, fs_shared->stripes_count);
for(U64 idx = 0; idx < fs_shared->stripes_count; idx += 1)
@@ -30,61 +30,78 @@ fs_init(void)
{
fs_shared->streamers[idx] = os_launch_thread(fs_streamer_thread__entry_point, (void *)idx, 0);
}
fs_shared->detector_thread = os_launch_thread(fs_detector_thread__entry_point, 0, 0);
}
////////////////////////////////
//~ rjf: Cache Interaction
internal U128
fs_hash_from_path(String8 path, U64 rewind_count, U64 endt_us)
fs_hash_from_path(String8 path, U64 endt_us)
{
Temp scratch = scratch_begin(0, 0);
U128 result = {0};
path = path_normalized_from_string(scratch.arena, path);
U128 path_key = hs_hash_from_data(path);
U128 result = hs_hash_from_key(path_key, rewind_count);
if(u128_match(result, u128_zero()))
for(U64 rewind_idx = 0; rewind_idx < 2; rewind_idx += 1)
{
U64 slot_idx = path_key.u64[0]%fs_shared->slots_count;
U64 stripe_idx = slot_idx%fs_shared->stripes_count;
FS_Slot *slot = &fs_shared->slots[slot_idx];
FS_Stripe *stripe = &fs_shared->stripes[stripe_idx];
OS_MutexScopeR(stripe->rw_mutex) for(;;)
result = hs_hash_from_key(path_key, rewind_idx);
if(!u128_match(result, u128_zero()))
{
FS_Node *node = 0;
for(FS_Node *n = slot->first; n != 0; n = n->next)
break;
}
else if(u128_match(result, u128_zero()) && rewind_idx == 0)
{
U64 slot_idx = path_key.u64[0]%fs_shared->slots_count;
U64 stripe_idx = slot_idx%fs_shared->stripes_count;
FS_Slot *slot = &fs_shared->slots[slot_idx];
FS_Stripe *stripe = &fs_shared->stripes[stripe_idx];
OS_MutexScopeR(stripe->rw_mutex) for(;;)
{
if(str8_match(path, n->path, 0))
FS_Node *node = 0;
for(FS_Node *n = slot->first; n != 0; n = n->next)
{
if(str8_match(path, n->path, 0))
{
node = n;
break;
}
}
if(node == 0) OS_MutexScopeRWPromote(stripe->rw_mutex)
{
node = push_array(stripe->arena, FS_Node, 1);
SLLQueuePush(slot->first, slot->last, node);
node->path = push_str8_copy(stripe->arena, path);
}
if(!ins_atomic_u32_eval_cond_assign(&node->is_working, 1, 0) &&
!fs_u2s_enqueue_path(path, endt_us))
{
ins_atomic_u32_eval_assign(&node->is_working, 0);
}
result = hs_hash_from_key(path_key, 0);
if(u128_match(result, u128_zero()) && os_now_microseconds() <= endt_us)
{
os_condition_variable_wait_rw_r(stripe->cv, stripe->rw_mutex, endt_us);
}
else
{
node = n;
break;
}
}
if(node == 0) OS_MutexScopeRWPromote(stripe->rw_mutex)
{
node = push_array(stripe->arena, FS_Node, 1);
SLLQueuePush(slot->first, slot->last, node);
node->path = push_str8_copy(stripe->arena, path);
}
if(os_now_microseconds() >= ins_atomic_u64_eval(&node->last_time_requested_us)+1000000 &&
fs_u2s_enqueue_path(path, endt_us))
{
ins_atomic_u64_eval_assign(&node->last_time_requested_us, os_now_microseconds());
}
result = hs_hash_from_key(path_key, rewind_count);
if(u128_match(result, u128_zero()) && os_now_microseconds() <= endt_us)
{
os_condition_variable_wait_rw_r(stripe->cv, stripe->rw_mutex, endt_us);
}
else
{
break;
}
}
}
scratch_end(scratch);
return result;
}
internal U128
fs_key_from_path(String8 path)
{
U128 key = hs_hash_from_data(path);
fs_hash_from_path(path, 0);
return key;
}
////////////////////////////////
//~ rjf: Streamer Threads
@@ -140,53 +157,114 @@ fs_u2s_dequeue_path(Arena *arena)
internal void
fs_streamer_thread__entry_point(void *p)
{
TCTX tctx_;
tctx_init_and_equip(&tctx_);
ThreadName("[fs] streamer #%I64u", (U64)p);
ThreadNameF("[fs] streamer #%I64u", (U64)p);
for(;;)
{
Temp scratch = scratch_begin(0, 0);
//- rjf: unpack path
String8 path = fs_u2s_dequeue_path(scratch.arena);
U128 key = hs_hash_from_data(path);
U64 slot_idx = key.u64[0]%fs_shared->slots_count;
U64 stripe_idx = slot_idx%fs_shared->stripes_count;
FS_Slot *slot = &fs_shared->slots[slot_idx];
FS_Stripe *stripe = &fs_shared->stripes[stripe_idx];
//- rjf: load
ProfBegin("load \"%.*s\"", str8_varg(path));
FileProperties pre_props = os_properties_from_file_path(path);
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite, path);
U64 data_arena_size = pre_props.size+ARENA_HEADER_SIZE;
data_arena_size += KB(4)-1;
data_arena_size -= data_arena_size%KB(4);
ProfBegin("allocate");
Arena *data_arena = arena_alloc__sized(data_arena_size, data_arena_size);
ProfEnd();
ProfBegin("read");
String8 data = os_string_from_file_range(data_arena, file, r1u64(0, pre_props.size));
ProfEnd();
os_file_close(file);
FileProperties post_props = os_properties_from_file_path(path);
//- rjf: abort if modification timestamps differ - we did not successfully read the file
if(pre_props.modified != post_props.modified)
{
arena_release(data_arena);
MemoryZeroStruct(&data);
ProfScope("abort")
{
arena_release(data_arena);
MemoryZeroStruct(&data);
data_arena = 0;
}
}
//- rjf: submit
else
{
U128 key = hs_hash_from_data(path);
hs_submit_data(key, &data_arena, data);
U64 slot_idx = key.u64[0]%fs_shared->slots_count;
U64 stripe_idx = slot_idx%fs_shared->stripes_count;
FS_Slot *slot = &fs_shared->slots[slot_idx];
FS_Stripe *stripe = &fs_shared->stripes[stripe_idx];
OS_MutexScopeW(stripe->rw_mutex)
ProfScope("submit")
{
FS_Node *node = 0;
for(FS_Node *n = slot->first; n != 0; n = n->next)
hs_submit_data(key, &data_arena, data);
}
}
//- rjf: commit info to cache
ProfScope("commit to cache") OS_MutexScopeW(stripe->rw_mutex)
{
FS_Node *node = 0;
for(FS_Node *n = slot->first; n != 0; n = n->next)
{
if(str8_match(n->path, path, 0))
{
if(str8_match(n->path, path, 0))
{
node = n;
break;
}
node = n;
break;
}
if(node != 0)
}
if(node != 0)
{
if(post_props.modified == pre_props.modified)
{
node->timestamp = post_props.modified;
}
ins_atomic_u32_eval_assign(&node->is_working, 0);
}
os_condition_variable_broadcast(stripe->cv);
}
os_condition_variable_broadcast(stripe->cv);
ProfEnd();
scratch_end(scratch);
}
}
////////////////////////////////
//~ rjf: Change Detector Thread
internal void
fs_detector_thread__entry_point(void *p)
{
ThreadNameF("[fs] detector");
for(;;)
{
U64 slots_per_stripe = fs_shared->slots_count/fs_shared->stripes_count;
for(U64 stripe_idx = 0; stripe_idx < fs_shared->stripes_count; stripe_idx += 1)
{
FS_Stripe *stripe = &fs_shared->stripes[stripe_idx];
OS_MutexScopeR(stripe->rw_mutex) for(U64 slot_in_stripe_idx = 0; slot_in_stripe_idx < slots_per_stripe; slot_in_stripe_idx += 1)
{
U64 slot_idx = stripe_idx*slots_per_stripe + slot_in_stripe_idx;
FS_Slot *slot = &fs_shared->slots[slot_idx];
for(FS_Node *n = slot->first; n != 0; n = n->next)
{
FileProperties props = os_properties_from_file_path(n->path);
if(props.modified != n->timestamp)
{
if(!ins_atomic_u32_eval_cond_assign(&n->is_working, 1, 0) &&
!fs_u2s_enqueue_path(n->path, os_now_microseconds()+100000))
{
ins_atomic_u32_eval_assign(&n->is_working, 0);
}
}
}
}
}
os_sleep_milliseconds(100);
}
}

Some files were not shown because too many files have changed in this diff Show More