Merge remote-tracking branch 'EpicGamesExt/dev'

This commit is contained in:
ed
2025-05-20 22:08:31 -04:00
297 changed files with 66737 additions and 50022 deletions
+14 -10
View File
@@ -13,6 +13,19 @@ jobs:
runs-on: windows-2022 runs-on: windows-2022
strategy: strategy:
fail-fast: false fail-fast: false
matrix:
target:
- raddbg
- radlink
- rdi_from_pdb
- raddump
- rdi_breakpad_from_pdb
compiler:
- msvc
- clang
mode:
- debug
- release
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
@@ -20,13 +33,4 @@ jobs:
shell: cmd shell: cmd
run: | run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 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 ${{ matrix.target }} ${{ matrix.compiler }} ${{ matrix.mode }} || exit /b 1
call build rdi_from_pdb msvc debug || exit /b 1
call build rdi_from_dwarf msvc debug || exit /b 1
call build rdi_dump msvc debug || exit /b 1
call build raddbg clang debug || exit /b 1
call build rdi_from_pdb clang debug || exit /b 1
call build rdi_from_dwarf clang debug || exit /b 1
call build rdi_dump clang debug || exit /b 1
call build radlink msvc debug || exit /b 1
call build radlink clang debug || exit /b 1
+14 -3
View File
@@ -90,10 +90,11 @@ You should see the following output:
``` ```
[debug mode] [debug mode]
[msvc compile] [msvc compile]
[default mode, assuming `raddbg` build]
metagen_main.c metagen_main.c
searching C:\devel\raddebugger/src... 309 files found searching C:\devel\raddebugger/src... 447 files found
parsing metadesk... 15 metadesk files parsed parsing metadesk... 14 metadesk files parsed
gathering tables... 96 tables found gathering tables... 93 tables found
generating layer code... generating layer code...
raddbg_main.c raddbg_main.c
``` ```
@@ -101,6 +102,16 @@ raddbg_main.c
If everything worked correctly, there will be a `build` folder in the root If everything worked correctly, there will be a `build` folder in the root
level of the codebase, and it will contain a freshly-built `raddbg.exe`. level of the codebase, and it will contain a freshly-built `raddbg.exe`.
This `raddbg.exe` will have been built in **debug mode**, which is not built
with optimizations, and may perform worse. To produce a
**release mode executable**, run `build.bat` with a `release` argument:
```
build release
```
This build will take significantly longer.
## Short-To-Medium-Term Roadmap ## Short-To-Medium-Term Roadmap
### The Initial Alpha Battle-Testing Phase ### The Initial Alpha Battle-Testing Phase
+10 -7
View File
@@ -40,6 +40,7 @@ if "%~1"=="release" if "%~2"=="" echo [default mode, assuming `raddbg` build] &&
set auto_compile_flags= set auto_compile_flags=
if "%telemetry%"=="1" set auto_compile_flags=%auto_compile_flags% -DPROFILE_TELEMETRY=1 && echo [telemetry profiling enabled] if "%telemetry%"=="1" set auto_compile_flags=%auto_compile_flags% -DPROFILE_TELEMETRY=1 && echo [telemetry profiling enabled]
if "%asan%"=="1" set auto_compile_flags=%auto_compile_flags% -fsanitize=address && echo [asan enabled] if "%asan%"=="1" set auto_compile_flags=%auto_compile_flags% -fsanitize=address && echo [asan enabled]
if "%opengl%"=="1" set auto_compile_flags=%auto_compile_flags% -DR_BACKEND=R_BACKEND_OPENGL && echo [opengl render backend]
:: --- Compile/Link Line Definitions ------------------------------------------ :: --- Compile/Link Line Definitions ------------------------------------------
set cl_common= /I..\src\ /I..\local\ /nologo /FC /Z7 set cl_common= /I..\src\ /I..\local\ /nologo /FC /Z7
@@ -52,14 +53,14 @@ set cl_link= /link /MANIFEST:EMBED /INCREMENTAL:NO /pdbaltpath:%%%%_PDB%%%
set clang_link= -fuse-ld=lld -Xlinker /MANIFEST:EMBED -Xlinker /pdbaltpath:%%%%_PDB%%%% -Xlinker /NATVIS:"%~dp0\src\natvis\base.natvis" set clang_link= -fuse-ld=lld -Xlinker /MANIFEST:EMBED -Xlinker /pdbaltpath:%%%%_PDB%%%% -Xlinker /NATVIS:"%~dp0\src\natvis\base.natvis"
set cl_out= /out: set cl_out= /out:
set clang_out= -o set clang_out= -o
set cl_natvis= /NATVIS: set cl_linker=
set clang_natvis= -Xlinker /NATVIS: set clang_linker= -Xlinker
:: --- Per-Build Settings ----------------------------------------------------- :: --- Per-Build Settings -----------------------------------------------------
set link_dll=-DLL set link_dll=-DLL
set link_icon=logo.res set link_icon=logo.res
if "%msvc%"=="1" set link_natvis=%cl_natvis% if "%msvc%"=="1" set linker=%cl_linker%
if "%clang%"=="1" set link_natvis=%clang_natvis% if "%clang%"=="1" set linker=%clang_linker%
if "%msvc%"=="1" set only_compile=/c if "%msvc%"=="1" set only_compile=/c
if "%clang%"=="1" set only_compile=-c if "%clang%"=="1" set only_compile=-c
if "%msvc%"=="1" set EHsc=/EHsc if "%msvc%"=="1" set EHsc=/EHsc
@@ -106,18 +107,20 @@ if not "%no_meta%"=="1" (
:: --- Build Everything (@build_targets) -------------------------------------- :: --- Build Everything (@build_targets) --------------------------------------
pushd build pushd build
if "%raddbg%"=="1" set didbuild=1 && %compile% ..\src\raddbg\raddbg_main.c %compile_link% %link_icon% %out%raddbg.exe || exit /b 1 if "%raddbg%"=="1" set didbuild=1 && %compile% ..\src\raddbg\raddbg_main.c %compile_link% %link_icon% %out%raddbg.exe || exit /b 1
if "%radlink%"=="1" set didbuild=1 && %compile% ..\src\linker\lnk.c %compile_link% %link_natvis%"%~dp0\src\linker\linker.natvis" %out%radlink.exe || exit /b 1 if "%radlink%"=="1" set didbuild=1 && %compile% ..\src\linker\lnk.c %compile_link% %linker% /NOIMPLIB %linker% /NATVIS:"%~dp0\src\linker\linker.natvis" %out%radlink.exe || exit /b 1
if "%radcon%"=="1" set didbuild=1 && %compile% ..\src\radcon\radcon_main.c %compile_link% %out%radcon.exe || exit /b 1
if "%raddump%"=="1" set didbuild=1 && %compile% ..\src\raddump\raddump_main.c %compile_link% %out%raddump.exe || exit /b 1 if "%raddump%"=="1" set didbuild=1 && %compile% ..\src\raddump\raddump_main.c %compile_link% %out%raddump.exe || exit /b 1
if "%rdi_from_pdb%"=="1" set didbuild=1 && %compile% ..\src\rdi_from_pdb\rdi_from_pdb_main.c %compile_link% %out%rdi_from_pdb.exe || exit /b 1 if "%rdi_from_pdb%"=="1" set didbuild=1 && %compile% ..\src\rdi_from_pdb\rdi_from_pdb_main.c %compile_link% %out%rdi_from_pdb.exe || exit /b 1
if "%rdi_from_dwarf%"=="1" set didbuild=1 && %compile% ..\src\rdi_from_dwarf\rdi_from_dwarf.c %compile_link% %out%rdi_from_dwarf.exe || exit /b 1 if "%rdi_from_dwarf%"=="1" set didbuild=1 && %compile% ..\src\rdi_from_dwarf\rdi_from_dwarf_main.c %compile_link% %out%rdi_from_dwarf.exe || exit /b 1
if "%rdi_dump%"=="1" set didbuild=1 && %compile% ..\src\rdi_dump\rdi_dump_main.c %compile_link% %out%rdi_dump.exe || exit /b 1
if "%rdi_breakpad_from_pdb%"=="1" set didbuild=1 && %compile% ..\src\rdi_breakpad_from_pdb\rdi_breakpad_from_pdb_main.c %compile_link% %out%rdi_breakpad_from_pdb.exe || exit /b 1 if "%rdi_breakpad_from_pdb%"=="1" set didbuild=1 && %compile% ..\src\rdi_breakpad_from_pdb\rdi_breakpad_from_pdb_main.c %compile_link% %out%rdi_breakpad_from_pdb.exe || exit /b 1
if "%tester%"=="1" set didbuild=1 && %compile% ..\src\tester\tester_main.c %compile_link% %out%tester.exe || exit /b 1 if "%tester%"=="1" set didbuild=1 && %compile% ..\src\tester\tester_main.c %compile_link% %out%tester.exe || exit /b 1
if "%ryan_scratch%"=="1" set didbuild=1 && %compile% ..\src\scratch\ryan_scratch.c %compile_link% %out%ryan_scratch.exe || exit /b 1 if "%ryan_scratch%"=="1" set didbuild=1 && %compile% ..\src\scratch\ryan_scratch.c %compile_link% %out%ryan_scratch.exe || exit /b 1
if "%eval_scratch%"=="1" set didbuild=1 && %compile% ..\src\scratch\eval_scratch.c %compile_link% %out%eval_scratch.exe || exit /b 1
if "%textperf%"=="1" set didbuild=1 && %compile% ..\src\scratch\textperf.c %compile_link% %out%textperf.exe || exit /b 1 if "%textperf%"=="1" set didbuild=1 && %compile% ..\src\scratch\textperf.c %compile_link% %out%textperf.exe || exit /b 1
if "%convertperf%"=="1" set didbuild=1 && %compile% ..\src\scratch\convertperf.c %compile_link% %out%convertperf.exe || exit /b 1 if "%convertperf%"=="1" set didbuild=1 && %compile% ..\src\scratch\convertperf.c %compile_link% %out%convertperf.exe || exit /b 1
if "%debugstringperf%"=="1" set didbuild=1 && %compile% ..\src\scratch\debugstringperf.c %compile_link% %out%debugstringperf.exe || exit /b 1 if "%debugstringperf%"=="1" set didbuild=1 && %compile% ..\src\scratch\debugstringperf.c %compile_link% %out%debugstringperf.exe || exit /b 1
if "%parse_inline_sites%"=="1" set didbuild=1 && %compile% ..\src\scratch\parse_inline_sites.c %compile_link% %out%parse_inline_sites.exe || exit /b 1 if "%parse_inline_sites%"=="1" set didbuild=1 && %compile% ..\src\scratch\parse_inline_sites.c %compile_link% %out%parse_inline_sites.exe || exit /b 1
if "%strip_lib_debug%"=="1" set didbuild=1 && %compile% ..\src\strip_lib_debug\strip_lib_debug.c %compile_link% %out%strip_lib_debug.exe || exit /b 1
if "%mule_main%"=="1" set didbuild=1 && del vc*.pdb mule*.pdb && %compile_release% %only_compile% ..\src\mule\mule_inline.cpp && %compile_release% %only_compile% ..\src\mule\mule_o2.cpp && %compile_debug% %EHsc% ..\src\mule\mule_main.cpp ..\src\mule\mule_c.c mule_inline.obj mule_o2.obj %compile_link% %no_aslr% %out%mule_main.exe || exit /b 1 if "%mule_main%"=="1" set didbuild=1 && del vc*.pdb mule*.pdb && %compile_release% %only_compile% ..\src\mule\mule_inline.cpp && %compile_release% %only_compile% ..\src\mule\mule_o2.cpp && %compile_debug% %EHsc% ..\src\mule\mule_main.cpp ..\src\mule\mule_c.c mule_inline.obj mule_o2.obj %compile_link% %no_aslr% %out%mule_main.exe || exit /b 1
if "%mule_module%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_module.cpp %compile_link% %link_dll% %out%mule_module.dll || exit /b 1 if "%mule_module%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_module.cpp %compile_link% %link_dll% %out%mule_module.dll || exit /b 1
if "%mule_hotload%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_hotload_main.c %compile_link% %out%mule_hotload.exe & %compile% ..\src\mule\mule_hotload_module_main.c %compile_link% %link_dll% %out%mule_hotload_module.dll || exit /b 1 if "%mule_hotload%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_hotload_main.c %compile_link% %out%mule_hotload.exe & %compile% ..\src\mule\mule_hotload_module_main.c %compile_link% %link_dll% %out%mule_hotload_module.dll || exit /b 1
+6 -4
View File
@@ -15,11 +15,11 @@ if [ -v gcc ]; then compiler="${CC:-gcc}"; echo "[gcc compile]"; fi
auto_compile_flags='' auto_compile_flags=''
# --- Get Current Git Commit Id ----------------------------------------------- # --- Get Current Git Commit Id -----------------------------------------------
git_hash=$(git rev-parse HEAD) git_hash=$(git describe --always --dirty)
git_hash_full=$(git rev-parse HEAD) git_hash_full=$(git rev-parse HEAD)
# --- Compile/Link Line Definitions ------------------------------------------- # --- Compile/Link Line Definitions -------------------------------------------
clang_common="-I../src/ -I../local/ -g -DBUILD_GIT_HASH=\"$git_hash\" -DBUILD_GIT_HASH_FULL=\"$git_hash_full\" -Wno-unknown-warning-option -fdiagnostics-absolute-paths -Wall -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 -Wno-compare-distinct-pointer-types -Wno-initializer-overrides -Wno-incompatible-pointer-types-discards-qualifiers -Wno-for-loop-analysis -Xclang -flto-visibility-public-std -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf" clang_common="-I../src/ -I/usr/include/freetype2/ -I../local/ -g -DBUILD_GIT_HASH=\"$git_hash\" -DBUILD_GIT_HASH_FULL=\"$git_hash_full\" -Wno-unknown-warning-option -fdiagnostics-absolute-paths -Wall -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 -Wno-compare-distinct-pointer-types -Wno-initializer-overrides -Wno-incompatible-pointer-types-discards-qualifiers -Wno-for-loop-analysis -Xclang -flto-visibility-public-std -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf"
clang_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${clang_common} ${auto_compile_flags}" clang_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${clang_common} ${auto_compile_flags}"
clang_release="$compiler -g -O2 -DBUILD_DEBUG=0 ${clang_common} ${auto_compile_flags}" clang_release="$compiler -g -O2 -DBUILD_DEBUG=0 ${clang_common} ${auto_compile_flags}"
clang_link="-lpthread -lm -lrt -ldl" clang_link="-lpthread -lm -lrt -ldl"
@@ -33,6 +33,8 @@ gcc_out="-o"
# --- Per-Build Settings ------------------------------------------------------ # --- Per-Build Settings ------------------------------------------------------
link_dll="-fPIC" link_dll="-fPIC"
link_os_gfx="-lX11 -lXext" link_os_gfx="-lX11 -lXext"
link_render="-lGL -lEGL"
link_font_provider="-lfreetype"
# --- Choose Compile/Link Lines ----------------------------------------------- # --- Choose Compile/Link Lines -----------------------------------------------
if [ -v gcc ]; then compile_debug="$gcc_debug"; fi if [ -v gcc ]; then compile_debug="$gcc_debug"; fi
@@ -62,13 +64,13 @@ fi
# --- Build Everything (@build_targets) --------------------------------------- # --- Build Everything (@build_targets) ---------------------------------------
cd build cd build
if [ -v raddbg ]; then didbuild=1 && $compile ../src/raddbg/raddbg_main.c $compile_link $link_os_gfx $out raddbg; fi if [ -v raddbg ]; then didbuild=1 && $compile ../src/raddbg/raddbg_main.c $compile_link $link_os_gfx $link_render $link_font_provider $out raddbg; fi
if [ -v radlink ]; then didbuild=1 && $compile ../src/linker/lnk.c $compile_link $out radlink; fi if [ -v radlink ]; then didbuild=1 && $compile ../src/linker/lnk.c $compile_link $out radlink; fi
if [ -v rdi_from_pdb ]; then didbuild=1 && $compile ../src/rdi_from_pdb/rdi_from_pdb_main.c $compile_link $out rdi_from_pdb; fi if [ -v rdi_from_pdb ]; then didbuild=1 && $compile ../src/rdi_from_pdb/rdi_from_pdb_main.c $compile_link $out rdi_from_pdb; fi
if [ -v rdi_from_dwarf ]; then didbuild=1 && $compile ../src/rdi_from_dwarf/rdi_from_dwarf.c $compile_link $out rdi_from_dwarf; fi if [ -v rdi_from_dwarf ]; then didbuild=1 && $compile ../src/rdi_from_dwarf/rdi_from_dwarf.c $compile_link $out rdi_from_dwarf; fi
if [ -v rdi_dump ]; then didbuild=1 && $compile ../src/rdi_dump/rdi_dump_main.c $compile_link $out rdi_dump; fi if [ -v rdi_dump ]; then didbuild=1 && $compile ../src/rdi_dump/rdi_dump_main.c $compile_link $out rdi_dump; fi
if [ -v rdi_breakpad_from_pdb ]; then didbuild=1 && $compile ../src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c $compile_link $out rdi_breakpad_from_pdb; fi if [ -v rdi_breakpad_from_pdb ]; then didbuild=1 && $compile ../src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c $compile_link $out rdi_breakpad_from_pdb; fi
if [ -v ryan_scratch ]; then didbuild=1 && $compile ../src/scratch/ryan_scratch.c $compile_link $link_os_gfx $out ryan_scratch; fi if [ -v ryan_scratch ]; then didbuild=1 && $compile ../src/scratch/ryan_scratch.c $compile_link $link_os_gfx $link_render $link_font_provider $out ryan_scratch; fi
cd .. cd ..
# --- Warn On No Builds ------------------------------------------------------- # --- Warn On No Builds -------------------------------------------------------
BIN
View File
Binary file not shown.
+14 -6
View File
@@ -45,12 +45,20 @@ load_paths =
commands = commands =
{ {
//- rjf: fkey command slots (change locally but do not commit) //- rjf: [raddbg]
.f1 = { .win = "build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.f2 = { .win = "build rdi_from_pdb", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.f3 = { .win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --project:local_dev.raddbg_project --xuto_run && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [textperf]
// .f1 = { .win = "build textperf release telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta telemetry textperf && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
// .f3 = { .win = "pushd build && textperf.exe --capture && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
//- rjf: [tester]
// .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta tester", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
//- rjf: running target
.f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
// .f3 = { .win = "pushd build && raddbg --user:dev.raddbg_user && popd", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
// .f3 = { .win = "C:/devel/raddebugger/build/raddbg.exe --capture --user:C:/devel/raddebugger/build/local_dev.raddbg_user --project:C:/devel/raddebugger/build/local_dev.raddbg_project", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
// .f3 = { .win = "wsl_launch /mnt/c/devel/raddebugger/build/raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
//- rjf: local target builds //- rjf: local target builds
.build_raddbg = { .win = "build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .build_raddbg = { .win = "build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
+12 -3
View File
@@ -1,6 +1,9 @@
// Copyright (c) 2024 Epic Games Tools // Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
#undef LAYER_COLOR
#define LAYER_COLOR 0x59b6c3ff
//////////////////////////////// ////////////////////////////////
//~ rjf: Top-Level Layer Initialization //~ rjf: Top-Level Layer Initialization
@@ -23,8 +26,9 @@ async_init(CmdLine *cmdline)
String8 work_thread_count_string = cmd_line_string(cmdline, str8_lit("work_threads_count")); String8 work_thread_count_string = cmd_line_string(cmdline, str8_lit("work_threads_count"));
if(work_thread_count_string.size == 0 || !try_u64_from_str8_c_rules(work_thread_count_string, &async_shared->work_threads_count)) if(work_thread_count_string.size == 0 || !try_u64_from_str8_c_rules(work_thread_count_string, &async_shared->work_threads_count))
{ {
async_shared->work_threads_count = Max(1, os_get_system_info()->logical_processor_count-1); async_shared->work_threads_count = Max(4, os_get_system_info()->logical_processor_count-1);
} }
async_shared->work_threads_count = Max(4, async_shared->work_threads_count);
async_shared->work_threads = push_array(arena, OS_Handle, async_shared->work_threads_count); async_shared->work_threads = push_array(arena, OS_Handle, async_shared->work_threads_count);
for EachIndex(idx, async_shared->work_threads_count) for EachIndex(idx, async_shared->work_threads_count)
{ {
@@ -57,6 +61,7 @@ async_push_work_(ASYNC_WorkFunctionType *work_function, ASYNC_WorkParams *params
work.output = params->output; work.output = params->output;
work.semaphore = params->semaphore; work.semaphore = params->semaphore;
work.completion_counter = params->completion_counter; work.completion_counter = params->completion_counter;
work.working_counter = params->working_counter;
// rjf: loop; try to write into user -> writer ring buffer. if we're on a // rjf: loop; try to write into user -> writer ring buffer. if we're on a
// worker thread, determine if we need to execute this task locally on this // worker thread, determine if we need to execute this task locally on this
@@ -159,7 +164,6 @@ async_task_join(ASYNC_Task *task)
internal ASYNC_Work internal ASYNC_Work
async_pop_work(void) async_pop_work(void)
{ {
ProfBeginFunction();
ASYNC_Work work = {0}; ASYNC_Work work = {0};
B32 done = 0; B32 done = 0;
ASYNC_Priority taken_priority = ASYNC_Priority_Low; ASYNC_Priority taken_priority = ASYNC_Priority_Low;
@@ -194,7 +198,6 @@ async_pop_work(void)
} }
os_condition_variable_broadcast(async_shared->ring_cv); os_condition_variable_broadcast(async_shared->ring_cv);
os_condition_variable_broadcast(async_shared->rings[taken_priority].ring_cv); os_condition_variable_broadcast(async_shared->rings[taken_priority].ring_cv);
ProfEnd();
return work; return work;
} }
@@ -223,6 +226,12 @@ async_execute_work(ASYNC_Work work)
{ {
ins_atomic_u64_inc_eval(work.completion_counter); ins_atomic_u64_inc_eval(work.completion_counter);
} }
//- rjf: decrement working counter
if(work.working_counter != 0)
{
ins_atomic_u64_dec_eval(work.working_counter);
}
} }
//////////////////////////////// ////////////////////////////////
+2
View File
@@ -29,6 +29,7 @@ struct ASYNC_WorkParams
void **output; void **output;
OS_Handle semaphore; OS_Handle semaphore;
U64 *completion_counter; U64 *completion_counter;
U64 *working_counter;
U64 endt_us; U64 endt_us;
ASYNC_Priority priority; ASYNC_Priority priority;
}; };
@@ -41,6 +42,7 @@ struct ASYNC_Work
void **output; void **output;
OS_Handle semaphore; OS_Handle semaphore;
U64 *completion_counter; U64 *completion_counter;
U64 *working_counter;
}; };
//////////////////////////////// ////////////////////////////////
+1 -1
View File
@@ -159,7 +159,7 @@
#endif #endif
#if !defined(BUILD_VERSION_PATCH) #if !defined(BUILD_VERSION_PATCH)
# define BUILD_VERSION_PATCH 15 # define BUILD_VERSION_PATCH 18
#endif #endif
#define BUILD_VERSION_STRING_LITERAL Stringify(BUILD_VERSION_MAJOR) "." Stringify(BUILD_VERSION_MINOR) "." Stringify(BUILD_VERSION_PATCH) #define BUILD_VERSION_STRING_LITERAL Stringify(BUILD_VERSION_MAJOR) "." Stringify(BUILD_VERSION_MINOR) "." Stringify(BUILD_VERSION_PATCH)
+34
View File
@@ -602,3 +602,37 @@ ring_read(U8 *ring_base, U64 ring_size, U64 ring_pos, void *dst_data, U64 read_s
} }
return read_size; return read_size;
} }
////////////////////////////////
internal U64
u64_array_bsearch(U64 *arr, U64 count, U64 value)
{
if(count > 1 && arr[0] <= value && value < arr[count-1])
{
U64 l = 0;
U64 r = count - 1;
for(; l <= r; )
{
U64 m = l + (r - l) / 2;
if(arr[m] == value)
{
return m;
}
else if(arr[m] < value)
{
l = m + 1;
}
else
{
r = m - 1;
}
}
}
else if (count == 1 && arr[0] == value)
{
return 0;
}
return max_U64;
}
+44 -7
View File
@@ -65,6 +65,14 @@
# define C_LINKAGE # define C_LINKAGE
#endif #endif
////////////////////////////////
//~ rjf: Versions
#define Version(major, minor, patch) (U64)((((U64)(major) & 0xffff) << 32) | ((((U64)(minor) & 0xffff) << 16)) | ((((U64)(patch) & 0xffff) << 0)))
#define MajorFromVersion(version) (((version) & 0xffff00000000ull) >> 32)
#define MinorFromVersion(version) (((version) & 0x0000ffff0000ull) >> 16)
#define PatchFromVersion(version) (((version) & 0x00000000ffffull) >> 0)
//////////////////////////////// ////////////////////////////////
//~ rjf: Units //~ rjf: Units
@@ -348,6 +356,9 @@ C_LINKAGE void __asan_unpoison_memory_region(void const volatile *addr, size_t s
#define IsPow2OrZero(x) ((((x) - 1)&(x)) == 0) #define IsPow2OrZero(x) ((((x) - 1)&(x)) == 0)
#define ExtractBit(word, idx) (((word) >> (idx)) & 1) #define ExtractBit(word, idx) (((word) >> (idx)) & 1)
#define Extract8(word, pos) (((word) >> ((pos)*8)) & max_U8)
#define Extract16(word, pos) (((word) >> ((pos)*16)) & max_U16)
#define Extract32(word, pos) (((word) >> ((pos)*32)) & max_U32)
#if LANG_CPP #if LANG_CPP
# define zero_struct {} # define zero_struct {}
@@ -379,11 +390,33 @@ typedef S64 B64;
typedef float F32; typedef float F32;
typedef double F64; typedef double F64;
typedef void VoidProc(void); typedef void VoidProc(void);
typedef struct U128 U128; typedef union U128 U128;
struct U128 union U128
{ {
U8 u8[16];
U16 u16[8];
U32 u32[4];
U64 u64[2]; U64 u64[2];
}; };
typedef union U256 U256;
union U256
{
U8 u8[32];
U16 u16[16];
U32 u32[8];
U64 u64[4];
U128 u128[2];
};
typedef union U512 U512;
union U512
{
U8 u8[64];
U16 u16[32];
U32 u32[16];
U64 u64[8];
U128 u128[4];
U256 u256[2];
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Basic Types & Spaces //~ rjf: Basic Types & Spaces
@@ -565,15 +598,15 @@ global U32 max_U32 = 0xffffffff;
global U16 max_U16 = 0xffff; global U16 max_U16 = 0xffff;
global U8 max_U8 = 0xff; global U8 max_U8 = 0xff;
global S64 max_S64 = (S64)0x7fffffffffffffffull; global S64 max_S64 = (S64)0x7fffffffffffffffll;
global S32 max_S32 = (S32)0x7fffffff; global S32 max_S32 = (S32)0x7fffffff;
global S16 max_S16 = (S16)0x7fff; global S16 max_S16 = (S16)0x7fff;
global S8 max_S8 = (S8)0x7f; global S8 max_S8 = (S8)0x7f;
global S64 min_S64 = (S64)0xffffffffffffffffull; global S64 min_S64 = (S64)0x8000000000000000ll;
global S32 min_S32 = (S32)0xffffffff; global S32 min_S32 = (S32)0x80000000;
global S16 min_S16 = (S16)0xffff; global S16 min_S16 = (S16)0x8000;
global S8 min_S8 = (S8)0xff; global S8 min_S8 = (S8)0x80;
global const U32 bitmask1 = 0x00000001; global const U32 bitmask1 = 0x00000001;
global const U32 bitmask2 = 0x00000003; global const U32 bitmask2 = 0x00000003;
@@ -885,4 +918,8 @@ internal U64 ring_read(U8 *ring_base, U64 ring_size, U64 ring_pos, void *dst_dat
#define quick_sort(ptr, count, element_size, cmp_function) qsort((ptr), (count), (element_size), (int (*)(const void *, const void *))(cmp_function)) #define quick_sort(ptr, count, element_size, cmp_function) qsort((ptr), (count), (element_size), (int (*)(const void *, const void *))(cmp_function))
////////////////////////////////
internal U64 u64_array_bsearch(U64 *arr, U64 count, U64 value);
#endif // BASE_CORE_H #endif // BASE_CORE_H
+3
View File
@@ -121,6 +121,9 @@ update(void)
{ {
ProfTick(0); ProfTick(0);
ins_atomic_u64_inc_eval(&global_update_tick_idx); ins_atomic_u64_inc_eval(&global_update_tick_idx);
#if defined(FONT_CACHE_H)
fnt_frame();
#endif
#if OS_FEATURE_GRAPHICAL #if OS_FEATURE_GRAPHICAL
B32 result = frame(); B32 result = frame();
#else #else
+2 -2
View File
@@ -4,8 +4,8 @@
//////////////////////////////// ////////////////////////////////
//~ rjf: Base Includes //~ rjf: Base Includes
#undef MARKUP_LAYER_COLOR #undef LAYER_COLOR
#define MARKUP_LAYER_COLOR 0.20f, 0.60f, 0.80f #define LAYER_COLOR 0.20f, 0.60f, 0.80f
#include "base_core.c" #include "base_core.c"
#include "base_profile.c" #include "base_profile.c"
+3 -3
View File
@@ -49,12 +49,12 @@ internal void log_select(Log *log);
internal void log_msg(LogMsgKind kind, String8 string); internal void log_msg(LogMsgKind kind, String8 string);
internal void log_msgf(LogMsgKind kind, char *fmt, ...); internal void log_msgf(LogMsgKind kind, char *fmt, ...);
#define log_info(s) log_msg(LogMsgKind_Info, (s)) #define log_info(s) log_msg(LogMsgKind_Info, (s))
#define log_infof(fmt, ...) log_msgf(LogMsgKind_Info, (fmt), __VA_ARGS__) #define log_infof(...) log_msgf(LogMsgKind_Info, __VA_ARGS__)
#define log_user_error(s) log_msg(LogMsgKind_UserError, (s)) #define log_user_error(s) log_msg(LogMsgKind_UserError, (s))
#define log_user_errorf(fmt, ...) log_msgf(LogMsgKind_UserError, (fmt), __VA_ARGS__) #define log_user_errorf(...) log_msgf(LogMsgKind_UserError, __VA_ARGS__)
#define LogInfoNamedBlock(s) DeferLoop(log_infof("%S:\n{\n", (s)), log_infof("}\n")) #define LogInfoNamedBlock(s) DeferLoop(log_infof("%S:\n{\n", (s)), log_infof("}\n"))
#define LogInfoNamedBlockF(fmt, ...) DeferLoop((log_infof(fmt, __VA_ARGS__), log_infof(":\n{\n")), log_infof("}\n")) #define LogInfoNamedBlockF(...) DeferLoop((log_infof(__VA_ARGS__), log_infof(":\n{\n")), log_infof("}\n"))
//////////////////////////////// ////////////////////////////////
//~ rjf: Log Scopes //~ rjf: Log Scopes
+12 -2
View File
@@ -4,9 +4,19 @@
#ifndef BASE_MARKUP_H #ifndef BASE_MARKUP_H
#define BASE_MARKUP_H #define BASE_MARKUP_H
#define RADDBG_MARKUP_IMPLEMENTATION
#define RADDBG_MARKUP_VSNPRINTF raddbg_vsnprintf
#if OS_LINUX
# define RADDBG_MARKUP_STUBS
#endif
#include "lib_raddbg_markup/raddbg_markup.h"
#if !defined(LAYER_COLOR)
# define LAYER_COLOR 0x404040ff
#endif
internal void set_thread_name(String8 string); internal void set_thread_name(String8 string);
internal void set_thread_namef(char *fmt, ...); internal void set_thread_namef(char *fmt, ...);
#define ThreadNameF(...) (set_thread_namef(__VA_ARGS__)) #define ThreadNameF(...) (set_thread_namef(__VA_ARGS__), raddbg_thread_color_u32(LAYER_COLOR))
#define ThreadName(str) (set_thread_name(str))
#endif // BASE_MARKUP_H #endif // BASE_MARKUP_H
+152 -7
View File
@@ -386,6 +386,21 @@ derotate_4x4f32(Mat4x4F32 mat)
return mat; return mat;
} }
internal Mat4x4F32
transpose_4x4f32(Mat4x4F32 mat)
{
Mat4x4F32 result =
{
{
mat.v[0][0], mat.v[1][0], mat.v[2][0], mat.v[3][0],
mat.v[0][1], mat.v[1][1], mat.v[2][1], mat.v[3][1],
mat.v[0][2], mat.v[1][2], mat.v[2][2], mat.v[3][2],
mat.v[0][3], mat.v[1][3], mat.v[2][3], mat.v[3][3],
}
};
return result;
}
//////////////////////////////// ////////////////////////////////
//~ rjf: Range Ops //~ rjf: Range Ops
@@ -480,7 +495,9 @@ internal Rng2F32 intersect_2f32(Rng2F32 a, Rng2F32 b) {Rng2F32 c; c.p0
internal Vec2F32 clamp_2f32(Rng2F32 r, Vec2F32 v) {v.x = Clamp(r.min.x, v.x, r.max.x); v.y = Clamp(r.min.y, v.y, r.max.y); return v;} internal Vec2F32 clamp_2f32(Rng2F32 r, Vec2F32 v) {v.x = Clamp(r.min.x, v.x, r.max.x); v.y = Clamp(r.min.y, v.y, r.max.y); return v;}
//////////////////////////////// ////////////////////////////////
//~ rjf: Miscellaneous Ops //~ rjf: Color Operations
//- rjf: hsv <-> rgb
internal Vec3F32 internal Vec3F32
hsv_from_rgb(Vec3F32 rgb) hsv_from_rgb(Vec3F32 rgb)
@@ -567,16 +584,102 @@ rgba_from_hsva(Vec4F32 hsva)
return rgba; return rgba;
} }
internal Vec4F32 //- rjf: srgb <-> linear
rgba_from_u32(U32 hex)
internal Vec3F32
linear_from_srgb(Vec3F32 srgb)
{ {
Vec4F32 result = v4f32(((hex&0xff000000)>>24)/255.f, Vec3F32 result;
((hex&0x00ff0000)>>16)/255.f, for EachElement(idx, srgb.v)
((hex&0x0000ff00)>> 8)/255.f, {
((hex&0x000000ff)>> 0)/255.f); result.v[idx] = (srgb.v[idx] < 0.0404482362771082f ? srgb.v[idx] / 12.92f : pow_f32((srgb.v[idx] + 0.055f) / 1.055f, 2.4f));
}
return result; return result;
} }
internal Vec3F32
srgb_from_linear(Vec3F32 linear)
{
Vec3F32 result;
for EachElement(idx, linear.v)
{
result.v[idx] = (0 <= linear.v[idx] && linear.v[idx] < 0.00313066844250063) ? linear.v[idx]*12.92f : 1.05f * pow_f32(linear.v[idx], 1.f/2.4f) - 0.055f;
}
return result;
}
internal Vec4F32
linear_from_srgba(Vec4F32 srgba)
{
Vec4F32 result;
result.xyz = linear_from_srgb(srgba.xyz);
result.w = srgba.w;
return result;
}
internal Vec4F32
srgba_from_linear(Vec4F32 linear)
{
Vec4F32 result;
result.xyz = srgb_from_linear(linear.xyz);
result.w = linear.w;
return result;
}
//- rjf: oklab <-> linear
internal Vec3F32
oklab_from_linear(Vec3F32 linear)
{
F32 l = (0.4122214708f * linear.x + 0.5363325363f * linear.y + 0.0514459929f * linear.z);
F32 m = (0.2119034982f * linear.x + 0.6806995451f * linear.y + 0.1073969566f * linear.z);
F32 s = (0.0883024619f * linear.x + 0.2817188376f * linear.y + 0.6299787005f * linear.z);
F32 l_ = cbrt_f32(l);
F32 m_ = cbrt_f32(m);
F32 s_ = cbrt_f32(s);
Vec3F32 result;
result.x = 0.2104542553f*l_ + 0.7936177850f*m_ - 0.0040720468f*s_;
result.y = 1.9779984951f*l_ - 2.4285922050f*m_ + 0.4505937099f*s_;
result.z = 0.0259040371f*l_ + 0.7827717662f*m_ - 0.8086757660f*s_;
return result;
}
internal Vec3F32
linear_from_oklab(Vec3F32 oklab)
{
F32 l_ = oklab.x + 0.3963377774f * oklab.y + 0.2158037573f * oklab.z;
F32 m_ = oklab.x - 0.1055613458f * oklab.y - 0.0638541728f * oklab.z;
F32 s_ = oklab.x - 0.0894841775f * oklab.y - 1.2914855480f * oklab.z;
F32 l = l_*l_*l_;
F32 m = m_*m_*m_;
F32 s = s_*s_*s_;
Vec3F32 result;
result.x = +4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s;
result.y = -1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s;
result.z = -0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s;
return result;
}
internal Vec4F32
oklab_from_lineara(Vec4F32 lineara)
{
Vec4F32 result;
result.xyz = oklab_from_linear(lineara.xyz);
result.w = lineara.w;
return result;
}
internal Vec4F32
lineara_from_oklab(Vec4F32 oklab)
{
Vec4F32 result;
result.xyz = linear_from_oklab(oklab.xyz);
result.w = oklab.w;
return result;
}
//- rjf: rgba <-> u32
internal U32 internal U32
u32_from_rgba(Vec4F32 rgba) u32_from_rgba(Vec4F32 rgba)
{ {
@@ -588,6 +691,16 @@ u32_from_rgba(Vec4F32 rgba)
return result; return result;
} }
internal Vec4F32
rgba_from_u32(U32 hex)
{
Vec4F32 result = v4f32(((hex&0xff000000)>>24)/255.f,
((hex&0x00ff0000)>>16)/255.f,
((hex&0x0000ff00)>> 8)/255.f,
((hex&0x000000ff)>> 0)/255.f);
return result;
}
//////////////////////////////// ////////////////////////////////
//~ rjf: List Type Functions //~ rjf: List Type Functions
@@ -634,6 +747,37 @@ rng1u64_array_from_list(Arena *arena, Rng1U64List *list)
return arr; return arr;
} }
internal U64
rng_1u64_array_bsearch(Rng1U64Array arr, U64 value)
{
if(arr.count > 0 && arr.v[0].min <= value && value < arr.v[arr.count-1].max)
{
U64 l = 0;
U64 r = arr.count - 1;
for(; l <= r; )
{
U64 m = l + (r - l) / 2;
if(contains_1u64(arr.v[m], value))
{
return m;
}
else if(arr.v[m].min < value)
{
l = m + 1;
}
else
{
r = m - 1;
}
}
}
else if(arr.count == 1 && contains_1u64(arr.v[0], value))
{
return 0;
}
return max_U64;
}
internal void internal void
rng1s64_list_push(Arena *arena, Rng1S64List *list, Rng1S64 rng) rng1s64_list_push(Arena *arena, Rng1S64List *list, Rng1S64 rng)
{ {
@@ -657,3 +801,4 @@ rng1s64_array_from_list(Arena *arena, Rng1S64List *list)
} }
return arr; return arr;
} }
+25 -7
View File
@@ -379,14 +379,15 @@ struct Rng1S64Array
#define abs_s64(v) (S64)llabs(v) #define abs_s64(v) (S64)llabs(v)
#define sqrt_f32(v) sqrtf(v) #define sqrt_f32(v) sqrtf(v)
#define cbrt_f32(v) cbrtf(v)
#define mod_f32(a, b) fmodf((a), (b)) #define mod_f32(a, b) fmodf((a), (b))
#define pow_f32(b, e) powf((b), (e)) #define pow_f32(b, e) powf((b), (e))
#define ceil_f32(v) ceilf(v) #define ceil_f32(v) ceilf(v)
#define floor_f32(v) floorf(v) #define floor_f32(v) floorf(v)
#define round_f32(v) roundf(v) #define round_f32(v) roundf(v)
#define abs_f32(v) fabsf(v) #define abs_f32(v) fabsf(v)
#define radians_from_turns_f32(v) ((v)*2*3.1415926535897f) #define radians_from_turns_f32(v) ((v)*(2*3.1415926535897f))
#define turns_from_radians_f32(v) ((v)/2*3.1415926535897f) #define turns_from_radians_f32(v) ((v)/(2*3.1415926535897f))
#define degrees_from_turns_f32(v) ((v)*360.f) #define degrees_from_turns_f32(v) ((v)*360.f)
#define turns_from_degrees_f32(v) ((v)/360.f) #define turns_from_degrees_f32(v) ((v)/360.f)
#define degrees_from_radians_f32(v) (degrees_from_turns_f32(turns_from_radians_f32(v))) #define degrees_from_radians_f32(v) (degrees_from_turns_f32(turns_from_radians_f32(v)))
@@ -396,14 +397,15 @@ struct Rng1S64Array
#define tan_f32(v) tanf(radians_from_turns_f32(v)) #define tan_f32(v) tanf(radians_from_turns_f32(v))
#define sqrt_f64(v) sqrt(v) #define sqrt_f64(v) sqrt(v)
#define cbrt_f64(v) cbrt(v)
#define mod_f64(a, b) fmod((a), (b)) #define mod_f64(a, b) fmod((a), (b))
#define pow_f64(b, e) pow((b), (e)) #define pow_f64(b, e) pow((b), (e))
#define ceil_f64(v) ceil(v) #define ceil_f64(v) ceil(v)
#define floor_f64(v) floor(v) #define floor_f64(v) floor(v)
#define round_f64(v) round(v) #define round_f64(v) round(v)
#define abs_f64(v) fabs(v) #define abs_f64(v) fabs(v)
#define radians_from_turns_f64(v) ((v)*2*3.1415926535897) #define radians_from_turns_f64(v) ((v)*(2*3.1415926535897))
#define turns_from_radians_f64(v) ((v)/2*3.1415926535897) #define turns_from_radians_f64(v) ((v)/(2*3.1415926535897))
#define degrees_from_turns_f64(v) ((v)*360.0) #define degrees_from_turns_f64(v) ((v)*360.0)
#define turns_from_degrees_f64(v) ((v)/360.0) #define turns_from_degrees_f64(v) ((v)/360.0)
#define degrees_from_radians_f64(v) (degrees_from_turns_f64(turns_from_radians_f64(v))) #define degrees_from_radians_f64(v) (degrees_from_turns_f64(turns_from_radians_f64(v)))
@@ -543,6 +545,7 @@ internal Mat4x4F32 mul_4x4f32(Mat4x4F32 a, Mat4x4F32 b);
internal Mat4x4F32 scale_4x4f32(Mat4x4F32 m, F32 scale); internal Mat4x4F32 scale_4x4f32(Mat4x4F32 m, F32 scale);
internal Mat4x4F32 inverse_4x4f32(Mat4x4F32 m); internal Mat4x4F32 inverse_4x4f32(Mat4x4F32 m);
internal Mat4x4F32 derotate_4x4f32(Mat4x4F32 mat); internal Mat4x4F32 derotate_4x4f32(Mat4x4F32 mat);
internal Mat4x4F32 transpose_4x4f32(Mat4x4F32 mat);
//////////////////////////////// ////////////////////////////////
//~ rjf: Range Ops //~ rjf: Range Ops
@@ -651,15 +654,29 @@ internal Rng2F32 intersect_2f32(Rng2F32 a, Rng2F32 b);
internal Vec2F32 clamp_2f32(Rng2F32 r, Vec2F32 v); internal Vec2F32 clamp_2f32(Rng2F32 r, Vec2F32 v);
//////////////////////////////// ////////////////////////////////
//~ rjf: Miscellaneous Ops //~ rjf: Color Operations
//- rjf: hsv <-> rgb
internal Vec3F32 hsv_from_rgb(Vec3F32 rgb); internal Vec3F32 hsv_from_rgb(Vec3F32 rgb);
internal Vec3F32 rgb_from_hsv(Vec3F32 hsv); internal Vec3F32 rgb_from_hsv(Vec3F32 hsv);
internal Vec4F32 hsva_from_rgba(Vec4F32 rgba); internal Vec4F32 hsva_from_rgba(Vec4F32 rgba);
internal Vec4F32 rgba_from_hsva(Vec4F32 hsva); internal Vec4F32 rgba_from_hsva(Vec4F32 hsva);
internal Vec4F32 rgba_from_u32(U32 hex);
internal U32 u32_from_rgba(Vec4F32 rgba);
//- rjf: srgb <-> linear
internal Vec3F32 linear_from_srgb(Vec3F32 srgb);
internal Vec3F32 srgb_from_linear(Vec3F32 linear);
internal Vec4F32 linear_from_srgba(Vec4F32 srgba);
internal Vec4F32 srgba_from_linear(Vec4F32 linear);
//- rjf: oklab <-> linear
internal Vec3F32 oklab_from_linear(Vec3F32 linear);
internal Vec3F32 linear_from_oklab(Vec3F32 oklab);
internal Vec4F32 oklab_from_lineara(Vec4F32 lineara);
internal Vec4F32 lineara_from_oklab(Vec4F32 oklab);
//- rjf: rgba <-> u32
internal U32 u32_from_rgba(Vec4F32 rgba);
internal Vec4F32 rgba_from_u32(U32 hex);
#define rgba_from_u32_lit_comp(h) { (((h)&0xff000000)>>24)/255.f, (((h)&0x00ff0000)>>16)/255.f, (((h)&0x0000ff00)>> 8)/255.f, (((h)&0x000000ff)>> 0)/255.f } #define rgba_from_u32_lit_comp(h) { (((h)&0xff000000)>>24)/255.f, (((h)&0x00ff0000)>>16)/255.f, (((h)&0x0000ff00)>> 8)/255.f, (((h)&0x000000ff)>> 0)/255.f }
//////////////////////////////// ////////////////////////////////
@@ -668,6 +685,7 @@ internal U32 u32_from_rgba(Vec4F32 rgba);
internal void rng1u64_list_push(Arena *arena, Rng1U64List *list, Rng1U64 rng); internal void rng1u64_list_push(Arena *arena, Rng1U64List *list, Rng1U64 rng);
internal void rng1u64_list_concat(Rng1U64List *list, Rng1U64List *to_concat); internal void rng1u64_list_concat(Rng1U64List *list, Rng1U64List *to_concat);
internal Rng1U64Array rng1u64_array_from_list(Arena *arena, Rng1U64List *list); internal Rng1U64Array rng1u64_array_from_list(Arena *arena, Rng1U64List *list);
internal U64 rng_1u64_array_bsearch(Rng1U64Array arr, U64 value);
internal void rng1s64_list_push(Arena *arena, Rng1S64List *list, Rng1S64 rng); internal void rng1s64_list_push(Arena *arena, Rng1S64List *list, Rng1S64 rng);
internal Rng1S64Array rng1s64_array_from_list(Arena *arena, Rng1S64List *list); internal Rng1S64Array rng1s64_array_from_list(Arena *arena, Rng1S64List *list);
-1
View File
@@ -45,7 +45,6 @@ typed_data_rebase_ptrs(Type *type, String8 data, void *base_ptr)
{ {
default:{}break; default:{}break;
case TypeKind_Ptr: case TypeKind_Ptr:
if(!(t->type->flags & TypeFlag_IsExternal))
{ {
*(U64 *)t->ptr = ((U64)(*(U8 **)t->ptr - (U8 *)base_ptr)); *(U64 *)t->ptr = ((U64)(*(U8 **)t->ptr - (U8 *)base_ptr));
}break; }break;
+3 -4
View File
@@ -100,10 +100,9 @@ TypeKind;
typedef U32 TypeFlags; typedef U32 TypeFlags;
enum enum
{ {
TypeFlag_IsExternal = (1<<0), TypeFlag_IsPlainText = (1<<0),
TypeFlag_IsPlainText = (1<<1), TypeFlag_IsCodeText = (1<<1),
TypeFlag_IsCodeText = (1<<2), TypeFlag_IsPathText = (1<<2),
TypeFlag_IsPathText = (1<<3),
}; };
typedef U32 MemberFlags; typedef U32 MemberFlags;
-4
View File
@@ -11,10 +11,6 @@
# define PROFILE_TELEMETRY 0 # define PROFILE_TELEMETRY 0
#endif #endif
#if !defined(MARKUP_LAYER_COLOR)
# define MARKUP_LAYER_COLOR 1.00f, 0.00f, 1.00f
#endif
//////////////////////////////// ////////////////////////////////
//~ rjf: Third Party Includes //~ rjf: Third Party Includes
+180 -140
View File
@@ -427,23 +427,53 @@ str8_chop(String8 str, U64 amt){
} }
internal String8 internal String8
str8_skip_chop_whitespace(String8 string){ str8_skip_chop_whitespace(String8 string)
{
U8 *first = string.str; U8 *first = string.str;
U8 *opl = first + string.size; U8 *opl = first + string.size;
for (;first < opl; first += 1){ for(;first < opl; first += 1)
if (!char_is_space(*first)){ {
if(!char_is_space(*first))
{
break; break;
} }
} }
for (;opl > first;){ for(;opl > first;)
{
opl -= 1; opl -= 1;
if (!char_is_space(*opl)){ if(!char_is_space(*opl))
{
opl += 1; opl += 1;
break; break;
} }
} }
String8 result = str8_range(first, opl); String8 result = str8_range(first, opl);
return(result); return result;
}
internal String8
str8_skip_chop_slashes(String8 string)
{
U8 *first = string.str;
U8 *opl = first + string.size;
for(;first < opl; first += 1)
{
if(!char_is_slash(*first))
{
break;
}
}
for(;opl > first;)
{
opl -= 1;
if(!char_is_slash(*opl))
{
opl += 1;
break;
}
}
String8 result = str8_range(first, opl);
return result;
} }
//////////////////////////////// ////////////////////////////////
@@ -573,44 +603,50 @@ s32_from_str8(String8 string, U32 radix)
} }
internal B32 internal B32
try_u64_from_str8_c_rules(String8 string, U64 *x){ try_u64_from_str8_c_rules(String8 string, U64 *x)
{
B32 is_integer = 0; B32 is_integer = 0;
if (str8_is_integer(string, 10)){ if(str8_is_integer(string, 10) && !str8_match(str8_prefix(string, 1), str8_lit("0"), 0))
{
is_integer = 1; is_integer = 1;
*x = u64_from_str8(string, 10); *x = u64_from_str8(string, 10);
} }
else{ else
{
String8 hex_string = str8_skip(string, 2); String8 hex_string = str8_skip(string, 2);
if(str8_match(str8_prefix(string, 2), str8_lit("0x"), 0) && if(str8_match(str8_prefix(string, 2), str8_lit("0x"), 0) &&
str8_is_integer(hex_string, 0x10)){ str8_is_integer(hex_string, 0x10))
{
is_integer = 1; is_integer = 1;
*x = u64_from_str8(hex_string, 0x10); *x = u64_from_str8(hex_string, 0x10);
} }
else if (str8_match(str8_prefix(string, 2), str8_lit("0b"), 0) && else if(str8_match(str8_prefix(string, 2), str8_lit("0b"), 0) && str8_is_integer(hex_string, 2))
str8_is_integer(hex_string, 2)){ {
is_integer = 1; is_integer = 1;
*x = u64_from_str8(hex_string, 2); *x = u64_from_str8(hex_string, 2);
} }
else{ else
{
String8 oct_string = str8_skip(string, 1); String8 oct_string = str8_skip(string, 1);
if (str8_match(str8_prefix(string, 1), str8_lit("0"), 0) && if(str8_match(str8_prefix(string, 1), str8_lit("0"), 0) && str8_is_integer(hex_string, 010))
str8_is_integer(hex_string, 010)){ {
is_integer = 1; is_integer = 1;
*x = u64_from_str8(oct_string, 010); *x = u64_from_str8(oct_string, 010);
} }
} }
} }
return(is_integer); return is_integer;
} }
internal B32 internal B32
try_s64_from_str8_c_rules(String8 string, S64 *x){ try_s64_from_str8_c_rules(String8 string, S64 *x)
{
String8 string_tail = {0}; String8 string_tail = {0};
S64 sign = sign_from_str8(string, &string_tail); S64 sign = sign_from_str8(string, &string_tail);
U64 x_u64 = 0; U64 x_u64 = 0;
B32 is_integer = try_u64_from_str8_c_rules(string_tail, &x_u64); B32 is_integer = try_u64_from_str8_c_rules(string_tail, &x_u64);
*x = x_u64*sign; *x = x_u64*sign;
return(is_integer); return is_integer;
} }
//- rjf: integer -> string //- rjf: integer -> string
@@ -1114,6 +1150,13 @@ str8_list_from_flags(Arena *arena, String8List *list,
//////////////////////////////// ////////////////////////////////
//~ rjf; String Arrays //~ rjf; String Arrays
internal String8Array
str8_array_zero(void)
{
String8Array result = {0};
return result;
}
internal String8Array internal String8Array
str8_array_from_list(Arena *arena, String8List *list) str8_array_from_list(Arena *arena, String8List *list)
{ {
@@ -1137,44 +1180,103 @@ str8_array_reserve(Arena *arena, U64 count)
return arr; return arr;
} }
internal String8Array
str8_array_copy(Arena *arena, String8Array array)
{
String8Array result = {0};
result.count = array.count;
result.v = push_array(arena, String8, result.count);
for EachIndex(idx, result.count)
{
result.v[idx] = push_str8_copy(arena, array.v[idx]);
}
return result;
}
////////////////////////////////
//~ rjf: String Version Helpers
internal U64
version_from_str8(String8 string)
{
U64 result = 0;
Temp scratch = scratch_begin(0, 0);
U64 version_major = 0;
U64 version_minor = 0;
U64 version_patch = 0;
String8List version_parts = str8_split(scratch.arena, string, (U8 *)".", 1, 0);
if(version_parts.first &&
version_parts.first->next &&
version_parts.first->next->next)
{
try_u64_from_str8_c_rules(version_parts.first->string, &version_major);
try_u64_from_str8_c_rules(version_parts.first->next->string, &version_minor);
try_u64_from_str8_c_rules(version_parts.first->next->next->string, &version_patch);
result = Version(version_major, version_minor, version_patch);
}
scratch_end(scratch);
return result;
}
internal String8
str8_from_version(Arena *arena, U64 version)
{
U64 version_major = MajorFromVersion(version);
U64 version_minor = MinorFromVersion(version);
U64 version_patch = PatchFromVersion(version);
String8 result = push_str8f(arena, "%I64d.%I64d.%I64d", version_major, version_minor, version_patch);
return result;
}
//////////////////////////////// ////////////////////////////////
//~ rjf: String Path Helpers //~ rjf: String Path Helpers
internal String8 internal String8
str8_chop_last_slash(String8 string){ str8_chop_last_slash(String8 string)
if (string.size > 0){ {
if(string.size > 0)
{
U8 *ptr = string.str + string.size - 1; U8 *ptr = string.str + string.size - 1;
for (;ptr >= string.str; ptr -= 1){ for(;ptr >= string.str; ptr -= 1)
if (*ptr == '/' || *ptr == '\\'){ {
if(*ptr == '/' || *ptr == '\\')
{
break; break;
} }
} }
if (ptr >= string.str){ if(ptr >= string.str)
{
string.size = (U64)(ptr - string.str); string.size = (U64)(ptr - string.str);
} }
else{ else
{
string.size = 0; string.size = 0;
} }
} }
return(string); return string;
} }
internal String8 internal String8
str8_skip_last_slash(String8 string){ str8_skip_last_slash(String8 string)
if (string.size > 0){ {
if(string.size > 0)
{
U8 *ptr = string.str + string.size - 1; U8 *ptr = string.str + string.size - 1;
for (;ptr >= string.str; ptr -= 1){ for(;ptr >= string.str; ptr -= 1)
if (*ptr == '/' || *ptr == '\\'){ {
if(*ptr == '/' || *ptr == '\\')
{
break; break;
} }
} }
if (ptr >= string.str){ if(ptr >= string.str)
{
ptr += 1; ptr += 1;
string.size = (U64)(string.str + string.size - ptr); string.size = (U64)(string.str + string.size - ptr);
string.str = ptr; string.str = ptr;
} }
} }
return(string); return string;
} }
internal String8 internal String8
@@ -1182,80 +1284,94 @@ str8_chop_last_dot(String8 string)
{ {
String8 result = string; String8 result = string;
U64 p = string.size; U64 p = string.size;
for (;p > 0;){ for(;p > 0;)
{
p -= 1; p -= 1;
if (string.str[p] == '.'){ if(string.str[p] == '.')
{
result = str8_prefix(string, p); result = str8_prefix(string, p);
break; break;
} }
} }
return(result); return result;
} }
internal String8 internal String8
str8_skip_last_dot(String8 string){ str8_skip_last_dot(String8 string)
{
String8 result = string; String8 result = string;
U64 p = string.size; U64 p = string.size;
for (;p > 0;){ for(;p > 0;)
{
p -= 1; p -= 1;
if (string.str[p] == '.'){ if(string.str[p] == '.')
{
result = str8_skip(string, p + 1); result = str8_skip(string, p + 1);
break; break;
} }
} }
return(result); return result;
} }
internal PathStyle internal PathStyle
path_style_from_str8(String8 string){ path_style_from_str8(String8 string)
{
PathStyle result = PathStyle_Relative; PathStyle result = PathStyle_Relative;
if (string.size >= 1 && string.str[0] == '/'){ if(string.size >= 1 && string.str[0] == '/')
{
result = PathStyle_UnixAbsolute; result = PathStyle_UnixAbsolute;
} }
else if(string.size >= 2 && else if(string.size >= 2 &&
char_is_alpha(string.str[0]) && char_is_alpha(string.str[0]) &&
string.str[1] == ':'){ string.str[1] == ':')
if (string.size == 2 || {
char_is_slash(string.str[2])){ if(string.size == 2 || char_is_slash(string.str[2]))
{
result = PathStyle_WindowsAbsolute; result = PathStyle_WindowsAbsolute;
} }
} }
return(result); return result;
} }
internal String8List internal String8List
str8_split_path(Arena *arena, String8 string){ str8_split_path(Arena *arena, String8 string)
{
String8List result = str8_split(arena, string, (U8*)"/\\", 2, 0); String8List result = str8_split(arena, string, (U8*)"/\\", 2, 0);
return(result); return result;
} }
internal void internal void
str8_path_list_resolve_dots_in_place(String8List *path, PathStyle style){ str8_path_list_resolve_dots_in_place(String8List *path, PathStyle style)
{
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
String8MetaNode *stack = 0; String8MetaNode *stack = 0;
String8MetaNode *free_meta_node = 0; String8MetaNode *free_meta_node = 0;
String8Node *first = path->first; String8Node *first = path->first;
MemoryZeroStruct(path); MemoryZeroStruct(path);
for(String8Node *node = first, *next = 0; for(String8Node *node = first, *next = 0;
node != 0; node != 0;
node = next){ node = next)
{
// save next now // save next now
next = node->next; next = node->next;
// cases: // cases:
if (node == first && style == PathStyle_WindowsAbsolute){ if(node == first && style == PathStyle_WindowsAbsolute)
{
goto save_without_stack; goto save_without_stack;
} }
if (node->string.size == 1 && node->string.str[0] == '.'){ if(node->string.size == 1 && node->string.str[0] == '.')
{
goto do_nothing; goto do_nothing;
} }
if (node->string.size == 2 && node->string.str[0] == '.' && node->string.str[1] == '.'){ if(node->string.size == 2 && node->string.str[0] == '.' && node->string.str[1] == '.')
if (stack != 0){ {
if(stack != 0)
{
goto eliminate_stack_top; goto eliminate_stack_top;
} }
else{ else
{
goto save_without_stack; goto save_without_stack;
} }
} }
@@ -1266,24 +1382,23 @@ str8_path_list_resolve_dots_in_place(String8List *path, PathStyle style){
save_with_stack: save_with_stack:
{ {
str8_list_push_node(path, node); str8_list_push_node(path, node);
String8MetaNode *stack_node = free_meta_node; String8MetaNode *stack_node = free_meta_node;
if (stack_node != 0){ if(stack_node != 0)
{
SLLStackPop(free_meta_node); SLLStackPop(free_meta_node);
} }
else{ else
{
stack_node = push_array_no_zero(scratch.arena, String8MetaNode, 1); stack_node = push_array_no_zero(scratch.arena, String8MetaNode, 1);
} }
SLLStackPush(stack, stack_node); SLLStackPush(stack, stack_node);
stack_node->node = node; stack_node->node = node;
continue; continue;
} }
save_without_stack: save_without_stack:
{ {
str8_list_push_node(path, node); str8_list_push_node(path, node);
continue; continue;
} }
@@ -1291,13 +1406,13 @@ str8_path_list_resolve_dots_in_place(String8List *path, PathStyle style){
{ {
path->node_count -= 1; path->node_count -= 1;
path->total_size -= stack->node->string.size; path->total_size -= stack->node->string.size;
SLLStackPop(stack); SLLStackPop(stack);
if(stack == 0)
if (stack == 0){ {
path->last = path->first; path->last = path->first;
} }
else{ else
{
path->last = stack->node; path->last = stack->node;
} }
continue; continue;
@@ -1402,7 +1517,7 @@ utf8_decode(U8 *str, U64 max){
}break; }break;
case 2: case 2:
{ {
if (2 < max) if (1 < max)
{ {
U8 cont_byte = str[1]; U8 cont_byte = str[1];
if (utf8_class[cont_byte >> 3] == 0) if (utf8_class[cont_byte >> 3] == 0)
@@ -1933,7 +2048,6 @@ escaped_from_raw_str8(Arena *arena, String8 string)
case '\v': {separator_replace = str8_lit("\\v");}break; case '\v': {separator_replace = str8_lit("\\v");}break;
case '\\': {separator_replace = str8_lit("\\\\");}break; case '\\': {separator_replace = str8_lit("\\\\");}break;
case '"': {separator_replace = str8_lit("\\\"");}break; case '"': {separator_replace = str8_lit("\\\"");}break;
case '?': {separator_replace = str8_lit("\\?");}break;
} }
if(split) if(split)
{ {
@@ -2370,77 +2484,3 @@ str8_deserial_read_block(String8 string, U64 off, U64 size, String8 *block_out)
*block_out = str8_substr(string, range); *block_out = str8_substr(string, range);
return block_out->size; return block_out->size;
} }
internal U64
str8_deserial_read_uleb128(String8 string, U64 off, U64 *value_out)
{
U64 value = 0;
U64 shift = 0;
U64 cursor = off;
for(;;)
{
U8 byte = 0;
U64 bytes_read = str8_deserial_read_struct(string, cursor, &byte);
if(bytes_read != sizeof(byte))
{
break;
}
U8 val = byte & 0x7fu;
value |= ((U64)val) << shift;
cursor += bytes_read;
shift += 7u;
if((byte & 0x80u) == 0)
{
break;
}
}
if(value_out != 0)
{
*value_out = value;
}
U64 bytes_read = cursor - off;
return bytes_read;
}
internal U64
str8_deserial_read_sleb128(String8 string, U64 off, S64 *value_out)
{
U64 value = 0;
U64 shift = 0;
U64 cursor = off;
for(;;)
{
U8 byte;
U64 bytes_read = str8_deserial_read_struct(string, cursor, &byte);
if(bytes_read != sizeof(byte))
{
break;
}
U8 val = byte & 0x7fu;
value |= ((U64)val) << shift;
cursor += bytes_read;
shift += 7u;
if((byte & 0x80u) == 0)
{
if(shift < sizeof(value) * 8 && (byte & 0x40u) != 0)
{
value |= -(S64)(1ull << shift);
}
break;
}
}
if(value_out != 0)
{
*value_out = value;
}
U64 bytes_read = cursor - off;
return bytes_read;
}
+24 -3
View File
@@ -96,7 +96,7 @@ typedef enum PathStyle
#elif OS_LINUX #elif OS_LINUX
PathStyle_SystemAbsolute = PathStyle_UnixAbsolute PathStyle_SystemAbsolute = PathStyle_UnixAbsolute
#else #else
# error "absolute path style is undefined for this OS" # error Absolute path style is undefined for this OS.
#endif #endif
} }
PathStyle; PathStyle;
@@ -223,6 +223,7 @@ internal String8 str8_skip(String8 str, U64 amt);
internal String8 str8_postfix(String8 str, U64 size); internal String8 str8_postfix(String8 str, U64 size);
internal String8 str8_chop(String8 str, U64 amt); internal String8 str8_chop(String8 str, U64 amt);
internal String8 str8_skip_chop_whitespace(String8 string); internal String8 str8_skip_chop_whitespace(String8 string);
internal String8 str8_skip_chop_slashes(String8 string);
//////////////////////////////// ////////////////////////////////
//~ rjf: String Formatting & Copying //~ rjf: String Formatting & Copying
@@ -287,12 +288,34 @@ internal void str8_list_from_flags(Arena *arena, String8List *list, U32
//////////////////////////////// ////////////////////////////////
//~ rjf; String Arrays //~ rjf; String Arrays
internal String8Array str8_array_zero(void);
internal String8Array str8_array_from_list(Arena *arena, String8List *list); internal String8Array str8_array_from_list(Arena *arena, String8List *list);
internal String8Array str8_array_reserve(Arena *arena, U64 count); internal String8Array str8_array_reserve(Arena *arena, U64 count);
internal String8Array str8_array_copy(Arena *arena, String8Array array);
////////////////////////////////
//~ rjf: String Version Helpers
internal U64 version_from_str8(String8 string);
internal String8 str8_from_version(Arena *arena, U64 version);
//////////////////////////////// ////////////////////////////////
//~ rjf: String Path Helpers //~ rjf: String Path Helpers
global read_only struct
{
String8 string;
PathStyle path_style;
}
g_path_style_map[] =
{
{ str8_lit_comp(""), PathStyle_Null },
{ str8_lit_comp("relative"), PathStyle_Relative },
{ str8_lit_comp("windows"), PathStyle_WindowsAbsolute },
{ str8_lit_comp("unix"), PathStyle_UnixAbsolute },
{ str8_lit_comp("system"), PathStyle_SystemAbsolute },
};
internal String8 str8_chop_last_slash(String8 string); internal String8 str8_chop_last_slash(String8 string);
internal String8 str8_skip_last_slash(String8 string); internal String8 str8_skip_last_slash(String8 string);
internal String8 str8_chop_last_dot(String8 string); internal String8 str8_chop_last_dot(String8 string);
@@ -407,8 +430,6 @@ internal void * str8_deserial_get_raw_ptr(String8 string, U64 off, U64 size);
internal U64 str8_deserial_read_cstr(String8 string, U64 off, String8 *cstr_out); internal U64 str8_deserial_read_cstr(String8 string, U64 off, String8 *cstr_out);
internal U64 str8_deserial_read_windows_utf16_string16(String8 string, U64 off, String16 *str_out); internal U64 str8_deserial_read_windows_utf16_string16(String8 string, U64 off, String16 *str_out);
internal U64 str8_deserial_read_block(String8 string, U64 off, U64 size, String8 *block_out); internal U64 str8_deserial_read_block(String8 string, U64 off, U64 size, String8 *block_out);
internal U64 str8_deserial_read_uleb128(String8 string, U64 off, U64 *value_out);
internal U64 str8_deserial_read_sleb128(String8 string, U64 off, S64 *value_out);
#define str8_deserial_read_array(string, off, ptr, count) str8_deserial_read((string), (off), (ptr), sizeof(*(ptr))*(count), sizeof(*(ptr))) #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_array(string, off, ptr, 1) #define str8_deserial_read_struct(string, off, ptr) str8_deserial_read_array(string, off, ptr, 1)
+1 -1
View File
@@ -26,7 +26,7 @@ internal void tctx_init_and_equip(TCTX *tctx);
internal void tctx_release(void); internal void tctx_release(void);
internal TCTX* tctx_get_equipped(void); internal TCTX* tctx_get_equipped(void);
internal Arena* tctx_get_scratch(Arena **conflicts, U64 countt); internal Arena* tctx_get_scratch(Arena **conflicts, U64 count);
internal void tctx_set_thread_name(String8 name); internal void tctx_set_thread_name(String8 name);
internal String8 tctx_get_thread_name(void); internal String8 tctx_get_thread_name(void);
+24 -24
View File
@@ -14,30 +14,30 @@ cv_arch_from_coff_machine(COFF_MachineType machine)
CV_Arch arch = 0; CV_Arch arch = 0;
switch(machine) switch(machine)
{ {
case COFF_Machine_X64: arch = CV_Arch_X64; break; case COFF_MachineType_X64: arch = CV_Arch_X64; break;
case COFF_Machine_X86: arch = CV_Arch_8086; break; case COFF_MachineType_X86: arch = CV_Arch_8086; break;
case COFF_Machine_Am33: arch = CV_Arch_AM33; break; case COFF_MachineType_Am33: arch = CV_Arch_AM33; break;
case COFF_Machine_Arm: NotImplemented; break; case COFF_MachineType_Arm: NotImplemented; break;
case COFF_Machine_Arm64: arch = CV_Arch_ARM64; break; case COFF_MachineType_Arm64: arch = CV_Arch_ARM64; break;
case COFF_Machine_ArmNt: arch = CV_Arch_ARMNT; break; case COFF_MachineType_ArmNt: arch = CV_Arch_ARMNT; break;
case COFF_Machine_Ebc: arch = CV_Arch_EBC; break; case COFF_MachineType_Ebc: arch = CV_Arch_EBC; break;
case COFF_Machine_Ia64: arch = CV_Arch_IA64; break; case COFF_MachineType_Ia64: arch = CV_Arch_IA64; break;
case COFF_Machine_M32R: arch = CV_Arch_M32R; break; case COFF_MachineType_M32R: arch = CV_Arch_M32R; break;
case COFF_Machine_Mips16: arch = CV_Arch_MIPS16; break; case COFF_MachineType_Mips16: arch = CV_Arch_MIPS16; break;
case COFF_Machine_MipsFpu: NotImplemented; break; case COFF_MachineType_MipsFpu: NotImplemented; break;
case COFF_Machine_MipsFpu16: NotImplemented; break; case COFF_MachineType_MipsFpu16: NotImplemented; break;
case COFF_Machine_PowerPc: NotImplemented; break; case COFF_MachineType_PowerPc: NotImplemented; break;
case COFF_Machine_PowerPcFp: arch = CV_Arch_PPCFP; break; case COFF_MachineType_PowerPcFp: arch = CV_Arch_PPCFP; break;
case COFF_Machine_R4000: NotImplemented; break; case COFF_MachineType_R4000: NotImplemented; break;
case COFF_Machine_RiscV32: NotImplemented; break; case COFF_MachineType_RiscV32: NotImplemented; break;
case COFF_Machine_RiscV64: NotImplemented; break; case COFF_MachineType_RiscV64: NotImplemented; break;
case COFF_Machine_RiscV128: NotImplemented; break; case COFF_MachineType_RiscV128: NotImplemented; break;
case COFF_Machine_Sh3: arch = CV_Arch_SH3; break; case COFF_MachineType_Sh3: arch = CV_Arch_SH3; break;
case COFF_Machine_Sh3Dsp: arch = CV_Arch_SH3DSP; break; case COFF_MachineType_Sh3Dsp: arch = CV_Arch_SH3DSP; break;
case COFF_Machine_Sh4: arch = CV_Arch_SH4; break; case COFF_MachineType_Sh4: arch = CV_Arch_SH4; break;
case COFF_Machine_Sh5: NotImplemented; break; case COFF_MachineType_Sh5: NotImplemented; break;
case COFF_Machine_Thumb: arch = CV_Arch_THUMB; break; case COFF_MachineType_Thumb: arch = CV_Arch_THUMB; break;
case COFF_Machine_WceMipsV2: NotImplemented; break; case COFF_MachineType_WceMipsV2: NotImplemented; break;
} }
return arch; return arch;
} }
+33 -33
View File
@@ -395,48 +395,48 @@ CV_BasicTypeTable:
{FBASICSTR 0x06 "" } {FBASICSTR 0x06 "" }
{NOTTRANS 0x07 "" } {NOTTRANS 0x07 "" }
{HRESULT 0x08 "HRESULT" } {HRESULT 0x08 "HRESULT" }
{CHAR 0x10 "char" } {CHAR 0x10 "CHAR" }
{SHORT 0x11 "S16" } {SHORT 0x11 "SHORT" }
{LONG 0x12 "S32" } {LONG 0x12 "LONG" }
{QUAD 0x13 "S64" } {QUAD 0x13 "QUAD" }
{OCT 0x14 "S128" } {OCT 0x14 "OCT" }
{UCHAR 0x20 "UCHAR" } {UCHAR 0x20 "UCHAR" }
{USHORT 0x21 "U16" } {USHORT 0x21 "USHORT" }
{ULONG 0x22 "U32" } {ULONG 0x22 "ULONG" }
{UQUAD 0x23 "U64" } {UQUAD 0x23 "UQUAD" }
{UOCT 0x24 "U128" } {UOCT 0x24 "UOCT" }
{BOOL8 0x30 "B8" } {BOOL8 0x30 "BOOL8" }
{BOOL16 0x31 "B16" } {BOOL16 0x31 "BOOL16" }
{BOOL32 0x32 "B32" } {BOOL32 0x32 "BOOL32" }
{BOOL64 0x33 "B64" } {BOOL64 0x33 "BOOL64" }
{FLOAT32 0x40 "F32" } {FLOAT32 0x40 "FLOAT32" }
{FLOAT64 0x41 "F64" } {FLOAT64 0x41 "FLOAT64" }
{FLOAT80 0x42 "F80" } {FLOAT80 0x42 "FLOAT80" }
{FLOAT128 0x43 "F128" } {FLOAT128 0x43 "FLOAT128" }
{FLOAT48 0x44 "F48" } {FLOAT48 0x44 "FLOAT48" }
{FLOAT32PP 0x45 "F32PP" } {FLOAT32PP 0x45 "FLOAT32PP" }
{FLOAT16 0x46 "F16" } {FLOAT16 0x46 "FLOAT16" }
{COMPLEX32 0x50 "ComplexF32" } {COMPLEX32 0x50 "ComplexF32" }
{COMPLEX64 0x51 "ComplexF64" } {COMPLEX64 0x51 "ComplexF64" }
{COMPLEX80 0x52 "ComplexF80" } {COMPLEX80 0x52 "ComplexF80" }
{COMPLEX128 0x53 "ComplexF128" } {COMPLEX128 0x53 "ComplexF128" }
{BIT 0x60 "" } {BIT 0x60 "" }
{PASCHAR 0x61 "" } {PASCHAR 0x61 "" }
{BOOL32FF 0x62 "B32FF" } {BOOL32FF 0x62 "BOOL32FF" }
{INT8 0x68 "S8" } {INT8 0x68 "int8" }
{UINT8 0x69 "U8" } {UINT8 0x69 "uint8" }
{RCHAR 0x70 "char" } {RCHAR 0x70 "char" }
{WCHAR 0x71 "WCHAR" } {WCHAR 0x71 "WCHAR" }
{INT16 0x72 "S16" } {INT16 0x72 "int16" }
{UINT16 0x73 "U16" } {UINT16 0x73 "uint16" }
{INT32 0x74 "S32" } {INT32 0x74 "int32" }
{UINT32 0x75 "U32" } {UINT32 0x75 "uint32" }
{INT64 0x76 "S64" } {INT64 0x76 "int64" }
{UINT64 0x77 "U64" } {UINT64 0x77 "uint64" }
{INT128 0x78 "S128" } {INT128 0x78 "int128" }
{UINT128 0x79 "U128" } {UINT128 0x79 "uint128" }
{CHAR16 0x7a "CHAR16" } {CHAR16 0x7a "char16" }
{CHAR32 0x7b "CHAR32" } {CHAR32 0x7b "char32" }
{CHAR8 0x7c "char" } {CHAR8 0x7c "char" }
{PTR 0xf0 "PTR" } {PTR 0xf0 "PTR" }
} }
-9
View File
@@ -930,15 +930,6 @@ cv_string_from_itemid(Arena *arena, CV_ItemId itemid)
return result; return result;
} }
internal String8
cv_string_from_reg_off(Arena *arena, CV_Arch arch, U32 reg, U32 off)
{
Temp scratch = scratch_begin(&arena, 1);
String8 result = push_str8f(arena, "%S+%x", cv_string_from_reg_id(scratch.arena, arch, reg), off);
scratch_end(scratch);
return result;
}
internal String8 internal String8
cv_string_from_symbol_type(Arena *arena, CV_SymKind symbol_type) cv_string_from_symbol_type(Arena *arena, CV_SymKind symbol_type)
{ {
-1
View File
@@ -41,7 +41,6 @@ internal String8 cv_string_from_defrange_register_rel_flags(Arena *arena, CV_Def
internal String8 cv_string_from_field_attribs(Arena *arena, CV_FieldAttribs attribs); internal String8 cv_string_from_field_attribs(Arena *arena, CV_FieldAttribs attribs);
internal String8 cv_string_from_itype(Arena *arena, CV_TypeIndex min_itype, CV_TypeIndex itype); internal String8 cv_string_from_itype(Arena *arena, CV_TypeIndex min_itype, CV_TypeIndex itype);
internal String8 cv_string_from_itemid(Arena *arena, CV_ItemId itemid); internal String8 cv_string_from_itemid(Arena *arena, CV_ItemId itemid);
internal String8 cv_string_from_reg_off(Arena *arena, CV_Arch arch, U32 reg, U32 off);
internal String8 cv_string_from_symbol_type(Arena *arena, CV_SymKind symbol_type); internal String8 cv_string_from_symbol_type(Arena *arena, CV_SymKind symbol_type);
internal String8 cv_string_from_symbol_kind(Arena *arena, CV_SymKind kind); internal String8 cv_string_from_symbol_kind(Arena *arena, CV_SymKind kind);
internal String8 cv_string_from_leaf_name(Arena *arena, U32 leaf_type); internal String8 cv_string_from_leaf_name(Arena *arena, U32 leaf_type);
+4
View File
@@ -137,6 +137,10 @@ cv_u64_from_numeric(CV_NumericParsed *num)
U64 result = 0; U64 result = 0;
switch(num->kind) switch(num->kind)
{ {
case CV_NumericKind_CHAR: {result = (U64)(S64)*(S8*)num->val;}break;
case CV_NumericKind_SHORT: {result = (U64)(S64)*(S16*)num->val;}break;
case CV_NumericKind_LONG: {result = (U64)(S64)*(S32*)num->val;}break;
case CV_NumericKind_QUADWORD: {result = (U64)(S64)*(S64*)num->val;}break;
case CV_NumericKind_USHORT: {result = *(U16*)num->val;}break; case CV_NumericKind_USHORT: {result = *(U16*)num->val;}break;
case CV_NumericKind_ULONG: {result = *(U32*)num->val;}break; case CV_NumericKind_ULONG: {result = *(U32*)num->val;}break;
case CV_NumericKind_UQUADWORD:{result = *(U64*)num->val;}break; case CV_NumericKind_UQUADWORD:{result = *(U64*)num->val;}break;
+33 -33
View File
@@ -392,48 +392,48 @@ case CV_BasicType_NBASICSTR:{result = str8_lit("");}break;
case CV_BasicType_FBASICSTR:{result = str8_lit("");}break; case CV_BasicType_FBASICSTR:{result = str8_lit("");}break;
case CV_BasicType_NOTTRANS:{result = str8_lit("");}break; case CV_BasicType_NOTTRANS:{result = str8_lit("");}break;
case CV_BasicType_HRESULT:{result = str8_lit("HRESULT");}break; case CV_BasicType_HRESULT:{result = str8_lit("HRESULT");}break;
case CV_BasicType_CHAR:{result = str8_lit("char");}break; case CV_BasicType_CHAR:{result = str8_lit("CHAR");}break;
case CV_BasicType_SHORT:{result = str8_lit("S16");}break; case CV_BasicType_SHORT:{result = str8_lit("SHORT");}break;
case CV_BasicType_LONG:{result = str8_lit("S32");}break; case CV_BasicType_LONG:{result = str8_lit("LONG");}break;
case CV_BasicType_QUAD:{result = str8_lit("S64");}break; case CV_BasicType_QUAD:{result = str8_lit("QUAD");}break;
case CV_BasicType_OCT:{result = str8_lit("S128");}break; case CV_BasicType_OCT:{result = str8_lit("OCT");}break;
case CV_BasicType_UCHAR:{result = str8_lit("UCHAR");}break; case CV_BasicType_UCHAR:{result = str8_lit("UCHAR");}break;
case CV_BasicType_USHORT:{result = str8_lit("U16");}break; case CV_BasicType_USHORT:{result = str8_lit("USHORT");}break;
case CV_BasicType_ULONG:{result = str8_lit("U32");}break; case CV_BasicType_ULONG:{result = str8_lit("ULONG");}break;
case CV_BasicType_UQUAD:{result = str8_lit("U64");}break; case CV_BasicType_UQUAD:{result = str8_lit("UQUAD");}break;
case CV_BasicType_UOCT:{result = str8_lit("U128");}break; case CV_BasicType_UOCT:{result = str8_lit("UOCT");}break;
case CV_BasicType_BOOL8:{result = str8_lit("B8");}break; case CV_BasicType_BOOL8:{result = str8_lit("BOOL8");}break;
case CV_BasicType_BOOL16:{result = str8_lit("B16");}break; case CV_BasicType_BOOL16:{result = str8_lit("BOOL16");}break;
case CV_BasicType_BOOL32:{result = str8_lit("B32");}break; case CV_BasicType_BOOL32:{result = str8_lit("BOOL32");}break;
case CV_BasicType_BOOL64:{result = str8_lit("B64");}break; case CV_BasicType_BOOL64:{result = str8_lit("BOOL64");}break;
case CV_BasicType_FLOAT32:{result = str8_lit("F32");}break; case CV_BasicType_FLOAT32:{result = str8_lit("FLOAT32");}break;
case CV_BasicType_FLOAT64:{result = str8_lit("F64");}break; case CV_BasicType_FLOAT64:{result = str8_lit("FLOAT64");}break;
case CV_BasicType_FLOAT80:{result = str8_lit("F80");}break; case CV_BasicType_FLOAT80:{result = str8_lit("FLOAT80");}break;
case CV_BasicType_FLOAT128:{result = str8_lit("F128");}break; case CV_BasicType_FLOAT128:{result = str8_lit("FLOAT128");}break;
case CV_BasicType_FLOAT48:{result = str8_lit("F48");}break; case CV_BasicType_FLOAT48:{result = str8_lit("FLOAT48");}break;
case CV_BasicType_FLOAT32PP:{result = str8_lit("F32PP");}break; case CV_BasicType_FLOAT32PP:{result = str8_lit("FLOAT32PP");}break;
case CV_BasicType_FLOAT16:{result = str8_lit("F16");}break; case CV_BasicType_FLOAT16:{result = str8_lit("FLOAT16");}break;
case CV_BasicType_COMPLEX32:{result = str8_lit("ComplexF32");}break; case CV_BasicType_COMPLEX32:{result = str8_lit("ComplexF32");}break;
case CV_BasicType_COMPLEX64:{result = str8_lit("ComplexF64");}break; case CV_BasicType_COMPLEX64:{result = str8_lit("ComplexF64");}break;
case CV_BasicType_COMPLEX80:{result = str8_lit("ComplexF80");}break; case CV_BasicType_COMPLEX80:{result = str8_lit("ComplexF80");}break;
case CV_BasicType_COMPLEX128:{result = str8_lit("ComplexF128");}break; case CV_BasicType_COMPLEX128:{result = str8_lit("ComplexF128");}break;
case CV_BasicType_BIT:{result = str8_lit("");}break; case CV_BasicType_BIT:{result = str8_lit("");}break;
case CV_BasicType_PASCHAR:{result = str8_lit("");}break; case CV_BasicType_PASCHAR:{result = str8_lit("");}break;
case CV_BasicType_BOOL32FF:{result = str8_lit("B32FF");}break; case CV_BasicType_BOOL32FF:{result = str8_lit("BOOL32FF");}break;
case CV_BasicType_INT8:{result = str8_lit("S8");}break; case CV_BasicType_INT8:{result = str8_lit("int8");}break;
case CV_BasicType_UINT8:{result = str8_lit("U8");}break; case CV_BasicType_UINT8:{result = str8_lit("uint8");}break;
case CV_BasicType_RCHAR:{result = str8_lit("char");}break; case CV_BasicType_RCHAR:{result = str8_lit("char");}break;
case CV_BasicType_WCHAR:{result = str8_lit("WCHAR");}break; case CV_BasicType_WCHAR:{result = str8_lit("WCHAR");}break;
case CV_BasicType_INT16:{result = str8_lit("S16");}break; case CV_BasicType_INT16:{result = str8_lit("int16");}break;
case CV_BasicType_UINT16:{result = str8_lit("U16");}break; case CV_BasicType_UINT16:{result = str8_lit("uint16");}break;
case CV_BasicType_INT32:{result = str8_lit("S32");}break; case CV_BasicType_INT32:{result = str8_lit("int32");}break;
case CV_BasicType_UINT32:{result = str8_lit("U32");}break; case CV_BasicType_UINT32:{result = str8_lit("uint32");}break;
case CV_BasicType_INT64:{result = str8_lit("S64");}break; case CV_BasicType_INT64:{result = str8_lit("int64");}break;
case CV_BasicType_UINT64:{result = str8_lit("U64");}break; case CV_BasicType_UINT64:{result = str8_lit("uint64");}break;
case CV_BasicType_INT128:{result = str8_lit("S128");}break; case CV_BasicType_INT128:{result = str8_lit("int128");}break;
case CV_BasicType_UINT128:{result = str8_lit("U128");}break; case CV_BasicType_UINT128:{result = str8_lit("uint128");}break;
case CV_BasicType_CHAR16:{result = str8_lit("CHAR16");}break; case CV_BasicType_CHAR16:{result = str8_lit("char16");}break;
case CV_BasicType_CHAR32:{result = str8_lit("CHAR32");}break; case CV_BasicType_CHAR32:{result = str8_lit("char32");}break;
case CV_BasicType_CHAR8:{result = str8_lit("char");}break; case CV_BasicType_CHAR8:{result = str8_lit("char");}break;
case CV_BasicType_PTR:{result = str8_lit("PTR");}break; case CV_BasicType_PTR:{result = str8_lit("PTR");}break;
} }
+17 -19
View File
@@ -52,14 +52,13 @@ coff_section_flag_from_align_size(U64 align)
} }
internal String8 internal String8
coff_name_from_section_header(String8 raw_coff, COFF_SectionHeader *header, U64 string_table_off) coff_name_from_section_header(String8 string_table, COFF_SectionHeader *header)
{ {
String8 name = str8_cstring_capped(header->name, header->name + sizeof(header->name)); String8 name = str8_cstring_capped(header->name, header->name + sizeof(header->name));
if (name.str[0] == '/') { if (name.str[0] == '/') {
String8 ascii_off = str8_skip(name, 1); String8 name_off_str = str8_skip(name, 1);
U64 name_rel_off = u64_from_str8(ascii_off, 10); U64 name_off = u64_from_str8(name_off_str, 10);
U64 name_off = name_rel_off + string_table_off; name = str8_cstring_capped(string_table.str + name_off, string_table.str+string_table.size);
name = str8_cstring_capped(raw_coff.str + name_off, raw_coff.str + raw_coff.size);
} }
return name; return name;
} }
@@ -94,12 +93,11 @@ coff_parse_section_name(String8 full_name, String8 *name_out, String8 *postfix_o
} }
internal String8 internal String8
coff_read_symbol_name(String8 raw_coff, U64 string_table_off, COFF_SymbolName *name) coff_read_symbol_name(String8 string_table, COFF_SymbolName *name)
{ {
String8 name_str = str8_lit(""); String8 name_str = str8_lit("");
if (name->long_name.zeroes == 0) { if (name->long_name.zeroes == 0) {
U64 name_string_off = string_table_off + name->long_name.string_table_offset; str8_deserial_read_cstr(string_table, name->long_name.string_table_offset, &name_str);
str8_deserial_read_cstr(raw_coff, name_string_off, &name_str);
} else { } else {
U32 i; U32 i;
for (i = 0; i < sizeof(name->short_name); ++i) { for (i = 0; i < sizeof(name->short_name); ++i) {
@@ -174,8 +172,8 @@ internal U64
coff_apply_size_from_reloc(COFF_MachineType machine, COFF_RelocType x) coff_apply_size_from_reloc(COFF_MachineType machine, COFF_RelocType x)
{ {
switch (machine) { switch (machine) {
case COFF_Machine_X64: return coff_apply_size_from_reloc_x64(x); case COFF_MachineType_X64: return coff_apply_size_from_reloc_x64(x);
case COFF_Machine_X86: return coff_apply_size_from_reloc_x86(x); case COFF_MachineType_X86: return coff_apply_size_from_reloc_x86(x);
default: NotImplemented; default: NotImplemented;
} }
return 0; return 0;
@@ -221,7 +219,7 @@ coff_make_import_header_by_name(Arena *arena,
flags |= COFF_ImportBy_Name << COFF_ImportHeader_ImportByShift; flags |= COFF_ImportBy_Name << COFF_ImportHeader_ImportByShift;
COFF_ImportHeader header = {0}; COFF_ImportHeader header = {0};
header.sig1 = COFF_Machine_Unknown; header.sig1 = COFF_MachineType_Unknown;
header.sig2 = max_U16; header.sig2 = max_U16;
header.version = 0; header.version = 0;
header.machine = machine; header.machine = machine;
@@ -264,7 +262,7 @@ coff_make_import_header_by_ordinal(Arena *arena,
flags |= COFF_ImportBy_Ordinal << COFF_ImportHeader_ImportByShift; flags |= COFF_ImportBy_Ordinal << COFF_ImportHeader_ImportByShift;
COFF_ImportHeader header = {0}; COFF_ImportHeader header = {0};
header.sig1 = COFF_Machine_Unknown; header.sig1 = COFF_MachineType_Unknown;
header.sig2 = max_U16; header.sig2 = max_U16;
header.version = 0; header.version = 0;
header.machine = machine; header.machine = machine;
@@ -298,8 +296,8 @@ coff_word_size_from_machine(COFF_MachineType machine)
{ {
U64 result = 0; U64 result = 0;
switch (machine) { switch (machine) {
case COFF_Machine_X64: result = 8; break; case COFF_MachineType_X64: result = 8; break;
case COFF_Machine_X86: result = 4; break; case COFF_MachineType_X86: result = 4; break;
} }
return result; return result;
} }
@@ -332,11 +330,11 @@ arch_from_coff_machine(COFF_MachineType machine)
{ {
Arch result = Arch_Null; Arch result = Arch_Null;
switch (machine) { switch (machine) {
case COFF_Machine_Unknown: break; case COFF_MachineType_Unknown: break;
case COFF_Machine_X86: result = Arch_x86; break; case COFF_MachineType_X86: result = Arch_x86; break;
case COFF_Machine_X64: result = Arch_x64; break; case COFF_MachineType_X64: result = Arch_x64; break;
case COFF_Machine_Arm: result = Arch_arm32; break; case COFF_MachineType_Arm: result = Arch_arm32; break;
case COFF_Machine_Arm64: result = Arch_arm64; break; case COFF_MachineType_Arm64: result = Arch_arm64; break;
} }
return result; return result;
} }
+29 -29
View File
@@ -47,31 +47,31 @@ enum
typedef U16 COFF_MachineType; typedef U16 COFF_MachineType;
enum enum
{ {
COFF_Machine_Unknown = 0x0, COFF_MachineType_Unknown = 0x0,
COFF_Machine_X86 = 0x14c, COFF_MachineType_X86 = 0x14c,
COFF_Machine_X64 = 0x8664, COFF_MachineType_X64 = 0x8664,
COFF_Machine_Am33 = 0x1d3, COFF_MachineType_Am33 = 0x1d3,
COFF_Machine_Arm = 0x1c0, COFF_MachineType_Arm = 0x1c0,
COFF_Machine_Arm64 = 0xaa64, COFF_MachineType_Arm64 = 0xaa64,
COFF_Machine_ArmNt = 0x1c4, COFF_MachineType_ArmNt = 0x1c4,
COFF_Machine_Ebc = 0xebc, COFF_MachineType_Ebc = 0xebc,
COFF_Machine_Ia64 = 0x200, COFF_MachineType_Ia64 = 0x200,
COFF_Machine_M32R = 0x9041, COFF_MachineType_M32R = 0x9041,
COFF_Machine_Mips16 = 0x266, COFF_MachineType_Mips16 = 0x266,
COFF_Machine_MipsFpu = 0x366, COFF_MachineType_MipsFpu = 0x366,
COFF_Machine_MipsFpu16 = 0x466, COFF_MachineType_MipsFpu16 = 0x466,
COFF_Machine_PowerPc = 0x1f0, COFF_MachineType_PowerPc = 0x1f0,
COFF_Machine_PowerPcFp = 0x1f1, COFF_MachineType_PowerPcFp = 0x1f1,
COFF_Machine_R4000 = 0x166, COFF_MachineType_R4000 = 0x166,
COFF_Machine_RiscV32 = 0x5032, COFF_MachineType_RiscV32 = 0x5032,
COFF_Machine_RiscV64 = 0x5064, COFF_MachineType_RiscV64 = 0x5064,
COFF_Machine_RiscV128 = 0x5128, COFF_MachineType_RiscV128 = 0x5128,
COFF_Machine_Sh3 = 0x1a2, COFF_MachineType_Sh3 = 0x1a2,
COFF_Machine_Sh3Dsp = 0x1a3, COFF_MachineType_Sh3Dsp = 0x1a3,
COFF_Machine_Sh4 = 0x1a6, COFF_MachineType_Sh4 = 0x1a6,
COFF_Machine_Sh5 = 0x1a8, COFF_MachineType_Sh5 = 0x1a8,
COFF_Machine_Thumb = 0x1c2, COFF_MachineType_Thumb = 0x1c2,
COFF_Machine_WceMipsV2 = 0x169 COFF_MachineType_WceMipsV2 = 0x169
}; };
typedef struct COFF_FileHeader typedef struct COFF_FileHeader
@@ -87,7 +87,7 @@ typedef struct COFF_FileHeader
typedef struct COFF_BigObjHeader typedef struct COFF_BigObjHeader
{ {
U16 sig1; // COFF_Machine_Unknown U16 sig1; // COFF_MachineType_Unknown
U16 sig2; // max_U16 U16 sig2; // max_U16
U16 version; // 2 U16 version; // 2
COFF_MachineType machine; COFF_MachineType machine;
@@ -547,7 +547,7 @@ enum
typedef struct COFF_ImportHeader typedef struct COFF_ImportHeader
{ {
U16 sig1; // COFF_Machine_Unknown U16 sig1; // COFF_MachineType_Unknown
U16 sig2; // max_U16 U16 sig2; // max_U16
U16 version; // 0 U16 version; // 0
COFF_MachineType machine; COFF_MachineType machine;
@@ -567,13 +567,13 @@ typedef struct COFF_ImportHeader
internal U64 coff_align_size_from_section_flags(COFF_SectionFlags flags); internal U64 coff_align_size_from_section_flags(COFF_SectionFlags flags);
internal COFF_SectionFlags coff_section_flag_from_align_size (U64 align); internal COFF_SectionFlags coff_section_flag_from_align_size (U64 align);
internal String8 coff_name_from_section_header(String8 raw_coff, COFF_SectionHeader *header, U64 string_table_off); internal String8 coff_name_from_section_header(String8 string_table, COFF_SectionHeader *header);
internal void coff_parse_section_name (String8 full_name, String8 *name_out, String8 *postfix_out); internal void coff_parse_section_name (String8 full_name, String8 *name_out, String8 *postfix_out);
//////////////////////////////// ////////////////////////////////
// Symbol // Symbol
internal String8 coff_read_symbol_name(String8 raw_coff, U64 string_table_off, COFF_SymbolName *name); internal String8 coff_read_symbol_name(String8 string_table, COFF_SymbolName *name);
//////////////////////////////// ////////////////////////////////
// Reloc // Reloc
+30 -30
View File
@@ -21,31 +21,31 @@ read_only struct
String8 string; String8 string;
COFF_MachineType machine; COFF_MachineType machine;
} g_coff_machine_map[] = { } g_coff_machine_map[] = {
{ str8_lit_comp(""), COFF_Machine_Unknown }, { str8_lit_comp(""), COFF_MachineType_Unknown },
{ str8_lit_comp("X86"), COFF_Machine_X86 }, { str8_lit_comp("X86"), COFF_MachineType_X86 },
{ str8_lit_comp("Amd64"), COFF_Machine_X64 }, { str8_lit_comp("Amd64"), COFF_MachineType_X64 },
{ str8_lit_comp("X64"), COFF_Machine_X64 }, { str8_lit_comp("X64"), COFF_MachineType_X64 },
{ str8_lit_comp("Am33"), COFF_Machine_Am33 }, { str8_lit_comp("Am33"), COFF_MachineType_Am33 },
{ str8_lit_comp("Arm"), COFF_Machine_Arm }, { str8_lit_comp("Arm"), COFF_MachineType_Arm },
{ str8_lit_comp("Arm64"), COFF_Machine_Arm64 }, { str8_lit_comp("Arm64"), COFF_MachineType_Arm64 },
{ str8_lit_comp("ArmNt"), COFF_Machine_ArmNt }, { str8_lit_comp("ArmNt"), COFF_MachineType_ArmNt },
{ str8_lit_comp("Ebc"), COFF_Machine_Ebc }, { str8_lit_comp("Ebc"), COFF_MachineType_Ebc },
{ str8_lit_comp("Ia64"), COFF_Machine_Ia64 }, { str8_lit_comp("Ia64"), COFF_MachineType_Ia64 },
{ str8_lit_comp("M32r"), COFF_Machine_M32R }, { str8_lit_comp("M32r"), COFF_MachineType_M32R },
{ str8_lit_comp("Mips16"), COFF_Machine_Mips16 }, { str8_lit_comp("Mips16"), COFF_MachineType_Mips16 },
{ str8_lit_comp("MipsFpu"), COFF_Machine_MipsFpu }, { str8_lit_comp("MipsFpu"), COFF_MachineType_MipsFpu },
{ str8_lit_comp("MipsFpu16"), COFF_Machine_MipsFpu16 }, { str8_lit_comp("MipsFpu16"), COFF_MachineType_MipsFpu16 },
{ str8_lit_comp("PowerPc"), COFF_Machine_PowerPc }, { str8_lit_comp("PowerPc"), COFF_MachineType_PowerPc },
{ str8_lit_comp("PowerPcFp"), COFF_Machine_PowerPcFp }, { str8_lit_comp("PowerPcFp"), COFF_MachineType_PowerPcFp },
{ str8_lit_comp("R4000"), COFF_Machine_R4000 }, { str8_lit_comp("R4000"), COFF_MachineType_R4000 },
{ str8_lit_comp("RiscV32"), COFF_Machine_RiscV32 }, { str8_lit_comp("RiscV32"), COFF_MachineType_RiscV32 },
{ str8_lit_comp("RiscV64"), COFF_Machine_RiscV64 }, { str8_lit_comp("RiscV64"), COFF_MachineType_RiscV64 },
{ str8_lit_comp("Sh3"), COFF_Machine_Sh3 }, { str8_lit_comp("Sh3"), COFF_MachineType_Sh3 },
{ str8_lit_comp("Sh3Dsp"), COFF_Machine_Sh3Dsp }, { str8_lit_comp("Sh3Dsp"), COFF_MachineType_Sh3Dsp },
{ str8_lit_comp("Sh4"), COFF_Machine_Sh4 }, { str8_lit_comp("Sh4"), COFF_MachineType_Sh4 },
{ str8_lit_comp("Sh5"), COFF_Machine_Sh5 }, { str8_lit_comp("Sh5"), COFF_MachineType_Sh5 },
{ str8_lit_comp("Thumb"), COFF_Machine_Thumb }, { str8_lit_comp("Thumb"), COFF_MachineType_Thumb },
{ str8_lit_comp("WceMipsV2"), COFF_Machine_WceMipsV2 }, { str8_lit_comp("WceMipsV2"), COFF_MachineType_WceMipsV2 },
}; };
read_only static struct { read_only static struct {
@@ -446,10 +446,10 @@ internal String8
coff_string_from_reloc(COFF_MachineType machine, COFF_RelocType x) coff_string_from_reloc(COFF_MachineType machine, COFF_RelocType x)
{ {
switch (machine) { switch (machine) {
case COFF_Machine_X86: return coff_string_from_reloc_x86(x); case COFF_MachineType_X86: return coff_string_from_reloc_x86(x);
case COFF_Machine_X64: return coff_string_from_reloc_x64(x); case COFF_MachineType_X64: return coff_string_from_reloc_x64(x);
case COFF_Machine_Arm: return coff_string_from_reloc_arm(x); case COFF_MachineType_Arm: return coff_string_from_reloc_arm(x);
case COFF_Machine_Arm64: return coff_string_from_reloc_arm64(x); case COFF_MachineType_Arm64: return coff_string_from_reloc_arm64(x);
} }
return str8_zero(); return str8_zero();
} }
@@ -462,7 +462,7 @@ coff_machine_from_string(String8 string)
return g_coff_machine_map[i].machine; return g_coff_machine_map[i].machine;
} }
} }
return COFF_Machine_Unknown; return COFF_MachineType_Unknown;
} }
internal COFF_ImportType internal COFF_ImportType
+31 -31
View File
@@ -7,7 +7,7 @@ coff_is_big_obj(String8 raw_coff)
B32 is_big_obj = 0; B32 is_big_obj = 0;
if (raw_coff.size >= sizeof(COFF_BigObjHeader)) { if (raw_coff.size >= sizeof(COFF_BigObjHeader)) {
COFF_BigObjHeader *file_header32 = (COFF_BigObjHeader*)(raw_coff.str); COFF_BigObjHeader *file_header32 = (COFF_BigObjHeader*)(raw_coff.str);
is_big_obj = file_header32->sig1 == COFF_Machine_Unknown && is_big_obj = file_header32->sig1 == COFF_MachineType_Unknown &&
file_header32->sig2 == max_U16 && file_header32->sig2 == max_U16 &&
file_header32->version >= 2 && file_header32->version >= 2 &&
MemoryCompare(file_header32->magic, g_coff_big_header_magic, sizeof(file_header32->magic)) == 0; MemoryCompare(file_header32->magic, g_coff_big_header_magic, sizeof(file_header32->magic)) == 0;
@@ -26,19 +26,19 @@ coff_is_obj(String8 raw_coff)
// validate machine // validate machine
B32 is_machine_type_valid = 0; B32 is_machine_type_valid = 0;
switch (header->machine) { switch (header->machine) {
case COFF_Machine_Unknown: case COFF_MachineType_Unknown:
case COFF_Machine_X86: case COFF_Machine_X64: case COFF_MachineType_X86: case COFF_MachineType_X64:
case COFF_Machine_Am33: case COFF_Machine_Arm: case COFF_MachineType_Am33: case COFF_MachineType_Arm:
case COFF_Machine_Arm64: case COFF_Machine_ArmNt: case COFF_MachineType_Arm64: case COFF_MachineType_ArmNt:
case COFF_Machine_Ebc: case COFF_Machine_Ia64: case COFF_MachineType_Ebc: case COFF_MachineType_Ia64:
case COFF_Machine_M32R: case COFF_Machine_Mips16: case COFF_MachineType_M32R: case COFF_MachineType_Mips16:
case COFF_Machine_MipsFpu:case COFF_Machine_MipsFpu16: case COFF_MachineType_MipsFpu:case COFF_MachineType_MipsFpu16:
case COFF_Machine_PowerPc:case COFF_Machine_PowerPcFp: case COFF_MachineType_PowerPc:case COFF_MachineType_PowerPcFp:
case COFF_Machine_R4000: case COFF_Machine_RiscV32: case COFF_MachineType_R4000: case COFF_MachineType_RiscV32:
case COFF_Machine_RiscV64:case COFF_Machine_RiscV128: case COFF_MachineType_RiscV64:case COFF_MachineType_RiscV128:
case COFF_Machine_Sh3: case COFF_Machine_Sh3Dsp: case COFF_MachineType_Sh3: case COFF_MachineType_Sh3Dsp:
case COFF_Machine_Sh4: case COFF_Machine_Sh5: case COFF_MachineType_Sh4: case COFF_MachineType_Sh5:
case COFF_Machine_Thumb: case COFF_Machine_WceMipsV2: case COFF_MachineType_Thumb: case COFF_MachineType_WceMipsV2:
{ {
is_machine_type_valid = 1; is_machine_type_valid = 1;
}break; }break;
@@ -99,33 +99,33 @@ coff_file_header_info_from_data(String8 raw_coff)
COFF_BigObjHeader *header32 = (COFF_BigObjHeader*)raw_coff.str; COFF_BigObjHeader *header32 = (COFF_BigObjHeader*)raw_coff.str;
info.is_big_obj = 1; info.is_big_obj = 1;
info.machine = header32->machine; info.machine = header32->machine;
info.header_size = sizeof(COFF_BigObjHeader);
info.section_array_off = sizeof(COFF_BigObjHeader);
info.section_count_no_null = header32->section_count; info.section_count_no_null = header32->section_count;
info.string_table_off = header32->symbol_table_foff + sizeof(COFF_Symbol32) * header32->symbol_count;
info.symbol_size = sizeof(COFF_Symbol32);
info.symbol_off = header32->symbol_table_foff;
info.symbol_count = header32->symbol_count; info.symbol_count = header32->symbol_count;
info.symbol_size = sizeof(COFF_Symbol32);
info.header_range = rng_1u64(0, sizeof(COFF_BigObjHeader));
info.section_table_range = rng_1u64(info.header_range.max, info.header_range.max + sizeof(COFF_SectionHeader) * header32->section_count);
info.symbol_table_range = rng_1u64(header32->symbol_table_foff, header32->symbol_table_foff + sizeof(COFF_Symbol32) * header32->symbol_count);
info.string_table_range = rng_1u64(info.symbol_table_range.max, raw_coff.size);
} else if (coff_is_obj(raw_coff)) { } else if (coff_is_obj(raw_coff)) {
COFF_FileHeader *header16 = (COFF_FileHeader*)raw_coff.str; COFF_FileHeader *header16 = (COFF_FileHeader*)raw_coff.str;
info.is_big_obj = 0; info.is_big_obj = 0;
info.machine = header16->machine; info.machine = header16->machine;
info.header_size = sizeof(COFF_FileHeader);
info.section_array_off = sizeof(COFF_FileHeader);
info.section_count_no_null = header16->section_count; info.section_count_no_null = header16->section_count;
info.string_table_off = header16->symbol_table_foff + sizeof(COFF_Symbol16) * header16->symbol_count;
info.symbol_size = sizeof(COFF_Symbol16);
info.symbol_off = header16->symbol_table_foff;
info.symbol_count = header16->symbol_count; info.symbol_count = header16->symbol_count;
info.symbol_size = sizeof(COFF_Symbol16);
info.header_range = rng_1u64(0, sizeof(COFF_FileHeader));
info.section_table_range = rng_1u64(info.header_range.max, info.header_range.max + sizeof(COFF_SectionHeader) * header16->section_count);
info.symbol_table_range = rng_1u64(header16->symbol_table_foff, header16->symbol_table_foff + sizeof(COFF_Symbol16) * header16->symbol_count);
info.string_table_range = rng_1u64(info.symbol_table_range.max, raw_coff.size);
} }
return info; return info;
} }
internal COFF_ParsedSymbol internal COFF_ParsedSymbol
coff_parse_symbol32(String8 raw_coff, U64 string_table_off, COFF_Symbol32 *sym32) coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32)
{ {
COFF_ParsedSymbol result = {0}; COFF_ParsedSymbol result = {0};
result.name = coff_read_symbol_name(raw_coff, string_table_off, &sym32->name); result.name = coff_read_symbol_name(string_table, &sym32->name);
result.value = sym32->value; result.value = sym32->value;
result.section_number = sym32->section_number; result.section_number = sym32->section_number;
result.type = sym32->type; result.type = sym32->type;
@@ -135,10 +135,10 @@ coff_parse_symbol32(String8 raw_coff, U64 string_table_off, COFF_Symbol32 *sym32
} }
internal COFF_ParsedSymbol internal COFF_ParsedSymbol
coff_parse_symbol16(String8 raw_coff, U64 string_table_off, COFF_Symbol16 *sym16) coff_parse_symbol16(String8 string_table, COFF_Symbol16 *sym16)
{ {
COFF_ParsedSymbol result = {0}; COFF_ParsedSymbol result = {0};
result.name = coff_read_symbol_name(raw_coff, string_table_off, &sym16->name); result.name = coff_read_symbol_name(string_table, &sym16->name);
result.value = sym16->value; result.value = sym16->value;
if (sym16->section_number == COFF_Symbol_DebugSection16) { if (sym16->section_number == COFF_Symbol_DebugSection16) {
result.section_number = COFF_Symbol_DebugSection32; result.section_number = COFF_Symbol_DebugSection32;
@@ -476,15 +476,15 @@ coff_write_resource(Arena *arena,
internal int internal int
coff_resource_id_compar(void *raw_a, void *raw_b) coff_resource_id_compar(void *raw_a, void *raw_b)
{ {
int cmp = 0; int cmp;
COFF_ResourceID *a = raw_a; COFF_ResourceID *a = raw_a;
COFF_ResourceID *b = raw_b; COFF_ResourceID *b = raw_b;
if (a->type == b->type) { if (a->type == b->type) {
switch (a->type) { switch (a->type) {
default:
case COFF_ResourceIDType_Null: cmp = 0; break; case COFF_ResourceIDType_Null: cmp = 0; break;
case COFF_ResourceIDType_Number: cmp = MemoryCompare(&a->u.number, &b->u.number, sizeof(a->u.number)); break; case COFF_ResourceIDType_Number: cmp = MemoryCompare(&a->u.number, &b->u.number, sizeof(a->u.number)); break;
case COFF_ResourceIDType_String: cmp = strncmp((char *)a->u.string.str, (char *)b->u.string.str, Min(a->u.string.size, b->u.string.size)); break; case COFF_ResourceIDType_String: cmp = strncmp((char *)a->u.string.str, (char *)b->u.string.str, Min(a->u.string.size, b->u.string.size)); break;
default: InvalidPath; break;
} }
} else { } else {
cmp = a->type < b->type ? -1 : a->type > b->type ? +1 : 0; cmp = a->type < b->type ? -1 : a->type > b->type ? +1 : 0;
@@ -499,7 +499,7 @@ coff_is_import(String8 raw_archive_member)
if (raw_archive_member.size >= sizeof(U16)*2) { if (raw_archive_member.size >= sizeof(U16)*2) {
U16 *sig1 = (U16*)raw_archive_member.str; U16 *sig1 = (U16*)raw_archive_member.str;
U16 *sig2 = sig1 + 1; U16 *sig2 = sig1 + 1;
is_import = *sig1 == COFF_Machine_Unknown && *sig2 == 0xffff; is_import = *sig1 == COFF_MachineType_Unknown && *sig2 == 0xffff;
} }
return is_import; return is_import;
} }
+6 -5
View File
@@ -9,12 +9,13 @@ typedef struct COFF_FileHeaderInfo
B32 is_big_obj; B32 is_big_obj;
COFF_MachineType machine; COFF_MachineType machine;
U64 header_size; U64 header_size;
U64 section_array_off;
U64 section_count_no_null; U64 section_count_no_null;
U64 string_table_off;
U64 symbol_size; U64 symbol_size;
U64 symbol_off;
U64 symbol_count; U64 symbol_count;
Rng1U64 header_range;
Rng1U64 section_table_range;
Rng1U64 symbol_table_range;
Rng1U64 string_table_range;
} COFF_FileHeaderInfo; } COFF_FileHeaderInfo;
//////////////////////////////// ////////////////////////////////
@@ -249,8 +250,8 @@ internal COFF_FileHeaderInfo coff_file_header_info_from_data(String8 raw_coff);
//////////////////////////////// ////////////////////////////////
// Symbol // Symbol
internal COFF_ParsedSymbol coff_parse_symbol32(String8 raw_coff, U64 string_table_off, COFF_Symbol32 *sym32); internal COFF_ParsedSymbol coff_parse_symbol32(String8 string_table, COFF_Symbol32 *sym32);
internal COFF_ParsedSymbol coff_parse_symbol16(String8 raw_coff, U64 string_table_off, COFF_Symbol16 *sym16); internal COFF_ParsedSymbol coff_parse_symbol16(String8 string_table, COFF_Symbol16 *sym16);
internal COFF_Symbol32Array coff_symbol_array_from_data_16(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count); internal COFF_Symbol32Array coff_symbol_array_from_data_16(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count);
internal COFF_Symbol32Array coff_symbol_array_from_data_32(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count); internal COFF_Symbol32Array coff_symbol_array_from_data_32(Arena *arena, String8 data, U64 symbol_array_off, U64 symbol_count);
+17 -9
View File
@@ -4,17 +4,19 @@
//////////////////////////////// ////////////////////////////////
//~ rjf: Entity Kinds //~ rjf: Entity Kinds
@table(name display_string) @table(name code_name display_string)
CTRL_EntityKindTable: CTRL_EntityKindTable:
{ {
{Root "Root" } {Root root "Root" }
{Machine "Machine" } {Machine machine "Machine" }
{Process "Process" } {Process process "Process" }
{Thread "Thread" } {Thread thread "Thread" }
{Module "Module" } {Module module "Module" }
{EntryPoint "Entry Point" } {EntryPoint entry_point "Entry Point" }
{DebugInfoPath "Debug Info Path" } {DebugInfoPath debug_info_path "Debug Info Path" }
{PendingThreadName "Pending Thread Name" } {PendingThreadName pending_thread_name "Pending Thread Name" }
{PendingThreadColor pending_thread_color "Pending Thread Color" }
{Breakpoint breakpoint "Breakpoint" }
} }
@enum CTRL_EntityKind: @enum CTRL_EntityKind:
@@ -24,6 +26,12 @@ CTRL_EntityKindTable:
COUNT, COUNT,
} }
@data(String8) ctrl_entity_kind_code_name_table:
{
`{0}`,
@expand(CTRL_EntityKindTable a) `str8_lit_comp("$(a.code_name)")`
}
@data(String8) ctrl_entity_kind_display_string_table: @data(String8) ctrl_entity_kind_display_string_table:
{ {
`{0}`, `{0}`,
+1707 -842
View File
File diff suppressed because it is too large Load Diff
+271 -327
View File
@@ -13,227 +13,51 @@ typedef U64 CTRL_MachineID;
#define CTRL_MachineID_Local (1) #define CTRL_MachineID_Local (1)
//////////////////////////////// ////////////////////////////////
//~ rjf: Meta Evaluation Types //~ rjf: User Breakpoint Types
//- rjf: auto-checkbox b32s typedef U32 CTRL_UserBreakpointFlags;
enum
typedef struct CTRL_CheckB32 CTRL_CheckB32;
struct CTRL_CheckB32
{ {
B32 b32; CTRL_UserBreakpointFlag_BreakOnWrite = (1<<0),
CTRL_UserBreakpointFlag_BreakOnRead = (1<<1),
CTRL_UserBreakpointFlag_BreakOnExecute = (1<<2),
}; };
struct_members(CTRL_CheckB32) typedef enum CTRL_UserBreakpointKind
{ {
member_lit_comp(CTRL_CheckB32, type(B32), b32), CTRL_UserBreakpointKind_Null,
}; CTRL_UserBreakpointKind_FileNameAndLineColNumber,
struct_type(CTRL_CheckB32); CTRL_UserBreakpointKind_Expression,
CTRL_UserBreakpointKind_COUNT
}
CTRL_UserBreakpointKind;
//- rjf: styled string types typedef struct CTRL_UserBreakpoint CTRL_UserBreakpoint;
struct CTRL_UserBreakpoint
ptr_type(CTRL_PlainString8__str_ptr_type, type(U8), .flags = TypeFlag_IsPlainText,.count_delimiter_name = str8_lit_comp("size"));
ptr_type(CTRL_CodeString8__str_ptr_type, type(U8), .flags = TypeFlag_IsCodeText, .count_delimiter_name = str8_lit_comp("size"));
ptr_type(CTRL_PathString8__str_ptr_type, type(U8), .flags = TypeFlag_IsPathText, .count_delimiter_name = str8_lit_comp("size"));
Member CTRL_PlainString8__members[] =
{ {
member_lit_comp(String8, &CTRL_PlainString8__str_ptr_type, str, .pretty_name = str8_lit_comp("Contents")), CTRL_UserBreakpointKind kind;
member_lit_comp(String8, type(U64), size, .pretty_name = str8_lit_comp("Size")), CTRL_UserBreakpointFlags flags;
}; U64 id;
Member CTRL_CodeString8__members[] = String8 string;
{ TxtPt pt;
member_lit_comp(String8, &CTRL_CodeString8__str_ptr_type, str, .pretty_name = str8_lit_comp("Contents")), U64 size;
member_lit_comp(String8, type(U64), size, .pretty_name = str8_lit_comp("Size")), String8 condition;
};
Member CTRL_PathString8__members[] =
{
member_lit_comp(String8, &CTRL_PathString8__str_ptr_type, str, .pretty_name = str8_lit_comp("Contents")),
member_lit_comp(String8, type(U64), size, .pretty_name = str8_lit_comp("Size")),
};
named_struct_type(CTRL_PlainString8, String8, .name = str8_lit_comp("string"));
named_struct_type(CTRL_CodeString8, String8, .name = str8_lit_comp("string"));
named_struct_type(CTRL_PathString8, String8, .name = str8_lit_comp("string"));
//- rjf: meta evaluation callstack types
typedef struct CTRL_MetaEvalFrame CTRL_MetaEvalFrame;
struct CTRL_MetaEvalFrame
{
U64 vaddr;
U64 inline_depth;
};
ptr_type(CTRL_MetaEvalFrame__vaddr_type, type(void), .flags = TypeFlag_IsExternal, .size = sizeof(U64));
struct_members(CTRL_MetaEvalFrame)
{
member_lit_comp(CTRL_MetaEvalFrame, &CTRL_MetaEvalFrame__vaddr_type, vaddr),
member_lit_comp(CTRL_MetaEvalFrame, type(U64), inline_depth),
};
struct_type(CTRL_MetaEvalFrame, .name = str8_lit_comp("callstack_frame"));
typedef struct CTRL_MetaEvalFrameArray CTRL_MetaEvalFrameArray;
struct CTRL_MetaEvalFrameArray
{
U64 count;
CTRL_MetaEvalFrame *v;
};
ptr_type(CTRL_MetaEvalFrameArray__v_ptr_type, type(CTRL_MetaEvalFrame), .count_delimiter_name = str8_lit_comp("count"));
struct_members(CTRL_MetaEvalFrameArray)
{
member_lit_comp(CTRL_MetaEvalFrameArray, type(U64), count, .pretty_name = str8_lit_comp("Frame Count")),
{str8_lit_comp("v"), str8_lit_comp("Frame Addresses"), &CTRL_MetaEvalFrameArray__v_ptr_type, OffsetOf(CTRL_MetaEvalFrameArray, v)},
};
struct_type(CTRL_MetaEvalFrameArray, .name = str8_lit_comp("callstack_frames"));
//- rjf: meta evaluation instance types
typedef struct CTRL_MetaEval CTRL_MetaEval;
struct CTRL_MetaEval
{
#define CTRL_MetaEval_MemberXList \
X(B32, enabled, "Enabled")\
X(B32, frozen, "Frozen")\
X(U64, hit_count, "Hit Count")\
X(U64, id, "ID")\
X(Rng1U64, vaddr_range, "Address Range")\
X(U32, color, "Color")\
X(CTRL_CheckB32, debug_subprocesses,"Debug Subprocesses")\
Y(String8, type(CTRL_CodeString8), label, "Label")\
Y(String8, type(CTRL_PathString8), exe, "Executable Path")\
Y(String8, type(CTRL_PathString8), dbg, "Debug Info Path")\
Y(String8, type(CTRL_PlainString8), args, "Arguments")\
Y(String8, type(CTRL_PathString8), working_directory, "Working Directory")\
Y(String8, type(CTRL_CodeString8), entry_point, "Custom Entry Point")\
Y(String8, type(CTRL_PathString8), stdout_path, "Standard Output Path")\
Y(String8, type(CTRL_PathString8), stderr_path, "Standard Error Path")\
Y(String8, type(CTRL_PathString8), stdin_path, "Standard Input Path")\
Y(String8, type(CTRL_PathString8), source_location, "Source Location")\
Y(String8, type(CTRL_CodeString8), function_location, "Function Location")\
Y(String8, type(CTRL_CodeString8), address_location, "Address Location")\
Y(String8, type(CTRL_PathString8), source_path, "Source Path")\
Y(String8, type(CTRL_PathString8), destination_path, "Destination Path")\
Y(String8, type(CTRL_CodeString8), type, "Type")\
Y(String8, type(CTRL_CodeString8), view_rule, "View Rule")\
Y(String8, type(CTRL_CodeString8), condition, "Condition")\
X(CTRL_MetaEvalFrameArray, callstack, "Call Stack")
#define X(T, name, pretty_name) T name;
#define Y(T, ti, name, pretty_name) T name;
CTRL_MetaEval_MemberXList
#undef X
#undef Y
};
struct_members(CTRL_MetaEval)
{
#define X(T, name, pretty_name_) member_lit_comp(CTRL_MetaEval, type(T), name, .pretty_name = str8_lit_comp(pretty_name_)),
#define Y(T, ti, name, pretty_name_) member_lit_comp(CTRL_MetaEval, (ti), name, .pretty_name = str8_lit_comp(pretty_name_)),
CTRL_MetaEval_MemberXList
#undef X
#undef Y
};
struct_type(CTRL_MetaEval);
//- rjf: filters on main meta evaluation bundle
struct_members(CTRL_BreakpointMetaEval)
{
member_lit_comp(CTRL_MetaEval, type(B32), enabled, .pretty_name = str8_lit_comp("Enabled")),
member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")),
member_lit_comp(CTRL_MetaEval, type(U64), hit_count, .pretty_name = str8_lit_comp("Hit Count")),
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Label")),
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), condition, .pretty_name = str8_lit_comp("Condition")),
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), source_location, .pretty_name = str8_lit_comp("Source Location")),
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), function_location, .pretty_name = str8_lit_comp("Function Location")),
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), address_location, .pretty_name = str8_lit_comp("Address Location")),
}; };
struct_members(CTRL_TargetMetaEval) typedef struct CTRL_UserBreakpointNode CTRL_UserBreakpointNode;
struct CTRL_UserBreakpointNode
{ {
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Label")), CTRL_UserBreakpointNode *next;
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), exe, .pretty_name = str8_lit_comp("Executable")), CTRL_UserBreakpoint v;
member_lit_comp(CTRL_MetaEval, type(CTRL_PlainString8),args, .pretty_name = str8_lit_comp("Arguments")),
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), working_directory, .pretty_name = str8_lit_comp("Working Directory")),
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), entry_point, .pretty_name = str8_lit_comp("Custom Entry Point")),
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), stdout_path, .pretty_name = str8_lit_comp("Standard Output Path")),
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), stderr_path, .pretty_name = str8_lit_comp("Standard Error Path")),
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), stdin_path, .pretty_name = str8_lit_comp("Standard Input Path")),
member_lit_comp(CTRL_MetaEval, type(CTRL_CheckB32), debug_subprocesses, .pretty_name = str8_lit_comp("Debug Subprocesses")),
}; };
struct_members(CTRL_PinMetaEval) typedef struct CTRL_UserBreakpointList CTRL_UserBreakpointList;
struct CTRL_UserBreakpointList
{ {
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Expression")), CTRL_UserBreakpointNode *first;
member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")), CTRL_UserBreakpointNode *last;
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), source_location, .pretty_name = str8_lit_comp("Source Location")),
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), address_location, .pretty_name = str8_lit_comp("Address Location")),
};
struct_members(CTRL_FilePathMapMetaEval)
{
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), source_path, .pretty_name = str8_lit_comp("Source Path")),
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), destination_path, .pretty_name = str8_lit_comp("Destination Path")),
};
struct_members(CTRL_AutoViewRuleMetaEval)
{
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), type, .pretty_name = str8_lit_comp("Type")),
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), view_rule, .pretty_name = str8_lit_comp("View Rule")),
};
struct_members(CTRL_MachineMetaEval)
{
member_lit_comp(CTRL_MetaEval, type(B32), frozen, .pretty_name = str8_lit_comp("Frozen")),
member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")),
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Name")),
};
struct_members(CTRL_ProcessMetaEval)
{
member_lit_comp(CTRL_MetaEval, type(B32), frozen, .pretty_name = str8_lit_comp("Frozen")),
member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")),
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Name")),
member_lit_comp(CTRL_MetaEval, type(U64), id, .pretty_name = str8_lit_comp("ID")),
};
struct_members(CTRL_ModuleMetaEval)
{
member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")),
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Name")),
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), exe, .pretty_name = str8_lit_comp("Executable Path")),
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), dbg, .pretty_name = str8_lit_comp("Debug Info Path")),
member_lit_comp(CTRL_MetaEval, type(Rng1U64), vaddr_range, .pretty_name = str8_lit_comp("Address Range")),
};
struct_members(CTRL_ThreadMetaEval)
{
member_lit_comp(CTRL_MetaEval, type(B32), frozen, .pretty_name = str8_lit_comp("Frozen")),
member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")),
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Name")),
member_lit_comp(CTRL_MetaEval, type(U64), id, .pretty_name = str8_lit_comp("ID")),
member_lit_comp(CTRL_MetaEval, type(CTRL_MetaEvalFrameArray), callstack, .pretty_name = str8_lit_comp("Call Stack")),
};
named_struct_type(CTRL_BreakpointMetaEval, CTRL_MetaEval, .name = str8_lit_comp("breakpoint"));
named_struct_type(CTRL_TargetMetaEval, CTRL_MetaEval, .name = str8_lit_comp("target"));
named_struct_type(CTRL_PinMetaEval, CTRL_MetaEval, .name = str8_lit_comp("pin"));
named_struct_type(CTRL_FilePathMapMetaEval, CTRL_MetaEval, .name = str8_lit_comp("file_path_map"));
named_struct_type(CTRL_AutoViewRuleMetaEval,CTRL_MetaEval, .name = str8_lit_comp("auto_view_rule"));
named_struct_type(CTRL_MachineMetaEval, CTRL_MetaEval, .name = str8_lit_comp("machine"));
named_struct_type(CTRL_ProcessMetaEval, CTRL_MetaEval, .name = str8_lit_comp("process"));
named_struct_type(CTRL_ModuleMetaEval, CTRL_MetaEval, .name = str8_lit_comp("module"));
named_struct_type(CTRL_ThreadMetaEval, CTRL_MetaEval, .name = str8_lit_comp("thread"));
//- rjf: meta evaluation array
typedef struct CTRL_MetaEvalArray CTRL_MetaEvalArray;
struct CTRL_MetaEvalArray
{
CTRL_MetaEval *v;
U64 count; U64 count;
}; };
ptr_type(CTRL_MetaEvalArray__v_ptr_type, type(CTRL_BreakpointMetaEval), .count_delimiter_name = str8_lit_comp("count"));
struct_members(CTRL_MetaEvalArray)
{
{str8_lit_comp("v"), {0}, &CTRL_MetaEvalArray__v_ptr_type, OffsetOf(CTRL_MetaEvalArray, v)},
member_lit_comp(CTRL_MetaEvalArray, type(U64), count),
};
struct_type(CTRL_MetaEvalArray);
//////////////////////////////// ////////////////////////////////
//~ rjf: Entity Handle Types //~ rjf: Entity Handle Types
@@ -279,12 +103,14 @@ struct CTRL_Entity
CTRL_EntityKind kind; CTRL_EntityKind kind;
Arch arch; Arch arch;
B32 is_frozen; B32 is_frozen;
B32 is_soloed;
U32 rgba; U32 rgba;
CTRL_Handle handle; CTRL_Handle handle;
U64 id; U64 id;
Rng1U64 vaddr_range; Rng1U64 vaddr_range;
U64 stack_base; U64 stack_base;
U64 timestamp; U64 timestamp;
CTRL_UserBreakpointFlags bp_flags;
String8 string; String8 string;
}; };
@@ -340,21 +166,45 @@ struct CTRL_EntityStringChunkNode
U64 size; U64 size;
}; };
typedef struct CTRL_EntityStore CTRL_EntityStore; read_only global U64 ctrl_entity_string_bucket_chunk_sizes[] =
struct CTRL_EntityStore {
16,
64,
256,
1024,
4096,
16384,
65536,
0xffffffffffffffffull,
};
typedef struct CTRL_EntityCtx CTRL_EntityCtx;
struct CTRL_EntityCtx
{
CTRL_Entity *root;
U64 hash_slots_count;
CTRL_EntityHashSlot *hash_slots;
U64 entity_kind_counts[CTRL_EntityKind_COUNT];
U64 entity_kind_alloc_gens[CTRL_EntityKind_COUNT];
};
typedef struct CTRL_EntityCtxRWStore CTRL_EntityCtxRWStore;
struct CTRL_EntityCtxRWStore
{ {
Arena *arena; Arena *arena;
CTRL_Entity *root; CTRL_EntityCtx ctx;
CTRL_Entity *free; CTRL_Entity *free;
CTRL_EntityHashSlot *hash_slots;
CTRL_EntityHashNode *hash_node_free; CTRL_EntityHashNode *hash_node_free;
U64 hash_slots_count; CTRL_EntityStringChunkNode *free_string_chunks[ArrayCount(ctrl_entity_string_bucket_chunk_sizes)];
CTRL_EntityStringChunkNode *free_string_chunks[8]; };
U64 entity_kind_counts[CTRL_EntityKind_COUNT];
Arena *entity_kind_lists_arenas[CTRL_EntityKind_COUNT]; typedef struct CTRL_EntityCtxLookupAccel CTRL_EntityCtxLookupAccel;
U64 entity_kind_lists_gens[CTRL_EntityKind_COUNT]; struct CTRL_EntityCtxLookupAccel
U64 entity_kind_alloc_gens[CTRL_EntityKind_COUNT]; {
CTRL_EntityList entity_kind_lists[CTRL_EntityKind_COUNT]; Arena *arena;
Arena *entity_kind_arrays_arenas[CTRL_EntityKind_COUNT];
CTRL_EntityArray entity_kind_arrays[CTRL_EntityKind_COUNT];
U64 entity_kind_arrays_gens[CTRL_EntityKind_COUNT];
}; };
//////////////////////////////// ////////////////////////////////
@@ -404,32 +254,21 @@ struct CTRL_Unwind
//////////////////////////////// ////////////////////////////////
//~ rjf: Call Stack Types //~ rjf: Call Stack Types
typedef struct CTRL_CallStackInlineFrame CTRL_CallStackInlineFrame;
struct CTRL_CallStackInlineFrame
{
CTRL_CallStackInlineFrame *next;
CTRL_CallStackInlineFrame *prev;
RDI_InlineSite *inline_site;
};
typedef struct CTRL_CallStackFrame CTRL_CallStackFrame; typedef struct CTRL_CallStackFrame CTRL_CallStackFrame;
struct CTRL_CallStackFrame struct CTRL_CallStackFrame
{ {
CTRL_CallStackInlineFrame *first_inline_frame; U64 unwind_count;
CTRL_CallStackInlineFrame *last_inline_frame; U64 inline_depth;
U64 inline_frame_count;
void *regs; void *regs;
RDI_Parsed *rdi;
RDI_Procedure *procedure;
}; };
typedef struct CTRL_CallStack CTRL_CallStack; typedef struct CTRL_CallStack CTRL_CallStack;
struct CTRL_CallStack struct CTRL_CallStack
{ {
CTRL_CallStackFrame *frames; CTRL_CallStackFrame *frames;
U64 concrete_frame_count; U64 frames_count;
U64 inline_frame_count; CTRL_CallStackFrame **concrete_frames;
U64 total_frame_count; U64 concrete_frames_count;
}; };
//////////////////////////////// ////////////////////////////////
@@ -476,44 +315,6 @@ struct CTRL_Spoof
U64 new_ip_value; U64 new_ip_value;
}; };
////////////////////////////////
//~ rjf: User Breakpoint Types
typedef enum CTRL_UserBreakpointKind
{
CTRL_UserBreakpointKind_Null,
CTRL_UserBreakpointKind_FileNameAndLineColNumber,
CTRL_UserBreakpointKind_SymbolNameAndOffset,
CTRL_UserBreakpointKind_VirtualAddress,
CTRL_UserBreakpointKind_COUNT
}
CTRL_UserBreakpointKind;
typedef struct CTRL_UserBreakpoint CTRL_UserBreakpoint;
struct CTRL_UserBreakpoint
{
CTRL_UserBreakpointKind kind;
String8 string;
TxtPt pt;
U64 u64;
String8 condition;
};
typedef struct CTRL_UserBreakpointNode CTRL_UserBreakpointNode;
struct CTRL_UserBreakpointNode
{
CTRL_UserBreakpointNode *next;
CTRL_UserBreakpoint v;
};
typedef struct CTRL_UserBreakpointList CTRL_UserBreakpointList;
struct CTRL_UserBreakpointList
{
CTRL_UserBreakpointNode *first;
CTRL_UserBreakpointNode *last;
U64 count;
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Evaluation Spaces //~ rjf: Evaluation Spaces
@@ -573,7 +374,6 @@ struct CTRL_Msg
String8 stdin_path; String8 stdin_path;
CTRL_TrapList traps; CTRL_TrapList traps;
CTRL_UserBreakpointList user_bps; CTRL_UserBreakpointList user_bps;
CTRL_MetaEvalArray meta_evals;
}; };
typedef struct CTRL_MsgNode CTRL_MsgNode; typedef struct CTRL_MsgNode CTRL_MsgNode;
@@ -618,10 +418,12 @@ typedef enum CTRL_EventKind
//- rjf: debug info changes //- rjf: debug info changes
CTRL_EventKind_ModuleDebugInfoPathChange, CTRL_EventKind_ModuleDebugInfoPathChange,
//- rjf: debug strings / decorations //- rjf: debug strings / decorations / markup
CTRL_EventKind_DebugString, CTRL_EventKind_DebugString,
CTRL_EventKind_ThreadName, CTRL_EventKind_ThreadName,
CTRL_EventKind_ThreadColor, CTRL_EventKind_ThreadColor,
CTRL_EventKind_SetBreakpoint,
CTRL_EventKind_UnsetBreakpoint,
//- rjf: memory //- rjf: memory
CTRL_EventKind_MemReserve, CTRL_EventKind_MemReserve,
@@ -677,6 +479,7 @@ struct CTRL_Event
U64 timestamp; U64 timestamp;
U32 exception_code; U32 exception_code;
U32 rgba; U32 rgba;
CTRL_UserBreakpointFlags bp_flags;
String8 string; String8 string;
}; };
@@ -702,13 +505,19 @@ typedef struct CTRL_ProcessMemoryRangeHashNode CTRL_ProcessMemoryRangeHashNode;
struct CTRL_ProcessMemoryRangeHashNode struct CTRL_ProcessMemoryRangeHashNode
{ {
CTRL_ProcessMemoryRangeHashNode *next; CTRL_ProcessMemoryRangeHashNode *next;
// rjf: key
Rng1U64 vaddr_range; Rng1U64 vaddr_range;
B32 zero_terminated; B32 zero_terminated;
Rng1U64 vaddr_range_clamped; HS_ID id;
U128 hash;
// rjf: staleness info
U64 mem_gen; U64 mem_gen;
// rjf: metadata
U64 working_count;
U64 last_time_requested_us; U64 last_time_requested_us;
B32 is_taken; U64 last_user_clock_idx_touched;
}; };
typedef struct CTRL_ProcessMemoryRangeHashSlot CTRL_ProcessMemoryRangeHashSlot; typedef struct CTRL_ProcessMemoryRangeHashSlot CTRL_ProcessMemoryRangeHashSlot;
@@ -725,6 +534,7 @@ struct CTRL_ProcessMemoryCacheNode
CTRL_ProcessMemoryCacheNode *prev; CTRL_ProcessMemoryCacheNode *prev;
Arena *arena; Arena *arena;
CTRL_Handle handle; CTRL_Handle handle;
HS_Root root;
U64 range_hash_slots_count; U64 range_hash_slots_count;
CTRL_ProcessMemoryRangeHashSlot *range_hash_slots; CTRL_ProcessMemoryRangeHashSlot *range_hash_slots;
}; };
@@ -800,6 +610,53 @@ struct CTRL_ThreadRegCache
CTRL_ThreadRegCacheStripe *stripes; CTRL_ThreadRegCacheStripe *stripes;
}; };
////////////////////////////////
//~ rjf: Call Stack Cache Types
typedef struct CTRL_CallStackCacheNode CTRL_CallStackCacheNode;
struct CTRL_CallStackCacheNode
{
CTRL_CallStackCacheNode *next;
CTRL_CallStackCacheNode *prev;
// rjf: key
CTRL_Handle thread;
U64 reg_gen;
U64 mem_gen;
// rjf: counters
U64 scope_touch_count;
U64 working_count;
// rjf: value
Arena *arena;
CTRL_CallStack call_stack;
};
typedef struct CTRL_CallStackCacheSlot CTRL_CallStackCacheSlot;
struct CTRL_CallStackCacheSlot
{
CTRL_CallStackCacheNode *first;
CTRL_CallStackCacheNode *last;
};
typedef struct CTRL_CallStackCacheStripe CTRL_CallStackCacheStripe;
struct CTRL_CallStackCacheStripe
{
Arena *arena;
OS_Handle rw_mutex;
OS_Handle cv;
};
typedef struct CTRL_CallStackCache CTRL_CallStackCache;
struct CTRL_CallStackCache
{
U64 slots_count;
CTRL_CallStackCacheSlot *slots;
U64 stripes_count;
CTRL_CallStackCacheStripe *stripes;
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Module Image Info Cache Types //~ rjf: Module Image Info Cache Types
@@ -815,6 +672,8 @@ struct CTRL_ModuleImageInfoCacheNode
U64 entry_point_voff; U64 entry_point_voff;
Rng1U64 tls_vaddr_range; Rng1U64 tls_vaddr_range;
String8 initial_debug_info_path; String8 initial_debug_info_path;
Rng1U64 raddbg_section_voff_range;
String8 raddbg_data;
}; };
typedef struct CTRL_ModuleImageInfoCacheSlot CTRL_ModuleImageInfoCacheSlot; typedef struct CTRL_ModuleImageInfoCacheSlot CTRL_ModuleImageInfoCacheSlot;
@@ -857,6 +716,45 @@ struct CTRL_DbgDirNode
U64 module_direct_count; U64 module_direct_count;
}; };
////////////////////////////////
//~ rjf: Control Thread Evaluation Scopes
typedef struct CTRL_EvalScope CTRL_EvalScope;
struct CTRL_EvalScope
{
DI_Scope *di_scope;
E_BaseCtx base_ctx;
E_IRCtx ir_ctx;
E_InterpretCtx interpret_ctx;
};
////////////////////////////////
//~ rjf: Control Cache Accessing Scopes
typedef struct CTRL_ScopeCallStackTouch CTRL_ScopeCallStackTouch;
struct CTRL_ScopeCallStackTouch
{
CTRL_ScopeCallStackTouch *next;
CTRL_CallStackCacheStripe *stripe;
CTRL_CallStackCacheNode *node;
};
typedef struct CTRL_Scope CTRL_Scope;
struct CTRL_Scope
{
CTRL_Scope *next;
CTRL_ScopeCallStackTouch *first_call_stack_touch;
CTRL_ScopeCallStackTouch *last_call_stack_touch;
};
typedef struct CTRL_TCTX CTRL_TCTX;
struct CTRL_TCTX
{
Arena *arena;
CTRL_Scope *free_scope;
CTRL_ScopeCallStackTouch *free_call_stack_touch;
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Wakeup Hook Function Types //~ rjf: Wakeup Hook Function Types
@@ -879,6 +777,7 @@ struct CTRL_State
// rjf: caches // rjf: caches
CTRL_ProcessMemoryCache process_memory_cache; CTRL_ProcessMemoryCache process_memory_cache;
CTRL_ThreadRegCache thread_reg_cache; CTRL_ThreadRegCache thread_reg_cache;
CTRL_CallStackCache call_stack_cache;
CTRL_ModuleImageInfoCache module_image_info_cache; CTRL_ModuleImageInfoCache module_image_info_cache;
// rjf: user -> ctrl msg ring buffer // rjf: user -> ctrl msg ring buffer
@@ -899,18 +798,19 @@ struct CTRL_State
OS_Handle c2u_ring_cv; OS_Handle c2u_ring_cv;
// rjf: ctrl thread state // rjf: ctrl thread state
U64 ctrl_thread_run_state;
String8 ctrl_thread_log_path; String8 ctrl_thread_log_path;
OS_Handle ctrl_thread; OS_Handle ctrl_thread;
Log *ctrl_thread_log; Log *ctrl_thread_log;
CTRL_EntityStore *ctrl_thread_entity_store; OS_Handle ctrl_thread_entity_ctx_rw_mutex;
CTRL_EntityCtxRWStore *ctrl_thread_entity_store;
E_Cache *ctrl_thread_eval_cache;
Arena *dmn_event_arena; Arena *dmn_event_arena;
DMN_EventNode *first_dmn_event_node; DMN_EventNode *first_dmn_event_node;
DMN_EventNode *last_dmn_event_node; DMN_EventNode *last_dmn_event_node;
DMN_EventNode *free_dmn_event_node; DMN_EventNode *free_dmn_event_node;
Arena *user_entry_point_arena; Arena *user_entry_point_arena;
String8List user_entry_points; String8List user_entry_points;
Arena *user_meta_eval_arena;
CTRL_MetaEvalArray user_meta_evals;
U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64]; U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64];
U64 process_counter; U64 process_counter;
Arena *dbg_dir_arena; Arena *dbg_dir_arena;
@@ -923,6 +823,14 @@ struct CTRL_State
U64 u2ms_ring_read_pos; U64 u2ms_ring_read_pos;
OS_Handle u2ms_ring_mutex; OS_Handle u2ms_ring_mutex;
OS_Handle u2ms_ring_cv; OS_Handle u2ms_ring_cv;
// rjf: user -> call stack builder ring buffer
U64 u2csb_ring_size;
U8 *u2csb_ring_base;
U64 u2csb_ring_write_pos;
U64 u2csb_ring_read_pos;
OS_Handle u2csb_ring_mutex;
OS_Handle u2csb_ring_cv;
}; };
//////////////////////////////// ////////////////////////////////
@@ -937,6 +845,8 @@ read_only global CTRL_Entity ctrl_entity_nil =
&ctrl_entity_nil, &ctrl_entity_nil,
&ctrl_entity_nil, &ctrl_entity_nil,
}; };
thread_static CTRL_TCTX *ctrl_tctx = 0;
thread_static CTRL_EntityCtxLookupAccel *ctrl_entity_ctx_lookup_accel = 0;
//////////////////////////////// ////////////////////////////////
//~ rjf: Logging Markup //~ rjf: Logging Markup
@@ -949,8 +859,12 @@ read_only global CTRL_Entity ctrl_entity_nil =
internal U64 ctrl_hash_from_string(String8 string); internal U64 ctrl_hash_from_string(String8 string);
internal U64 ctrl_hash_from_handle(CTRL_Handle handle); internal U64 ctrl_hash_from_handle(CTRL_Handle handle);
internal CTRL_EventCause ctrl_event_cause_from_dmn_event_kind(DMN_EventKind event_kind); internal CTRL_EventCause ctrl_event_cause_from_dmn_event_kind(DMN_EventKind event_kind);
internal CTRL_ExceptionKind ctrl_exception_kind_from_dmn(DMN_ExceptionKind kind);
internal String8 ctrl_string_from_event_kind(CTRL_EventKind kind); internal String8 ctrl_string_from_event_kind(CTRL_EventKind kind);
internal String8 ctrl_string_from_msg_kind(CTRL_MsgKind kind); internal String8 ctrl_string_from_msg_kind(CTRL_MsgKind kind);
internal CTRL_EntityKind ctrl_entity_kind_from_string(String8 string);
internal DMN_TrapFlags ctrl_dmn_trap_flags_from_user_breakpoint_flags(CTRL_UserBreakpointFlags flags);
internal CTRL_UserBreakpointFlags ctrl_user_breakpoint_flags_from_dmn_trap_flags(DMN_TrapFlags flags);
//////////////////////////////// ////////////////////////////////
//~ rjf: Handle Type Functions //~ rjf: Handle Type Functions
@@ -960,6 +874,8 @@ internal CTRL_Handle ctrl_handle_make(CTRL_MachineID machine_id, DMN_Handle dmn_
internal B32 ctrl_handle_match(CTRL_Handle a, CTRL_Handle b); internal B32 ctrl_handle_match(CTRL_Handle a, CTRL_Handle b);
internal void ctrl_handle_list_push(Arena *arena, CTRL_HandleList *list, CTRL_Handle *pair); internal void ctrl_handle_list_push(Arena *arena, CTRL_HandleList *list, CTRL_Handle *pair);
internal CTRL_HandleList ctrl_handle_list_copy(Arena *arena, CTRL_HandleList *src); internal CTRL_HandleList ctrl_handle_list_copy(Arena *arena, CTRL_HandleList *src);
internal String8 ctrl_string_from_handle(Arena *arena, CTRL_Handle handle);
internal CTRL_Handle ctrl_handle_from_string(String8 string);
//////////////////////////////// ////////////////////////////////
//~ rjf: Trap Type Functions //~ rjf: Trap Type Functions
@@ -1004,38 +920,21 @@ internal CTRL_Event ctrl_event_from_serialized_string(Arena *arena, String8 stri
//- rjf: entity list data structures //- rjf: entity list data structures
internal void ctrl_entity_list_push(Arena *arena, CTRL_EntityList *list, CTRL_Entity *entity); internal void ctrl_entity_list_push(Arena *arena, CTRL_EntityList *list, CTRL_Entity *entity);
internal CTRL_EntityList ctrl_entity_list_from_handle_list(Arena *arena, CTRL_EntityStore *store, CTRL_HandleList *list); internal CTRL_EntityList ctrl_entity_list_from_handle_list(Arena *arena, CTRL_EntityCtx *ctx, CTRL_HandleList *list);
#define ctrl_entity_list_first(list) ((list)->first ? (list)->first->v : &ctrl_entity_nil) #define ctrl_entity_list_first(list) ((list)->first ? (list)->first->v : &ctrl_entity_nil)
//- rjf: entity array data structure //- rjf: entity array data structure
internal CTRL_EntityArray ctrl_entity_array_from_list(Arena *arena, CTRL_EntityList *list); internal CTRL_EntityArray ctrl_entity_array_from_list(Arena *arena, CTRL_EntityList *list);
#define ctrl_entity_array_first(array) ((array)->count != 0 ? (array)->v[0] : &ctrl_entity_nil)
//- rjf: cache creation/destruction //- rjf: entity context (entity group read-only) functions
internal CTRL_EntityStore *ctrl_entity_store_alloc(void); internal CTRL_Entity *ctrl_entity_from_handle(CTRL_EntityCtx *ctx, CTRL_Handle handle);
internal void ctrl_entity_store_release(CTRL_EntityStore *store);
//- rjf: string allocation/deletion
internal U64 ctrl_name_bucket_idx_from_string_size(U64 size);
internal String8 ctrl_entity_string_alloc(CTRL_EntityStore *store, String8 string);
internal void ctrl_entity_string_release(CTRL_EntityStore *store, String8 string);
//- rjf: entity construction/deletion
internal CTRL_Entity *ctrl_entity_alloc(CTRL_EntityStore *store, CTRL_Entity *parent, CTRL_EntityKind kind, Arch arch, CTRL_Handle handle, U64 id);
internal void ctrl_entity_release(CTRL_EntityStore *store, CTRL_Entity *entity);
//- rjf: entity equipment
internal void ctrl_entity_equip_string(CTRL_EntityStore *store, CTRL_Entity *entity, String8 string);
//- rjf: entity store lookups
internal CTRL_Entity *ctrl_entity_from_handle(CTRL_EntityStore *store, CTRL_Handle handle);
internal CTRL_Entity *ctrl_entity_child_from_kind(CTRL_Entity *parent, CTRL_EntityKind kind); internal CTRL_Entity *ctrl_entity_child_from_kind(CTRL_Entity *parent, CTRL_EntityKind kind);
internal CTRL_Entity *ctrl_entity_ancestor_from_kind(CTRL_Entity *entity, CTRL_EntityKind kind); internal CTRL_Entity *ctrl_entity_ancestor_from_kind(CTRL_Entity *entity, CTRL_EntityKind kind);
internal CTRL_Entity *ctrl_process_from_entity(CTRL_Entity *entity); internal CTRL_Entity *ctrl_process_from_entity(CTRL_Entity *entity);
internal CTRL_Entity *ctrl_module_from_process_vaddr(CTRL_Entity *process, U64 vaddr); internal CTRL_Entity *ctrl_module_from_process_vaddr(CTRL_Entity *process, U64 vaddr);
internal DI_Key ctrl_dbgi_key_from_module(CTRL_Entity *module); internal DI_Key ctrl_dbgi_key_from_module(CTRL_Entity *module);
internal CTRL_EntityList ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityStore *store, DI_Key *dbgi_key); internal CTRL_Entity *ctrl_module_from_thread_candidates(CTRL_EntityCtx *ctx, CTRL_Entity *thread, CTRL_EntityList *candidates);
internal CTRL_Entity *ctrl_module_from_thread_candidates(CTRL_EntityStore *store, CTRL_Entity *thread, CTRL_EntityList *candidates);
internal CTRL_EntityList ctrl_entity_list_from_kind(CTRL_EntityStore *store, CTRL_EntityKind kind);
internal U64 ctrl_vaddr_from_voff(CTRL_Entity *module, U64 voff); internal U64 ctrl_vaddr_from_voff(CTRL_Entity *module, U64 voff);
internal U64 ctrl_voff_from_vaddr(CTRL_Entity *module, U64 vaddr); internal U64 ctrl_voff_from_vaddr(CTRL_Entity *module, U64 vaddr);
internal Rng1U64 ctrl_vaddr_range_from_voff_range(CTRL_Entity *module, Rng1U64 voff_range); internal Rng1U64 ctrl_vaddr_range_from_voff_range(CTRL_Entity *module, Rng1U64 voff_range);
@@ -1047,8 +946,37 @@ internal CTRL_EntityRec ctrl_entity_rec_depth_first(CTRL_Entity *entity, CTRL_En
#define ctrl_entity_rec_depth_first_pre(entity, subtree_root) ctrl_entity_rec_depth_first((entity), (subtree_root), OffsetOf(CTRL_Entity, next), OffsetOf(CTRL_Entity, first)) #define ctrl_entity_rec_depth_first_pre(entity, subtree_root) ctrl_entity_rec_depth_first((entity), (subtree_root), OffsetOf(CTRL_Entity, next), OffsetOf(CTRL_Entity, first))
#define ctrl_entity_rec_depth_first_post(entity, subtree_root) ctrl_entity_rec_depth_first((entity), (subtree_root), OffsetOf(CTRL_Entity, prev), OffsetOf(CTRL_Entity, last)) #define ctrl_entity_rec_depth_first_post(entity, subtree_root) ctrl_entity_rec_depth_first((entity), (subtree_root), OffsetOf(CTRL_Entity, prev), OffsetOf(CTRL_Entity, last))
//- rjf: entity ctx r/w store state functions
internal CTRL_EntityCtxRWStore *ctrl_entity_ctx_rw_store_alloc(void);
internal void ctrl_entity_ctx_rw_store_release(CTRL_EntityCtxRWStore *store);
//- rjf: string allocation/deletion
internal U64 ctrl_name_bucket_num_from_string_size(U64 size);
internal String8 ctrl_entity_string_alloc(CTRL_EntityCtxRWStore *store, String8 string);
internal void ctrl_entity_string_release(CTRL_EntityCtxRWStore *store, String8 string);
//- rjf: entity construction/deletion
internal CTRL_Entity *ctrl_entity_alloc(CTRL_EntityCtxRWStore *store, CTRL_Entity *parent, CTRL_EntityKind kind, Arch arch, CTRL_Handle handle, U64 id);
internal void ctrl_entity_release(CTRL_EntityCtxRWStore *store, CTRL_Entity *entity);
//- rjf: entity equipment
internal void ctrl_entity_equip_string(CTRL_EntityCtxRWStore *store, CTRL_Entity *entity, String8 string);
//- rjf: accelerated entity context lookups
internal CTRL_EntityCtxLookupAccel *ctrl_thread_entity_ctx_lookup_accel(void);
internal CTRL_EntityArray ctrl_entity_array_from_kind(CTRL_EntityCtx *ctx, CTRL_EntityKind kind);
internal CTRL_EntityList ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityCtx *ctx, DI_Key *dbgi_key);
internal CTRL_Entity *ctrl_thread_from_id(CTRL_EntityCtx *ctx, U64 id);
//- rjf: applying events to entity caches //- rjf: applying events to entity caches
internal void ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list); internal void ctrl_entity_store_apply_events(CTRL_EntityCtxRWStore *store, CTRL_EventList *list);
////////////////////////////////
//~ rjf: Cache Accessing Scopes
internal CTRL_Scope *ctrl_scope_open(void);
internal void ctrl_scope_close(CTRL_Scope *scope);
internal void ctrl_scope_touch_call_stack_node__stripe_r_guarded(CTRL_Scope *scope, CTRL_CallStackCacheStripe *stripe, CTRL_CallStackCacheNode *node);
//////////////////////////////// ////////////////////////////////
//~ rjf: Main Layer Initialization //~ rjf: Main Layer Initialization
@@ -1063,18 +991,13 @@ internal void ctrl_set_wakeup_hook(CTRL_WakeupFunctionType *wakeup_hook);
//////////////////////////////// ////////////////////////////////
//~ rjf: Process Memory Functions //~ rjf: Process Memory Functions
//- rjf: process memory cache interaction //- rjf: process memory cache key reading
internal U128 ctrl_calc_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated); internal HS_Key ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us, B32 *out_is_stale);
internal U128 ctrl_stored_hash_from_process_vaddr_range(CTRL_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_Handle process, Rng1U64 range, B32 zero_terminated);
//- rjf: process memory cache reading helpers //- rjf: process memory cache reading helpers
internal CTRL_ProcessMemorySlice ctrl_query_cached_data_from_process_vaddr_range(Arena *arena, CTRL_Handle process, Rng1U64 range, U64 endt_us); internal CTRL_ProcessMemorySlice ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rng1U64 range, U64 endt_us);
internal CTRL_ProcessMemorySlice ctrl_query_cached_zero_terminated_data_from_process_vaddr_limit(Arena *arena, CTRL_Handle process, U64 vaddr, U64 limit, U64 element_size, U64 endt_us); internal B32 ctrl_process_memory_read(CTRL_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 endt_us);
internal B32 ctrl_read_cached_process_memory(CTRL_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 endt_us); #define ctrl_process_memory_read_struct(process, vaddr, is_stale_out, ptr, endt_us) ctrl_process_memory_read((process), r1u64((vaddr), (vaddr)+(sizeof(*(ptr)))), (is_stale_out), (ptr), (endt_us))
#define ctrl_read_cached_process_memory_struct(process, vaddr, is_stale_out, ptr, endt_us) ctrl_read_cached_process_memory((process), r1u64((vaddr), (vaddr)+(sizeof(*(ptr)))), (is_stale_out), (ptr), (endt_us))
//- rjf: process memory writing //- rjf: process memory writing
internal B32 ctrl_process_write(CTRL_Handle process, Rng1U64 range, void *src); internal B32 ctrl_process_write(CTRL_Handle process, Rng1U64 range, void *src);
@@ -1083,10 +1006,10 @@ internal B32 ctrl_process_write(CTRL_Handle process, Rng1U64 range, void *src);
//~ rjf: Thread Register Functions //~ rjf: Thread Register Functions
//- rjf: thread register cache reading //- rjf: thread register cache reading
internal void *ctrl_query_cached_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle handle); internal void *ctrl_reg_block_from_thread(Arena *arena, CTRL_EntityCtx *ctx, CTRL_Handle handle);
internal U64 ctrl_query_cached_tls_root_vaddr_from_thread(CTRL_EntityStore *store, CTRL_Handle handle); internal U64 ctrl_tls_root_vaddr_from_thread(CTRL_EntityCtx *ctx, CTRL_Handle handle);
internal U64 ctrl_query_cached_rip_from_thread(CTRL_EntityStore *store, CTRL_Handle handle); internal U64 ctrl_rip_from_thread(CTRL_EntityCtx *ctx, CTRL_Handle handle);
internal U64 ctrl_query_cached_rsp_from_thread(CTRL_EntityStore *store, CTRL_Handle handle); internal U64 ctrl_rsp_from_thread(CTRL_EntityCtx *ctx, CTRL_Handle handle);
//- rjf: thread register writing //- rjf: thread register writing
internal B32 ctrl_thread_write_reg_block(CTRL_Handle thread, void *block); internal B32 ctrl_thread_write_reg_block(CTRL_Handle thread, void *block);
@@ -1099,6 +1022,7 @@ internal PE_IntelPdata *ctrl_intel_pdata_from_module_voff(Arena *arena, CTRL_Han
internal U64 ctrl_entry_point_voff_from_module(CTRL_Handle module_handle); internal U64 ctrl_entry_point_voff_from_module(CTRL_Handle module_handle);
internal Rng1U64 ctrl_tls_vaddr_range_from_module(CTRL_Handle module_handle); internal Rng1U64 ctrl_tls_vaddr_range_from_module(CTRL_Handle module_handle);
internal String8 ctrl_initial_debug_info_path_from_module(Arena *arena, CTRL_Handle module_handle); internal String8 ctrl_initial_debug_info_path_from_module(Arena *arena, CTRL_Handle module_handle);
internal String8 ctrl_raddbg_data_from_module(Arena *arena, CTRL_Handle module_handle);
//////////////////////////////// ////////////////////////////////
//~ rjf: Unwinding Functions //~ rjf: Unwinding Functions
@@ -1108,18 +1032,24 @@ internal CTRL_Unwind ctrl_unwind_deep_copy(Arena *arena, Arch arch, CTRL_Unwind
//- rjf: [x64] //- rjf: [x64]
internal REGS_Reg64 *ctrl_unwind_reg_from_pe_gpr_reg__pe_x64(REGS_RegBlockX64 *regs, PE_UnwindGprRegX64 gpr_reg); internal REGS_Reg64 *ctrl_unwind_reg_from_pe_gpr_reg__pe_x64(REGS_RegBlockX64 *regs, PE_UnwindGprRegX64 gpr_reg);
internal CTRL_UnwindStepResult ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CTRL_Handle module_handle, REGS_RegBlockX64 *regs, U64 endt_us); internal CTRL_UnwindStepResult ctrl_unwind_step__pe_x64(CTRL_Handle process_handle, CTRL_Handle module_handle, U64 module_base_vaddr, REGS_RegBlockX64 *regs, U64 endt_us);
//- rjf: abstracted unwind step //- rjf: abstracted unwind step
internal CTRL_UnwindStepResult ctrl_unwind_step(CTRL_EntityStore *store, CTRL_Handle process, CTRL_Handle module, Arch arch, void *reg_block, U64 endt_us); internal CTRL_UnwindStepResult ctrl_unwind_step(CTRL_Handle process, CTRL_Handle module, U64 module_base_vaddr, Arch arch, void *reg_block, U64 endt_us);
//- rjf: abstracted full unwind //- rjf: abstracted full unwind
internal CTRL_Unwind ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle thread, U64 endt_us); internal CTRL_Unwind ctrl_unwind_from_thread(Arena *arena, CTRL_EntityCtx *ctx, CTRL_Handle thread, U64 endt_us);
//////////////////////////////// ////////////////////////////////
//~ rjf: Call Stack Building Functions //~ rjf: Call Stack Building Functions
internal CTRL_CallStack ctrl_call_stack_from_unwind(Arena *arena, DI_Scope *di_scope, CTRL_Entity *process, CTRL_Unwind *base_unwind); internal CTRL_CallStack ctrl_call_stack_from_unwind(Arena *arena, CTRL_Entity *process, CTRL_Unwind *base_unwind);
internal CTRL_CallStackFrame *ctrl_call_stack_frame_from_unwind_and_inline_depth(CTRL_CallStack *call_stack, U64 unwind_count, U64 inline_depth);
////////////////////////////////
//~ rjf: Call Stack Cache Functions
internal CTRL_CallStack ctrl_call_stack_from_thread(CTRL_Scope *scope, CTRL_EntityCtx *entity_ctx, CTRL_Entity *thread, B32 high_priority, U64 endt_us);
//////////////////////////////// ////////////////////////////////
//~ rjf: Halting All Attached Processes //~ rjf: Halting All Attached Processes
@@ -1153,12 +1083,13 @@ internal CTRL_EventList ctrl_c2u_pop_events(Arena *arena);
internal void ctrl_thread__entry_point(void *p); internal void ctrl_thread__entry_point(void *p);
//- rjf: breakpoint resolution //- rjf: breakpoint resolution
internal void ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_Handle process, CTRL_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); internal void ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_EvalScope *eval_scope, CTRL_Handle process, CTRL_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out);
internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_EvalScope *eval_scope, CTRL_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out);
internal void ctrl_thread__append_program_defined_bp_traps(Arena *arena, CTRL_Entity *bp, DMN_TrapChunkList *traps_out);
//- rjf: module lifetime open/close work //- rjf: module lifetime open/close work
internal void ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range, String8 path); internal void ctrl_thread__module_open(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range, String8 path);
internal void ctrl_thread__module_close(CTRL_Handle module); internal void ctrl_thread__module_close(CTRL_Handle process, CTRL_Handle module, Rng1U64 vaddr_range);
//- rjf: attached process running/event gathering //- rjf: attached process running/event gathering
internal DMN_Event *ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, DMN_RunCtrls *run_ctrls, CTRL_Spoof *spoof); internal DMN_Event *ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, DMN_RunCtrls *run_ctrls, CTRL_Spoof *spoof);
@@ -1166,6 +1097,10 @@ internal DMN_Event *ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_
//- rjf: eval helpers //- rjf: eval helpers
internal B32 ctrl_eval_space_read(void *u, E_Space space, void *out, Rng1U64 vaddr_range); internal B32 ctrl_eval_space_read(void *u, E_Space space, void *out, Rng1U64 vaddr_range);
//- rjf: control thread eval scopes
internal CTRL_EvalScope *ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread);
internal void ctrl_thread__eval_scope_end(CTRL_EvalScope *scope);
//- rjf: log flusher //- rjf: log flusher
internal void ctrl_thread__flush_info_log(String8 string); internal void ctrl_thread__flush_info_log(String8 string);
internal void ctrl_thread__end_and_flush_info_log(void); internal void ctrl_thread__end_and_flush_info_log(void);
@@ -1180,14 +1115,23 @@ 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); internal void ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
//////////////////////////////// ////////////////////////////////
//~ rjf: Memory-Stream Thread Functions //~ rjf: Asynchronous Memory Streaming Functions
//- rjf: user -> memory stream communication //- rjf: user -> memory stream communication
internal B32 ctrl_u2ms_enqueue_req(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us); internal B32 ctrl_u2ms_enqueue_req(HS_Key key, CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us);
internal void ctrl_u2ms_dequeue_req(CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated); internal void ctrl_u2ms_dequeue_req(HS_Key *out_key, CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated);
//- rjf: entry point //- rjf: entry point
ASYNC_WORK_DEF(ctrl_mem_stream_work); ASYNC_WORK_DEF(ctrl_mem_stream_work);
internal void ctrl_mem_stream_thread__entry_point(void *p);
////////////////////////////////
//~ rjf: Asynchronous Call Stack Building Functions
//- rjf: user -> memory stream communication
internal B32 ctrl_u2csb_enqueue_req(CTRL_Handle thread, U64 endt_us);
internal void ctrl_u2csb_dequeue_req(CTRL_Handle *out_thread);
//- rjf: entry point
ASYNC_WORK_DEF(ctrl_call_stack_build_work);
#endif // CTRL_CORE_H #endif // CTRL_CORE_H
+3
View File
@@ -1,4 +1,7 @@
// Copyright (c) 2024 Epic Games Tools // Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
#undef LAYER_COLOR
#define LAYER_COLOR 0x969696ff
#include "ctrl_core.c" #include "ctrl_core.c"
+18 -1
View File
@@ -4,7 +4,22 @@
//- GENERATED CODE //- GENERATED CODE
C_LINKAGE_BEGIN C_LINKAGE_BEGIN
String8 ctrl_entity_kind_display_string_table[9] = String8 ctrl_entity_kind_code_name_table[11] =
{
{0},
str8_lit_comp("root"),
str8_lit_comp("machine"),
str8_lit_comp("process"),
str8_lit_comp("thread"),
str8_lit_comp("module"),
str8_lit_comp("entry_point"),
str8_lit_comp("debug_info_path"),
str8_lit_comp("pending_thread_name"),
str8_lit_comp("pending_thread_color"),
str8_lit_comp("breakpoint"),
};
String8 ctrl_entity_kind_display_string_table[11] =
{ {
{0}, {0},
str8_lit_comp("Root"), str8_lit_comp("Root"),
@@ -15,6 +30,8 @@ str8_lit_comp("Module"),
str8_lit_comp("EntryPoint"), str8_lit_comp("EntryPoint"),
str8_lit_comp("DebugInfoPath"), str8_lit_comp("DebugInfoPath"),
str8_lit_comp("PendingThreadName"), str8_lit_comp("PendingThreadName"),
str8_lit_comp("PendingThreadColor"),
str8_lit_comp("Breakpoint"),
}; };
U32 ctrl_exception_code_kind_code_table[38] = U32 ctrl_exception_code_kind_code_table[38] =
+4 -1
View File
@@ -17,6 +17,8 @@ CTRL_EntityKind_Module,
CTRL_EntityKind_EntryPoint, CTRL_EntityKind_EntryPoint,
CTRL_EntityKind_DebugInfoPath, CTRL_EntityKind_DebugInfoPath,
CTRL_EntityKind_PendingThreadName, CTRL_EntityKind_PendingThreadName,
CTRL_EntityKind_PendingThreadColor,
CTRL_EntityKind_Breakpoint,
CTRL_EntityKind_COUNT, CTRL_EntityKind_COUNT,
} CTRL_EntityKind; } CTRL_EntityKind;
@@ -64,7 +66,8 @@ CTRL_ExceptionCodeKind_COUNT,
} CTRL_ExceptionCodeKind; } CTRL_ExceptionCodeKind;
C_LINKAGE_BEGIN C_LINKAGE_BEGIN
extern String8 ctrl_entity_kind_display_string_table[9]; extern String8 ctrl_entity_kind_code_name_table[11];
extern String8 ctrl_entity_kind_display_string_table[11];
extern U32 ctrl_exception_code_kind_code_table[38]; 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_display_string_table[38];
extern String8 ctrl_exception_code_kind_lowercase_code_string_table[38]; extern String8 ctrl_exception_code_kind_lowercase_code_string_table[38];
+44 -70
View File
@@ -1,6 +1,9 @@
// Copyright (c) 2024 Epic Games Tools // Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
#undef LAYER_COLOR
#define LAYER_COLOR 0xe34cd4ff
//////////////////////////////// ////////////////////////////////
//~ rjf: Instruction Decoding/Disassembling Type Functions //~ rjf: Instruction Decoding/Disassembling Type Functions
@@ -342,10 +345,13 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params)
DASM_Info info = {0}; DASM_Info info = {0};
if(!u128_match(hash, u128_zero())) if(!u128_match(hash, u128_zero()))
{ {
//- rjf: unpack hash
U64 slot_idx = hash.u64[1]%dasm_shared->slots_count; U64 slot_idx = hash.u64[1]%dasm_shared->slots_count;
U64 stripe_idx = slot_idx%dasm_shared->stripes_count; U64 stripe_idx = slot_idx%dasm_shared->stripes_count;
DASM_Slot *slot = &dasm_shared->slots[slot_idx]; DASM_Slot *slot = &dasm_shared->slots[slot_idx];
DASM_Stripe *stripe = &dasm_shared->stripes[stripe_idx]; DASM_Stripe *stripe = &dasm_shared->stripes[stripe_idx];
//- rjf: try to get existing results
B32 found = 0; B32 found = 0;
OS_MutexScopeR(stripe->rw_mutex) OS_MutexScopeR(stripe->rw_mutex)
{ {
@@ -360,9 +366,13 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params)
} }
} }
} }
B32 node_is_new = 0;
//- rjf: miss -> kick off work to fill cache
if(!found) if(!found)
{ {
B32 node_is_new = 0;
U64 *node_working_count = 0;
HS_Root root = {0};
OS_MutexScopeW(stripe->rw_mutex) OS_MutexScopeW(stripe->rw_mutex)
{ {
DASM_Node *node = 0; DASM_Node *node = 0;
@@ -376,16 +386,7 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params)
} }
if(node == 0) if(node == 0)
{ {
LogInfoNamedBlockF("dasm_new_node") // rjf: allocate node
{
log_infof("hash: [0x%I64x 0x%I64x]\n", hash.u64[0], hash.u64[1]);
log_infof("vaddr: 0x%I64x\n", params->vaddr);
log_infof("arch: %S\n", string_from_arch(params->arch));
log_infof("style_flags: 0x%x\n", params->style_flags);
log_infof("syntax: %i\n", params->syntax);
log_infof("base_vaddr: 0x%I64x\n", params->base_vaddr);
log_infof("dbgi_key: [%S 0x%I64x]\n", params->dbgi_key.path, params->dbgi_key.min_timestamp);
}
node = stripe->free_node; node = stripe->free_node;
if(node) if(node)
{ {
@@ -396,26 +397,34 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params)
node = push_array_no_zero(stripe->arena, DASM_Node, 1); node = push_array_no_zero(stripe->arena, DASM_Node, 1);
} }
MemoryZeroStruct(node); MemoryZeroStruct(node);
// rjf: fill node
DLLPushBack(slot->first, slot->last, node); DLLPushBack(slot->first, slot->last, node);
node->hash = hash; node->hash = hash;
MemoryCopyStruct(&node->params, params); MemoryCopyStruct(&node->params, params);
node->root = hs_root_alloc();
// TODO(rjf): need to make this releasable - currently all exe_paths just leak // TODO(rjf): need to make this releasable - currently all exe_paths just leak
node->params.dbgi_key = di_key_copy(stripe->arena, &node->params.dbgi_key); node->params.dbgi_key = di_key_copy(stripe->arena, &node->params.dbgi_key);
// rjf: gather work kickoff params
node_is_new = 1; node_is_new = 1;
} ins_atomic_u64_inc_eval(&node->working_count);
node_working_count = &node->working_count;
root = node->root;
} }
} }
if(node_is_new) if(node_is_new)
{ {
dasm_u2p_enqueue_req(hash, params, max_U64); dasm_u2p_enqueue_req(root, hash, params, max_U64);
async_push_work(dasm_parse_work); async_push_work(dasm_parse_work, .working_counter = node_working_count);
}
} }
} }
return info; return info;
} }
internal DASM_Info internal DASM_Info
dasm_info_from_key_params(DASM_Scope *scope, U128 key, DASM_Params *params, U128 *hash_out) dasm_info_from_key_params(DASM_Scope *scope, HS_Key key, DASM_Params *params, U128 *hash_out)
{ {
DASM_Info result = {0}; DASM_Info result = {0};
for(U64 rewind_idx = 0; rewind_idx < HS_KEY_HASH_HISTORY_COUNT; rewind_idx += 1) for(U64 rewind_idx = 0; rewind_idx < HS_KEY_HASH_HISTORY_COUNT; rewind_idx += 1)
@@ -438,16 +447,17 @@ dasm_info_from_key_params(DASM_Scope *scope, U128 key, DASM_Params *params, U128
//~ rjf: Parse Threads //~ rjf: Parse Threads
internal B32 internal B32
dasm_u2p_enqueue_req(U128 hash, DASM_Params *params, U64 endt_us) dasm_u2p_enqueue_req(HS_Root root, U128 hash, DASM_Params *params, U64 endt_us)
{ {
B32 good = 0; B32 good = 0;
OS_MutexScope(dasm_shared->u2p_ring_mutex) for(;;) OS_MutexScope(dasm_shared->u2p_ring_mutex) for(;;)
{ {
U64 unconsumed_size = dasm_shared->u2p_ring_write_pos - dasm_shared->u2p_ring_read_pos; 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; U64 available_size = dasm_shared->u2p_ring_size - unconsumed_size;
if(available_size >= sizeof(hash)+sizeof(U64)+sizeof(Arch)+sizeof(DASM_StyleFlags)+sizeof(DASM_Syntax)+sizeof(U64)+sizeof(U64)+params->dbgi_key.path.size+sizeof(U64)) if(available_size >= sizeof(root)+sizeof(hash)+sizeof(U64)+sizeof(Arch)+sizeof(DASM_StyleFlags)+sizeof(DASM_Syntax)+sizeof(U64)+sizeof(U64)+params->dbgi_key.path.size+sizeof(U64))
{ {
good = 1; 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, &root);
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, &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, &params->vaddr); dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, &params->vaddr);
dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, &params->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, &params->arch);
@@ -473,13 +483,14 @@ dasm_u2p_enqueue_req(U128 hash, DASM_Params *params, U64 endt_us)
} }
internal void internal void
dasm_u2p_dequeue_req(Arena *arena, U128 *hash_out, DASM_Params *params_out) dasm_u2p_dequeue_req(Arena *arena, HS_Root *root_out, U128 *hash_out, DASM_Params *params_out)
{ {
OS_MutexScope(dasm_shared->u2p_ring_mutex) for(;;) OS_MutexScope(dasm_shared->u2p_ring_mutex) for(;;)
{ {
U64 unconsumed_size = dasm_shared->u2p_ring_write_pos - dasm_shared->u2p_ring_read_pos; U64 unconsumed_size = dasm_shared->u2p_ring_write_pos - dasm_shared->u2p_ring_read_pos;
if(unconsumed_size >= sizeof(*hash_out)+sizeof(U64)+sizeof(Arch)+sizeof(DASM_StyleFlags)+sizeof(DASM_Syntax)+sizeof(U64)+sizeof(U64)+sizeof(U64)) if(unconsumed_size >= sizeof(*hash_out)+sizeof(U64)+sizeof(Arch)+sizeof(DASM_StyleFlags)+sizeof(DASM_Syntax)+sizeof(U64)+sizeof(U64)+sizeof(U64))
{ {
dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, root_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, 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, &params_out->vaddr); dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, &params_out->vaddr);
dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, &params_out->arch); 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, &params_out->arch);
@@ -506,9 +517,10 @@ ASYNC_WORK_DEF(dasm_parse_work)
TXT_Scope *txt_scope = txt_scope_open(); TXT_Scope *txt_scope = txt_scope_open();
//- rjf: get next request //- rjf: get next request
HS_Root root = {0};
U128 hash = {0}; U128 hash = {0};
DASM_Params params = {0}; DASM_Params params = {0};
dasm_u2p_dequeue_req(scratch.arena, &hash, &params); dasm_u2p_dequeue_req(scratch.arena, &root, &hash, &params);
U64 change_gen = fs_change_gen(); U64 change_gen = fs_change_gen();
//- rjf: unpack hash //- rjf: unpack hash
@@ -517,38 +529,19 @@ ASYNC_WORK_DEF(dasm_parse_work)
DASM_Slot *slot = &dasm_shared->slots[slot_idx]; DASM_Slot *slot = &dasm_shared->slots[slot_idx];
DASM_Stripe *stripe = &dasm_shared->stripes[stripe_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) && dasm_params_match(&n->params, &params))
{
got_task = !ins_atomic_u32_eval_cond_assign(&n->is_working, 1, 0);
break;
}
}
}
//- rjf: get dbg info //- rjf: get dbg info
RDI_Parsed *rdi = &di_rdi_parsed_nil; RDI_Parsed *rdi = &rdi_parsed_nil;
if(got_task && params.dbgi_key.path.size != 0) if(params.dbgi_key.path.size != 0)
{ {
rdi = di_rdi_from_key(di_scope, &params.dbgi_key, max_U64); rdi = di_rdi_from_key(di_scope, &params.dbgi_key, max_U64);
} }
//- rjf: hash -> data //- rjf: hash -> data
String8 data = {0}; String8 data = hs_data_from_hash(hs_scope, hash);
if(got_task)
{
data = hs_data_from_hash(hs_scope, hash);
}
//- rjf: data * arch * addr * dbg -> decode artifacts //- rjf: data * arch * addr * dbg -> decode artifacts
DASM_LineChunkList line_list = {0}; DASM_LineChunkList line_list = {0};
String8List inst_strings = {0}; String8List inst_strings = {0};
if(got_task)
{ {
switch(params.arch) switch(params.arch)
{ {
@@ -573,7 +566,7 @@ ASYNC_WORK_DEF(dasm_parse_work)
// rjf: push strings derived from voff -> line info // rjf: push strings derived from voff -> line info
if(params.style_flags & (DASM_StyleFlag_SourceFilesNames|DASM_StyleFlag_SourceLines)) if(params.style_flags & (DASM_StyleFlag_SourceFilesNames|DASM_StyleFlag_SourceLines))
{ {
if(rdi != &di_rdi_parsed_nil) if(rdi != &rdi_parsed_nil)
{ {
U64 voff = (params.vaddr+off) - params.base_vaddr; U64 voff = (params.vaddr+off) - params.base_vaddr;
U32 unit_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_UnitVMap, voff); U32 unit_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_UnitVMap, voff);
@@ -618,7 +611,7 @@ ASYNC_WORK_DEF(dasm_parse_work)
{ {
// TODO(rjf): need redirection path - this may map to a different path on the local machine, // TODO(rjf): need redirection path - this may map to a different path on the local machine,
// need frontend to communicate path remapping info to this layer // need frontend to communicate path remapping info to this layer
U128 key = fs_key_from_path_range(file_normalized_full_path, r1u64(0, max_U64)); HS_Key key = fs_key_from_path_range(file_normalized_full_path, r1u64(0, max_U64), 0);
TXT_LangKind lang_kind = txt_lang_kind_from_extension(file_normalized_full_path); TXT_LangKind lang_kind = txt_lang_kind_from_extension(file_normalized_full_path);
U64 endt_us = max_U64; U64 endt_us = max_U64;
U128 hash = {0}; U128 hash = {0};
@@ -655,7 +648,7 @@ ASYNC_WORK_DEF(dasm_parse_work)
String8 addr_part = {0}; String8 addr_part = {0};
if(params.style_flags & DASM_StyleFlag_Addresses) if(params.style_flags & DASM_StyleFlag_Addresses)
{ {
addr_part = push_str8f(scratch.arena, "%s0x%016I64x ", rdi != &di_rdi_parsed_nil ? " " : "", params.vaddr+off); addr_part = push_str8f(scratch.arena, "%s0x%016I64x ", rdi != &rdi_parsed_nil ? " " : "", params.vaddr+off);
} }
String8 code_bytes_part = {0}; String8 code_bytes_part = {0};
if(params.style_flags & DASM_StyleFlag_CodeBytes) if(params.style_flags & DASM_StyleFlag_CodeBytes)
@@ -677,7 +670,7 @@ ASYNC_WORK_DEF(dasm_parse_work)
code_bytes_part = str8_list_join(scratch.arena, &code_bytes_strings, 0); code_bytes_part = str8_list_join(scratch.arena, &code_bytes_strings, 0);
} }
String8 symbol_part = {0}; String8 symbol_part = {0};
if(inst.jump_dest_vaddr != 0 && rdi != &di_rdi_parsed_nil && params.style_flags & DASM_StyleFlag_SymbolNames) if(inst.jump_dest_vaddr != 0 && rdi != &rdi_parsed_nil && params.style_flags & DASM_StyleFlag_SymbolNames)
{ {
RDI_U32 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, inst.jump_dest_vaddr-params.base_vaddr); RDI_U32 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, inst.jump_dest_vaddr-params.base_vaddr);
if(scope_idx != 0) if(scope_idx != 0)
@@ -709,7 +702,6 @@ ASYNC_WORK_DEF(dasm_parse_work)
//- rjf: artifacts -> value bundle //- rjf: artifacts -> value bundle
Arena *info_arena = 0; Arena *info_arena = 0;
DASM_Info info = {0}; DASM_Info info = {0};
if(got_task)
{ {
//- rjf: produce joined text //- rjf: produce joined text
Arena *text_arena = arena_alloc(); Arena *text_arena = arena_alloc();
@@ -718,21 +710,7 @@ ASYNC_WORK_DEF(dasm_parse_work)
String8 text = str8_list_join(text_arena, &inst_strings, &text_join); String8 text = str8_list_join(text_arena, &inst_strings, &text_join);
//- rjf: produce unique key for this disassembly's text //- rjf: produce unique key for this disassembly's text
U128 text_key = {0}; HS_Key text_key = hs_key_make(root, hs_id_make(0, 0));
{
U64 hash_data[] =
{
hash.u64[0],
hash.u64[1],
params.vaddr,
(U64)params.arch,
(U64)params.style_flags,
(U64)params.syntax,
(U64)rdi,
0x4d534144,
};
text_key = hs_hash_from_data(str8((U8 *)hash_data, sizeof(hash_data)));
}
//- rjf: submit text data to hash store //- rjf: submit text data to hash store
U128 text_hash = hs_submit_data(text_key, &text_arena, text); U128 text_hash = hs_submit_data(text_key, &text_arena, text);
@@ -744,7 +722,7 @@ ASYNC_WORK_DEF(dasm_parse_work)
} }
//- rjf: commit results to cache //- rjf: commit results to cache
if(got_task) OS_MutexScopeW(stripe->rw_mutex) OS_MutexScopeW(stripe->rw_mutex)
{ {
for(DASM_Node *n = slot->first; n != 0; n = n->next) for(DASM_Node *n = slot->first; n != 0; n = n->next)
{ {
@@ -752,7 +730,7 @@ ASYNC_WORK_DEF(dasm_parse_work)
{ {
n->info_arena = info_arena; n->info_arena = info_arena;
MemoryCopyStruct(&n->info, &info); MemoryCopyStruct(&n->info, &info);
if(rdi != &di_rdi_parsed_nil && params.style_flags & (DASM_StyleFlag_SourceLines|DASM_StyleFlag_SourceFilesNames)) if(rdi != &rdi_parsed_nil && params.style_flags & (DASM_StyleFlag_SourceLines|DASM_StyleFlag_SourceFilesNames))
{ {
n->change_gen = change_gen; n->change_gen = change_gen;
} }
@@ -760,8 +738,6 @@ ASYNC_WORK_DEF(dasm_parse_work)
{ {
n->change_gen = 0; n->change_gen = 0;
} }
ins_atomic_u32_eval_assign(&n->is_working, 0);
ins_atomic_u64_inc_eval(&n->load_count);
break; break;
} }
} }
@@ -804,8 +780,7 @@ dasm_evictor_detector_thread__entry_point(void *p)
if(n->scope_ref_count == 0 && if(n->scope_ref_count == 0 &&
n->last_time_touched_us+evict_threshold_us <= check_time_us && 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->last_user_clock_idx_touched+evict_threshold_user_clocks <= check_time_user_clocks &&
n->load_count != 0 && ins_atomic_u64_eval(&n->working_count) == 0)
n->is_working == 0)
{ {
slot_has_work = 1; slot_has_work = 1;
break; break;
@@ -827,8 +802,7 @@ dasm_evictor_detector_thread__entry_point(void *p)
if(n->scope_ref_count == 0 && if(n->scope_ref_count == 0 &&
n->last_time_touched_us+evict_threshold_us <= check_time_us && 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->last_user_clock_idx_touched+evict_threshold_user_clocks <= check_time_user_clocks &&
n->load_count != 0 && ins_atomic_u64_eval(&n->working_count) == 0)
n->is_working == 0)
{ {
DLLRemove(slot->first, slot->last, n); DLLRemove(slot->first, slot->last, n);
if(n->info_arena != 0) if(n->info_arena != 0)
@@ -841,7 +815,7 @@ dasm_evictor_detector_thread__entry_point(void *p)
n->last_time_requested_us+retry_threshold_us <= check_time_us && n->last_time_requested_us+retry_threshold_us <= check_time_us &&
n->last_user_clock_idx_requested+retry_threshold_user_clocks <= check_time_user_clocks) n->last_user_clock_idx_requested+retry_threshold_user_clocks <= check_time_user_clocks)
{ {
if(dasm_u2p_enqueue_req(n->hash, &n->params, max_U64)) if(dasm_u2p_enqueue_req(n->root, n->hash, &n->params, max_U64))
{ {
async_push_work(dasm_parse_work); async_push_work(dasm_parse_work);
n->last_time_requested_us = os_now_microseconds(); n->last_time_requested_us = os_now_microseconds();
+8 -6
View File
@@ -159,7 +159,7 @@ struct DASM_Result
typedef struct DASM_Info DASM_Info; typedef struct DASM_Info DASM_Info;
struct DASM_Info struct DASM_Info
{ {
U128 text_key; HS_Key text_key;
DASM_LineArray lines; DASM_LineArray lines;
}; };
@@ -177,6 +177,9 @@ struct DASM_Node
U128 hash; U128 hash;
DASM_Params params; DASM_Params params;
// rjf: root
HS_Root root;
// rjf: generations // rjf: generations
U64 change_gen; U64 change_gen;
@@ -185,11 +188,10 @@ struct DASM_Node
DASM_Info info; DASM_Info info;
// rjf: metadata // rjf: metadata
B32 is_working; U64 working_count;
U64 scope_ref_count; U64 scope_ref_count;
U64 last_time_touched_us; U64 last_time_touched_us;
U64 last_user_clock_idx_touched; U64 last_user_clock_idx_touched;
U64 load_count;
U64 last_time_requested_us; U64 last_time_requested_us;
U64 last_user_clock_idx_requested; U64 last_user_clock_idx_requested;
}; };
@@ -309,13 +311,13 @@ internal void dasm_scope_touch_node__stripe_r_guarded(DASM_Scope *scope, DASM_No
//~ rjf: Cache Lookups //~ rjf: Cache Lookups
internal DASM_Info dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params); internal DASM_Info dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params);
internal DASM_Info dasm_info_from_key_params(DASM_Scope *scope, U128 key, DASM_Params *params, U128 *hash_out); internal DASM_Info dasm_info_from_key_params(DASM_Scope *scope, HS_Key key, DASM_Params *params, U128 *hash_out);
//////////////////////////////// ////////////////////////////////
//~ rjf: Parse Threads //~ rjf: Parse Threads
internal B32 dasm_u2p_enqueue_req(U128 hash, DASM_Params *params, U64 endt_us); internal B32 dasm_u2p_enqueue_req(HS_Root root, U128 hash, DASM_Params *params, U64 endt_us);
internal void dasm_u2p_dequeue_req(Arena *arena, U128 *hash_out, DASM_Params *params_out); internal void dasm_u2p_dequeue_req(Arena *arena, HS_Root *root_out, U128 *hash_out, DASM_Params *params_out);
ASYNC_WORK_DEF(dasm_parse_work); ASYNC_WORK_DEF(dasm_parse_work);
//////////////////////////////// ////////////////////////////////
+36 -79
View File
@@ -4,53 +4,52 @@
//////////////////////////////// ////////////////////////////////
//~ rjf: Built-In Command Tables //~ rjf: Built-In Command Tables
@table(name ui_vis ipc_docs_vis q_slot q_view q_ent_kind q_ctrl_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 ) @table(name ui_vis ipc_docs_vis text_pt_vis text_rng_vis q_expr q_slot q_view q_ent_kind q_ctrl_ent_kind q_allow_files q_allow_folders q_keep_oi q_select_oi q_is_code q_floating q_required canonical_icon string display_name desc search_tags ctx_filter)
// / | | | \___ _________________________________/ | | | | | // / | | | | | | \___ _________________________________/ | | | | | |
// / | | | \ / | | | | | // / | | | | | | \ / | | | | | |
D_CmdTable: // | | | | | | | | | | D_CmdTable: // | | | | | | | | | | | | | |
{ {
//- rjf: low-level target control operations //- rjf: low-level target control operations
{LaunchAndRun 1 1 Entity null Target Null 0 0 0 0 0 1 Play "launch_and_run" "Launch and Run" "Starts debugging a new instance of a target, then runs." "launch,start,run,target" } {LaunchAndRun 1 1 0 0 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 Play "launch_and_run" "Launch and Run" "Starts debugging a new instance of a target, then runs." "launch,start,run,target" "" }
{LaunchAndInit 1 1 Entity null Target Null 0 0 0 0 0 1 PlayStepForward "launch_and_init" "Launch and Initialize" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" } {LaunchAndStepInto 1 1 0 0 "query:targets" Cfg null Target Null 0 0 0 0 0 1 1 PlayStepForward "launch_and_step_into" "Launch and Step Into" "Starts debugging a new instance of a target, then stops at the program's entry point." "launch,start,entry,point" "" }
{Kill 1 1 Process null Nil Process 0 0 0 0 0 1 X "kill" "Kill" "Kills the specified existing attached process(es)." "stop,kill" } {Kill 1 1 0 0 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 X "kill" "Kill" "Kills the specified existing attached process(es)." "stop,kill" "" }
{KillAll 1 1 Null null Nil Null 0 0 0 0 0 0 Stop "kill_all" "Kill All" "Kills all attached processes." "stop,kill,all" } {KillAll 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Stop "kill_all" "Kill All" "Kills all attached processes." "stop,kill,all" "" }
{Detach 1 1 Process null Nil Process 0 0 0 0 0 1 Null "detach" "Detach" "Detaches the specified attached process(es)." "detach" } {Detach 1 1 0 0 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 Null "detach" "Detach" "Detaches the specified attached process(es)." "detach" "" }
{Continue 1 1 Null null Nil Null 0 0 0 0 0 0 Play "continue" "Continue" "Continues executing all attached processes." "" } {Continue 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Play "continue" "Continue" "Continues executing all attached processes." "" "" }
{StepIntoInst 1 1 Null null Nil Null 0 0 0 0 0 0 StepInto "step_into_inst" "Step Into (Assembly)" "Performs a step that goes into calls, at the instruction level." "single,step,thread" } {StepIntoInst 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 StepInto "step_into_inst" "Step Into (Assembly)" "Performs a step that goes into calls, at the instruction level." "single,step,thread" "" }
{StepOverInst 1 1 Null null Nil Null 0 0 0 0 0 0 StepOver "step_over_inst" "Step Over (Assembly)" "Performs a step that skips calls, at the instruction level." "single,step,thread" } {StepOverInst 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 StepOver "step_over_inst" "Step Over (Assembly)" "Performs a step that skips calls, at the instruction level." "single,step,thread" "" }
{StepIntoLine 1 1 Null null Nil Null 0 0 0 0 0 0 StepInto "step_into_line" "Step Into (Line)" "Performs a step that goes into calls, at the source code line level." "step,thread" } {StepIntoLine 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 StepInto "step_into_line" "Step Into (Line)" "Performs a step that goes into calls, at the source code line level." "step,thread" "" }
{StepOverLine 1 1 Null null Nil Null 0 0 0 0 0 0 StepOver "step_over_line" "Step Over (Line)" "Performs a step that skips calls, at the source code line level." "step,thread" } {StepOverLine 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 StepOver "step_over_line" "Step Over (Line)" "Performs a step that skips calls, at the source code line level." "step,thread" "" }
{StepOut 1 1 Null null Nil Null 0 0 0 0 0 0 StepOut "step_out" "Step Out" "Runs to the end of the current function and exits it." "" } {StepOut 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 StepOut "step_out" "Step Out" "Runs to the end of the current function and exits it." "" "" }
{Halt 1 1 Null null Nil Null 0 0 0 0 0 0 Pause "halt" "Halt" "Halts all attached processes." "pause" } {Halt 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Pause "halt" "Halt" "Halts all attached processes." "pause" "" }
{SoftHaltRefresh 1 1 Null null Nil Null 0 0 0 0 0 0 Refresh "soft_halt_refresh" "Soft Halt Refresh" "Interrupts all attached processes to collect data, and then resumes them." "" } {SoftHaltRefresh 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Refresh "soft_halt_refresh" "Soft Halt Refresh" "Interrupts all attached processes to collect data, and then resumes them." "" "" }
{SetThreadIP 0 1 Vaddr null Nil Null 0 0 0 0 1 1 Null "set_thread_ip" "Set Thread IP" "Sets the specified thread's instruction pointer at the specified address." "" } {SetThreadIP 0 1 0 0 "" Vaddr null Nil Null 0 0 0 0 1 1 1 Null "set_thread_ip" "Set Thread IP" "Sets the specified thread's instruction pointer at the specified address." "" "" }
//- rjf: high-level composite target control operations //- rjf: high-level composite target control operations
{RunToLine 0 1 Null null Nil Null 0 0 0 0 0 0 Play "run_to_line" "Run To Line" "Runs until a particular source line is hit." "" } {RunToLine 1 1 1 0 "" Null null Nil Null 0 0 0 0 0 0 0 Play "run_to_line" "Run To Line" "Runs until a particular source line is hit." "" "$text_pt," }
{RunToAddress 1 1 Vaddr null Nil Null 0 0 0 0 1 1 PlayStepForward "run_to_address" "Run To Address" "Runs until a particular address is hit." "" } {Run 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Play "run" "Run" "Runs all targets after starting them if they have not been started yet." "play" "" }
{Run 1 1 Null null Nil Null 0 0 0 0 0 0 Play "run" "Run" "Runs all targets after starting them if they have not been started yet." "play" } {Restart 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Redo "restart" "Restart" "Kills all attached processes, then launches all active targets." "restart,retry" "" }
{Restart 1 1 Null null Nil Null 0 0 0 0 0 0 Redo "restart" "Restart" "Kills all attached processes, then launches all active targets." "restart,retry" } {StepInto 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 StepInto "step_into" "Step Into" "Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)." "" "" }
{StepInto 1 1 Null null Nil Null 0 0 0 0 0 0 StepInto "step_into" "Step Into" "Steps once, possibly into function calls, for either source lines or instructions (whichever is selected)." "" } {StepOver 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 StepOver "step_over" "Step Over" "Steps once, always over function calls, for either source lines or instructions." "" "" }
{StepOver 1 1 Null null Nil Null 0 0 0 0 0 0 StepOver "step_over" "Step Over" "Steps once, always over function calls, for either source lines or instructions." "" }
//- rjf: debug control context management operations //- rjf: debug control context management operations
{FreezeThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Locked "freeze_thread" "Freeze Thread" "Freezes the passed thread." "callstack,unwind" } {FreezeThread 1 1 0 0 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Locked "freeze_thread" "Freeze Thread" "Freezes the passed thread." "callstack,unwind" "" }
{ThawThread 1 1 Thread null Nil Thread 0 0 0 0 0 1 Unlocked "thaw_thread" "Thaw Thread" "Thaws the passed thread." "" } {ThawThread 1 1 0 0 "query:threads" Thread null Nil Thread 0 0 0 0 0 1 1 Unlocked "thaw_thread" "Thaw Thread" "Thaws the passed thread." "" "" }
{FreezeProcess 1 1 Process null Nil Process 0 0 0 0 0 1 Locked "freeze_process" "Freeze Process" "Freezes the passed process." "" } {FreezeProcess 1 1 0 0 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 Locked "freeze_process" "Freeze Process" "Freezes the passed process." "" "" }
{ThawProcess 1 1 Process null Nil Process 0 0 0 0 0 1 Unlocked "thaw_process" "Thaw Process" "Thaws the passed process." "" } {ThawProcess 1 1 0 0 "query:processes" Process null Nil Process 0 0 0 0 0 1 1 Unlocked "thaw_process" "Thaw Process" "Thaws the passed process." "" "" }
{FreezeMachine 0 1 Machine null Nil Machine 0 0 0 0 0 1 Locked "freeze_machine" "Freeze Machine" "Freezes the passed machine." "" } {FreezeMachine 0 1 0 0 "query:machines" Machine null Nil Machine 0 0 0 0 0 1 1 Locked "freeze_machine" "Freeze Machine" "Freezes the passed machine." "" "" }
{ThawMachine 0 1 Machine null Nil Machine 0 0 0 0 0 1 Unlocked "thaw_machine" "Thaw Machine" "Thaws the passed machine." "" } {ThawMachine 0 1 0 0 "query:machines" Machine null Nil Machine 0 0 0 0 0 1 1 Unlocked "thaw_machine" "Thaw Machine" "Thaws the passed machine." "" "" }
{FreezeLocalMachine 1 1 Null null Nil Null 0 0 0 0 0 0 Machine "freeze_local_machine" "Freeze Local Machine" "Freezes the local machine." "" } {FreezeLocalMachine 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Machine "freeze_local_machine" "Freeze Local Machine" "Freezes the local machine." "" "" }
{ThawLocalMachine 1 1 Null null Nil Null 0 0 0 0 0 0 Machine "thaw_local_machine" "Thaw Local Machine" "Thaws the local machine." "" } {ThawLocalMachine 1 1 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Machine "thaw_local_machine" "Thaw Local Machine" "Thaws the local machine." "" "" }
{FreezeEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "freeze_entity" "Freeze Entity" "Freezes an entity." "" } {FreezeEntity 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Unlocked "freeze_entity" "Freeze Entity" "Freezes an entity." "" "" }
{ThawEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "thaw_entity" "Thaw Entity" "Thaws an entity." "" } {ThawEntity 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Locked "thaw_entity" "Thaw Entity" "Thaws an entity." "" "" }
//- rjf: entity decoration //- rjf: entity decoration
{SetEntityColor 0 0 Null null Nil Null 0 0 0 0 0 0 Null "set_entity_color" "Set Entity Color" "Sets the passed entity's color." "" } {SetEntityColor 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "set_entity_color" "Set Entity Color" "Sets the passed entity's color." "" "" }
{SetEntityName 0 0 Null null Nil Null 0 0 0 0 0 0 Null "set_entity_name" "Set Entity Name" "Sets the passed entity's name." "" } {SetEntityName 0 0 0 0 "" Null null Nil Null 0 0 0 0 0 0 0 Null "set_entity_name" "Set Entity Name" "Sets the passed entity's name." "" "" }
//- rjf: attaching //- rjf: attaching
{Attach 1 1 PID null Nil Null 0 0 0 0 0 1 Null "attach" "Attach" "Attaches to a process that is already running on the local machine." "" } {Attach 1 1 0 0 "query:unattached_processes" PID null Nil Null 0 0 0 0 0 1 1 Null "attach" "Attach" "Attaches to a process that is already running on the local machine." "" "" }
} }
@enum D_CmdKind: @enum D_CmdKind:
@@ -60,47 +59,6 @@ D_CmdTable: // | | | |
COUNT, COUNT,
} }
////////////////////////////////
//~ rjf: Built-In VieNull w Rules
@table(coverage_check name name_lower string ih ex xp vb display_name docs schema description)
D_ViewRuleTable:
{
{x Default default "default" - - - x "Default" - "" "" }
{x Array array "array" - - x - "Array" x "x:{expr}" "Specifies that a pointer points to N elements, rather than only 1." }
{x Slice slice "slice" - - x - "Slice" x "" "Specifies that a pointer within a struct, also containing an integer, points to the number of elements encoded by the integer." }
{- List list "list" - - - x "List" - "x:{member}" "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." }
{x ByteSwap bswap "bswap" x - x - "Byte Swap" x "" "Specifies that all integral evaluations should be byte-swapped, such that their endianness is reversed." }
{x Cast cast "cast" - - x - "Cast" x "x:{type}" "Specifies that the expression to which the view rule is applied should be casted to the provided type." }
{- BaseDec base_dec "dec" x - - - "Decimal Base (Base 10)" x "" "Specifies that all integral evaluations should appear in base-10 form." }
{- BaseBin base_bin "bin" x - - - "Binary Base (Base 2)" x "" "Specifies that all integral evaluations should appear in base-2 form." }
{- BaseOct base_oct "oct" x - - - "Octal Base (Base 8)" x "" "Specifies that all integral evaluations should appear in base-8 form." }
{- BaseHex base_hex "hex" x - - - "Hexadecimal Base (Base 16)" x "" "Specifies that all integral evaluations should appear in base-16 form." }
{- Only only "only" x - - x "Only Specified Members" x "x:{member}" "Specifies that only the specified members should appear in struct, union, or class evaluations." }
{- Omit omit "omit" x - - x "Omit Specified Members" x "x:{member}" "Omits a list of member names from appearing in struct, union, or class evaluations." }
{- NoAddr no_addr "no_addr" x - - - "Disable Address Values" x "" "Displays only what pointers point to, if possible, without the pointer's address value." }
{x Checkbox checkbox "checkbox" - - - - "Checkbox" x "" "Displays simple integer values as checkboxes, encoding zero or nonzero values." }
{- ColorRGBA color_rgba "color_rgba" - x - x "Color (RGBA)" x "" "Displays as a color, interpreting the data as encoding R, G, B, and A values." }
{x Text text "text" - x - x "Text" x "x:{'lang':lang, 'size':expr}" "Displays as text." }
{x Disasm disasm "disasm" - x - x "Disassembly" x "x:{'arch':arch, 'size':expr}" "Displays as disassembled instructions, interpreting the data as raw machine code." }
{x Memory memory "memory" - x - x "Memory" x "x:{'size':expr}" "Displays as a raw memory grid." }
{- Graph graph "graph" - x - x "Graph" x "" "Displays as a pointer graph, visualizing nodes and edges formed by pointers directly." }
{x Bitmap bitmap "bitmap" - x - x "Bitmap" x "x:{'w':expr, 'h':expr, 'fmt':tex2dformat}" "Displays as a bitmap, interpreting the data as raw pixel data." }
{- Geo3D geo3d "geo3d" - x - x "Geometry (3D)" x "x:{'count':expr, 'vtx':expr, 'vtx_size':expr}" "Displays as geometry, interpreting the data as index or vertex data." }
}
@enum D_ViewRuleKind:
{
@expand(D_ViewRuleTable a) `$(a.name)`,
COUNT,
}
@data(D_ViewRuleSpecInfo) @c_file d_core_view_rule_spec_info_table:
{
@expand(D_ViewRuleTable a)
```{str8_lit_comp("$(a.string)"), str8_lit_comp("$(a.display_name)"), str8_lit_comp("$(a.schema)"), str8_lit_comp("$(a.description)"), (D_ViewRuleSpecInfoFlag_Inherited*$(a.ih == "x"))|(D_ViewRuleSpecInfoFlag_Expandable*$(a.ex == "x"))|(D_ViewRuleSpecInfoFlag_ExprResolution*$(a.xp == "x"))|(D_ViewRuleSpecInfoFlag_VizBlockProd*$(a.vb == "x")), }```;
}
//////////////////////////////// ////////////////////////////////
//~ rjf: Developer Toggles //~ rjf: Developer Toggles
@@ -114,7 +72,6 @@ D_DevToggleTable:
{eval_compiler_tooltips} {eval_compiler_tooltips}
{eval_watch_key_tooltips} {eval_watch_key_tooltips}
{cmd_context_tooltips} {cmd_context_tooltips}
{scratch_mouse_draw}
{updating_indicator} {updating_indicator}
} }
+122 -374
View File
@@ -1,8 +1,8 @@
// Copyright (c) 2024 Epic Games Tools // Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
#undef MARKUP_LAYER_COLOR #undef LAYER_COLOR
#define MARKUP_LAYER_COLOR 0.70f, 0.50f, 0.25f #define LAYER_COLOR 0x4d9ae3ff
//////////////////////////////// ////////////////////////////////
//~ rjf: Generated Code //~ rjf: Generated Code
@@ -12,14 +12,16 @@
//////////////////////////////// ////////////////////////////////
//~ rjf: Basic Helpers //~ rjf: Basic Helpers
#if !defined(XXH_IMPLEMENTATION)
# define XXH_IMPLEMENTATION
# define XXH_STATIC_LINKING_ONLY
# include "third_party/xxHash/xxhash.h"
#endif
internal U64 internal U64
d_hash_from_seed_string(U64 seed, String8 string) d_hash_from_seed_string(U64 seed, String8 string)
{ {
U64 result = seed; U64 result = XXH3_64bits_withSeed(string.str, string.size, seed);
for(U64 i = 0; i < string.size; i += 1)
{
result = ((result << 5) + result) + string.str[i];
}
return result; return result;
} }
@@ -59,7 +61,7 @@ d_breakpoint_array_copy(Arena *arena, D_BreakpointArray *src)
for(U64 idx = 0; idx < dst.count; idx += 1) for(U64 idx = 0; idx < dst.count; idx += 1)
{ {
dst.v[idx].file_path = push_str8_copy(arena, dst.v[idx].file_path); dst.v[idx].file_path = push_str8_copy(arena, dst.v[idx].file_path);
dst.v[idx].symbol_name = push_str8_copy(arena, dst.v[idx].symbol_name); dst.v[idx].vaddr_expr = push_str8_copy(arena, dst.v[idx].vaddr_expr);
dst.v[idx].condition = push_str8_copy(arena, dst.v[idx].condition); dst.v[idx].condition = push_str8_copy(arena, dst.v[idx].condition);
} }
return dst; return dst;
@@ -194,59 +196,6 @@ d_cmd_list_push_new(Arena *arena, D_CmdList *cmds, D_CmdKind kind, D_CmdParams *
cmds->count += 1; cmds->count += 1;
} }
////////////////////////////////
//~ rjf: View Rule Spec Stateful Functions
internal void
d_register_view_rule_specs(D_ViewRuleSpecInfoArray specs)
{
for(U64 idx = 0; idx < specs.count; idx += 1)
{
// rjf: extract info from array slot
D_ViewRuleSpecInfo *info = &specs.v[idx];
// rjf: skip empties
if(info->string.size == 0)
{
continue;
}
// rjf: determine hash/slot
U64 hash = d_hash_from_string(info->string);
U64 slot_idx = hash%d_state->view_rule_spec_table_size;
// rjf: allocate node & push
D_ViewRuleSpec *spec = push_array(d_state->arena, D_ViewRuleSpec, 1);
SLLStackPush_N(d_state->view_rule_spec_table[slot_idx], spec, hash_next);
// rjf: fill node
D_ViewRuleSpecInfo *info_copy = &spec->info;
MemoryCopyStruct(info_copy, info);
info_copy->string = push_str8_copy(d_state->arena, info->string);
info_copy->display_string = push_str8_copy(d_state->arena, info->display_string);
info_copy->description = push_str8_copy(d_state->arena, info->description);
}
}
internal D_ViewRuleSpec *
d_view_rule_spec_from_string(String8 string)
{
D_ViewRuleSpec *spec = &d_nil_core_view_rule_spec;
{
U64 hash = d_hash_from_string(string);
U64 slot_idx = hash%d_state->view_rule_spec_table_size;
for(D_ViewRuleSpec *s = d_state->view_rule_spec_table[slot_idx]; s != 0; s = s->hash_next)
{
if(str8_match(string, s->info.string, 0))
{
spec = s;
break;
}
}
}
return spec;
}
//////////////////////////////// ////////////////////////////////
//~ rjf: Stepping "Trap Net" Builders //~ rjf: Stepping "Trap Net" Builders
@@ -351,13 +300,13 @@ d_trap_net_from_thread__step_over_inst(Arena *arena, CTRL_Entity *thread)
// rjf: thread => unpacked info // rjf: thread => unpacked info
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
Arch arch = thread->arch; Arch arch = thread->arch;
U64 ip_vaddr = ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle); U64 ip_vaddr = ctrl_rip_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle);
// rjf: ip => machine code // rjf: ip => machine code
String8 machine_code = {0}; String8 machine_code = {0};
{ {
Rng1U64 rng = r1u64(ip_vaddr, ip_vaddr+max_instruction_size_from_arch(arch)); Rng1U64 rng = r1u64(ip_vaddr, ip_vaddr+max_instruction_size_from_arch(arch));
CTRL_ProcessMemorySlice machine_code_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->handle, rng, os_now_microseconds()+5000); CTRL_ProcessMemorySlice machine_code_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, rng, os_now_microseconds()+5000);
machine_code = machine_code_slice.data; machine_code = machine_code_slice.data;
} }
@@ -388,7 +337,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread)
// rjf: thread => info // rjf: thread => info
Arch arch = thread->arch; Arch arch = thread->arch;
U64 ip_vaddr = ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle); U64 ip_vaddr = ctrl_rip_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ip_vaddr); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ip_vaddr);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
@@ -431,7 +380,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread)
String8 machine_code = {0}; String8 machine_code = {0};
if(good_line_info) if(good_line_info)
{ {
CTRL_ProcessMemorySlice machine_code_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, os_now_microseconds()+50000); CTRL_ProcessMemorySlice machine_code_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, os_now_microseconds()+50000);
machine_code = machine_code_slice.data; machine_code = machine_code_slice.data;
LogInfoNamedBlockF("machine_code_slice") LogInfoNamedBlockF("machine_code_slice")
{ {
@@ -549,7 +498,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread)
// rjf: thread => info // rjf: thread => info
Arch arch = thread->arch; Arch arch = thread->arch;
U64 ip_vaddr = ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle); U64 ip_vaddr = ctrl_rip_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ip_vaddr); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ip_vaddr);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module); DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
@@ -587,7 +536,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread)
String8 machine_code = {0}; String8 machine_code = {0};
if(good_line_info) if(good_line_info)
{ {
CTRL_ProcessMemorySlice machine_code_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, os_now_microseconds()+5000); CTRL_ProcessMemorySlice machine_code_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, line_vaddr_rng, os_now_microseconds()+5000);
machine_code = machine_code_slice.data; machine_code = machine_code_slice.data;
} }
@@ -606,6 +555,16 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread)
machine_code); machine_code);
} }
// rjf: determine last
DASM_CtrlFlowPoint *last_call_point = 0;
if(good_line_info) for(DASM_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next)
{
if(n->v.inst_flags & DASM_InstFlag_Call)
{
last_call_point = &n->v;
}
}
// rjf: push traps for all exit points // rjf: push traps for all exit points
if(good_line_info) for(DASM_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next) if(good_line_info) for(DASM_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next)
{ {
@@ -614,6 +573,23 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread)
B32 add = 1; B32 add = 1;
U64 trap_addr = point->vaddr; U64 trap_addr = point->vaddr;
// rjf: if this is not the last call instruction in the control flow,
// and if we have no line info for this address, then do not add.
if(point != last_call_point &&
point->inst_flags & DASM_InstFlag_Call &&
point->jump_dest_vaddr != 0)
{
U64 jump_dest_vaddr = point->jump_dest_vaddr;
CTRL_Entity *jump_dest_module = ctrl_module_from_process_vaddr(process, jump_dest_vaddr);
U64 jump_dest_voff = ctrl_voff_from_vaddr(jump_dest_module, jump_dest_vaddr);
DI_Key jump_dest_dbgi_key = ctrl_dbgi_key_from_module(jump_dest_module);
D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, &jump_dest_dbgi_key, jump_dest_voff);
if(lines.count == 0)
{
add = 0;
}
}
// rjf: branches/jumps/returns => single-step & end, OR trap @ destination. // rjf: branches/jumps/returns => single-step & end, OR trap @ destination.
if(point->inst_flags & (DASM_InstFlag_Call| if(point->inst_flags & (DASM_InstFlag_Call|
DASM_InstFlag_Branch| DASM_InstFlag_Branch|
@@ -664,67 +640,6 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread)
//////////////////////////////// ////////////////////////////////
//~ rjf: Debug Info Lookups //~ rjf: Debug Info Lookups
//- rjf: symbol lookups
internal String8
d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, B32 decorated)
{
String8 result = {0};
{
Temp scratch = scratch_begin(&arena, 1);
DI_Scope *scope = di_scope_open();
RDI_Parsed *rdi = di_rdi_from_key(scope, dbgi_key, 0);
if(result.size == 0)
{
U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff);
RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx);
U64 proc_idx = scope->proc_idx;
RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx);
E_TypeKey type = e_type_key_ext(E_TypeKind_Function, procedure->type_idx, e_parse_ctx_module_idx_from_rdi(rdi));
String8 name = {0};
name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size);
if(decorated && procedure->type_idx != 0)
{
String8List list = {0};
e_type_lhs_string_from_key(scratch.arena, type, &list, 0, 0);
str8_list_push(scratch.arena, &list, name);
e_type_rhs_string_from_key(scratch.arena, type, &list, 0);
result = str8_list_join(arena, &list, 0);
}
else
{
result = push_str8_copy(arena, name);
}
}
if(result.size == 0)
{
U64 global_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_GlobalVMap, voff);
RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, global_idx);
U64 name_size = 0;
U8 *name_ptr = rdi_string_from_idx(rdi, global_var->name_string_idx, &name_size);
result = push_str8_copy(arena, str8(name_ptr, name_size));
}
di_scope_close(scope);
scratch_end(scratch);
}
return result;
}
internal String8
d_symbol_name_from_process_vaddr(Arena *arena, CTRL_Entity *process, U64 vaddr, B32 decorated)
{
ProfBeginFunction();
String8 result = {0};
{
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
U64 voff = ctrl_voff_from_vaddr(module, vaddr);
result = d_symbol_name_from_dbgi_key_voff(arena, &dbgi_key, voff, decorated);
}
ProfEnd();
return result;
}
//- rjf: symbol -> voff lookups //- rjf: symbol -> voff lookups
internal U64 internal U64
@@ -741,7 +656,7 @@ d_voff_from_dbgi_key_symbol_name(DI_Key *dbgi_key, String8 symbol_name)
RDI_NameMapKind_GlobalVariables, RDI_NameMapKind_GlobalVariables,
RDI_NameMapKind_Procedures, RDI_NameMapKind_Procedures,
}; };
if(rdi != &di_rdi_parsed_nil) if(rdi != &rdi_parsed_nil)
{ {
for(U64 name_map_kind_idx = 0; for(U64 name_map_kind_idx = 0;
name_map_kind_idx < ArrayCount(name_map_kinds); name_map_kind_idx < ArrayCount(name_map_kinds);
@@ -808,45 +723,6 @@ d_voff_from_dbgi_key_symbol_name(DI_Key *dbgi_key, String8 symbol_name)
return result; return result;
} }
internal U64
d_type_num_from_dbgi_key_name(DI_Key *dbgi_key, String8 name)
{
ProfBeginFunction();
DI_Scope *scope = di_scope_open();
U64 result = 0;
{
RDI_Parsed *rdi = di_rdi_from_key(scope, dbgi_key, 0);
RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Types);
RDI_ParsedNameMap parsed_name_map = {0};
rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map);
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, name.str, name.size);
U64 entity_num = 0;
if(node != 0)
{
switch(node->match_count)
{
case 1:
{
entity_num = node->match_idx_or_idx_run_first + 1;
}break;
default:
{
U32 num = 0;
U32 *run = rdi_matches_from_map_node(rdi, node, &num);
if(num != 0)
{
entity_num = run[0]+1;
}
}break;
}
}
result = entity_num;
}
di_scope_close(scope);
ProfEnd();
return result;
}
//- rjf: voff -> line info //- rjf: voff -> line info
internal D_LineList internal D_LineList
@@ -968,7 +844,7 @@ d_lines_array_from_dbgi_key_file_path_line_range(Arena *arena, DI_Key dbgi_key,
// rjf: file_path_normalized * rdi -> src_id // rjf: file_path_normalized * rdi -> src_id
B32 good_src_id = 0; B32 good_src_id = 0;
U32 src_id = 0; U32 src_id = 0;
if(rdi != &di_rdi_parsed_nil) ProfScope("file_path_normalized * rdi -> src_id") if(rdi != &rdi_parsed_nil) ProfScope("file_path_normalized * rdi -> src_id")
{ {
RDI_NameMap *mapptr = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_NormalSourcePaths); RDI_NameMap *mapptr = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_NormalSourcePaths);
RDI_ParsedNameMap map = {0}; RDI_ParsedNameMap map = {0};
@@ -1066,7 +942,7 @@ d_lines_array_from_file_path_line_range(Arena *arena, String8 file_path, Rng1S64
// rjf: file_path_normalized * rdi -> src_id // rjf: file_path_normalized * rdi -> src_id
B32 good_src_id = 0; B32 good_src_id = 0;
U32 src_id = 0; U32 src_id = 0;
if(rdi != &di_rdi_parsed_nil) ProfScope("file_path_normalized * rdi -> src_id") if(rdi != &rdi_parsed_nil) ProfScope("file_path_normalized * rdi -> src_id")
{ {
RDI_NameMap *mapptr = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_NormalSourcePaths); RDI_NameMap *mapptr = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_NormalSourcePaths);
RDI_ParsedNameMap map = {0}; RDI_ParsedNameMap map = {0};
@@ -1185,7 +1061,7 @@ d_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64
U64 tls_index = 0; U64 tls_index = 0;
if(addr_size != 0) if(addr_size != 0)
{ {
CTRL_ProcessMemorySlice tls_index_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->handle, tls_vaddr_range, 0); CTRL_ProcessMemorySlice tls_index_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, tls_vaddr_range, 0);
if(tls_index_slice.data.size >= addr_size) if(tls_index_slice.data.size >= addr_size)
{ {
tls_index = *(U64 *)tls_index_slice.data.str; tls_index = *(U64 *)tls_index_slice.data.str;
@@ -1198,13 +1074,13 @@ d_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64
U64 thread_info_addr = root_vaddr; U64 thread_info_addr = root_vaddr;
U64 tls_addr_off = tls_index*addr_size; U64 tls_addr_off = tls_index*addr_size;
U64 tls_addr_array = 0; U64 tls_addr_array = 0;
CTRL_ProcessMemorySlice tls_addr_array_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->handle, r1u64(thread_info_addr, thread_info_addr+addr_size), 0); CTRL_ProcessMemorySlice tls_addr_array_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, r1u64(thread_info_addr, thread_info_addr+addr_size), 0);
String8 tls_addr_array_data = tls_addr_array_slice.data; String8 tls_addr_array_data = tls_addr_array_slice.data;
if(tls_addr_array_data.size >= 8) if(tls_addr_array_data.size >= 8)
{ {
MemoryCopy(&tls_addr_array, tls_addr_array_data.str, sizeof(U64)); MemoryCopy(&tls_addr_array, tls_addr_array_data.str, sizeof(U64));
} }
CTRL_ProcessMemorySlice result_slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->handle, r1u64(tls_addr_array + tls_addr_off, tls_addr_array + tls_addr_off + addr_size), 0); CTRL_ProcessMemorySlice result_slice = ctrl_process_memory_slice_from_vaddr_range(scratch.arena, process->handle, r1u64(tls_addr_array + tls_addr_off, tls_addr_array + tls_addr_off + addr_size), 0);
String8 result_data = result_slice.data; String8 result_data = result_slice.data;
if(result_data.size >= 8) if(result_data.size >= 8)
{ {
@@ -1299,10 +1175,10 @@ internal DI_KeyList
d_push_active_dbgi_key_list(Arena *arena) d_push_active_dbgi_key_list(Arena *arena)
{ {
DI_KeyList dbgis = {0}; DI_KeyList dbgis = {0};
CTRL_EntityList modules = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); CTRL_EntityArray modules = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Module);
for(CTRL_EntityNode *n = modules.first; n != 0; n = n->next) for EachIndex(idx, modules.count)
{ {
CTRL_Entity *module = n->v; CTRL_Entity *module = modules.v[idx];
DI_Key key = ctrl_dbgi_key_from_module(module); DI_Key key = ctrl_dbgi_key_from_module(module);
di_key_list_push(arena, &dbgis, &key); di_key_list_push(arena, &dbgis, &key);
} }
@@ -1311,61 +1187,6 @@ d_push_active_dbgi_key_list(Arena *arena)
//- rjf: per-run caches //- rjf: per-run caches
internal CTRL_Unwind
d_query_cached_unwind_from_thread(CTRL_Entity *thread)
{
Temp scratch = scratch_begin(0, 0);
CTRL_Unwind result = {0};
if(thread->kind == CTRL_EntityKind_Thread)
{
U64 reg_gen = ctrl_reg_gen();
U64 mem_gen = ctrl_mem_gen();
D_UnwindCache *cache = &d_state->unwind_cache;
CTRL_Handle handle = thread->handle;
U64 hash = d_hash_from_string(str8_struct(&handle));
U64 slot_idx = hash%cache->slots_count;
D_UnwindCacheSlot *slot = &cache->slots[slot_idx];
D_UnwindCacheNode *node = 0;
for(D_UnwindCacheNode *n = slot->first; n != 0; n = n->next)
{
if(ctrl_handle_match(handle, n->thread))
{
node = n;
break;
}
}
if(node == 0)
{
node = cache->free_node;
if(node != 0)
{
SLLStackPop(cache->free_node);
}
else
{
node = push_array_no_zero(d_state->arena, D_UnwindCacheNode, 1);
}
MemoryZeroStruct(node);
DLLPushBack(slot->first, slot->last, node);
node->arena = arena_alloc();
node->thread = handle;
}
if(!d_state->ctrl_is_running && (node->reggen != reg_gen || node->memgen != mem_gen))
{
CTRL_Unwind new_unwind = ctrl_unwind_from_thread(scratch.arena, d_state->ctrl_entity_store, thread->handle, os_now_microseconds()+100);
if(!(new_unwind.flags & (CTRL_UnwindFlag_Error|CTRL_UnwindFlag_Stale)) && new_unwind.frames.count != 0)
{
node->unwind = ctrl_unwind_deep_copy(node->arena, thread->arch, &new_unwind);
node->reggen = reg_gen;
node->memgen = mem_gen;
}
}
result = node->unwind;
}
scratch_end(scratch);
return result;
}
internal U64 internal U64
d_query_cached_rip_from_thread(CTRL_Entity *thread) d_query_cached_rip_from_thread(CTRL_Entity *thread)
{ {
@@ -1379,15 +1200,17 @@ d_query_cached_rip_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count)
U64 result = 0; U64 result = 0;
if(unwind_count == 0) if(unwind_count == 0)
{ {
result = ctrl_query_cached_rip_from_thread(d_state->ctrl_entity_store, thread->handle); result = ctrl_rip_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle);
} }
else else
{ {
CTRL_Unwind unwind = d_query_cached_unwind_from_thread(thread); CTRL_Scope *ctrl_scope = ctrl_scope_open();
if(unwind.frames.count != 0) CTRL_CallStack callstack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, thread, 1, 0);
if(callstack.concrete_frames_count != 0)
{ {
result = regs_rip_from_arch_block(thread->arch, unwind.frames.v[unwind_count%unwind.frames.count].regs); result = regs_rip_from_arch_block(thread->arch, callstack.concrete_frames[unwind_count%callstack.concrete_frames_count]->regs);
} }
ctrl_scope_close(ctrl_scope);
} }
return result; return result;
} }
@@ -1594,22 +1417,13 @@ d_init(void)
d_state = push_array(arena, D_State, 1); d_state = push_array(arena, D_State, 1);
d_state->arena = arena; d_state->arena = arena;
d_state->cmds_arena = arena_alloc(); d_state->cmds_arena = arena_alloc();
d_state->output_log_key = hs_hash_from_data(str8_lit("output_log_key")); d_state->output_log_key = hs_key_make(hs_root_alloc(), hs_id_make(0, 0));
d_state->ctrl_entity_store = ctrl_entity_store_alloc(); hs_submit_data(d_state->output_log_key, 0, str8_zero());
d_state->ctrl_entity_store = ctrl_entity_ctx_rw_store_alloc();
d_state->ctrl_stop_arena = arena_alloc(); d_state->ctrl_stop_arena = arena_alloc();
d_state->view_rule_spec_table_size = 1024;
d_state->view_rule_spec_table = push_array(arena, D_ViewRuleSpec *, d_state->view_rule_spec_table_size);
d_state->ctrl_msg_arena = arena_alloc(); d_state->ctrl_msg_arena = arena_alloc();
// rjf: register core view rules
{
D_ViewRuleSpecInfoArray array = {d_core_view_rule_spec_info_table, ArrayCount(d_core_view_rule_spec_info_table)};
d_register_view_rule_specs(array);
}
// rjf: set up caches // rjf: set up caches
d_state->unwind_cache.slots_count = 1024;
d_state->unwind_cache.slots = push_array(arena, D_UnwindCacheSlot, d_state->unwind_cache.slots_count);
for(U64 idx = 0; idx < ArrayCount(d_state->tls_base_caches); idx += 1) for(U64 idx = 0; idx < ArrayCount(d_state->tls_base_caches); idx += 1)
{ {
d_state->tls_base_caches[idx].arena = arena_alloc(); d_state->tls_base_caches[idx].arena = arena_alloc();
@@ -1628,13 +1442,12 @@ d_init(void)
} }
internal D_EventList internal D_EventList
d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64], CTRL_MetaEvalArray *meta_evals) d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64])
{ {
ProfBeginFunction(); ProfBeginFunction();
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
D_EventList result = {0}; D_EventList result = {0};
d_state->frame_index += 1; d_state->frame_index += 1;
d_state->frame_eval_memread_endt_us = os_now_microseconds() + 1000;
////////////////////////////// //////////////////////////////
//- rjf: sync with ctrl thread //- rjf: sync with ctrl thread
@@ -1699,7 +1512,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
// rjf: push stop event to caller, if this is not a soft-halt // rjf: push stop event to caller, if this is not a soft-halt
if(should_snap) if(should_snap)
{ {
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, event->entity); CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, event->entity);
D_EventCause cause = D_EventCause_Null; D_EventCause cause = D_EventCause_Null;
switch(event->cause) switch(event->cause)
{ {
@@ -1725,6 +1538,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
evt->cause = cause; evt->cause = cause;
evt->thread = thread->kind == CTRL_EntityKind_Thread ? thread->handle : ctrl_handle_zero(); evt->thread = thread->kind == CTRL_EntityKind_Thread ? thread->handle : ctrl_handle_zero();
evt->vaddr = event->rip_vaddr; evt->vaddr = event->rip_vaddr;
evt->id = event->u64_code;
} }
}break; }break;
@@ -1733,7 +1547,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case CTRL_EventKind_NewProc: case CTRL_EventKind_NewProc:
{ {
// rjf: the first process? -> clear session output // rjf: the first process? -> clear session output
CTRL_EntityList existing_processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); CTRL_EntityArray existing_processes = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process);
if(existing_processes.count == 1) if(existing_processes.count == 1)
{ {
MTX_Op op = {r1u64(0, 0xffffffffffffffffull), str8_lit("[new session]\n")}; MTX_Op op = {r1u64(0, 0xffffffffffffffffull), str8_lit("[new session]\n")};
@@ -1816,10 +1630,10 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
// rjf: build data strings of all param data // rjf: build data strings of all param data
String8List strings = {0}; String8List strings = {0};
{ {
CTRL_EntityList threads = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); CTRL_EntityArray threads = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Thread);
for(CTRL_EntityNode *n = threads.first; n != 0; n = n->next) for EachIndex(idx, threads.count)
{ {
CTRL_Entity *thread = n->v; CTRL_Entity *thread = threads.v[idx];
if(thread->is_frozen) if(thread->is_frozen)
{ {
str8_list_push(scratch.arena, &strings, str8_struct(&thread->id)); str8_list_push(scratch.arena, &strings, str8_struct(&thread->id));
@@ -1831,8 +1645,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
D_Breakpoint *bp = &breakpoints->v[idx]; D_Breakpoint *bp = &breakpoints->v[idx];
str8_list_push(scratch.arena, &strings, bp->file_path); str8_list_push(scratch.arena, &strings, bp->file_path);
str8_list_push(scratch.arena, &strings, str8_struct(&bp->pt)); str8_list_push(scratch.arena, &strings, str8_struct(&bp->pt));
str8_list_push(scratch.arena, &strings, bp->symbol_name); str8_list_push(scratch.arena, &strings, bp->vaddr_expr);
str8_list_push(scratch.arena, &strings, str8_struct(&bp->vaddr));
str8_list_push(scratch.arena, &strings, bp->condition); str8_list_push(scratch.arena, &strings, bp->condition);
} }
} }
@@ -1854,53 +1667,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
d_cmd(D_CmdKind_SoftHaltRefresh); d_cmd(D_CmdKind_SoftHaltRefresh);
} }
//////////////////////////////
//- rjf: garbage collect eliminated thread unwinds
//
for(U64 slot_idx = 0; slot_idx < d_state->unwind_cache.slots_count; slot_idx += 1)
{
D_UnwindCacheSlot *slot = &d_state->unwind_cache.slots[slot_idx];
for(D_UnwindCacheNode *n = slot->first, *next = 0; n != 0; n = next)
{
next = n->next;
if(ctrl_entity_from_handle(d_state->ctrl_entity_store, n->thread) == &ctrl_entity_nil)
{
DLLRemove(slot->first, slot->last, n);
arena_release(n->arena);
SLLStackPush(d_state->unwind_cache.free_node, n);
}
}
}
//////////////////////////////
//- rjf: sync with di parsers
//
ProfScope("sync with di parsers")
{
DI_EventList events = di_p2u_pop_events(scratch.arena, 0);
for(DI_EventNode *n = events.first; n != 0; n = n->next)
{
DI_Event *event = &n->v;
switch(event->kind)
{
default:{}break;
case DI_EventKind_ConversionStarted:
{
RD_Entity *task = rd_entity_alloc(rd_entity_root(), RD_EntityKind_ConversionTask);
rd_entity_equip_name(task, event->string);
}break;
case DI_EventKind_ConversionEnded:
{
RD_Entity *task = rd_entity_from_name_and_kind(event->string, RD_EntityKind_ConversionTask);
if(!rd_entity_is_nil(task))
{
rd_entity_mark_for_deletion(task);
}
}break;
}
}
}
////////////////////////////// //////////////////////////////
//- rjf: process top-level commands //- rjf: process top-level commands
// //
@@ -1927,7 +1693,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
//- rjf: low-level target control operations //- rjf: low-level target control operations
case D_CmdKind_LaunchAndRun: case D_CmdKind_LaunchAndRun:
case D_CmdKind_LaunchAndInit: case D_CmdKind_LaunchAndStepInto:
{ {
// rjf: get list of targets to launch // rjf: get list of targets to launch
D_TargetArray *targets_to_launch = &params->targets; D_TargetArray *targets_to_launch = &params->targets;
@@ -1998,7 +1764,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
msg->debug_subprocesses = target->debug_subprocesses; msg->debug_subprocesses = target->debug_subprocesses;
msg->env_inherit = 1; msg->env_inherit = 1;
MemoryCopyArray(msg->exception_code_filters, exception_code_filters); MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
MemoryCopyStruct(&msg->meta_evals, meta_evals);
str8_list_push(scratch.arena, &msg->entry_points, custom_entry_point_name); str8_list_push(scratch.arena, &msg->entry_points, custom_entry_point_name);
msg->env_string_list = env; msg->env_string_list = env;
} }
@@ -2008,7 +1773,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
need_run = 1; need_run = 1;
run_kind = D_RunKind_Run; run_kind = D_RunKind_Run;
run_thread = &ctrl_entity_nil; run_thread = &ctrl_entity_nil;
run_flags = (cmd->kind == D_CmdKind_LaunchAndInit) ? CTRL_RunFlag_StopOnEntryPoint : 0; run_flags = (cmd->kind == D_CmdKind_LaunchAndStepInto) ? CTRL_RunFlag_StopOnEntryPoint : 0;
} }
// rjf: no targets -> error // rjf: no targets -> error
@@ -2019,7 +1784,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}break; }break;
case D_CmdKind_Kill: case D_CmdKind_Kill:
{ {
CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->process); CTRL_Entity *process = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, params->process);
if(process == &ctrl_entity_nil) if(process == &ctrl_entity_nil)
{ {
log_user_error(str8_lit("Cannot kill; no process was specified.")); log_user_error(str8_lit("Cannot kill; no process was specified."));
@@ -2031,7 +1796,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
msg->exit_code = 1; msg->exit_code = 1;
msg->entity = process->handle; msg->entity = process->handle;
MemoryCopyArray(msg->exception_code_filters, exception_code_filters); MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
MemoryCopyStruct(&msg->meta_evals, meta_evals);
} }
}break; }break;
case D_CmdKind_KillAll: case D_CmdKind_KillAll:
@@ -2040,11 +1804,10 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
msg->kind = CTRL_MsgKind_KillAll; msg->kind = CTRL_MsgKind_KillAll;
msg->exit_code = 1; msg->exit_code = 1;
MemoryCopyArray(msg->exception_code_filters, exception_code_filters); MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
MemoryCopyStruct(&msg->meta_evals, meta_evals);
}break; }break;
case D_CmdKind_Detach: case D_CmdKind_Detach:
{ {
CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->process); CTRL_Entity *process = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, params->process);
if(process == &ctrl_entity_nil) if(process == &ctrl_entity_nil)
{ {
log_user_error(str8_lit("Cannot detach; no process specified.")); log_user_error(str8_lit("Cannot detach; no process specified."));
@@ -2055,18 +1818,18 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
msg->kind = CTRL_MsgKind_Detach; msg->kind = CTRL_MsgKind_Detach;
msg->entity = process->handle; msg->entity = process->handle;
MemoryCopyArray(msg->exception_code_filters, exception_code_filters); MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
MemoryCopyStruct(&msg->meta_evals, meta_evals);
} }
}break; }break;
case D_CmdKind_Continue: case D_CmdKind_Continue:
{ {
B32 good_to_run = 0; B32 good_to_run = 0;
CTRL_EntityList threads = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); CTRL_EntityArray threads = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Thread);
if(threads.count > 0) if(threads.count > 0)
{ {
for(CTRL_EntityNode *n = threads.first; n != 0; n = n->next) for EachIndex(idx, threads.count)
{ {
if(!n->v->is_frozen) CTRL_Entity *thread = threads.v[idx];
if(!thread->is_frozen)
{ {
good_to_run = 1; good_to_run = 1;
break; break;
@@ -2090,7 +1853,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_StepOverLine: case D_CmdKind_StepOverLine:
case D_CmdKind_StepOut: case D_CmdKind_StepOut:
{ {
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->thread); CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, params->thread);
if(thread == &ctrl_entity_nil) if(thread == &ctrl_entity_nil)
{ {
log_user_error(str8_lit("Must have a selected thread to step.")); log_user_error(str8_lit("Must have a selected thread to step."));
@@ -2119,13 +1882,15 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_StepOverLine: {traps = d_trap_net_from_thread__step_over_line(scratch.arena, thread);}break; case D_CmdKind_StepOverLine: {traps = d_trap_net_from_thread__step_over_line(scratch.arena, thread);}break;
case D_CmdKind_StepOut: case D_CmdKind_StepOut:
{ {
// rjf: thread => full unwind CTRL_Scope *ctrl_scope = ctrl_scope_open();
CTRL_Unwind unwind = ctrl_unwind_from_thread(scratch.arena, d_state->ctrl_entity_store, thread->handle, os_now_microseconds()+10000);
// rjf: thread => call stack
CTRL_CallStack callstack = ctrl_call_stack_from_thread(ctrl_scope, &d_state->ctrl_entity_store->ctx, thread, 1, os_now_microseconds()+10000);
// rjf: use first unwind frame to generate trap // rjf: use first unwind frame to generate trap
if(unwind.flags == 0 && unwind.frames.count > 1) if(callstack.concrete_frames_count > 1)
{ {
U64 vaddr = regs_rip_from_arch_block(thread->arch, unwind.frames.v[1].regs); U64 vaddr = regs_rip_from_arch_block(thread->arch, callstack.concrete_frames[1]->regs);
CTRL_Trap trap = {CTRL_TrapFlag_EndStepping|CTRL_TrapFlag_IgnoreStackPointerCheck, vaddr}; CTRL_Trap trap = {CTRL_TrapFlag_EndStepping|CTRL_TrapFlag_IgnoreStackPointerCheck, vaddr};
ctrl_trap_list_push(scratch.arena, &traps, &trap); ctrl_trap_list_push(scratch.arena, &traps, &trap);
} }
@@ -2134,6 +1899,8 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
log_user_error(str8_lit("Could not find the return address of the current callstack frame successfully.")); log_user_error(str8_lit("Could not find the return address of the current callstack frame successfully."));
good = 0; good = 0;
} }
ctrl_scope_close(ctrl_scope);
}break; }break;
} }
if(good && traps.count != 0) if(good && traps.count != 0)
@@ -2164,38 +1931,18 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
{ {
need_run = 1; need_run = 1;
run_kind = d_state->ctrl_last_run_kind; run_kind = d_state->ctrl_last_run_kind;
run_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, d_state->ctrl_last_run_thread_handle); run_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, d_state->ctrl_last_run_thread_handle);
run_flags = d_state->ctrl_last_run_flags; run_flags = d_state->ctrl_last_run_flags;
run_traps = d_state->ctrl_last_run_traps; run_traps = d_state->ctrl_last_run_traps;
}break; }break;
case D_CmdKind_SetThreadIP: case D_CmdKind_SetThreadIP:
{ {
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->thread); CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, params->thread);
U64 vaddr = params->vaddr; U64 vaddr = params->vaddr;
void *block = ctrl_query_cached_reg_block_from_thread(scratch.arena, d_state->ctrl_entity_store, thread->handle); void *block = ctrl_reg_block_from_thread(scratch.arena, &d_state->ctrl_entity_store->ctx, thread->handle);
regs_arch_block_write_rip(thread->arch, block, vaddr); regs_arch_block_write_rip(thread->arch, block, vaddr);
B32 result = ctrl_thread_write_reg_block(thread->handle, block); B32 result = ctrl_thread_write_reg_block(thread->handle, block);
(void)result;
// rjf: early mutation of unwind cache for immediate frontend effect
if(result)
{
D_UnwindCache *cache = &d_state->unwind_cache;
if(cache->slots_count != 0)
{
CTRL_Handle thread_handle = thread->handle;
U64 hash = d_hash_from_string(str8_struct(&thread_handle));
U64 slot_idx = hash%cache->slots_count;
D_UnwindCacheSlot *slot = &cache->slots[slot_idx];
for(D_UnwindCacheNode *n = slot->first; n != 0; n = n->next)
{
if(ctrl_handle_match(n->thread, thread_handle) && n->unwind.frames.count != 0)
{
regs_arch_block_write_rip(thread->arch, n->unwind.frames.v[0].regs, vaddr);
break;
}
}
}
}
}break; }break;
//- rjf: high-level composite target control operations //- rjf: high-level composite target control operations
@@ -2203,20 +1950,20 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
{ {
run_extra_bps.count = 1; run_extra_bps.count = 1;
run_extra_bps.v = push_array(scratch.arena, D_Breakpoint, 1); run_extra_bps.v = push_array(scratch.arena, D_Breakpoint, 1);
if(params->file_path.size != 0)
{
run_extra_bps.v[0].file_path = params->file_path; run_extra_bps.v[0].file_path = params->file_path;
run_extra_bps.v[0].pt = params->cursor; run_extra_bps.v[0].pt = params->cursor;
d_cmd(D_CmdKind_Run); }
}break; else if(params->vaddr != 0)
case D_CmdKind_RunToAddress:
{ {
run_extra_bps.count = 1; run_extra_bps.v[0].vaddr_expr = push_str8f(scratch.arena, "0x%I64x", params->vaddr);
run_extra_bps.v = push_array(scratch.arena, D_Breakpoint, 1); }
run_extra_bps.v[0].vaddr = params->vaddr;
d_cmd(D_CmdKind_Run); d_cmd(D_CmdKind_Run);
}break; }break;
case D_CmdKind_Run: case D_CmdKind_Run:
{ {
CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); CTRL_EntityArray processes = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process);
if(processes.count != 0) if(processes.count != 0)
{ {
d_cmd(D_CmdKind_Continue); d_cmd(D_CmdKind_Continue);
@@ -2228,7 +1975,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
}break; }break;
case D_CmdKind_Restart: case D_CmdKind_Restart:
{ {
CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); CTRL_EntityArray processes = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process);
if(processes.count != 0) if(processes.count != 0)
{ {
d_cmd(D_CmdKind_KillAll); d_cmd(D_CmdKind_KillAll);
@@ -2238,7 +1985,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_StepInto: case D_CmdKind_StepInto:
case D_CmdKind_StepOver: case D_CmdKind_StepOver:
{ {
CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); CTRL_EntityArray processes = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Process);
if(processes.count != 0) if(processes.count != 0)
{ {
D_CmdKind step_cmd_kind = (cmd->kind == D_CmdKind_StepInto D_CmdKind step_cmd_kind = (cmd->kind == D_CmdKind_StepInto
@@ -2255,7 +2002,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
} }
else if(!d_ctrl_targets_running()) else if(!d_ctrl_targets_running())
{ {
d_cmd(D_CmdKind_LaunchAndInit, .targets = *targets); d_cmd(D_CmdKind_LaunchAndStepInto, .targets = *targets);
} }
}break; }break;
@@ -2277,18 +2024,18 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_FreezeLocalMachine: case D_CmdKind_FreezeLocalMachine:
{ {
CTRL_MachineID machine_id = CTRL_MachineID_Local; CTRL_MachineID machine_id = CTRL_MachineID_Local;
d_cmd(D_CmdKind_FreezeMachine, .machine = ctrl_handle_make(machine_id, dmn_handle_zero())); d_cmd(D_CmdKind_FreezeMachine, .entity = ctrl_handle_make(machine_id, dmn_handle_zero()));
}break; }break;
case D_CmdKind_ThawLocalMachine: case D_CmdKind_ThawLocalMachine:
{ {
CTRL_MachineID machine_id = CTRL_MachineID_Local; CTRL_MachineID machine_id = CTRL_MachineID_Local;
d_cmd(D_CmdKind_ThawMachine, .machine = ctrl_handle_make(machine_id, dmn_handle_zero())); d_cmd(D_CmdKind_ThawMachine, .entity = ctrl_handle_make(machine_id, dmn_handle_zero()));
}break; }break;
case D_CmdKind_FreezeEntity: case D_CmdKind_FreezeEntity:
case D_CmdKind_ThawEntity: case D_CmdKind_ThawEntity:
{ {
B32 should_freeze = (cmd->kind == D_CmdKind_FreezeEntity); B32 should_freeze = (cmd->kind == D_CmdKind_FreezeEntity);
CTRL_Entity *root = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->entity); CTRL_Entity *root = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, params->entity);
for(CTRL_Entity *e = root; e != &ctrl_entity_nil; e = ctrl_entity_rec_depth_first_pre(e, root).next) for(CTRL_Entity *e = root; e != &ctrl_entity_nil; e = ctrl_entity_rec_depth_first_pre(e, root).next)
{ {
if(e->kind == CTRL_EntityKind_Thread) if(e->kind == CTRL_EntityKind_Thread)
@@ -2303,7 +2050,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
{ {
need_run = 1; need_run = 1;
run_kind = d_state->ctrl_last_run_kind; run_kind = d_state->ctrl_last_run_kind;
run_thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, d_state->ctrl_last_run_thread_handle); run_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, d_state->ctrl_last_run_thread_handle);
run_flags = d_state->ctrl_last_run_flags; run_flags = d_state->ctrl_last_run_flags;
run_traps = d_state->ctrl_last_run_traps; run_traps = d_state->ctrl_last_run_traps;
} }
@@ -2312,12 +2059,12 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
//- rjf: entity decoration //- rjf: entity decoration
case D_CmdKind_SetEntityColor: case D_CmdKind_SetEntityColor:
{ {
CTRL_Entity *entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->entity); CTRL_Entity *entity = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, params->entity);
entity->rgba = params->rgba; entity->rgba = params->rgba;
}break; }break;
case D_CmdKind_SetEntityName: case D_CmdKind_SetEntityName:
{ {
CTRL_Entity *entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, params->entity); CTRL_Entity *entity = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, params->entity);
ctrl_entity_equip_string(d_state->ctrl_entity_store, entity, params->string); ctrl_entity_equip_string(d_state->ctrl_entity_store, entity, params->string);
}break; }break;
@@ -2331,7 +2078,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
msg->kind = CTRL_MsgKind_Attach; msg->kind = CTRL_MsgKind_Attach;
msg->entity_id = pid; msg->entity_id = pid;
MemoryCopyArray(msg->exception_code_filters, exception_code_filters); MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
MemoryCopyStruct(&msg->meta_evals, meta_evals);
} }
}break; }break;
} }
@@ -2353,7 +2099,6 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
msg->entity = run_thread->handle; msg->entity = run_thread->handle;
msg->parent = process->handle; msg->parent = process->handle;
MemoryCopyArray(msg->exception_code_filters, exception_code_filters); MemoryCopyArray(msg->exception_code_filters, exception_code_filters);
MemoryCopyStruct(&msg->meta_evals, meta_evals);
MemoryCopyStruct(&msg->traps, &run_traps); MemoryCopyStruct(&msg->traps, &run_traps);
D_BreakpointArray *bp_batches[] = D_BreakpointArray *bp_batches[] =
{ {
@@ -2368,6 +2113,12 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
// rjf: unpack user breakpoint entity // rjf: unpack user breakpoint entity
D_Breakpoint *bp = &batch_breakpoints->v[idx]; D_Breakpoint *bp = &batch_breakpoints->v[idx];
// rjf: d -> ctrl flags
CTRL_UserBreakpointFlags ctrl_bp_flags = 0;
if(bp->flags & D_BreakpointFlag_BreakOnWrite) { ctrl_bp_flags |= CTRL_UserBreakpointFlag_BreakOnWrite; }
if(bp->flags & D_BreakpointFlag_BreakOnRead) { ctrl_bp_flags |= CTRL_UserBreakpointFlag_BreakOnRead; }
if(bp->flags & D_BreakpointFlag_BreakOnExecute) { ctrl_bp_flags |= CTRL_UserBreakpointFlag_BreakOnExecute; }
// rjf: textual location -> add breakpoints for all possible override locations // rjf: textual location -> add breakpoints for all possible override locations
if(bp->file_path.size != 0 && bp->pt.line != 0) if(bp->file_path.size != 0 && bp->pt.line != 0)
{ {
@@ -2375,28 +2126,25 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
for(String8Node *n = overrides.first; n != 0; n = n->next) for(String8Node *n = overrides.first; n != 0; n = n->next)
{ {
CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_FileNameAndLineColNumber}; CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_FileNameAndLineColNumber};
ctrl_user_bp.flags = ctrl_bp_flags;
ctrl_user_bp.id = bp->id;
ctrl_user_bp.string = n->string; ctrl_user_bp.string = n->string;
ctrl_user_bp.pt = bp->pt; ctrl_user_bp.pt = bp->pt;
ctrl_user_bp.condition = bp->condition; ctrl_user_bp.condition = bp->condition;
ctrl_user_bp.size = bp->size;
ctrl_user_breakpoint_list_push(scratch.arena, &msg->user_bps, &ctrl_user_bp); ctrl_user_breakpoint_list_push(scratch.arena, &msg->user_bps, &ctrl_user_bp);
} }
} }
// rjf: virtual address location -> add breakpoint for address // rjf: virtual address expression -> add expression breakpoint
else if(bp->vaddr != 0) else if(bp->vaddr_expr.size != 0)
{ {
CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_VirtualAddress}; CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_Expression};
ctrl_user_bp.u64 = bp->vaddr; ctrl_user_bp.flags = ctrl_bp_flags;
ctrl_user_bp.condition = bp->condition; ctrl_user_bp.id = bp->id;
ctrl_user_breakpoint_list_push(scratch.arena, &msg->user_bps, &ctrl_user_bp); ctrl_user_bp.string = bp->vaddr_expr;
}
// rjf: symbol name location -> add breakpoint for symbol name
else if(bp->symbol_name.size != 0)
{
CTRL_UserBreakpoint ctrl_user_bp = {CTRL_UserBreakpointKind_SymbolNameAndOffset};
ctrl_user_bp.string = bp->symbol_name;
ctrl_user_bp.condition = bp->condition; ctrl_user_bp.condition = bp->condition;
ctrl_user_bp.size = bp->size;
ctrl_user_breakpoint_list_push(scratch.arena, &msg->user_bps, &ctrl_user_bp); ctrl_user_breakpoint_list_push(scratch.arena, &msg->user_bps, &ctrl_user_bp);
} }
} }
+16 -89
View File
@@ -28,14 +28,24 @@ struct D_TargetArray
U64 count; U64 count;
}; };
typedef U32 D_BreakpointFlags;
enum
{
D_BreakpointFlag_BreakOnWrite = (1<<0),
D_BreakpointFlag_BreakOnRead = (1<<1),
D_BreakpointFlag_BreakOnExecute = (1<<2),
};
typedef struct D_Breakpoint D_Breakpoint; typedef struct D_Breakpoint D_Breakpoint;
struct D_Breakpoint struct D_Breakpoint
{ {
D_BreakpointFlags flags;
U64 id;
String8 file_path; String8 file_path;
TxtPt pt; TxtPt pt;
String8 symbol_name; String8 vaddr_expr;
U64 vaddr;
String8 condition; String8 condition;
U64 size;
}; };
typedef struct D_BreakpointArray D_BreakpointArray; typedef struct D_BreakpointArray D_BreakpointArray;
@@ -89,6 +99,7 @@ struct D_Event
CTRL_Handle thread; CTRL_Handle thread;
U64 vaddr; U64 vaddr;
U64 code; U64 code;
U64 id;
}; };
typedef struct D_EventNode D_EventNode; typedef struct D_EventNode D_EventNode;
@@ -158,42 +169,6 @@ D_RunKind;
#include "dbg_engine/generated/dbg_engine.meta.h" #include "dbg_engine/generated/dbg_engine.meta.h"
////////////////////////////////
//~ rjf: View Rules
typedef U32 D_ViewRuleSpecInfoFlags; // NOTE(rjf): see @view_rule_info
enum
{
D_ViewRuleSpecInfoFlag_Inherited = (1<<0),
D_ViewRuleSpecInfoFlag_Expandable = (1<<1),
D_ViewRuleSpecInfoFlag_ExprResolution = (1<<2),
D_ViewRuleSpecInfoFlag_VizBlockProd = (1<<3),
};
typedef struct D_ViewRuleSpecInfo D_ViewRuleSpecInfo;
struct D_ViewRuleSpecInfo
{
String8 string;
String8 display_string;
String8 schema;
String8 description;
D_ViewRuleSpecInfoFlags flags;
};
typedef struct D_ViewRuleSpecInfoArray D_ViewRuleSpecInfoArray;
struct D_ViewRuleSpecInfoArray
{
D_ViewRuleSpecInfo *v;
U64 count;
};
typedef struct D_ViewRuleSpec D_ViewRuleSpec;
struct D_ViewRuleSpec
{
D_ViewRuleSpec *hash_next;
D_ViewRuleSpecInfo info;
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Command Types //~ rjf: Command Types
@@ -240,35 +215,6 @@ struct D_CmdList
//////////////////////////////// ////////////////////////////////
//~ rjf: Main State Caches //~ rjf: Main State Caches
//- rjf: per-thread unwind cache
typedef struct D_UnwindCacheNode D_UnwindCacheNode;
struct D_UnwindCacheNode
{
D_UnwindCacheNode *next;
D_UnwindCacheNode *prev;
U64 reggen;
U64 memgen;
Arena *arena;
CTRL_Handle thread;
CTRL_Unwind unwind;
};
typedef struct D_UnwindCacheSlot D_UnwindCacheSlot;
struct D_UnwindCacheSlot
{
D_UnwindCacheNode *first;
D_UnwindCacheNode *last;
};
typedef struct D_UnwindCache D_UnwindCache;
struct D_UnwindCache
{
U64 slots_count;
D_UnwindCacheSlot *slots;
D_UnwindCacheNode *free_node;
};
//- rjf: per-run tls-base-vaddr cache //- rjf: per-run tls-base-vaddr cache
typedef struct D_RunTLSBaseCacheNode D_RunTLSBaseCacheNode; typedef struct D_RunTLSBaseCacheNode D_RunTLSBaseCacheNode;
@@ -331,17 +277,15 @@ struct D_State
// rjf: top-level state // rjf: top-level state
Arena *arena; Arena *arena;
U64 frame_index; U64 frame_index;
U64 frame_eval_memread_endt_us;
// rjf: commands // rjf: commands
Arena *cmds_arena; Arena *cmds_arena;
D_CmdList cmds; D_CmdList cmds;
// rjf: output log key // rjf: output log key
U128 output_log_key; HS_Key output_log_key;
// rjf: per-run caches // rjf: per-run caches
D_UnwindCache unwind_cache;
U64 tls_base_cache_reggen_idx; U64 tls_base_cache_reggen_idx;
U64 tls_base_cache_memgen_idx; U64 tls_base_cache_memgen_idx;
D_RunTLSBaseCache tls_base_caches[2]; D_RunTLSBaseCache tls_base_caches[2];
@@ -353,10 +297,6 @@ struct D_State
D_RunLocalsCache member_caches[2]; D_RunLocalsCache member_caches[2];
U64 member_cache_gen; U64 member_cache_gen;
// rjf: view rule specification table
U64 view_rule_spec_table_size;
D_ViewRuleSpec **view_rule_spec_table;
// rjf: user -> ctrl driving state // rjf: user -> ctrl driving state
Arena *ctrl_last_run_arena; Arena *ctrl_last_run_arena;
D_RunKind ctrl_last_run_kind; D_RunKind ctrl_last_run_kind;
@@ -373,7 +313,7 @@ struct D_State
CTRL_MsgList ctrl_msgs; CTRL_MsgList ctrl_msgs;
// rjf: ctrl -> user reading state // rjf: ctrl -> user reading state
CTRL_EntityStore *ctrl_entity_store; CTRL_EntityCtxRWStore *ctrl_entity_store;
Arena *ctrl_stop_arena; Arena *ctrl_stop_arena;
CTRL_Event ctrl_last_stop_event; CTRL_Event ctrl_last_stop_event;
}; };
@@ -381,7 +321,6 @@ struct D_State
//////////////////////////////// ////////////////////////////////
//~ rjf: Globals //~ rjf: Globals
read_only global D_ViewRuleSpec d_nil_core_view_rule_spec = {0};
global D_State *d_state = 0; global D_State *d_state = 0;
//////////////////////////////// ////////////////////////////////
@@ -416,12 +355,6 @@ internal D_CmdParams d_cmd_params_copy(Arena *arena, D_CmdParams *src);
//- rjf: command lists //- rjf: command lists
internal void d_cmd_list_push_new(Arena *arena, D_CmdList *cmds, D_CmdKind kind, D_CmdParams *params); internal void d_cmd_list_push_new(Arena *arena, D_CmdList *cmds, D_CmdKind kind, D_CmdParams *params);
////////////////////////////////
//~ rjf: View Rule Spec Stateful Functions
internal void d_register_view_rule_specs(D_ViewRuleSpecInfoArray specs);
internal D_ViewRuleSpec *d_view_rule_spec_from_string(String8 string);
//////////////////////////////// ////////////////////////////////
//~ rjf: Stepping "Trap Net" Builders //~ rjf: Stepping "Trap Net" Builders
@@ -432,13 +365,8 @@ internal CTRL_TrapList d_trap_net_from_thread__step_into_line(Arena *arena, CTRL
//////////////////////////////// ////////////////////////////////
//~ rjf: Debug Info Lookups //~ rjf: Debug Info Lookups
//- rjf: voff|vaddr -> symbol lookups
internal String8 d_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff, B32 decorated);
internal String8 d_symbol_name_from_process_vaddr(Arena *arena, CTRL_Entity *process, U64 vaddr, B32 decorated);
//- rjf: symbol -> voff lookups //- rjf: symbol -> voff lookups
internal U64 d_voff_from_dbgi_key_symbol_name(DI_Key *dbgi_key, String8 symbol_name); internal U64 d_voff_from_dbgi_key_symbol_name(DI_Key *dbgi_key, String8 symbol_name);
internal U64 d_type_num_from_dbgi_key_name(DI_Key *dbgi_key, String8 name);
//- rjf: voff -> line info //- rjf: voff -> line info
internal D_LineList d_lines_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff); internal D_LineList d_lines_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff);
@@ -477,7 +405,6 @@ internal B32 d_ctrl_targets_running(void);
internal DI_KeyList d_push_active_dbgi_key_list(Arena *arena); internal DI_KeyList d_push_active_dbgi_key_list(Arena *arena);
//- rjf: per-run caches //- rjf: per-run caches
internal CTRL_Unwind d_query_cached_unwind_from_thread(CTRL_Entity *thread);
internal U64 d_query_cached_rip_from_thread(CTRL_Entity *thread); internal U64 d_query_cached_rip_from_thread(CTRL_Entity *thread);
internal U64 d_query_cached_rip_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count); internal U64 d_query_cached_rip_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count);
internal U64 d_query_cached_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64 rip_vaddr); internal U64 d_query_cached_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64 rip_vaddr);
@@ -495,6 +422,6 @@ internal B32 d_next_cmd(D_Cmd **cmd);
//~ rjf: Main Layer Top-Level Calls //~ rjf: Main Layer Top-Level Calls
internal void d_init(void); internal void d_init(void);
internal D_EventList d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64], CTRL_MetaEvalArray *meta_evals); internal D_EventList d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_PathMapArray *path_maps, U64 exception_code_filters[(CTRL_ExceptionCodeKind_COUNT+63)/64]);
#endif // DBG_ENGINE_CORE_H #endif // DBG_ENGINE_CORE_H
@@ -3,31 +3,3 @@
//- GENERATED CODE //- GENERATED CODE
C_LINKAGE_BEGIN
D_ViewRuleSpecInfo d_core_view_rule_spec_info_table[21] =
{
{str8_lit_comp("default"), str8_lit_comp("Default"), str8_lit_comp(""), str8_lit_comp(""), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), },
{str8_lit_comp("array"), str8_lit_comp("Array"), str8_lit_comp("x:{expr}"), str8_lit_comp("Specifies that a pointer points to N elements, rather than only 1."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*1)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), },
{str8_lit_comp("slice"), str8_lit_comp("Slice"), str8_lit_comp(""), str8_lit_comp("Specifies that a pointer within a struct, also containing an integer, points to the number of elements encoded by the integer."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*1)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), },
{str8_lit_comp("list"), str8_lit_comp("List"), str8_lit_comp("x:{member}"), 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."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), },
{str8_lit_comp("bswap"), str8_lit_comp("Byte Swap"), str8_lit_comp(""), str8_lit_comp("Specifies that all integral evaluations should be byte-swapped, such that their endianness is reversed."), (D_ViewRuleSpecInfoFlag_Inherited*1)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*1)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), },
{str8_lit_comp("cast"), str8_lit_comp("Cast"), str8_lit_comp("x:{type}"), str8_lit_comp("Specifies that the expression to which the view rule is applied should be casted to the provided type."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*1)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), },
{str8_lit_comp("dec"), str8_lit_comp("Decimal Base (Base 10)"), str8_lit_comp(""), str8_lit_comp("Specifies that all integral evaluations should appear in base-10 form."), (D_ViewRuleSpecInfoFlag_Inherited*1)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), },
{str8_lit_comp("bin"), str8_lit_comp("Binary Base (Base 2)"), str8_lit_comp(""), str8_lit_comp("Specifies that all integral evaluations should appear in base-2 form."), (D_ViewRuleSpecInfoFlag_Inherited*1)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), },
{str8_lit_comp("oct"), str8_lit_comp("Octal Base (Base 8)"), str8_lit_comp(""), str8_lit_comp("Specifies that all integral evaluations should appear in base-8 form."), (D_ViewRuleSpecInfoFlag_Inherited*1)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), },
{str8_lit_comp("hex"), str8_lit_comp("Hexadecimal Base (Base 16)"), str8_lit_comp(""), str8_lit_comp("Specifies that all integral evaluations should appear in base-16 form."), (D_ViewRuleSpecInfoFlag_Inherited*1)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), },
{str8_lit_comp("only"), str8_lit_comp("Only Specified Members"), str8_lit_comp("x:{member}"), str8_lit_comp("Specifies that only the specified members should appear in struct, union, or class evaluations."), (D_ViewRuleSpecInfoFlag_Inherited*1)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), },
{str8_lit_comp("omit"), str8_lit_comp("Omit Specified Members"), str8_lit_comp("x:{member}"), str8_lit_comp("Omits a list of member names from appearing in struct, union, or class evaluations."), (D_ViewRuleSpecInfoFlag_Inherited*1)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), },
{str8_lit_comp("no_addr"), str8_lit_comp("Disable Address Values"), str8_lit_comp(""), str8_lit_comp("Displays only what pointers point to, if possible, without the pointer's address value."), (D_ViewRuleSpecInfoFlag_Inherited*1)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), },
{str8_lit_comp("checkbox"), str8_lit_comp("Checkbox"), str8_lit_comp(""), str8_lit_comp("Displays simple integer values as checkboxes, encoding zero or nonzero values."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*0)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*0), },
{str8_lit_comp("color_rgba"), str8_lit_comp("Color (RGBA)"), str8_lit_comp(""), str8_lit_comp("Displays as a color, interpreting the data as encoding R, G, B, and A values."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*1)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), },
{str8_lit_comp("text"), str8_lit_comp("Text"), str8_lit_comp("x:{'lang':lang, 'size':expr}"), str8_lit_comp("Displays as text."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*1)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), },
{str8_lit_comp("disasm"), str8_lit_comp("Disassembly"), str8_lit_comp("x:{'arch':arch, 'size':expr}"), str8_lit_comp("Displays as disassembled instructions, interpreting the data as raw machine code."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*1)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), },
{str8_lit_comp("memory"), str8_lit_comp("Memory"), str8_lit_comp("x:{'size':expr}"), str8_lit_comp("Displays as a raw memory grid."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*1)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), },
{str8_lit_comp("graph"), str8_lit_comp("Graph"), str8_lit_comp(""), str8_lit_comp("Displays as a pointer graph, visualizing nodes and edges formed by pointers directly."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*1)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), },
{str8_lit_comp("bitmap"), str8_lit_comp("Bitmap"), str8_lit_comp("x:{'w':expr, 'h':expr, 'fmt':tex2dformat}"), str8_lit_comp("Displays as a bitmap, interpreting the data as raw pixel data."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*1)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), },
{str8_lit_comp("geo3d"), str8_lit_comp("Geometry (3D)"), str8_lit_comp("x:{'count':expr, 'vtx':expr, 'vtx_size':expr}"), str8_lit_comp("Displays as geometry, interpreting the data as index or vertex data."), (D_ViewRuleSpecInfoFlag_Inherited*0)|(D_ViewRuleSpecInfoFlag_Expandable*1)|(D_ViewRuleSpecInfoFlag_ExprResolution*0)|(D_ViewRuleSpecInfoFlag_VizBlockProd*1), },
};
C_LINKAGE_END
+1 -30
View File
@@ -10,7 +10,7 @@ typedef enum D_CmdKind
{ {
D_CmdKind_Null, D_CmdKind_Null,
D_CmdKind_LaunchAndRun, D_CmdKind_LaunchAndRun,
D_CmdKind_LaunchAndInit, D_CmdKind_LaunchAndStepInto,
D_CmdKind_Kill, D_CmdKind_Kill,
D_CmdKind_KillAll, D_CmdKind_KillAll,
D_CmdKind_Detach, D_CmdKind_Detach,
@@ -24,7 +24,6 @@ D_CmdKind_Halt,
D_CmdKind_SoftHaltRefresh, D_CmdKind_SoftHaltRefresh,
D_CmdKind_SetThreadIP, D_CmdKind_SetThreadIP,
D_CmdKind_RunToLine, D_CmdKind_RunToLine,
D_CmdKind_RunToAddress,
D_CmdKind_Run, D_CmdKind_Run,
D_CmdKind_Restart, D_CmdKind_Restart,
D_CmdKind_StepInto, D_CmdKind_StepInto,
@@ -45,32 +44,6 @@ D_CmdKind_Attach,
D_CmdKind_COUNT, D_CmdKind_COUNT,
} D_CmdKind; } D_CmdKind;
typedef enum D_ViewRuleKind
{
D_ViewRuleKind_Default,
D_ViewRuleKind_Array,
D_ViewRuleKind_Slice,
D_ViewRuleKind_List,
D_ViewRuleKind_ByteSwap,
D_ViewRuleKind_Cast,
D_ViewRuleKind_BaseDec,
D_ViewRuleKind_BaseBin,
D_ViewRuleKind_BaseOct,
D_ViewRuleKind_BaseHex,
D_ViewRuleKind_Only,
D_ViewRuleKind_Omit,
D_ViewRuleKind_NoAddr,
D_ViewRuleKind_Checkbox,
D_ViewRuleKind_ColorRGBA,
D_ViewRuleKind_Text,
D_ViewRuleKind_Disasm,
D_ViewRuleKind_Memory,
D_ViewRuleKind_Graph,
D_ViewRuleKind_Bitmap,
D_ViewRuleKind_Geo3D,
D_ViewRuleKind_COUNT,
} D_ViewRuleKind;
global B32 DEV_simulate_lag = 0; global B32 DEV_simulate_lag = 0;
global B32 DEV_draw_ui_text_pos = 0; global B32 DEV_draw_ui_text_pos = 0;
global B32 DEV_draw_ui_focus_debug = 0; global B32 DEV_draw_ui_focus_debug = 0;
@@ -78,7 +51,6 @@ global B32 DEV_draw_ui_box_heatmap = 0;
global B32 DEV_eval_compiler_tooltips = 0; global B32 DEV_eval_compiler_tooltips = 0;
global B32 DEV_eval_watch_key_tooltips = 0; global B32 DEV_eval_watch_key_tooltips = 0;
global B32 DEV_cmd_context_tooltips = 0; global B32 DEV_cmd_context_tooltips = 0;
global B32 DEV_scratch_mouse_draw = 0;
global B32 DEV_updating_indicator = 0; global B32 DEV_updating_indicator = 0;
struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] = struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] =
{ {
@@ -89,7 +61,6 @@ struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] =
{&DEV_eval_compiler_tooltips, str8_lit_comp("eval_compiler_tooltips")}, {&DEV_eval_compiler_tooltips, str8_lit_comp("eval_compiler_tooltips")},
{&DEV_eval_watch_key_tooltips, str8_lit_comp("eval_watch_key_tooltips")}, {&DEV_eval_watch_key_tooltips, str8_lit_comp("eval_watch_key_tooltips")},
{&DEV_cmd_context_tooltips, str8_lit_comp("cmd_context_tooltips")}, {&DEV_cmd_context_tooltips, str8_lit_comp("cmd_context_tooltips")},
{&DEV_scratch_mouse_draw, str8_lit_comp("scratch_mouse_draw")},
{&DEV_updating_indicator, str8_lit_comp("updating_indicator")}, {&DEV_updating_indicator, str8_lit_comp("updating_indicator")},
}; };
#endif // DBG_ENGINE_META_H #endif // DBG_ENGINE_META_H
+39 -26
View File
@@ -1,6 +1,9 @@
// Copyright (c) 2024 Epic Games Tools // Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
#undef LAYER_COLOR
#define LAYER_COLOR 0x7c4ce3ff
//////////////////////////////// ////////////////////////////////
//~ rjf: Basic Helpers //~ rjf: Basic Helpers
@@ -262,22 +265,26 @@ di_scope_open(void)
scope = push_array_no_zero(di_tctx->arena, DI_Scope, 1); scope = push_array_no_zero(di_tctx->arena, DI_Scope, 1);
} }
MemoryZeroStruct(scope); MemoryZeroStruct(scope);
DLLPushBack(di_tctx->first_scope, di_tctx->last_scope, scope);
return scope; return scope;
} }
internal void internal void
di_scope_close(DI_Scope *scope) di_scope_close(DI_Scope *scope)
{ {
DLLRemove(di_tctx->first_scope, di_tctx->last_scope, scope);
for(DI_Touch *t = scope->first_touch, *next = 0; t != 0; t = next) for(DI_Touch *t = scope->first_touch, *next = 0; t != 0; t = next)
{ {
next = t->next; next = t->next;
if(t->node != 0) if(t->node != 0)
{ {
ins_atomic_u64_dec_eval(&t->node->touch_count); ins_atomic_u64_dec_eval(&t->node->touch_count);
os_condition_variable_broadcast(t->stripe->cv);
} }
if(t->search_node != 0) if(t->search_node != 0)
{ {
ins_atomic_u64_dec_eval(&t->search_node->scope_refcount); ins_atomic_u64_dec_eval(&t->search_node->scope_refcount);
os_condition_variable_broadcast(t->search_stripe->cv);
} }
SLLStackPush(di_tctx->free_touch, t); SLLStackPush(di_tctx->free_touch, t);
} }
@@ -285,7 +292,7 @@ di_scope_close(DI_Scope *scope)
} }
internal void internal void
di_scope_touch_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_Node *node) di_scope_touch_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_Stripe *stripe, DI_Node *node)
{ {
if(node != 0) if(node != 0)
{ {
@@ -303,10 +310,11 @@ di_scope_touch_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_Node *node)
MemoryZeroStruct(touch); MemoryZeroStruct(touch);
SLLQueuePush(scope->first_touch, scope->last_touch, touch); SLLQueuePush(scope->first_touch, scope->last_touch, touch);
touch->node = node; touch->node = node;
touch->stripe = stripe;
} }
internal void internal void
di_scope_touch_search_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_SearchNode *node) di_scope_touch_search_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_SearchStripe *stripe, DI_SearchNode *node)
{ {
if(node != 0) if(node != 0)
{ {
@@ -324,6 +332,7 @@ di_scope_touch_search_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_SearchNod
MemoryZeroStruct(touch); MemoryZeroStruct(touch);
SLLQueuePush(scope->first_touch, scope->last_touch, touch); SLLQueuePush(scope->first_touch, scope->last_touch, touch);
touch->search_node = node; touch->search_node = node;
touch->search_stripe = stripe;
} }
//////////////////////////////// ////////////////////////////////
@@ -522,6 +531,7 @@ di_close(DI_Key *key)
DI_Slot *slot = &di_shared->slots[slot_idx]; DI_Slot *slot = &di_shared->slots[slot_idx];
DI_Stripe *stripe = &di_shared->stripes[stripe_idx]; DI_Stripe *stripe = &di_shared->stripes[stripe_idx];
log_infof("close_debug_info: {\"%S\", 0x%I64x}\n", key_normalized.path, key_normalized.min_timestamp); log_infof("close_debug_info: {\"%S\", 0x%I64x}\n", key_normalized.path, key_normalized.min_timestamp);
B32 closed = 0;
OS_MutexScopeW(stripe->rw_mutex) OS_MutexScopeW(stripe->rw_mutex)
{ {
//- rjf: find existing node //- rjf: find existing node
@@ -533,16 +543,8 @@ di_close(DI_Key *key)
node->ref_count -= 1; node->ref_count -= 1;
if(node->ref_count == 0) for(;;) if(node->ref_count == 0) for(;;)
{ {
//- rjf: wait for touch count to go to 0
if(ins_atomic_u64_eval(&node->touch_count) != 0)
{
os_rw_mutex_drop_w(stripe->rw_mutex);
for(U64 start_t = os_now_microseconds(); os_now_microseconds() <= start_t + 250;);
os_rw_mutex_take_w(stripe->rw_mutex);
}
//- rjf: release //- rjf: release
if(node->ref_count == 0 && ins_atomic_u64_eval(&node->touch_count) == 0) if(ins_atomic_u64_eval(&node->touch_count) == 0)
{ {
di_string_release__stripe_mutex_w_guarded(stripe, node->key.path); di_string_release__stripe_mutex_w_guarded(stripe, node->key.path);
if(node->file_base != 0) if(node->file_base != 0)
@@ -565,6 +567,9 @@ di_close(DI_Key *key)
SLLStackPush(stripe->free_node, node); SLLStackPush(stripe->free_node, node);
break; break;
} }
//- rjf: wait for touch count to go to 0
os_condition_variable_wait_rw_w(stripe->cv, stripe->rw_mutex, max_U64);
} }
} }
} }
@@ -580,7 +585,7 @@ internal RDI_Parsed *
di_rdi_from_key(DI_Scope *scope, DI_Key *key, U64 endt_us) di_rdi_from_key(DI_Scope *scope, DI_Key *key, U64 endt_us)
{ {
ProfBeginFunction(); ProfBeginFunction();
RDI_Parsed *result = &di_rdi_parsed_nil; RDI_Parsed *result = &rdi_parsed_nil;
if(key->path.size != 0) if(key->path.size != 0)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
@@ -610,7 +615,7 @@ di_rdi_from_key(DI_Scope *scope, DI_Key *key, U64 endt_us)
//- rjf: parse done -> touch, grab result //- rjf: parse done -> touch, grab result
if(node != 0 && node->parse_done) if(node != 0 && node->parse_done)
{ {
di_scope_touch_node__stripe_mutex_r_guarded(scope, node); di_scope_touch_node__stripe_mutex_r_guarded(scope, stripe, node);
result = &node->rdi; result = &node->rdi;
break; break;
} }
@@ -702,12 +707,11 @@ di_search_items_from_key_params_query(DI_Scope *scope, U128 key, DI_SearchParams
B32 params_stale = 1; B32 params_stale = 1;
B32 query_stale = 1; B32 query_stale = 1;
B32 results_stale = 1; B32 results_stale = 1;
if(params_hash == node->buckets[node->bucket_read_gen%ArrayCount(node->buckets)].params_hash && if(node->bucket_read_gen != 0)
node->bucket_read_gen != 0)
{ {
di_scope_touch_search_node__stripe_mutex_r_guarded(scope, node); di_scope_touch_search_node__stripe_mutex_r_guarded(scope, stripe, node);
items = node->items; items = node->items;
params_stale = 0; params_stale = (params_hash != node->buckets[node->bucket_read_gen%ArrayCount(node->buckets)].params_hash);
query_stale = !str8_match(query, node->buckets[node->bucket_read_gen%ArrayCount(node->buckets)].query, 0); query_stale = !str8_match(query, node->buckets[node->bucket_read_gen%ArrayCount(node->buckets)].query, 0);
results_stale = (node->bucket_read_gen < node->bucket_write_gen); results_stale = (node->bucket_read_gen < node->bucket_write_gen);
} }
@@ -716,8 +720,8 @@ di_search_items_from_key_params_query(DI_Scope *scope, U128 key, DI_SearchParams
*stale_out = (params_stale || query_stale || results_stale); *stale_out = (params_stale || query_stale || results_stale);
} }
// rjf: if query stale -> request again // rjf: if query or params stale -> request again
if(query_stale && node->bucket_read_gen <= node->bucket_write_gen && node->bucket_write_gen < node->bucket_read_gen + ArrayCount(node->buckets)-1) if((query_stale || params_stale) && node->bucket_read_gen <= node->bucket_write_gen && node->bucket_write_gen < node->bucket_read_gen + ArrayCount(node->buckets)-1)
{ {
node->bucket_write_gen += 1; node->bucket_write_gen += 1;
if(node->bucket_write_gen >= node->bucket_items_gen + ArrayCount(node->buckets)) if(node->bucket_write_gen >= node->bucket_items_gen + ArrayCount(node->buckets))
@@ -1084,7 +1088,7 @@ ASYNC_WORK_DEF(di_parse_work)
//////////////////////////// ////////////////////////////
//- rjf: do initial parse of rdi //- rjf: do initial parse of rdi
// //
RDI_Parsed rdi_parsed_maybe_compressed = di_rdi_parsed_nil; RDI_Parsed rdi_parsed_maybe_compressed = rdi_parsed_nil;
{ {
RDI_ParseStatus parse_status = rdi_parse((U8 *)file_base, file_props.size, &rdi_parsed_maybe_compressed); RDI_ParseStatus parse_status = rdi_parse((U8 *)file_base, file_props.size, &rdi_parsed_maybe_compressed);
(void)parse_status; (void)parse_status;
@@ -1349,7 +1353,6 @@ di_search_thread__entry_point(void *p)
for(;;) for(;;)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
DI_Scope *di_scope = di_scope_open();
//- rjf: get next key, unpack //- rjf: get next key, unpack
U128 key = di_u2s_dequeue_req(thread_idx); U128 key = di_u2s_dequeue_req(thread_idx);
@@ -1380,6 +1383,9 @@ di_search_thread__entry_point(void *p)
} }
} }
//- rjf: begin debug info scope
DI_Scope *di_scope = di_scope_open();
//- rjf: get all rdis //- rjf: get all rdis
U64 rdis_count = params.dbgi_keys.count; U64 rdis_count = params.dbgi_keys.count;
RDI_Parsed **rdis = push_array(scratch.arena, RDI_Parsed *, rdis_count); RDI_Parsed **rdis = push_array(scratch.arena, RDI_Parsed *, rdis_count);
@@ -1428,6 +1434,9 @@ di_search_thread__entry_point(void *p)
cancelled = (cancelled || out->cancelled); cancelled = (cancelled || out->cancelled);
} }
//- rjf: end debug info scope
di_scope_close(di_scope);
//- rjf: list -> array //- rjf: list -> array
DI_SearchItemArray items = {0}; DI_SearchItemArray items = {0};
if(arena != 0 && !cancelled) if(arena != 0 && !cancelled)
@@ -1464,13 +1473,14 @@ di_search_thread__entry_point(void *p)
quick_sort(items.v, items.count, sizeof(DI_SearchItem), di_qsort_compare_search_items); quick_sort(items.v, items.count, sizeof(DI_SearchItem), di_qsort_compare_search_items);
} }
//- rjf: commit to cache - busyloop on scope touches //- rjf: commit to cache - wait on scope touches
if(arena != 0) if(arena != 0)
{ {
for(B32 done = 0; !done;) OS_MutexScopeW(stripe->rw_mutex) for(;;)
{ {
B32 found = 0; B32 found = 0;
OS_MutexScopeW(stripe->rw_mutex) for(DI_SearchNode *n = slot->first; n != 0; n = n->next) B32 done = 0;
for(DI_SearchNode *n = slot->first; n != 0; n = n->next)
{ {
if(u128_match(n->key, key)) if(u128_match(n->key, key))
{ {
@@ -1489,14 +1499,17 @@ di_search_thread__entry_point(void *p)
break; break;
} }
} }
if(!found) if((found && done) || !found)
{ {
break; break;
} }
if(found && !done)
{
os_condition_variable_wait_rw_w(stripe->cv, stripe->rw_mutex, os_now_microseconds()+1000);
}
} }
} }
di_scope_close(di_scope);
scratch_end(scratch); scratch_end(scratch);
} }
} }
+7 -3
View File
@@ -218,13 +218,16 @@ struct DI_Touch
{ {
DI_Touch *next; DI_Touch *next;
DI_Node *node; DI_Node *node;
DI_Stripe *stripe;
DI_SearchNode *search_node; DI_SearchNode *search_node;
DI_SearchStripe *search_stripe;
}; };
typedef struct DI_Scope DI_Scope; typedef struct DI_Scope DI_Scope;
struct DI_Scope struct DI_Scope
{ {
DI_Scope *next; DI_Scope *next;
DI_Scope *prev;
DI_Touch *first_touch; DI_Touch *first_touch;
DI_Touch *last_touch; DI_Touch *last_touch;
}; };
@@ -233,6 +236,8 @@ typedef struct DI_TCTX DI_TCTX;
struct DI_TCTX struct DI_TCTX
{ {
Arena *arena; Arena *arena;
DI_Scope *first_scope;
DI_Scope *last_scope;
DI_Scope *free_scope; DI_Scope *free_scope;
DI_Touch *free_touch; DI_Touch *free_touch;
}; };
@@ -376,7 +381,6 @@ struct DI_Shared
global DI_Shared *di_shared = 0; global DI_Shared *di_shared = 0;
thread_static DI_TCTX *di_tctx = 0; thread_static DI_TCTX *di_tctx = 0;
global RDI_Parsed di_rdi_parsed_nil = {0};
//////////////////////////////// ////////////////////////////////
//~ rjf: Basic Helpers //~ rjf: Basic Helpers
@@ -407,8 +411,8 @@ internal void di_init(void);
internal DI_Scope *di_scope_open(void); internal DI_Scope *di_scope_open(void);
internal void di_scope_close(DI_Scope *scope); internal void di_scope_close(DI_Scope *scope);
internal void di_scope_touch_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_Node *node); internal void di_scope_touch_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_Stripe *stripe, DI_Node *node);
internal void di_scope_touch_search_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_SearchNode *node); internal void di_scope_touch_search_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_SearchStripe *stripe, DI_SearchNode *node);
//////////////////////////////// ////////////////////////////////
//~ rjf: Per-Slot Functions //~ rjf: Per-Slot Functions
+11 -1
View File
@@ -73,7 +73,7 @@ struct DMN_Event
U64 size; U64 size;
String8 string; String8 string;
U32 code; // code gives pid & tid on CreateProcess and CreateThread (respectfully) U32 code; // code gives pid & tid on CreateProcess and CreateThread (respectfully)
U32 flags; U32 flags; // DMN_TrapFlags, if `DMN_EventKind_SetBreakpoint`
S32 signo; S32 signo;
S32 sigcode; S32 sigcode;
U64 instruction_pointer; U64 instruction_pointer;
@@ -100,12 +100,22 @@ struct DMN_EventList
//////////////////////////////// ////////////////////////////////
//~ rjf: Run Control Types //~ rjf: Run Control Types
typedef U32 DMN_TrapFlags;
enum
{
DMN_TrapFlag_BreakOnWrite = (1<<0),
DMN_TrapFlag_BreakOnRead = (1<<1),
DMN_TrapFlag_BreakOnExecute = (1<<2),
};
typedef struct DMN_Trap DMN_Trap; typedef struct DMN_Trap DMN_Trap;
struct DMN_Trap struct DMN_Trap
{ {
DMN_Handle process; DMN_Handle process;
U64 vaddr; U64 vaddr;
U64 id; U64 id;
DMN_TrapFlags flags;
U32 size;
}; };
typedef struct DMN_TrapChunkNode DMN_TrapChunkNode; typedef struct DMN_TrapChunkNode DMN_TrapChunkNode;
+3
View File
@@ -21,6 +21,9 @@ DMN_EventKindTable:
{Memory} {Memory}
{DebugString} {DebugString}
{SetThreadName} {SetThreadName}
{SetThreadColor}
{SetBreakpoint}
{UnsetBreakpoint}
} }
@table(name) @table(name)
+4 -1
View File
@@ -4,7 +4,7 @@
//- GENERATED CODE //- GENERATED CODE
C_LINKAGE_BEGIN C_LINKAGE_BEGIN
String8 dmn_event_kind_string_table[17] = String8 dmn_event_kind_string_table[20] =
{ {
str8_lit_comp("Null"), str8_lit_comp("Null"),
str8_lit_comp("Error"), str8_lit_comp("Error"),
@@ -23,6 +23,9 @@ str8_lit_comp("Halt"),
str8_lit_comp("Memory"), str8_lit_comp("Memory"),
str8_lit_comp("DebugString"), str8_lit_comp("DebugString"),
str8_lit_comp("SetThreadName"), str8_lit_comp("SetThreadName"),
str8_lit_comp("SetThreadColor"),
str8_lit_comp("SetBreakpoint"),
str8_lit_comp("UnsetBreakpoint"),
}; };
String8 dmn_exception_kind_string_table[5] = String8 dmn_exception_kind_string_table[5] =
+4 -1
View File
@@ -25,6 +25,9 @@ DMN_EventKind_Halt,
DMN_EventKind_Memory, DMN_EventKind_Memory,
DMN_EventKind_DebugString, DMN_EventKind_DebugString,
DMN_EventKind_SetThreadName, DMN_EventKind_SetThreadName,
DMN_EventKind_SetThreadColor,
DMN_EventKind_SetBreakpoint,
DMN_EventKind_UnsetBreakpoint,
DMN_EventKind_COUNT, DMN_EventKind_COUNT,
} DMN_EventKind; } DMN_EventKind;
@@ -58,7 +61,7 @@ DMN_ExceptionKind_COUNT,
} DMN_ExceptionKind; } DMN_ExceptionKind;
C_LINKAGE_BEGIN C_LINKAGE_BEGIN
extern String8 dmn_event_kind_string_table[17]; extern String8 dmn_event_kind_string_table[20];
extern String8 dmn_exception_kind_string_table[5]; extern String8 dmn_exception_kind_string_table[5];
C_LINKAGE_END C_LINKAGE_END
+21
View File
@@ -15,6 +15,8 @@ dmn_init(void)
internal DMN_CtrlCtx * internal DMN_CtrlCtx *
dmn_ctrl_begin(void) dmn_ctrl_begin(void)
{ {
DMN_CtrlCtx *ctx = (DMN_CtrlCtx *)1;
return ctx;
} }
internal void internal void
@@ -30,26 +32,32 @@ dmn_ctrl_exclusive_access_end(void)
internal U32 internal U32
dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params) dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params)
{ {
return 0;
} }
internal B32 internal B32
dmn_ctrl_attach(DMN_CtrlCtx *ctx, U32 pid) dmn_ctrl_attach(DMN_CtrlCtx *ctx, U32 pid)
{ {
return 0;
} }
internal B32 internal B32
dmn_ctrl_kill(DMN_CtrlCtx *ctx, DMN_Handle process, U32 exit_code) dmn_ctrl_kill(DMN_CtrlCtx *ctx, DMN_Handle process, U32 exit_code)
{ {
return 0;
} }
internal B32 internal B32
dmn_ctrl_detach(DMN_CtrlCtx *ctx, DMN_Handle process) dmn_ctrl_detach(DMN_CtrlCtx *ctx, DMN_Handle process)
{ {
return 0;
} }
internal DMN_EventList internal DMN_EventList
dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
{ {
DMN_EventList evts = {0};
return evts;
} }
//////////////////////////////// ////////////////////////////////
@@ -68,16 +76,19 @@ dmn_halt(U64 code, U64 user_data)
internal U64 internal U64
dmn_run_gen(void) dmn_run_gen(void)
{ {
return 0;
} }
internal U64 internal U64
dmn_mem_gen(void) dmn_mem_gen(void)
{ {
return 0;
} }
internal U64 internal U64
dmn_reg_gen(void) dmn_reg_gen(void)
{ {
return 0;
} }
//- rjf: non-blocking-control-thread access barriers //- rjf: non-blocking-control-thread access barriers
@@ -85,6 +96,7 @@ dmn_reg_gen(void)
internal B32 internal B32
dmn_access_open(void) dmn_access_open(void)
{ {
return 0;
} }
internal void internal void
@@ -97,6 +109,7 @@ dmn_access_close(void)
internal U64 internal U64
dmn_process_memory_reserve(DMN_Handle process, U64 vaddr, U64 size) dmn_process_memory_reserve(DMN_Handle process, U64 vaddr, U64 size)
{ {
return 0;
} }
internal void internal void
@@ -122,11 +135,13 @@ dmn_process_memory_protect(DMN_Handle process, U64 vaddr, U64 size, OS_AccessFla
internal U64 internal U64
dmn_process_read(DMN_Handle process, Rng1U64 range, void *dst) dmn_process_read(DMN_Handle process, Rng1U64 range, void *dst)
{ {
return 0;
} }
internal B32 internal B32
dmn_process_write(DMN_Handle process, Rng1U64 range, void *src) dmn_process_write(DMN_Handle process, Rng1U64 range, void *src)
{ {
return 0;
} }
//- rjf: threads //- rjf: threads
@@ -134,26 +149,31 @@ dmn_process_write(DMN_Handle process, Rng1U64 range, void *src)
internal Arch internal Arch
dmn_arch_from_thread(DMN_Handle handle) dmn_arch_from_thread(DMN_Handle handle)
{ {
return Arch_Null;
} }
internal U64 internal U64
dmn_stack_base_vaddr_from_thread(DMN_Handle handle) dmn_stack_base_vaddr_from_thread(DMN_Handle handle)
{ {
return 0;
} }
internal U64 internal U64
dmn_tls_root_vaddr_from_thread(DMN_Handle handle) dmn_tls_root_vaddr_from_thread(DMN_Handle handle)
{ {
return 0;
} }
internal B32 internal B32
dmn_thread_read_reg_block(DMN_Handle handle, void *reg_block) dmn_thread_read_reg_block(DMN_Handle handle, void *reg_block)
{ {
return 0;
} }
internal B32 internal B32
dmn_thread_write_reg_block(DMN_Handle handle, void *reg_block) dmn_thread_write_reg_block(DMN_Handle handle, void *reg_block)
{ {
return 0;
} }
//- rjf: system process listing //- rjf: system process listing
@@ -166,6 +186,7 @@ dmn_process_iter_begin(DMN_ProcessIter *iter)
internal B32 internal B32
dmn_process_iter_next(Arena *arena, DMN_ProcessIter *iter, DMN_ProcessInfo *info_out) dmn_process_iter_next(Arena *arena, DMN_ProcessIter *iter, DMN_ProcessInfo *info_out)
{ {
return 0;
} }
internal void internal void
+332 -33
View File
@@ -56,16 +56,17 @@ dmn_w32_entity_alloc(DMN_W32_Entity *parent, DMN_W32_EntityKind kind, U64 id)
// rjf: allocate // rjf: allocate
DMN_W32_Entity *e = dmn_w32_shared->entities_first_free; DMN_W32_Entity *e = dmn_w32_shared->entities_first_free;
{ {
U32 gen = 0;
if(e != 0) if(e != 0)
{ {
SLLStackPop(dmn_w32_shared->entities_first_free); SLLStackPop(dmn_w32_shared->entities_first_free);
gen = e->gen;
} }
else else
{ {
e = push_array_no_zero(dmn_w32_shared->entities_arena, DMN_W32_Entity, 1); e = push_array_no_zero(dmn_w32_shared->entities_arena, DMN_W32_Entity, 1);
dmn_w32_shared->entities_count += 1; dmn_w32_shared->entities_count += 1;
} }
U32 gen = e->gen;
MemoryZeroStruct(e); MemoryZeroStruct(e);
e->gen = gen+1; e->gen = gen+1;
} }
@@ -155,6 +156,7 @@ dmn_w32_entity_release(DMN_W32_Entity *entity)
{ {
CloseHandle(t->e->handle); CloseHandle(t->e->handle);
} }
t->e->kind = DMN_W32_EntityKind_Null;
// rjf: remove from id -> entity map // rjf: remove from id -> entity map
if(t->e->id != 0) if(t->e->id != 0)
@@ -469,9 +471,9 @@ dmn_w32_image_info_from_process_base_vaddr(HANDLE process, U64 base_vaddr)
} }
// rjf: get COFF header // rjf: get COFF header
B32 got_file_header = 0; B32 got_coff_header = 0;
U64 file_header_off = 0; U64 coff_header_off = 0;
COFF_FileHeader file_header = {0}; COFF_FileHeader coff_header = {0};
if(pe_offset > 0) if(pe_offset > 0)
{ {
U64 pe_magic_off = base_vaddr + pe_offset; U64 pe_magic_off = base_vaddr + pe_offset;
@@ -479,28 +481,28 @@ dmn_w32_image_info_from_process_base_vaddr(HANDLE process, U64 base_vaddr)
dmn_w32_process_read_struct(process, pe_magic_off, &pe_magic); dmn_w32_process_read_struct(process, pe_magic_off, &pe_magic);
if(pe_magic == PE_MAGIC) if(pe_magic == PE_MAGIC)
{ {
file_header_off = pe_magic_off + sizeof(pe_magic); coff_header_off = pe_magic_off + sizeof(pe_magic);
if(dmn_w32_process_read_struct(process, file_header_off, &file_header)) if(dmn_w32_process_read_struct(process, coff_header_off, &coff_header))
{ {
got_file_header = 1; got_coff_header = 1;
} }
} }
} }
// rjf: get arch and size // rjf: get arch and size
DMN_W32_ImageInfo result = zero_struct; DMN_W32_ImageInfo result = zero_struct;
if(got_file_header) if(got_coff_header)
{ {
U64 optional_size_off = 0; U64 optional_size_off = 0;
Arch arch = Arch_Null; Arch arch = Arch_Null;
switch(file_header.machine) switch(coff_header.machine)
{ {
case COFF_Machine_X86: case COFF_MachineType_X86:
{ {
arch = Arch_x86; arch = Arch_x86;
optional_size_off = OffsetOf(PE_OptionalHeader32, sizeof_image); optional_size_off = OffsetOf(PE_OptionalHeader32, sizeof_image);
}break; }break;
case COFF_Machine_X64: case COFF_MachineType_X64:
{ {
arch = Arch_x64; arch = Arch_x64;
optional_size_off = OffsetOf(PE_OptionalHeader32Plus, sizeof_image); optional_size_off = OffsetOf(PE_OptionalHeader32Plus, sizeof_image);
@@ -510,7 +512,7 @@ dmn_w32_image_info_from_process_base_vaddr(HANDLE process, U64 base_vaddr)
} }
if(arch != Arch_Null) if(arch != Arch_Null)
{ {
U64 optional_off = file_header_off + sizeof(COFF_FileHeader); U64 optional_off = coff_header_off + sizeof(coff_header);
U32 size = 0; U32 size = 0;
if(dmn_w32_process_read_struct(process, optional_off+optional_size_off, &size) >= sizeof(size)) if(dmn_w32_process_read_struct(process, optional_off+optional_size_off, &size) >= sizeof(size))
{ {
@@ -749,12 +751,12 @@ dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block)
dst->fs.u16 = ctx->SegFs; dst->fs.u16 = ctx->SegFs;
dst->gs.u16 = ctx->SegGs; dst->gs.u16 = ctx->SegGs;
dst->ss.u16 = ctx->SegSs; dst->ss.u16 = ctx->SegSs;
dst->dr0.u32 = ctx->Dr0; dst->dr0.u64 = ctx->Dr0;
dst->dr1.u32 = ctx->Dr1; dst->dr1.u64 = ctx->Dr1;
dst->dr2.u32 = ctx->Dr2; dst->dr2.u64 = ctx->Dr2;
dst->dr3.u32 = ctx->Dr3; dst->dr3.u64 = ctx->Dr3;
dst->dr6.u32 = ctx->Dr6; dst->dr6.u64 = ctx->Dr6;
dst->dr7.u32 = ctx->Dr7; dst->dr7.u64 = ctx->Dr7;
// NOTE(rjf): this bit is "supposed to always be 1", according to old info. // NOTE(rjf): this bit is "supposed to always be 1", according to old info.
// may need to be investigated. // may need to be investigated.
dst->rflags.u64 = ctx->EFlags | 0x2; dst->rflags.u64 = ctx->EFlags | 0x2;
@@ -1020,12 +1022,12 @@ dmn_w32_thread_write_reg_block(Arch arch, HANDLE thread, void *reg_block)
ctx->SegFs = src->fs.u16; ctx->SegFs = src->fs.u16;
ctx->SegGs = src->gs.u16; ctx->SegGs = src->gs.u16;
ctx->SegSs = src->ss.u16; ctx->SegSs = src->ss.u16;
ctx->Dr0 = src->dr0.u32; ctx->Dr0 = src->dr0.u64;
ctx->Dr1 = src->dr1.u32; ctx->Dr1 = src->dr1.u64;
ctx->Dr2 = src->dr2.u32; ctx->Dr2 = src->dr2.u64;
ctx->Dr3 = src->dr3.u32; ctx->Dr3 = src->dr3.u64;
ctx->Dr6 = src->dr6.u32; ctx->Dr6 = src->dr6.u64;
ctx->Dr7 = src->dr7.u32; ctx->Dr7 = src->dr7.u64;
ctx->EFlags = src->rflags.u64; ctx->EFlags = src->rflags.u64;
fxsave->ControlWord = src->fcw.u16; fxsave->ControlWord = src->fcw.u16;
fxsave->StatusWord = src->fsw.u16; fxsave->StatusWord = src->fsw.u16;
@@ -1291,7 +1293,6 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params)
inherit_handles = 1; inherit_handles = 1;
} }
PROCESS_INFORMATION process_info = {0}; PROCESS_INFORMATION process_info = {0};
AllocConsole();
if(CreateProcessW(0, (WCHAR*)cmd16.str, 0, 0, 1, creation_flags, (WCHAR*)env16.str, (WCHAR*)dir16.str, &startup_info, &process_info)) if(CreateProcessW(0, (WCHAR*)cmd16.str, 0, 0, 1, creation_flags, (WCHAR*)env16.str, (WCHAR*)dir16.str, &startup_info, &process_info))
{ {
// check if we are 32-bit app, and just close it immediately // check if we are 32-bit app, and just close it immediately
@@ -1313,15 +1314,13 @@ dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params)
} }
else else
{ {
MessageBox(0, "Error starting process.", "Process error", MB_OK|MB_ICONSTOP); DWORD error = GetLastError();
} LPWSTR message = 0;
FreeConsole(); FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0, error, MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL), (LPWSTR)&message, 0, 0);
String8 message8 = message ? str8_from_16(scratch.arena, str16_cstring(message)) : str8_lit("unknown error");
LocalFree(message);
//- rjf: eliminate all handles which have stuck around from the AllocConsole log_user_errorf("There was an error starting %S: %S", params->cmd_line.first->string, message8);
{
SetStdHandle(STD_INPUT_HANDLE, 0);
SetStdHandle(STD_OUTPUT_HANDLE, 0);
SetStdHandle(STD_ERROR_HANDLE, 0);
} }
} }
scratch_end(scratch); scratch_end(scratch);
@@ -1560,6 +1559,8 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
for(U64 n_idx = 0; n_idx < n->count; n_idx += 1, trap_idx += 1) for(U64 n_idx = 0; n_idx < n->count; n_idx += 1, trap_idx += 1)
{ {
DMN_Trap *trap = n->v+n_idx; DMN_Trap *trap = n->v+n_idx;
if(trap->flags == 0)
{
trap_swap_bytes[trap_idx] = 0xCC; trap_swap_bytes[trap_idx] = 0xCC;
dmn_process_read(trap->process, r1u64(trap->vaddr, trap->vaddr+1), trap_swap_bytes+trap_idx); dmn_process_read(trap->process, r1u64(trap->vaddr, trap->vaddr+1), trap_swap_bytes+trap_idx);
U8 int3 = 0xCC; U8 int3 = 0xCC;
@@ -1567,6 +1568,155 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
} }
} }
} }
}
//////////////////////////
//- rjf: gather all flagged traps, bucketed by process
//
typedef struct DMN_FlaggedTrapTask DMN_FlaggedTrapTask;
struct DMN_FlaggedTrapTask
{
DMN_FlaggedTrapTask *next;
DMN_Handle process;
DMN_TrapChunkList traps;
};
DMN_FlaggedTrapTask *first_flagged_trap_task = 0;
DMN_FlaggedTrapTask *last_flagged_trap_task= 0;
for(DMN_TrapChunkNode *n = ctrls->traps.first; n != 0; n = n->next)
{
for(U64 n_idx = 0; n_idx < n->count; n_idx += 1)
{
DMN_Trap *trap = n->v+n_idx;
if(trap->flags != 0)
{
DMN_FlaggedTrapTask *task = 0;
for(DMN_FlaggedTrapTask *t = first_flagged_trap_task; t != 0; t = t->next)
{
if(dmn_handle_match(t->process, trap->process))
{
task = t;
break;
}
}
if(task == 0)
{
task = push_array(scratch.arena, DMN_FlaggedTrapTask, 1);
SLLQueuePush(first_flagged_trap_task, last_flagged_trap_task, task);
task->process = trap->process;
}
B32 already_in_task = 0;
for(DMN_TrapChunkNode *n = task->traps.first; n != 0; n = n->next)
{
for(U64 n_idx = 0; n_idx < n->count; n_idx += 1)
{
if(n->v[n_idx].id == trap->id)
{
already_in_task = 1;
goto end_look_for_existing_trap_in_task;
}
}
}
end_look_for_existing_trap_in_task:;
if(!already_in_task)
{
dmn_trap_chunk_list_push(scratch.arena, &task->traps, 8, trap);
}
}
}
}
//////////////////////////
//- rjf: write all debug register states, for flagged-traps
//
ProfScope("write all debug register states, for flagged-traps")
{
//- rjf: for each flagged trap task, iterate all threads in the
// associated process, and prepare debug registers accordingly
for(DMN_FlaggedTrapTask *t = first_flagged_trap_task; t != 0; t = t->next)
{
DMN_Handle process = t->process;
DMN_W32_Entity *process_entity = dmn_w32_entity_from_handle(process);
for(DMN_W32_Entity *child = process_entity->first;
child != &dmn_w32_entity_nil;
child = child->next)
{
if(child->kind == DMN_W32_EntityKind_Thread)
{
switch(child->arch)
{
default:{}break;
//- rjf: x64
case Arch_x64:
{
REGS_RegBlockX64 regs = {0};
dmn_w32_thread_read_reg_block(child->arch, child->handle, &regs);
{
U64 trap_idx = 0;
for(DMN_TrapChunkNode *n = t->traps.first; n != 0; n = n->next)
{
for(U64 n_idx = 0; n_idx < n->count && trap_idx < 4; n_idx += 1, trap_idx += 1)
{
DMN_Trap *trap = &n->v[n_idx];
REGS_Reg64 *addr_reg = &regs.dr0;
switch(trap_idx)
{
default:{}break;
case 0:{addr_reg = &regs.dr0;}break;
case 1:{addr_reg = &regs.dr1;}break;
case 2:{addr_reg = &regs.dr2;}break;
case 3:{addr_reg = &regs.dr3;}break;
}
addr_reg->u64 = trap->vaddr;
regs.dr7.u64 |= bit9|bit10|bit11;
regs.dr7.u64 |= (1ull << (trap_idx*2));
// NOTE(rjf): global-enable regs.dr7.u64 |= (1ull << (trap_idx*2+1));
regs.dr7.u64 &= ~((U64)(bit17|bit18|bit19|bit20) << (trap_idx*4));
regs.dr7.u64 &= ~((U64)(bit15|bit16));
switch(trap->flags)
{
case DMN_TrapFlag_BreakOnExecute:
default:{}break;
case DMN_TrapFlag_BreakOnWrite:
case DMN_TrapFlag_BreakOnWrite|DMN_TrapFlag_BreakOnExecute:
{
regs.dr7.u64 |= ((U64)bit17) << (trap_idx*4);
}break;
case DMN_TrapFlag_BreakOnRead|DMN_TrapFlag_BreakOnWrite|DMN_TrapFlag_BreakOnExecute:
case DMN_TrapFlag_BreakOnRead|DMN_TrapFlag_BreakOnWrite:
{
regs.dr7.u64 |= (((U64)bit17) << (trap_idx*4));
regs.dr7.u64 |= (((U64)bit18) << (trap_idx*4));
}break;
}
switch(trap->size)
{
case 1:
default:{}break;
case 2:
{
regs.dr7.u64 |= (((U64)bit19) << (trap_idx*4));
}break;
case 4:
{
regs.dr7.u64 |= (((U64)bit19) << (trap_idx*4));
regs.dr7.u64 |= (((U64)bit20) << (trap_idx*4));
}break;
case 8:
{
regs.dr7.u64 |= (((U64)bit20) << (trap_idx*4));
}break;
}
}
}
}
dmn_w32_thread_write_reg_block(child->arch, child->handle, &regs);
}break;
}
}
}
}
}
////////////////////////// //////////////////////////
//- rjf: produce list of threads which will run //- rjf: produce list of threads which will run
@@ -1721,6 +1871,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
{ {
dmn_w32_shared->resume_needed = 0; dmn_w32_shared->resume_needed = 0;
resume_good = !!ContinueDebugEvent(dmn_w32_shared->resume_pid, dmn_w32_shared->resume_tid, resume_code); resume_good = !!ContinueDebugEvent(dmn_w32_shared->resume_pid, dmn_w32_shared->resume_tid, resume_code);
DWORD error = GetLastError();
dmn_w32_shared->resume_needed = 0; dmn_w32_shared->resume_needed = 0;
dmn_w32_shared->resume_tid = 0; dmn_w32_shared->resume_tid = 0;
dmn_w32_shared->resume_pid = 0; dmn_w32_shared->resume_pid = 0;
@@ -1736,6 +1887,8 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
} }
else else
{ {
DWORD err = GetLastError();
(void)err;
keep_going = 1; keep_going = 1;
} }
ins_atomic_u64_inc_eval(&dmn_w32_shared->run_gen); ins_atomic_u64_inc_eval(&dmn_w32_shared->run_gen);
@@ -1843,6 +1996,15 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
{ {
DMN_W32_Entity *process = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Process, evt.dwProcessId); DMN_W32_Entity *process = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Process, evt.dwProcessId);
// rjf: if this was the process we were going to resume, then we will
// just not resume, and wait for another debug event
if(evt.dwProcessId == dmn_w32_shared->resume_pid)
{
dmn_w32_shared->resume_needed = 0;
dmn_w32_shared->resume_tid = 0;
dmn_w32_shared->resume_pid = 0;
}
// rjf: generate events for children // rjf: generate events for children
for(DMN_W32_Entity *child = process->first; child != &dmn_w32_entity_nil; child = child->next) for(DMN_W32_Entity *child = process->first; child != &dmn_w32_entity_nil; child = child->next)
{ {
@@ -1948,6 +2110,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
e->kind = DMN_EventKind_Halt; e->kind = DMN_EventKind_Halt;
dmn_w32_shared->halter_process = dmn_handle_zero(); dmn_w32_shared->halter_process = dmn_handle_zero();
dmn_w32_shared->halter_tid = 0; dmn_w32_shared->halter_tid = 0;
keep_going = 0;
} }
// rjf: if this thread is *not* the halter, then generate a regular exit-thread event // rjf: if this thread is *not* the halter, then generate a regular exit-thread event
@@ -2089,6 +2252,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
//- rjf: check if this trap is a usage-code-specified trap or something else //- rjf: check if this trap is a usage-code-specified trap or something else
B32 hit_user_trap = 0; B32 hit_user_trap = 0;
U64 user_trap_id = 0;
if(is_trap) if(is_trap)
{ {
for(DMN_TrapChunkNode *n = ctrls->traps.first; n != 0; n = n->next) for(DMN_TrapChunkNode *n = ctrls->traps.first; n != 0; n = n->next)
@@ -2098,6 +2262,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
if(dmn_handle_match(n->v[idx].process, dmn_w32_handle_from_entity(process)) && n->v[idx].vaddr == instruction_pointer) if(dmn_handle_match(n->v[idx].process, dmn_w32_handle_from_entity(process)) && n->v[idx].vaddr == instruction_pointer)
{ {
hit_user_trap = 1; hit_user_trap = 1;
user_trap_id = n->v[idx].id;
break; break;
} }
} }
@@ -2186,6 +2351,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
e->code = exception->ExceptionCode; e->code = exception->ExceptionCode;
e->flags = exception->ExceptionFlags; e->flags = exception->ExceptionFlags;
e->instruction_pointer = (U64)exception->ExceptionAddress; e->instruction_pointer = (U64)exception->ExceptionAddress;
e->user_data = user_trap_id;
//- rjf: fill according to exception code //- rjf: fill according to exception code
switch(exception->ExceptionCode) switch(exception->ExceptionCode)
@@ -2215,6 +2381,72 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
case DMN_W32_EXCEPTION_SINGLE_STEP: case DMN_W32_EXCEPTION_SINGLE_STEP:
{ {
e->kind = DMN_EventKind_SingleStep; e->kind = DMN_EventKind_SingleStep;
// NOTE(rjf): data breakpoints are reported via single-steps
// over the instructions which caused the breakpoint to be
// hit - so if we have data breakpoints set, we need to
// check this thread's debug registers, to determine if this
// is a regular single-step or a data breakpoint hit.
if(first_flagged_trap_task != 0)
{
// rjf: first determine the flagged trap index
U64 flagged_trap_idx = 0;
switch(thread->arch)
{
default:{NotImplemented;}break;
case Arch_x64:
{
REGS_RegBlockX64 regs = {0};
dmn_w32_thread_read_reg_block(thread->arch, thread->handle, &regs);
if(regs.dr6.u64 & 0xF)
{
e->kind = DMN_EventKind_Breakpoint;
if(0){}
else if(regs.dr7.u64 & (1ull<<0) && regs.dr6.u64 & (1ull<<0)) { flagged_trap_idx = 0; }
else if(regs.dr7.u64 & (1ull<<2) && regs.dr6.u64 & (1ull<<1)) { flagged_trap_idx = 1; }
else if(regs.dr7.u64 & (1ull<<4) && regs.dr6.u64 & (1ull<<2)) { flagged_trap_idx = 2; }
else if(regs.dr7.u64 & (1ull<<8) && regs.dr6.u64 & (1ull<<3)) { flagged_trap_idx = 3; }
}
}break;
}
// rjf: find the flagged trap task for this thread's process
DMN_W32_Entity *process = thread->parent;
DMN_FlaggedTrapTask *task = 0;
for(DMN_FlaggedTrapTask *t = first_flagged_trap_task; t != 0; t = t->next)
{
if(dmn_handle_match(t->process, dmn_w32_handle_from_entity(process)))
{
task = t;
break;
}
}
// rjf: find the trap
DMN_Trap *trap = 0;
if(task != 0)
{
U64 trap_idx = 0;
for(DMN_TrapChunkNode *n = task->traps.first; n != 0; n = n->next)
{
for(U64 n_idx = 0; n_idx < n->count; n_idx += 1, trap_idx += 1)
{
if(trap_idx == flagged_trap_idx)
{
trap = &n->v[n_idx];
goto break_search_for_flagged_trap;
}
}
}
break_search_for_flagged_trap:;
}
// rjf: fill event based on trap
if(trap != 0)
{
e->user_data = trap->id;
}
}
}break; }break;
//- rjf: fill throw info //- rjf: fill throw info
@@ -2303,6 +2535,31 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
} }
}break; }break;
//- rjf: fill set-thread-color info
case DMN_W32_EXCEPTION_RADDBG_SET_THREAD_COLOR:
{
e->kind = DMN_EventKind_SetThreadColor;
e->code = exception->ExceptionInformation[0];
e->user_data = exception->ExceptionInformation[1];
}break;
//- rjf: fill set-data-breakpoint info
case DMN_W32_EXCEPTION_RADDBG_SET_BREAKPOINT:
{
U64 vaddr = exception->ExceptionInformation[0];
U64 size = exception->ExceptionInformation[1];
U64 read = exception->ExceptionInformation[2];
U64 write = exception->ExceptionInformation[3];
U64 exec = exception->ExceptionInformation[4];
U64 set = exception->ExceptionInformation[5];
e->kind = set ? DMN_EventKind_SetBreakpoint : DMN_EventKind_UnsetBreakpoint;
e->address = vaddr;
e->size = size;
if(read) { e->flags |= DMN_TrapFlag_BreakOnRead; }
if(write) { e->flags |= DMN_TrapFlag_BreakOnWrite; }
if(exec) { e->flags |= DMN_TrapFlag_BreakOnExecute; }
}break;
//- rjf: unhandled exception case //- rjf: unhandled exception case
default: default:
{ {
@@ -2400,6 +2657,10 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
for(DMN_W32_EntityNode *n = first_run_thread; n != 0; n = n->next) for(DMN_W32_EntityNode *n = first_run_thread; n != 0; n = n->next)
{ {
DMN_W32_Entity *thread = n->v; DMN_W32_Entity *thread = n->v;
if(thread->kind != DMN_W32_EntityKind_Thread)
{
continue;
}
DWORD suspend_result = SuspendThread(thread->handle); DWORD suspend_result = SuspendThread(thread->handle);
switch(suspend_result) switch(suspend_result)
{ {
@@ -2428,7 +2689,9 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
} }
} }
////////////////////////
//- rjf: gather new thread-names //- rjf: gather new thread-names
//
ProfScope("gather new thread names") if(dmn_w32_GetThreadDescription != 0) ProfScope("gather new thread names") if(dmn_w32_GetThreadDescription != 0)
{ {
for(DMN_W32_Entity *process = dmn_w32_shared->entities_base->first; for(DMN_W32_Entity *process = dmn_w32_shared->entities_base->first;
@@ -2481,6 +2744,8 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
for(U64 n_idx = 0; n_idx < n->count; n_idx += 1, trap_idx += 1) for(U64 n_idx = 0; n_idx < n->count; n_idx += 1, trap_idx += 1)
{ {
DMN_Trap *trap = n->v+n_idx; DMN_Trap *trap = n->v+n_idx;
if(trap->flags == 0)
{
U8 og_byte = trap_swap_bytes[trap_idx]; U8 og_byte = trap_swap_bytes[trap_idx];
if(og_byte != 0xCC) if(og_byte != 0xCC)
{ {
@@ -2489,6 +2754,40 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
} }
} }
} }
}
//////////////////////////
//- rjf: clear all debug register states, for flagged-traps
//
ProfScope("clear all debug register states, for flagged-traps")
{
for(DMN_FlaggedTrapTask *t = first_flagged_trap_task; t != 0; t = t->next)
{
DMN_Handle process = t->process;
DMN_W32_Entity *process_entity = dmn_w32_entity_from_handle(process);
for(DMN_W32_Entity *child = process_entity->first;
child != &dmn_w32_entity_nil;
child = child->next)
{
if(child->kind == DMN_W32_EntityKind_Thread)
{
switch(child->arch)
{
default:{}break;
//- rjf: x64
case Arch_x64:
{
REGS_RegBlockX64 regs = {0};
dmn_w32_thread_read_reg_block(child->arch, child->handle, &regs);
regs.dr7.u64 = 0;
dmn_w32_thread_write_reg_block(child->arch, child->handle, &regs);
}break;
}
}
}
}
}
////////////////////////// //////////////////////////
//- rjf: unset single step bit //- rjf: unset single step bit
+2
View File
@@ -56,6 +56,8 @@
#define DMN_W32_EXCEPTION_SET_THREAD_NAME 0x406d1388u #define DMN_W32_EXCEPTION_SET_THREAD_NAME 0x406d1388u
#define DMN_w32_EXCEPTION_CLRDBG_NOTIFICATION 0x04242420u #define DMN_w32_EXCEPTION_CLRDBG_NOTIFICATION 0x04242420u
#define DMN_w32_EXCEPTION_CLR 0xE0434352u #define DMN_w32_EXCEPTION_CLR 0xE0434352u
#define DMN_W32_EXCEPTION_RADDBG_SET_THREAD_COLOR 0x00524144u
#define DMN_W32_EXCEPTION_RADDBG_SET_BREAKPOINT 0x00524145u
//////////////////////////////// ////////////////////////////////
//~ rjf: Win32 Register Codes //~ rjf: Win32 Register Codes
+115 -40
View File
@@ -45,9 +45,9 @@ dr_hash_from_string(String8 string)
//~ rjf: Fancy String Type Functions //~ rjf: Fancy String Type Functions
internal void internal void
dr_fancy_string_list_push(Arena *arena, DR_FancyStringList *list, DR_FancyString *str) dr_fstrs_push(Arena *arena, DR_FStrList *list, DR_FStr *str)
{ {
DR_FancyStringNode *n = push_array_no_zero(arena, DR_FancyStringNode, 1); DR_FStrNode *n = push_array_no_zero(arena, DR_FStrNode, 1);
MemoryCopyStruct(&n->v, str); MemoryCopyStruct(&n->v, str);
SLLQueuePush(list->first, list->last, n); SLLQueuePush(list->first, list->last, n);
list->node_count += 1; list->node_count += 1;
@@ -55,7 +55,38 @@ dr_fancy_string_list_push(Arena *arena, DR_FancyStringList *list, DR_FancyString
} }
internal void internal void
dr_fancy_string_list_concat_in_place(DR_FancyStringList *dst, DR_FancyStringList *to_push) dr_fstrs_push_new_(Arena *arena, DR_FStrList *list, DR_FStrParams *params, DR_FStrParams *overrides, String8 string)
{
DR_FStr fstr = {string, *params};
if(!fnt_tag_match(fnt_tag_zero(), overrides->font))
{
fstr.params.font = overrides->font;
}
if(overrides->raster_flags != 0)
{
fstr.params.raster_flags = overrides->raster_flags;
}
if(overrides->color.x != 0 || overrides->color.y != 0 || overrides->color.z != 0 || overrides->color.w != 0)
{
fstr.params.color = overrides->color;
}
if(overrides->size != 0)
{
fstr.params.size = overrides->size;
}
if(overrides->underline_thickness != 0)
{
fstr.params.underline_thickness = overrides->underline_thickness;
}
if(overrides->strikethrough_thickness != 0)
{
fstr.params.strikethrough_thickness = overrides->strikethrough_thickness;
}
dr_fstrs_push(arena, list, &fstr);
}
internal void
dr_fstrs_concat_in_place(DR_FStrList *dst, DR_FStrList *to_push)
{ {
if(dst->last != 0 && to_push->first != 0) if(dst->last != 0 && to_push->first != 0)
{ {
@@ -71,34 +102,80 @@ dr_fancy_string_list_concat_in_place(DR_FancyStringList *dst, DR_FancyStringList
MemoryZeroStruct(to_push); MemoryZeroStruct(to_push);
} }
internal DR_FStrList
dr_fstrs_copy(Arena *arena, DR_FStrList *src)
{
DR_FStrList dst = {0};
for(DR_FStrNode *src_n = src->first; src_n != 0; src_n = src_n->next)
{
DR_FStr fstr = src_n->v;
fstr.string = push_str8_copy(arena, fstr.string);
dr_fstrs_push(arena, &dst, &fstr);
}
return dst;
}
internal String8 internal String8
dr_string_from_fancy_string_list(Arena *arena, DR_FancyStringList *list) dr_string_from_fstrs(Arena *arena, DR_FStrList *list)
{ {
String8 result = {0}; String8 result = {0};
result.size = list->total_size;
result.str = push_array_no_zero(arena, U8, result.size);
U64 idx = 0;
for(DR_FancyStringNode *n = list->first; n != 0; n = n->next)
{ {
MemoryCopy(result.str+idx, n->v.string.str, n->v.string.size); Temp scratch = scratch_begin(&arena, 1);
idx += n->v.string.size; String8List parts = {0};
for(DR_FStrNode *n = list->first; n != 0; n = n->next)
{
if(!fnt_tag_match(n->v.params.font, dr_thread_ctx->icon_font))
{
str8_list_push(scratch.arena, &parts, n->v.string);
}
}
result = str8_list_join(arena, &parts, 0);
result = str8_skip_chop_whitespace(result);
scratch_end(scratch);
} }
return result; return result;
} }
internal DR_FancyRunList internal FuzzyMatchRangeList
dr_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, FNT_RasterFlags flags, DR_FancyStringList *strs) dr_fuzzy_match_find_from_fstrs(Arena *arena, DR_FStrList *fstrs, String8 needle)
{
Temp scratch = scratch_begin(&arena, 1);
String8 fstrs_string = {0};
fstrs_string.size = fstrs->total_size;
fstrs_string.str = push_array(arena, U8, fstrs_string.size);
{
// TODO(rjf): the fact that we only increment on non-icon portions is super weird?
// we are only doing that because of the rendering of the fuzzy matches, so maybe
// once that is straightened out, we can fix the code here too...
U64 off = 0;
for(DR_FStrNode *n = fstrs->first; n != 0; n = n->next)
{
if(!fnt_tag_match(n->v.params.font, dr_thread_ctx->icon_font))
{
MemoryCopy(fstrs_string.str + off, n->v.string.str, n->v.string.size);
off += n->v.string.size;
}
}
}
FuzzyMatchRangeList ranges = fuzzy_match_find(arena, needle, fstrs_string);
scratch_end(scratch);
return ranges;
}
internal DR_FRunList
dr_fruns_from_fstrs(Arena *arena, F32 tab_size_px, DR_FStrList *strs)
{ {
ProfBeginFunction(); ProfBeginFunction();
DR_FancyRunList run_list = {0}; DR_FRunList run_list = {0};
F32 base_align_px = 0; F32 base_align_px = 0;
for(DR_FancyStringNode *n = strs->first; n != 0; n = n->next) for(DR_FStrNode *n = strs->first; n != 0; n = n->next)
{ {
DR_FancyRunNode *dst_n = push_array(arena, DR_FancyRunNode, 1); DR_FRunNode *dst_n = push_array(arena, DR_FRunNode, 1);
dst_n->v.run = fnt_push_run_from_string(arena, n->v.font, n->v.size, base_align_px, tab_size_px, flags, n->v.string); dst_n->v.run = fnt_run_from_string(n->v.params.font, n->v.params.size, base_align_px, tab_size_px, n->v.params.raster_flags, n->v.string);
dst_n->v.color = n->v.color; dst_n->v.color = n->v.params.color;
dst_n->v.underline_thickness = n->v.underline_thickness; dst_n->v.underline_thickness = n->v.params.underline_thickness;
dst_n->v.strikethrough_thickness = n->v.strikethrough_thickness; dst_n->v.strikethrough_thickness = n->v.params.strikethrough_thickness;
dst_n->v.icon = (fnt_tag_match(n->v.params.font, dr_thread_ctx->icon_font));
SLLQueuePush(run_list.first, run_list.last, dst_n); SLLQueuePush(run_list.first, run_list.last, dst_n);
run_list.node_count += 1; run_list.node_count += 1;
run_list.dim.x += dst_n->v.run.dim.x; run_list.dim.x += dst_n->v.run.dim.x;
@@ -109,20 +186,14 @@ dr_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, FNT_Rast
return run_list; return run_list;
} }
internal DR_FancyRunList internal Vec2F32
dr_fancy_run_list_copy(Arena *arena, DR_FancyRunList *src) dr_dim_from_fstrs(F32 tab_size_px, DR_FStrList *fstrs)
{ {
DR_FancyRunList dst = {0}; Temp scratch = scratch_begin(0, 0);
for(DR_FancyRunNode *src_n = src->first; src_n != 0; src_n = src_n->next) DR_FRunList fruns = dr_fruns_from_fstrs(scratch.arena, tab_size_px, fstrs);
{ Vec2F32 dim = fruns.dim;
DR_FancyRunNode *dst_n = push_array(arena, DR_FancyRunNode, 1); scratch_end(scratch);
SLLQueuePush(dst.first, dst.last, dst_n); return dim;
MemoryCopyStruct(&dst_n->v, &src_n->v);
dst_n->v.run.pieces = fnt_piece_array_copy(arena, &src_n->v.run.pieces);
dst.node_count += 1;
}
dst.dim = src->dim;
return dst;
} }
//////////////////////////////// ////////////////////////////////
@@ -131,7 +202,7 @@ dr_fancy_run_list_copy(Arena *arena, DR_FancyRunList *src)
// (Frame boundaries) // (Frame boundaries)
internal void internal void
dr_begin_frame(void) dr_begin_frame(FNT_Tag icon_font)
{ {
if(dr_thread_ctx == 0) if(dr_thread_ctx == 0)
{ {
@@ -143,6 +214,7 @@ dr_begin_frame(void)
arena_pop_to(dr_thread_ctx->arena, dr_thread_ctx->arena_frame_start_pos); arena_pop_to(dr_thread_ctx->arena, dr_thread_ctx->arena_frame_start_pos);
dr_thread_ctx->free_bucket_selection = 0; dr_thread_ctx->free_bucket_selection = 0;
dr_thread_ctx->top_bucket = 0; dr_thread_ctx->top_bucket = 0;
dr_thread_ctx->icon_font = icon_font;
} }
internal void internal void
@@ -455,7 +527,7 @@ dr_sub_bucket(DR_Bucket *bucket)
//- rjf: text //- rjf: text
internal void internal void
dr_truncated_fancy_run_list(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FNT_Run trailer_run) dr_truncated_fancy_run_list(Vec2F32 p, DR_FRunList *list, F32 max_x, FNT_Run trailer_run)
{ {
ProfBeginFunction(); ProfBeginFunction();
@@ -467,9 +539,9 @@ dr_truncated_fancy_run_list(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FNT_Run
B32 trailer_found = 0; B32 trailer_found = 0;
Vec4F32 last_color = {0}; Vec4F32 last_color = {0};
U64 byte_off = 0; U64 byte_off = 0;
for(DR_FancyRunNode *n = list->first; n != 0; n = n->next) for(DR_FRunNode *n = list->first; n != 0; n = n->next)
{ {
DR_FancyRun *fr = &n->v; DR_FRun *fr = &n->v;
Rng1F32 pixel_range = {0}; Rng1F32 pixel_range = {0};
{ {
pixel_range.min = 100000; pixel_range.min = 100000;
@@ -558,7 +630,7 @@ dr_truncated_fancy_run_list(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FNT_Run
} }
internal void internal void
dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color) dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color)
{ {
for(FuzzyMatchRangeNode *match_n = ranges->first; match_n != 0; match_n = match_n->next) for(FuzzyMatchRangeNode *match_n = ranges->first; match_n != 0; match_n = match_n->next)
{ {
@@ -573,9 +645,9 @@ dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FancyRunList *list, F32 max_x
F32 advance = 0; F32 advance = 0;
F32 ascent = 0; F32 ascent = 0;
F32 descent = 0; F32 descent = 0;
for(DR_FancyRunNode *fr_n = list->first; fr_n != 0; fr_n = fr_n->next) for(DR_FRunNode *fr_n = list->first; fr_n != 0; fr_n = fr_n->next)
{ {
DR_FancyRun *fr = &fr_n->v; DR_FRun *fr = &fr_n->v;
FNT_Run *run = &fr->run; FNT_Run *run = &fr->run;
ascent = run->ascent; ascent = run->ascent;
descent = run->descent; descent = run->descent;
@@ -589,7 +661,10 @@ dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FancyRunList *list, F32 max_x
pixel_range.min = Min(pre_advance, pixel_range.min); pixel_range.min = Min(pre_advance, pixel_range.min);
pixel_range.max = Max(post_advance, pixel_range.max); pixel_range.max = Max(post_advance, pixel_range.max);
} }
if(!fr->icon)
{
byte_off += piece->decode_size; byte_off += piece->decode_size;
}
advance += piece->advance; advance += piece->advance;
} }
} }
@@ -637,7 +712,7 @@ internal void
dr_text(FNT_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, FNT_RasterFlags flags, Vec2F32 p, Vec4F32 color, String8 string) dr_text(FNT_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, FNT_RasterFlags flags, Vec2F32 p, Vec4F32 color, String8 string)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
FNT_Run run = fnt_push_run_from_string(scratch.arena, font, size, base_align_px, tab_size_px, flags, string); FNT_Run run = fnt_run_from_string(font, size, base_align_px, tab_size_px, flags, string);
dr_text_run(p, color, run); dr_text_run(p, color, run);
scratch_end(scratch); scratch_end(scratch);
} }
+42 -30
View File
@@ -7,54 +7,62 @@
//////////////////////////////// ////////////////////////////////
//~ rjf: Fancy String Types //~ rjf: Fancy String Types
typedef struct DR_FancyString DR_FancyString; typedef struct DR_FStrParams DR_FStrParams;
struct DR_FancyString struct DR_FStrParams
{ {
FNT_Tag font; FNT_Tag font;
String8 string; FNT_RasterFlags raster_flags;
Vec4F32 color; Vec4F32 color;
F32 size; F32 size;
F32 underline_thickness; F32 underline_thickness;
F32 strikethrough_thickness; F32 strikethrough_thickness;
}; };
typedef struct DR_FancyStringNode DR_FancyStringNode; typedef struct DR_FStr DR_FStr;
struct DR_FancyStringNode struct DR_FStr
{ {
DR_FancyStringNode *next; String8 string;
DR_FancyString v; DR_FStrParams params;
}; };
typedef struct DR_FancyStringList DR_FancyStringList; typedef struct DR_FStrNode DR_FStrNode;
struct DR_FancyStringList struct DR_FStrNode
{ {
DR_FancyStringNode *first; DR_FStrNode *next;
DR_FancyStringNode *last; DR_FStr v;
};
typedef struct DR_FStrList DR_FStrList;
struct DR_FStrList
{
DR_FStrNode *first;
DR_FStrNode *last;
U64 node_count; U64 node_count;
U64 total_size; U64 total_size;
}; };
typedef struct DR_FancyRun DR_FancyRun; typedef struct DR_FRun DR_FRun;
struct DR_FancyRun struct DR_FRun
{ {
FNT_Run run; FNT_Run run;
Vec4F32 color; Vec4F32 color;
F32 underline_thickness; F32 underline_thickness;
F32 strikethrough_thickness; F32 strikethrough_thickness;
B32 icon;
}; };
typedef struct DR_FancyRunNode DR_FancyRunNode; typedef struct DR_FRunNode DR_FRunNode;
struct DR_FancyRunNode struct DR_FRunNode
{ {
DR_FancyRunNode *next; DR_FRunNode *next;
DR_FancyRun v; DR_FRun v;
}; };
typedef struct DR_FancyRunList DR_FancyRunList; typedef struct DR_FRunList DR_FRunList;
struct DR_FancyRunList struct DR_FRunList
{ {
DR_FancyRunNode *first; DR_FRunNode *first;
DR_FancyRunNode *last; DR_FRunNode *last;
U64 node_count; U64 node_count;
Vec2F32 dim; Vec2F32 dim;
}; };
@@ -91,6 +99,7 @@ struct DR_ThreadCtx
{ {
Arena *arena; Arena *arena;
U64 arena_frame_start_pos; U64 arena_frame_start_pos;
FNT_Tag icon_font;
DR_BucketSelectionNode *top_bucket; DR_BucketSelectionNode *top_bucket;
DR_BucketSelectionNode *free_bucket_selection; DR_BucketSelectionNode *free_bucket_selection;
}; };
@@ -108,19 +117,22 @@ internal U64 dr_hash_from_string(String8 string);
//////////////////////////////// ////////////////////////////////
//~ rjf: Fancy String Type Functions //~ rjf: Fancy String Type Functions
internal void dr_fancy_string_list_push(Arena *arena, DR_FancyStringList *list, DR_FancyString *str); internal void dr_fstrs_push(Arena *arena, DR_FStrList *list, DR_FStr *str);
#define dr_fancy_string_list_push_new(arena, list, font_, size_, color_, string_, ...) dr_fancy_string_list_push((arena), (list), &(DR_FancyString){.font = (font_), .string = (string_), .color = (color_), .size = (size_), __VA_ARGS__}) internal void dr_fstrs_push_new_(Arena *arena, DR_FStrList *list, DR_FStrParams *params, DR_FStrParams *overrides, String8 string);
internal void dr_fancy_string_list_concat_in_place(DR_FancyStringList *dst, DR_FancyStringList *to_push); #define dr_fstrs_push_new(arena, list, params, string, ...) dr_fstrs_push_new_((arena), (list), (params), &(DR_FStrParams){.size = 0, __VA_ARGS__}, (string))
internal String8 dr_string_from_fancy_string_list(Arena *arena, DR_FancyStringList *list); internal void dr_fstrs_concat_in_place(DR_FStrList *dst, DR_FStrList *to_push);
internal DR_FancyRunList dr_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, FNT_RasterFlags flags, DR_FancyStringList *strs); internal DR_FStrList dr_fstrs_copy(Arena *arena, DR_FStrList *src);
internal DR_FancyRunList dr_fancy_run_list_copy(Arena *arena, DR_FancyRunList *src); internal String8 dr_string_from_fstrs(Arena *arena, DR_FStrList *list);
internal FuzzyMatchRangeList dr_fuzzy_match_find_from_fstrs(Arena *arena, DR_FStrList *fstrs, String8 needle);
internal DR_FRunList dr_fruns_from_fstrs(Arena *arena, F32 tab_size_px, DR_FStrList *strs);
internal Vec2F32 dr_dim_from_fstrs(F32 tab_size_px, DR_FStrList *fstrs);
//////////////////////////////// ////////////////////////////////
//~ rjf: Top-Level API //~ rjf: Top-Level API
// //
// (Frame boundaries & bucket submission) // (Frame boundaries & bucket submission)
internal void dr_begin_frame(void); internal void dr_begin_frame(FNT_Tag icon_font);
internal void dr_submit_bucket(OS_Handle os_window, R_Handle r_window, DR_Bucket *bucket); internal void dr_submit_bucket(OS_Handle os_window, R_Handle r_window, DR_Bucket *bucket);
//////////////////////////////// ////////////////////////////////
@@ -184,8 +196,8 @@ internal void dr_sub_bucket(DR_Bucket *bucket);
//~ rjf: Draw Call Helpers //~ rjf: Draw Call Helpers
//- rjf: text //- rjf: text
internal void dr_truncated_fancy_run_list(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FNT_Run trailer_run); internal void dr_truncated_fancy_run_list(Vec2F32 p, DR_FRunList *list, F32 max_x, FNT_Run trailer_run);
internal void dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color); internal void dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color);
internal void dr_text_run(Vec2F32 p, Vec4F32 color, FNT_Run run); internal void dr_text_run(Vec2F32 p, Vec4F32 color, FNT_Run run);
internal void dr_text(FNT_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, FNT_RasterFlags flags, Vec2F32 p, Vec4F32 color, String8 string); internal void dr_text(FNT_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, FNT_RasterFlags flags, Vec2F32 p, Vec4F32 color, String8 string);
+132 -10
View File
@@ -1,6 +1,74 @@
// Copyright (c) 2024 Epic Games Tools // Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
internal U64
dw_reg_size_from_code_x86(DW_Reg reg_code)
{
switch (reg_code) {
#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX86_##reg_name_dw: return reg_size;
DW_Regs_X86_XList(X)
#undef X
}
return 0;
}
internal U64
dw_reg_pos_from_code_x86(DW_Reg reg_code)
{
switch (reg_code) {
#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX86_##reg_name_dw: return reg_pos;
DW_Regs_X86_XList(X)
#undef X
}
return max_U64;
}
internal U64
dw_reg_size_from_code_x64(DW_Reg reg_code)
{
switch (reg_code) {
#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX64_##reg_name_dw: return reg_size;
DW_Regs_X64_XList(X)
#undef X
}
return 0;
}
internal U64
dw_reg_pos_from_code_x64(DW_Reg reg_code)
{
switch (reg_code) {
#define X(reg_name_dw, reg_code_dw, reg_name_rdi, reg_pos, reg_size) case DW_RegX64_##reg_name_dw: return reg_pos;
DW_Regs_X64_XList(X)
#undef X
}
return max_U64;
}
internal U64
dw_reg_size_from_code(Arch arch, DW_Reg reg_code)
{
switch (arch) {
case Arch_Null: break;
case Arch_x86: return dw_reg_size_from_code_x86(reg_code);
case Arch_x64: return dw_reg_size_from_code_x64(reg_code);
default: NotImplemented; break;
}
return 0;
}
internal U64
dw_reg_pos_from_code(Arch arch, DW_Reg reg_code)
{
switch (arch) {
case Arch_Null: break;
case Arch_x86: return dw_reg_pos_from_code_x86(reg_code);
case Arch_x64: return dw_reg_pos_from_code_x64(reg_code);
default: NotImplemented; break;
}
return max_U64;
}
internal DW_AttribClass internal DW_AttribClass
dw_attrib_class_from_attrib_kind_v2(DW_AttribKind k) dw_attrib_class_from_attrib_kind_v2(DW_AttribKind k)
{ {
@@ -135,6 +203,11 @@ internal DW_AttribClass
dw_attrib_class_from_form_kind(DW_Version ver, DW_FormKind k) dw_attrib_class_from_form_kind(DW_Version ver, DW_FormKind k)
{ {
#define X(_N,_C) case DW_Form_##_N: return _C; #define X(_N,_C) case DW_Form_##_N: return _C;
switch (k) {
DW_Form_AttribClass_GNU_XList(X)
}
switch (ver) { switch (ver) {
case DW_Version_5: { case DW_Version_5: {
switch (k) { switch (k) {
@@ -207,20 +280,20 @@ dw_dwo_name_string_from_section_kind(DW_SectionKind k)
} }
internal U64 internal U64
dw_offset_size_from_mode(DW_Mode mode) dw_size_from_format(DW_Format format)
{ {
U64 result = 0; U64 result = 0;
switch (mode) { switch (format) {
case DW_Mode_Null: break; case DW_Format_Null: break;
case DW_Mode_32Bit: result = 4; break; case DW_Format_32Bit: result = 4; break;
case DW_Mode_64Bit: result = 8; break; case DW_Format_64Bit: result = 8; break;
default: InvalidPath; break; default: InvalidPath; break;
} }
return result; return result;
} }
internal DW_AttribClass internal DW_AttribClass
dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, DW_Language lang, B32 relaxed, DW_AttribKind attrib_kind, DW_FormKind form_kind) dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, B32 relaxed, DW_AttribKind attrib_kind, DW_FormKind form_kind)
{ {
// NOTE(rjf): DWARF's spec specifies two mappings: // NOTE(rjf): DWARF's spec specifies two mappings:
// (DW_AttribKind) => List(DW_AttribClass) // (DW_AttribKind) => List(DW_AttribClass)
@@ -257,10 +330,59 @@ dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, DW_Language lang, B32 rel
} }
} }
if (attrib_kind != DW_Attrib_Null && form_kind != DW_Form_Null) {
//Assert(result != DW_AttribClass_Null && result != DW_AttribClass_Undefined);
}
return result; return result;
} }
internal U64
dw_pick_default_lower_bound(DW_Language lang)
{
U64 lower_bound = max_U64;
switch (lang) {
case DW_Language_Null: break;
case DW_Language_C89:
case DW_Language_C:
case DW_Language_CPlusPlus:
case DW_Language_C99:
case DW_Language_CPlusPlus03:
case DW_Language_CPlusPlus11:
case DW_Language_C11:
case DW_Language_CPlusPlus14:
case DW_Language_Java:
case DW_Language_ObjC:
case DW_Language_ObjCPlusPlus:
case DW_Language_UPC:
case DW_Language_D:
case DW_Language_Python:
case DW_Language_OpenCL:
case DW_Language_Go:
case DW_Language_Haskell:
case DW_Language_OCaml:
case DW_Language_Rust:
case DW_Language_Swift:
case DW_Language_Dylan:
case DW_Language_RenderScript:
case DW_Language_BLISS:
lower_bound = 0;
break;
case DW_Language_Ada83:
case DW_Language_Cobol74:
case DW_Language_Cobol85:
case DW_Language_Fortran77:
case DW_Language_Fortran90:
case DW_Language_Pascal83:
case DW_Language_Modula2:
case DW_Language_Ada95:
case DW_Language_Fortran95:
case DW_Language_PLI:
case DW_Language_Modula3:
case DW_Language_Julia:
case DW_Language_Fortran03:
case DW_Language_Fortran08:
lower_bound = 1;
default:
NotImplemented;
break;
}
return lower_bound;
}
+194 -100
View File
@@ -29,12 +29,15 @@ typedef enum DW_ExtEnum
DW_Ext_All = DW_Ext_GNU|DW_Ext_LLVM|DW_Ext_APPLE|DW_Ext_MIPS, DW_Ext_All = DW_Ext_GNU|DW_Ext_LLVM|DW_Ext_APPLE|DW_Ext_MIPS,
} DW_ExtEnum; } DW_ExtEnum;
typedef enum DW_Mode #define DW_FormatFromSize(size) ((size) >= max_U32 ? DW_Format_64Bit : DW_Format_32Bit)
typedef enum DW_Format
{ {
DW_Mode_Null, DW_Format_Null,
DW_Mode_32Bit, DW_Format_32Bit,
DW_Mode_64Bit DW_Format_64Bit
} DW_Mode; } DW_Format;
#define DW_SentinelFromSize(address_size) ((address_size) == 4 ? max_U32 : (address_size) == 8 ? max_U64 : 0)
#define DW_SectionKind_XList(X )\ #define DW_SectionKind_XList(X )\
X(Null, "", "", "" )\ X(Null, "", "", "" )\
@@ -52,8 +55,8 @@ typedef enum DW_Mode
X(Addr, ".debug_addr", "__debug_addr", ".debug_addr.dwo" )\ X(Addr, ".debug_addr", "__debug_addr", ".debug_addr.dwo" )\
X(LocLists, ".debug_loclists", "__debug_loclists", ".debug_loclists.dwo" )\ X(LocLists, ".debug_loclists", "__debug_loclists", ".debug_loclists.dwo" )\
X(RngLists, ".debug_rnglists", "__debug_rnglists", ".debug_rnglists.dwo" )\ X(RngLists, ".debug_rnglists", "__debug_rnglists", ".debug_rnglists.dwo" )\
X(StrOffsets, ".debug_stroffsets", "__debug_stroffsets", ".debug_stroffsets.dwo" ) \ X(StrOffsets, ".debug_str_offsets", "__debug_str_offsets", ".debug_str_offsets.dwo")\
X(LineStr, ".debug_linestr", "__debug_linestr", ".debug_linestr.dwo" ) \ X(LineStr, ".debug_line_str", "__debug_line_str", ".debug_line_str.dwo" )\
X(Names, ".debug_names", "__debug_names", ".debug_names.dwo" ) X(Names, ".debug_names", "__debug_names", ".debug_names.dwo" )
typedef U64 DW_SectionKind; typedef U64 DW_SectionKind;
@@ -82,8 +85,8 @@ typedef enum DW_SectionKindEnum
X(Ada95, 0x0D) \ X(Ada95, 0x0D) \
X(Fortran95, 0x0E) \ X(Fortran95, 0x0E) \
X(PLI, 0x0F) \ X(PLI, 0x0F) \
X(ObjectiveC, 0x10) \ X(ObjC, 0x10) \
X(ObjectiveCPlusPlus, 0x11) \ X(ObjCPlusPlus, 0x11) \
X(UPC, 0x12) \ X(UPC, 0x12) \
X(D, 0x13) \ X(D, 0x13) \
X(Python, 0x14) \ X(Python, 0x14) \
@@ -119,6 +122,20 @@ typedef enum DW_LanguageEnum
DW_Language_UserHi = 0xffff, DW_Language_UserHi = 0xffff,
} DW_LanguageEnum; } DW_LanguageEnum;
#define DW_Inl_XList(X) \
X(NotInlined, 0) \
X(Inlined, 1) \
X(DeclaredNotInlined, 2) \
X(DeclaredInlined, 3)
typedef U32 DW_InlKind;
typedef enum DW_InlKindEnum
{
#define X(_N,_ID) DW_Inl_##_N = _ID,
DW_Inl_XList(X)
#undef X
} DW_InlKindEnum;
#define DW_StdOpcode_XList(X) \ #define DW_StdOpcode_XList(X) \
X(ExtendedOpcode, 0x00) \ X(ExtendedOpcode, 0x00) \
X(Copy, 0x01) \ X(Copy, 0x01) \
@@ -157,19 +174,19 @@ typedef enum DW_ExtOpcode
#undef X #undef X
} DW_ExtOpcode; } DW_ExtOpcode;
#define DW_NameCase_XList(X) \ #define DW_IDCaseKind_XList(X) \
X(Sensitive, 0x00) \ X(CaseSensitive, 0x00) \
X(Upper, 0x01) \ X(UpCase, 0x01) \
X(Lower, 0x02) \ X(DownCase, 0x02) \
X(Insensitive, 0x03) X(CaseInsensitive, 0x03)
typedef enum DW_NameCase typedef U64 DW_IDCaseKind;
typedef enum DW_IDCaseKindEnum
{ {
#define X(_N,_ID) DW_NameCase_##_N = _ID, #define X(_N,_ID) DW_IDCase_##_N = _ID,
DW_NameCase_XList(X) DW_IDCaseKind_XList(X)
#undef X #undef X
DW_NameCase_Count } DW_IDCaseKindEnum;
} DW_NameCase;
#define DW_Tag_V3_XList(X) \ #define DW_Tag_V3_XList(X) \
X(ArrayType, 0x01) \ X(ArrayType, 0x01) \
@@ -250,6 +267,7 @@ typedef enum DW_NameCase
typedef U64 DW_TagKind; typedef U64 DW_TagKind;
typedef enum DW_TagKindEnum typedef enum DW_TagKindEnum
{ {
DW_Tag_Null,
#define X(_N,_ID) DW_Tag_##_N = _ID, #define X(_N,_ID) DW_Tag_##_N = _ID,
DW_Tag_V3_XList(X) DW_Tag_V3_XList(X)
DW_Tag_V5_XList(X) DW_Tag_V5_XList(X)
@@ -436,7 +454,7 @@ typedef enum DW_AttribClassEnum
X(LineStrp, DW_AttribClass_String) \ X(LineStrp, DW_AttribClass_String) \
X(ImplicitConst, DW_AttribClass_Const) \ X(ImplicitConst, DW_AttribClass_Const) \
X(LocListx, DW_AttribClass_LocListPtr) \ X(LocListx, DW_AttribClass_LocListPtr) \
X(RngListx, DW_AttribClass_RngListPtr) \ X(RngListx, DW_AttribClass_RngList) \
X(RefSup8, DW_AttribClass_Reference) \ X(RefSup8, DW_AttribClass_Reference) \
X(Strx1, DW_AttribClass_String) \ X(Strx1, DW_AttribClass_String) \
X(Strx2, DW_AttribClass_String) \ X(Strx2, DW_AttribClass_String) \
@@ -447,6 +465,18 @@ typedef enum DW_AttribClassEnum
X(Addrx3, DW_AttribClass_Address) \ X(Addrx3, DW_AttribClass_Address) \
X(Addrx4, DW_AttribClass_Address) X(Addrx4, DW_AttribClass_Address)
#define DW_Form_GNU_XList(X) \
X(GNU_AddrIndex, 0x1f01) \
X(GNU_StrIndex, 0x1f02) \
X(GNU_RefAlt, 0x1f20) \
X(GNU_StrpAlt, 0x1f21)
#define DW_Form_AttribClass_GNU_XList(X) \
X(GNU_AddrIndex, DW_AttribClass_Undefined) \
X(GNU_StrIndex, DW_AttribClass_Undefined) \
X(GNU_RefAlt, DW_AttribClass_Undefined) \
X(GNU_StrpAlt, DW_AttribClass_String)
typedef U64 DW_FormKind; typedef U64 DW_FormKind;
typedef enum DW_FormEnum typedef enum DW_FormEnum
{ {
@@ -455,6 +485,7 @@ typedef enum DW_FormEnum
DW_Form_V2_XList(X) DW_Form_V2_XList(X)
DW_Form_V4_XList(X) DW_Form_V4_XList(X)
DW_Form_V5_XList(X) DW_Form_V5_XList(X)
DW_Form_GNU_XList(X)
#undef X #undef X
} DW_FormEnum; } DW_FormEnum;
@@ -1143,7 +1174,7 @@ typedef enum DW_AttribKindEnum
DW_Attrib_UserHi = 0x3fff DW_Attrib_UserHi = 0x3fff
} DW_AttribKindEnum; } DW_AttribKindEnum;
#define DW_AttribTypeEncodingKind_XList(X) \ #define DW_ATE_XList(X) \
X(Null, 0x00) \ X(Null, 0x00) \
X(Address, 0x01) \ X(Address, 0x01) \
X(Boolean, 0x02) \ X(Boolean, 0x02) \
@@ -1164,20 +1195,20 @@ typedef enum DW_AttribKindEnum
X(Ucs, 0x11) \ X(Ucs, 0x11) \
X(Ascii, 0x12) X(Ascii, 0x12)
typedef U64 DW_AttribTypeEncodingKind; typedef U64 DW_ATE;
typedef enum DW_AttribTypeEncodingKindEnum typedef enum DW_ATEEnum
{ {
#define X(_N,_ID) DW_AttribTypeEncodingKind_##_N = _ID, #define X(_N,_ID) DW_ATE_##_N = _ID,
DW_AttribTypeEncodingKind_XList(X) DW_ATE_XList(X)
#undef X #undef X
} DW_AttribTypeEncodingKindEnum; } DW_ATEnum;
#define DW_CallingConventionKind_XList(X) \ #define DW_CallingConventionKind_XList(X) \
X(DW_CallingConvention_Normal, 0x0) \ X(Normal, 0x0) \
X(DW_CallingConvention_Program, 0x1) \ X(Program, 0x1) \
X(DW_CallingConvention_NoCall, 0x2) \ X(NoCall, 0x3) \
X(DW_CallingConvention_PassByValue, 0x1) \ X(PassByValue, 0x4) \
X(DW_CallingConvention_PassByReference, 0x2) X(PassByReference, 0x5)
typedef U64 DW_CallingConventionKind; typedef U64 DW_CallingConventionKind;
typedef enum DW_CallingConventionKindEnum typedef enum DW_CallingConventionKindEnum
@@ -1188,9 +1219,9 @@ typedef enum DW_CallingConventionKindEnum
} DW_CallingConventionKindEnum; } DW_CallingConventionKindEnum;
#define DW_AccessKind_XList(X) \ #define DW_AccessKind_XList(X) \
X(DW_Access_Public, 0x00) \ X(Public, 0x00) \
X(DW_Access_Private, 0x01) \ X(Private, 0x01) \
X(DW_Access_Protected, 0x02) X(Protected, 0x02)
typedef U64 DW_AccessKind; typedef U64 DW_AccessKind;
typedef enum DW_AccessKindEnum typedef enum DW_AccessKindEnum
@@ -1215,7 +1246,7 @@ typedef enum DW_VirtualityEnum
#define DW_RngListEntryKind(X) \ #define DW_RngListEntryKind(X) \
X(EndOfList, 0x00) \ X(EndOfList, 0x00) \
X(BaseAddressX, 0x01) \ X(BaseAddressx, 0x01) \
X(StartxEndx, 0x02) \ X(StartxEndx, 0x02) \
X(StartxLength, 0x03) \ X(StartxLength, 0x03) \
X(OffsetPair, 0x04) \ X(OffsetPair, 0x04) \
@@ -1223,32 +1254,51 @@ typedef enum DW_VirtualityEnum
X(StartEnd, 0x06) \ X(StartEnd, 0x06) \
X(StartLength, 0x07) X(StartLength, 0x07)
typedef U64 DW_RngListEntryKind; typedef U8 DW_RLE;
typedef enum DW_RngListEntryKindEnum typedef enum DW_RLE_Enum
{ {
#define X(_N,_ID) DW_RngListEntryKind_##_N = _ID, #define X(_N,_ID) DW_RLE_##_N = _ID,
DW_RngListEntryKind(X) DW_RngListEntryKind(X)
#undef X #undef X
} DW_RngListEntryKindEnum; } DW_RLE_Enum;
#define DW_LocListEntry_XList(X) \ #define DW_LocListEntry_XList(X) \
X(EndOfList, 0x00) \ X(EndOfList, 0x00) \
X(BaseAddressX, 0x01) \ X(BaseAddressx, 0x01) \
X(StartXEndX, 0x02) \ X(StartxEndx, 0x02) \
X(StartXLength, 0x03) \ X(StartxLength, 0x03) \
X(OffsetPair, 0x04) \ X(OffsetPair, 0x04) \
X(DefaultLocation, 0x05) \ X(DefaultLocation, 0x05) \
X(BaseAddress, 0x06) \ X(BaseAddress, 0x06) \
X(StartEnd, 0x07) \ X(StartEnd, 0x07) \
X(StartLength, 0x08) X(StartLength, 0x08)
typedef U64 DW_LocListEntryKind; #define DW_LocListEntry_GNU_XList(X) \
typedef enum DW_LocListEntryEnum X(GNU_ViewPair, 0x9)
typedef U8 DW_LLE;
typedef enum DW_LLE_Enum
{ {
#define X(_N,_ID) DW_LocListEntryKind_##_N = _ID, #define X(_N,_ID) DW_LLE_##_N = _ID,
DW_LocListEntry_XList(X) DW_LocListEntry_XList(X)
#undef X #undef X
} DW_LocListEntryEnum; } DW_LLEEnum;
#define DW_AddrClass_XList(X) \
X(None, 0) \
X(Near16, 1) \
X(Far16, 2) \
X(Huge16, 3) \
X(Near32, 4) \
X(Far32, 5)
typedef U64 DW_AddrClass;
typedef enum DW_AddrClassEnum
{
#define X(_N, _ID) DW_AddrClassKind_##_N = _ID,
DW_AddrClass_XList(X)
#undef X
} DW_AddrClassEnum;
#define DW_CompUnitKind_XList(X) \ #define DW_CompUnitKind_XList(X) \
X(Reserved, 0) \ X(Reserved, 0) \
@@ -1269,16 +1319,23 @@ typedef enum DW_CompUnitKindEnum
DW_CompUnitKind_UserHi = 0xff DW_CompUnitKind_UserHi = 0xff
} DW_CompUnitKindEnum; } DW_CompUnitKindEnum;
typedef enum DW_LNCT #define DW_LNCT_XList(X) \
X(Path, 0x1) \
X(DirectoryIndex, 0x2) \
X(TimeStamp, 0x3) \
X(Size, 0x4) \
X(MD5, 0x5) \
X(LLVM_Source, 0x2001)
typedef U64 DW_LNCT;
typedef enum DW_LNCTEnum
{ {
DW_LNCT_Path = 0x1, #define X(_N, _ID) DW_LNCT_##_N = _ID,
DW_LNCT_DirectoryIndex = 0x2, DW_LNCT_XList(X)
DW_LNCT_TimeStamp = 0x3, #undef X
DW_LNCT_Size = 0x4,
DW_LNCT_MD5 = 0x5,
DW_LNCT_UserLo = 0x2000, DW_LNCT_UserLo = 0x2000,
DW_LNCT_UserHi = 0x3fff DW_LNCT_UserHi = 0x3fff
} DW_LNCT; } DW_LNCTEnum;
#define DW_CFA_Kind1_XList(X) \ #define DW_CFA_Kind1_XList(X) \
X(Nop, 0x0) \ X(Nop, 0x0) \
@@ -1507,7 +1564,17 @@ enum
#define DW_Expr_GNU_XList(X) \ #define DW_Expr_GNU_XList(X) \
X(GNU_PushTlsAddress, 0xe0) \ X(GNU_PushTlsAddress, 0xe0) \
X(GNU_UnInit, 0xf0) X(GNU_UnInit, 0xf0) \
X(GNU_ImplicitPointer, 0xf2) \
X(GNU_EntryValue, 0xf3) \
X(GNU_ConstType, 0xf4) \
X(GNU_RegvalType, 0xf5) \
X(GNU_DerefType, 0xf6) \
X(GNU_Convert, 0xf7) \
X(GNU_ParameterRef, 0xfa) \
X(GNU_AddrIndex, 0xfb) \
X(GNU_ConstIndex, 0xfc)
typedef U64 DW_ExprOp; typedef U64 DW_ExprOp;
typedef enum DW_ExprOpEnum typedef enum DW_ExprOpEnum
{ {
@@ -1541,22 +1608,22 @@ typedef enum DW_ExprOpEnum
X(St5, 16, st5, 0, 10) \ X(St5, 16, st5, 0, 10) \
X(St6, 17, st6, 0, 10) \ X(St6, 17, st6, 0, 10) \
X(St7, 18, st7, 0, 10) \ X(St7, 18, st7, 0, 10) \
X(Xmm0, 21, xmm0, 0, 16) \ X(Xmm0, 21, ymm0, 0, 16) \
X(Xmm1, 22, xmm1, 0, 16) \ X(Xmm1, 22, ymm1, 0, 16) \
X(Xmm2, 23, xmm2, 0, 16) \ X(Xmm2, 23, ymm2, 0, 16) \
X(Xmm3, 24, xmm3, 0, 16) \ X(Xmm3, 24, ymm3, 0, 16) \
X(Xmm4, 25, xmm4, 0, 16) \ X(Xmm4, 25, ymm4, 0, 16) \
X(Xmm5, 26, xmm5, 0, 16) \ X(Xmm5, 26, ymm5, 0, 16) \
X(Xmm6, 27, xmm6, 0, 16) \ X(Xmm6, 27, ymm6, 0, 16) \
X(Xmm7, 28, xmm7, 0, 16) \ X(Xmm7, 28, ymm7, 0, 16) \
X(Mm0, 29, mm0, 0, 4) \ X(Mm0, 29, fpr0, 0, 8) \
X(Mm1, 30, mm1, 0, 4) \ X(Mm1, 30, fpr1, 0, 8) \
X(Mm2, 31, mm2, 0, 4) \ X(Mm2, 31, fpr2, 0, 8) \
X(Mm3, 32, mm3, 0, 4) \ X(Mm3, 32, fpr3, 0, 8) \
X(Mm4, 33, mm4, 0, 4) \ X(Mm4, 33, fpr4, 0, 8) \
X(Mm5, 34, mm5, 0, 4) \ X(Mm5, 34, fpr5, 0, 8) \
X(Mm6, 35, mm6, 0, 4) \ X(Mm6, 35, fpr6, 0, 8) \
X(Mm7, 36, mm7, 0, 4) \ X(Mm7, 36, fpr7, 0, 8) \
X(Fcw, 37, fcw, 0, 2) \ X(Fcw, 37, fcw, 0, 2) \
X(Fsw, 38, fsw, 0, 2) \ X(Fsw, 38, fsw, 0, 2) \
X(Mxcsr, 39, mxcsr, 0, 4) \ X(Mxcsr, 39, mxcsr, 0, 4) \
@@ -1587,22 +1654,38 @@ typedef enum DW_ExprOpEnum
X(R14, 14, r14, 0, 8) \ X(R14, 14, r14, 0, 8) \
X(R15, 15, r15, 0, 8) \ X(R15, 15, r15, 0, 8) \
X(Rip, 16, rip, 0, 8) \ X(Rip, 16, rip, 0, 8) \
X(Xmm0, 17, ymm0, 0, 16) \ X(Xmm0, 17, zmm0, 0, 16) \
X(Xmm1, 18, ymm1, 0, 16) \ X(Xmm1, 18, zmm1, 0, 16) \
X(Xmm2, 19, ymm2, 0, 16) \ X(Xmm2, 19, zmm2, 0, 16) \
X(Xmm3, 20, ymm3, 0, 16) \ X(Xmm3, 20, zmm3, 0, 16) \
X(Xmm4, 21, ymm4, 0, 16) \ X(Xmm4, 21, zmm4, 0, 16) \
X(Xmm5, 22, ymm5, 0, 16) \ X(Xmm5, 22, zmm5, 0, 16) \
X(Xmm6, 23, ymm6, 0, 16) \ X(Xmm6, 23, zmm6, 0, 16) \
X(Xmm7, 24, ymm7, 0, 16) \ X(Xmm7, 24, zmm7, 0, 16) \
X(Xmm8, 25, ymm8, 0, 16) \ X(Xmm8, 25, zmm8, 0, 16) \
X(Xmm9, 26, ymm9, 0, 16) \ X(Xmm9, 26, zmm9, 0, 16) \
X(Xmm10, 27, ymm10, 0, 16) \ X(Xmm10, 27, zmm10, 0, 16) \
X(Xmm11, 28, ymm11, 0, 16) \ X(Xmm11, 28, zmm11, 0, 16) \
X(Xmm12, 29, ymm12, 0, 16) \ X(Xmm12, 29, zmm12, 0, 16) \
X(Xmm13, 30, ymm13, 0, 16) \ X(Xmm13, 30, zmm13, 0, 16) \
X(Xmm14, 31, ymm14, 0, 16) \ X(Xmm14, 31, zmm14, 0, 16) \
X(Xmm15, 32, ymm15, 0, 16) \ X(Xmm15, 32, zmm15, 0, 16) \
X(Xmm16, 67, zmm16, 0, 16) \
X(Xmm17, 68, zmm17, 0, 16) \
X(Xmm18, 69, zmm18, 0, 16) \
X(Xmm19, 70, zmm19, 0, 16) \
X(Xmm20, 71, zmm20, 0, 16) \
X(Xmm21, 72, zmm21, 0, 16) \
X(Xmm22, 73, zmm22, 0, 16) \
X(Xmm23, 74, zmm23, 0, 16) \
X(Xmm24, 75, zmm24, 0, 16) \
X(Xmm25, 76, zmm25, 0, 16) \
X(Xmm26, 77, zmm26, 0, 16) \
X(Xmm27, 78, zmm27, 0, 16) \
X(Xmm28, 79, zmm28, 0, 16) \
X(Xmm29, 80, zmm29, 0, 16) \
X(Xmm30, 81, zmm30, 0, 16) \
X(Xmm31, 82, zmm31, 0, 16) \
X(St0, 33, st0, 0, 10) \ X(St0, 33, st0, 0, 10) \
X(St1, 34, st1, 0, 10) \ X(St1, 34, st1, 0, 10) \
X(St2, 35, st2, 0, 10) \ X(St2, 35, st2, 0, 10) \
@@ -1611,14 +1694,14 @@ typedef enum DW_ExprOpEnum
X(St5, 38, st5, 0, 10) \ X(St5, 38, st5, 0, 10) \
X(St6, 39, st6, 0, 10) \ X(St6, 39, st6, 0, 10) \
X(St7, 40, st7, 0, 10) \ X(St7, 40, st7, 0, 10) \
X(Mm0, 41, mm0, 0, 8) \ X(Mm0, 41, fpr0, 0, 8) \
X(Mm1, 42, mm1, 0, 8) \ X(Mm1, 42, fpr1, 0, 8) \
X(Mm2, 43, mm2, 0, 8) \ X(Mm2, 43, fpr2, 0, 8) \
X(Mm3, 44, mm3, 0, 8) \ X(Mm3, 44, fpr3, 0, 8) \
X(Mm4, 45, mm4, 0, 8) \ X(Mm4, 45, fpr4, 0, 8) \
X(Mm5, 46, mm5, 0, 8) \ X(Mm5, 46, fpr5, 0, 8) \
X(Mm6, 47, mm6, 0, 8) \ X(Mm6, 47, fpr6, 0, 8) \
X(Mm7, 48, mm7, 0, 8) \ X(Mm7, 48, fpr7, 0, 8) \
X(Rflags, 49, rflags, 0, 4) \ X(Rflags, 49, rflags, 0, 4) \
X(Es, 50, es, 0, 2) \ X(Es, 50, es, 0, 2) \
X(Cs, 51, cs, 0, 2) \ X(Cs, 51, cs, 0, 2) \
@@ -1631,24 +1714,33 @@ typedef enum DW_ExprOpEnum
X(Tr, 62, nil, 0, 0) \ X(Tr, 62, nil, 0, 0) \
X(Ldtr, 63, nil, 0, 0) X(Ldtr, 63, nil, 0, 0)
typedef U32 DW_RegX86; typedef U32 DW_Reg;
typedef DW_Reg DW_RegX86;
typedef enum DW_RegX86Enum typedef enum DW_RegX86Enum
{ {
#define X(_N,_ID,...) DW_Reg_x86_##_N = _ID, #define X(_N,_ID,...) DW_RegX86_##_N = _ID,
DW_Regs_X86_XList(X) DW_Regs_X86_XList(X)
#undef X #undef X
} DW_RegX86Enum; } DW_RegX86Enum;
typedef U32 DW_RegX64; typedef DW_Reg DW_RegX64;
typedef enum DW_RegX64Enum typedef enum DW_RegX64Enum
{ {
#define X(_N,_ID,...) DW_Reg_x64_##_N = _ID, #define X(_N,_ID,...) DW_RegX64_##_N = _ID,
DW_Regs_X64_XList(X) DW_Regs_X64_XList(X)
#undef X #undef X
} DW_RegX64Enum; } DW_RegX64Enum;
//////////////////////////////// ////////////////////////////////
internal U64 dw_reg_size_from_code_x86(DW_Reg reg_code);
internal U64 dw_reg_pos_from_code_x86(DW_Reg reg_code);
internal U64 dw_reg_size_from_code_x64(DW_Reg reg_code);
internal U64 dw_reg_pos_from_code_x64(DW_Reg reg_code);
internal U64 dw_reg_size_from_code(Arch arch, DW_Reg reg_code);
internal U64 dw_reg_pos_from_code(Arch arch, DW_Reg reg_code);
//- Attrib Class Encodings //- Attrib Class Encodings
// Speced Encodings // Speced Encodings
@@ -1679,10 +1771,12 @@ internal String8 dw_dwo_name_string_from_section_kind (DW_SectionKind k);
//////////////////////////////// ////////////////////////////////
internal U64 dw_offset_size_from_mode(DW_Mode mode); internal U64 dw_size_from_format(DW_Format format);
//////////////////////////////// ////////////////////////////////
internal DW_AttribClass dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, DW_Language lang, B32 relaxed, DW_AttribKind attrib, DW_FormKind form_kind); internal DW_AttribClass dw_pick_attrib_value_class(DW_Version ver, DW_Ext ext, B32 relaxed, DW_AttribKind attrib, DW_FormKind form_kind);
internal U64 dw_pick_default_lower_bound(DW_Language lang);
#endif // DWARF_H #endif // DWARF_H
+68
View File
@@ -0,0 +1,68 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal B32
dw_is_dwarf_present_coff_section_table(String8 raw_image,
String8 string_table,
U64 section_count,
COFF_SectionHeader *section_table)
{
B32 is_dwarf_present = 0;
for (U64 i = 0; i < section_count; ++i) {
COFF_SectionHeader *header = &section_table[i];
String8 name = coff_name_from_section_header(string_table, header);
DW_SectionKind s = dw_section_kind_from_string(name);
if (s == DW_Section_Null) {
s = dw_section_dwo_kind_from_string(name);
}
is_dwarf_present = s != DW_Section_Null;
if (is_dwarf_present) {
break;
}
}
return is_dwarf_present;
}
internal DW_Input
dw_input_from_coff_section_table(Arena *arena,
String8 raw_image,
String8 string_table,
U64 section_count,
COFF_SectionHeader *section_table)
{
DW_Input input = {0};
B32 sect_status[ArrayCount(input.sec)] = {0};
for (U64 i = 0; i < section_count; ++i) {
COFF_SectionHeader *header = &section_table[i];
Rng1U64 raw_data_range = rng_1u64(header->foff, header->foff + header->fsize);
String8 name = coff_name_from_section_header(string_table, header);
DW_SectionKind s = dw_section_kind_from_string(name);
B32 is_dwo = 0;
if (s == DW_Section_Null) {
s = dw_section_dwo_kind_from_string(name);
is_dwo = 1;
}
if (s != DW_Section_Null) {
if (sect_status[s]) {
Assert(!"too many debug sections with identical name, picking first");
} else {
sect_status[s] = 1;
DW_Section *d = &input.sec[s];
d->name = push_str8_copy(arena, name);
d->data = str8_substr(raw_image, raw_data_range);
d->is_dwo = is_dwo;
}
}
}
return input;
}
+10
View File
@@ -0,0 +1,10 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DWARF_COFF_H
#define DWARF_COFF_H
internal DW_Input dw_input_from_coff_section_table(Arena *arena, String8 raw_image, String8 string_table, U64 section_count, COFF_SectionHeader *section_table);
#endif // DWARF_COFF_H
+132
View File
@@ -0,0 +1,132 @@
// Copyright (c) 2025 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal B32
dw_is_dwarf_present_elf_section_table(String8 raw_image, ELF_BinInfo *bin)
{
Temp scratch = scratch_begin(0,0);
B32 is_dwarf_present = 0;
ELF_Shdr64Array sections = elf_shdr64_array_from_bin(scratch.arena, raw_image, &bin->hdr);
for (U64 i = 0; i < sections.count; ++i) {
ELF_Shdr64 *shdr = &sections.v[i];
String8 name = elf_name_from_shdr64(raw_image, &bin->hdr, bin->sh_name_range, shdr);
if (shdr->sh_type != ELF_SectionCode_ProgBits) {
continue;
}
DW_SectionKind s = dw_section_kind_from_string(name);
if (s == DW_Section_Null) {
s = dw_section_dwo_kind_from_string(name);
}
is_dwarf_present = s != DW_Section_Null;
if (is_dwarf_present) {
break;
}
}
scratch_end(scratch);
return is_dwarf_present;
}
internal DW_Input
dw_input_from_elf_section_table(Arena *arena, String8 raw_image, ELF_BinInfo *bin)
{
Temp scratch = scratch_begin(&arena, 1);
DW_Input result = {0};
B32 sect_status[ArrayCount(result.sec)] = {0};
ELF_Shdr64Array sections = elf_shdr64_array_from_bin(scratch.arena, raw_image, &bin->hdr);
for (U64 sect_idx = 1; sect_idx < sections.count; ++sect_idx) {
ELF_Shdr64 *shdr = &sections.v[sect_idx];
// skip BSS sections
if (shdr->sh_type != ELF_SectionCode_ProgBits) {
continue;
}
String8 name = elf_name_from_shdr64(raw_image, &bin->hdr, bin->sh_name_range, shdr);
DW_SectionKind s = dw_section_kind_from_string(name);
B32 is_dwo = 0;
if (s == DW_Section_Null) {
s = dw_section_dwo_kind_from_string(name);
is_dwo = 1;
}
if (s != DW_Section_Null) {
if (sect_status[s]) {
Assert(!"too many debug sections with identical name, picking first");
} else {
Rng1U64 raw_data_range = rng_1u64(shdr->sh_offset, shdr->sh_offset + shdr->sh_size);
String8 data = str8_substr(raw_image, raw_data_range);
// ELF was compiled with compressed debug info
if (shdr->sh_flags & ELF_Shf_Compressed) {
String8 comp_data_with_header = data;
// read header
ELF_Chdr64 chdr64 = {0};
U64 chdr_size = 0;
if (ELF_HdrIs64Bit(bin->hdr.e_ident)) {
chdr_size = str8_deserial_read_struct(comp_data_with_header, 0, &chdr64);
if (chdr_size != sizeof(chdr64)) {
Assert(!"not enough bytes to read header");
}
} else if (ELF_HdrIs32Bit(bin->hdr.e_ident)) {
ELF_Chdr32 chdr32 = {0};
chdr_size = str8_deserial_read_struct(comp_data_with_header, 0, &chdr32);
if (chdr_size == sizeof(chdr32)) {
chdr64 = elf_chdr64_from_chdr32(chdr32);
}
}
AssertAlways(IsPow2(chdr64.ch_addr_align));
// skip header
String8 comp_data = str8_skip(comp_data_with_header, chdr_size);
// push buffer for the decompressor
U8 *decomp_buffer = push_array_no_zero_aligned(arena, U8, chdr64.ch_size, chdr64.ch_addr_align);
U64 actual_decomp_size = 0;
// decompress
switch (chdr64.ch_type) {
case ELF_CompressType_None: {
AssertAlways(!"unexpected compression type");
} break;
case ELF_CompressType_ZLib: {
actual_decomp_size = zsinflate(decomp_buffer, chdr64.ch_size, comp_data.str, comp_data.size);
} break;
case ELF_CompressType_ZStd: {
// TODO: zstd lib
NotImplemented;
} break;
default: InvalidPath; break;
}
// TODO: error handling
AssertAlways(actual_decomp_size == chdr64.ch_size);
// set decompressed section data
data = str8(decomp_buffer, actual_decomp_size);
}
sect_status[s] = 1;
DW_Section *d = &result.sec[s];
d->name = push_str8_copy(arena, name);
d->data = data;
d->is_dwo = is_dwo;
}
}
}
scratch_end(scratch);
return result;
}
+11
View File
@@ -0,0 +1,11 @@
// Copyright (c) 2025 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DWARF_ELF_H
#define DWARF_ELF_H
internal DW_Input dw_input_from_elf_section_table(Arena *arena, String8 raw_image, ELF_BinInfo *bin);
#endif // DWARF_ELF_H
+53 -10
View File
@@ -7,12 +7,10 @@ dw_string_from_expr_op(Arena *arena, DW_Version ver, DW_Ext ext, DW_ExprOp op)
String8 result = {0}; String8 result = {0};
#define X(_N,...) case DW_ExprOp_##_N: result = str8_lit(Stringify(_N)); goto exit; #define X(_N,...) case DW_ExprOp_##_N: result = str8_lit(Stringify(_N)); goto exit;
switch (ext) { if (ext & DW_Ext_GNU) {
case DW_Ext_Null: break; switch (op) {
case DW_Ext_LLVM: break; DW_Expr_GNU_XList(X);
case DW_Ext_APPLE: break; }
case DW_Ext_MIPS: break;
case DW_Ext_GNU: DW_Expr_GNU_XList(X); break;
} }
switch (ver) { switch (ver) {
@@ -48,6 +46,7 @@ internal String8
dw_string_from_tag_kind(Arena *arena, DW_TagKind kind) dw_string_from_tag_kind(Arena *arena, DW_TagKind kind)
{ {
switch (kind) { switch (kind) {
case DW_Tag_Null: return str8_lit("Null");
#define X(_N,_ID) case DW_Tag_##_N: return str8_lit(Stringify(_N)); #define X(_N,_ID) case DW_Tag_##_N: return str8_lit(Stringify(_N));
DW_Tag_V3_XList(X) DW_Tag_V3_XList(X)
DW_Tag_V5_XList(X) DW_Tag_V5_XList(X)
@@ -149,6 +148,50 @@ dw_string_from_language(Arena *arena, DW_Language kind)
return push_str8f(arena, "%x", kind); return push_str8f(arena, "%x", kind);
} }
internal String8
dw_string_from_inl(Arena *arena, DW_InlKind kind)
{
switch (kind) {
#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N));
DW_Inl_XList(X)
#undef X
}
return push_str8f(arena, "%x", kind);
}
internal String8
dw_string_from_access_kind(Arena *arena, DW_AccessKind kind)
{
switch (kind) {
#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N));
DW_AccessKind_XList(X)
#undef X
}
return push_str8f(arena, "%llx", kind);
}
internal String8
dw_string_from_calling_convetion(Arena *arena, DW_CallingConventionKind kind)
{
switch (kind) {
#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N));
DW_CallingConventionKind_XList(X)
#undef X
}
return push_str8f(arena, "%llx", kind);
}
internal String8
dw_string_from_attrib_type_encoding(Arena *arena, DW_ATE kind)
{
switch (kind) {
#define X(_N,_ID) case _ID: return str8_lit(Stringify(_N));
DW_ATE_XList(X)
#undef X
}
return push_str8f(arena, "%llx", kind);
}
internal String8 internal String8
dw_string_from_std_opcode(Arena *arena, DW_StdOpcode kind) dw_string_from_std_opcode(Arena *arena, DW_StdOpcode kind)
{ {
@@ -173,7 +216,7 @@ dw_string_from_ext_opcode(Arena *arena, DW_ExtOpcode kind)
} }
internal String8 internal String8
dw_string_from_loc_list_entry_kind(Arena *arena, DW_LocListEntryKind kind) dw_string_from_loc_list_entry_kind(Arena *arena, DW_LLE kind)
{ {
NotImplemented; NotImplemented;
return str8_zero(); return str8_zero();
@@ -187,7 +230,7 @@ dw_string_from_section_kind(Arena *arena, DW_SectionKind kind)
} }
internal String8 internal String8
dw_string_from_rng_list_entry_kind(Arena *arena, DW_RngListEntryKind kind) dw_string_from_rng_list_entry_kind(Arena *arena, DW_RLE kind)
{ {
NotImplemented; NotImplemented;
return str8_zero(); return str8_zero();
@@ -201,14 +244,14 @@ dw_string_from_register(Arena *arena, Arch arch, U64 reg_id)
case Arch_Null: break; case Arch_Null: break;
case Arch_x86: { case Arch_x86: {
switch (reg_id) { switch (reg_id) {
#define X(_N, _ID, ...) case DW_Reg_x86_##_N: reg_str = str8_lit(Stringify(_ID)); break; #define X(_N, _ID, ...) case DW_RegX86_##_N: reg_str = str8_lit(Stringify(_N)); break;
DW_Regs_X86_XList(X) DW_Regs_X86_XList(X)
#undef X #undef X
} }
} break; } break;
case Arch_x64: { case Arch_x64: {
switch (reg_id) { switch (reg_id) {
#define X(_N, _ID, ...) case DW_Reg_x64_##_N: reg_str = str8_lit(Stringify(_ID)); break; #define X(_N, _ID, ...) case DW_RegX64_##_N: reg_str = str8_lit(Stringify(_N)); break;
DW_Regs_X64_XList(X) DW_Regs_X64_XList(X)
#undef X #undef X
} }
+1
View File
@@ -8,6 +8,7 @@ internal String8 dw_string_from_expr_op(Arena *arena, DW_Version ver, DW_Ext ext
internal String8 dw_string_from_tag_kind(Arena *arena, DW_TagKind kind); internal String8 dw_string_from_tag_kind(Arena *arena, DW_TagKind kind);
internal String8 dw_string_from_attrib_kind(Arena *arena, DW_Version ver, DW_Ext ext, DW_AttribKind kind); internal String8 dw_string_from_attrib_kind(Arena *arena, DW_Version ver, DW_Ext ext, DW_AttribKind kind);
internal String8 dw_string_from_form_kind(Arena *arena, DW_Version ver, DW_FormKind kind); internal String8 dw_string_from_form_kind(Arena *arena, DW_Version ver, DW_FormKind kind);
internal String8 dw_string_access_kind(Arena *arena, DW_AccessKind kind);
//internal String8 dw_string_from_register(Arena *arena, Arch arch, U64 reg_id); //internal String8 dw_string_from_register(Arena *arena, Arch arch, U64 reg_id);
+10 -1
View File
@@ -3,13 +3,16 @@
//- analyzers //- analyzers
#if 0
internal DW_SimpleLoc internal DW_SimpleLoc
dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base) dw_expr__analyze_fast(void *base, Rng1U64 range, U64 text_section_base)
{ {
DW_SimpleLoc result = {DW_SimpleLocKind_Empty}; DW_SimpleLoc result = {DW_SimpleLocKind_Empty};
String8 expr_data = str8((U8*)data+range.min, (U8*)data+range.max);
U8 op = 0; U8 op = 0;
if (dw_based_range_read(base, range, 0, 1, &op)) { if (str8_deserial_read_struct(expr_data, 0, &op)) {
// step params // step params
U64 size_param = 0; U64 size_param = 0;
B32 is_signed = 0; B32 is_signed = 0;
@@ -548,12 +551,14 @@ dw_expr__analyze_details(void *in_base, Rng1U64 in_range, DW_ExprMachineCallConf
scratch_end(scratch); scratch_end(scratch);
return result; return result;
} }
#endif
//- full eval //- full eval
internal DW_Location internal DW_Location
dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_ExprMachineConfig *config) dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_ExprMachineConfig *config)
{ {
#if 0
Temp scratch = scratch_begin(&arena_optional, 1); Temp scratch = scratch_begin(&arena_optional, 1);
DW_Location result = {0}; DW_Location result = {0};
@@ -1322,8 +1327,12 @@ dw_expr__eval(Arena *arena_optional, void *expr_base, Rng1U64 expr_range, DW_Exp
// clear stack // clear stack
scratch_end(scratch); scratch_end(scratch);
return result; return result;
#endif
DW_Location result = {0};
return result;
} }
//- dw expr val stack //- dw expr val stack
internal DW_ExprStack internal DW_ExprStack
+2626 -1876
View File
File diff suppressed because it is too large Load Diff
+294 -335
View File
@@ -4,38 +4,49 @@
#ifndef DWARF_PARSE_H #ifndef DWARF_PARSE_H
#define DWARF_PARSE_H #define DWARF_PARSE_H
// NOTE(rjf): Some rules about the spaces of offsets and ranges: typedef struct DW_Section
//
// - Every stored/passed offset is relative to the base of its section.
// - Every stored/passed range has endpoints relative to the base of their section.
// - Upon calling a syms_based_range_* function, these offsets need to be
// converted into range-relative.
////////////////////////////////
//~ rjf: Constants
#define DWARF_VOID_TYPE_ID 0xffffffffffffffffull
////////////////////////////////
//~ rjf: Files + External Debug References
typedef struct DW_ExtDebugRef DW_ExtDebugRef;
struct DW_ExtDebugRef
{ {
// NOTE(rjf): .dwo => an external DWARF V5 .dwo file String8 name;
String8 dwo_path; String8 data;
U64 dwo_id; B32 is_dwo;
}; } DW_Section;
//////////////////////////////// typedef struct DW_Input
//~ rjf: Abbrev Table {
DW_Section sec[DW_Section_Count];
DW_Section sup[DW_Section_Count];
} DW_Input;
typedef struct DW_AbbrevTableEntry DW_AbbrevTableEntry; typedef struct DW_ListUnit
struct DW_AbbrevTableEntry {
DW_Version version;
U64 address_size;
U64 segment_selector_size;
U64 entry_size;
String8 entries;
} DW_ListUnit;
typedef struct DW_ListUnitInput
{
U64 addr_count;
U64 str_offset_count;
U64 rnglist_count;
U64 loclist_count;
Rng1U64Array addr_ranges;
Rng1U64Array str_offset_ranges;
Rng1U64Array rnglist_ranges;
Rng1U64Array loclist_ranges;
DW_ListUnit *addrs;
DW_ListUnit *str_offsets;
DW_ListUnit *rnglists;
DW_ListUnit *loclists;
} DW_ListUnitInput;
typedef struct DW_AbbrevTableEntry
{ {
U64 id; U64 id;
U64 off; U64 off;
}; } DW_AbbrevTableEntry;
typedef struct DW_AbbrevTable DW_AbbrevTable; typedef struct DW_AbbrevTable DW_AbbrevTable;
struct DW_AbbrevTable struct DW_AbbrevTable
@@ -44,62 +55,6 @@ struct DW_AbbrevTable
DW_AbbrevTableEntry *entries; DW_AbbrevTableEntry *entries;
}; };
////////////////////////////////
//~ Sections
typedef struct DW_Section DW_Section;
struct DW_Section
{
String8 name;
String8 data;
DW_Mode mode;
B32 is_dwo;
};
typedef struct DW_SectionArray DW_SectionArray;
struct DW_SectionArray
{
DW_Section v[DW_Section_Count];
};
////////////////////////////////
//~ rjf: Basic Line Info
typedef struct DW_LineFile DW_LineFile;
struct DW_LineFile
{
String8 file_name;
U64 dir_idx;
U64 modify_time;
U64 md5_digest[2];
U64 file_size;
};
typedef struct DW_LineVMFileNode DW_LineVMFileNode;
struct DW_LineVMFileNode
{
DW_LineVMFileNode *next;
DW_LineFile file;
};
typedef struct DW_LineVMFileList DW_LineVMFileList;
struct DW_LineVMFileList
{
U64 node_count;
DW_LineVMFileNode *first;
DW_LineVMFileNode *last;
};
typedef struct DW_LineVMFileArray DW_LineVMFileArray;
struct DW_LineVMFileArray
{
U64 count;
DW_LineFile *v;
};
////////////////////////////////
//~ rjf: Abbrevs
typedef enum DW_AbbrevKind typedef enum DW_AbbrevKind
{ {
DW_Abbrev_Null, DW_Abbrev_Null,
@@ -108,215 +63,169 @@ typedef enum DW_AbbrevKind
DW_Abbrev_AttribSequenceEnd, DW_Abbrev_AttribSequenceEnd,
DW_Abbrev_DIEBegin, DW_Abbrev_DIEBegin,
DW_Abbrev_DIEEnd, DW_Abbrev_DIEEnd,
} } DW_AbbrevKind;
DW_AbbrevKind;
typedef U32 DW_AbbrevFlags; typedef U32 DW_AbbrevFlags;
enum{ enum
{
DW_AbbrevFlag_HasImplicitConst = (1 << 0), DW_AbbrevFlag_HasImplicitConst = (1 << 0),
DW_AbbrevFlag_HasChildren = (1 << 1), DW_AbbrevFlag_HasChildren = (1 << 1),
}; };
typedef struct DW_Abbrev DW_Abbrev; typedef struct DW_Abbrev
struct DW_Abbrev
{ {
DW_AbbrevKind kind; DW_AbbrevKind kind;
Rng1U64 abbrev_range;
U64 sub_kind; U64 sub_kind;
U64 id; U64 id;
U64 const_value; U64 const_value;
DW_AbbrevFlags flags; DW_AbbrevFlags flags;
}; } DW_Abbrev;
//////////////////////////////// typedef union DW_Form
//~ rjf: Attribs
typedef struct DW_AttribValueResolveParams DW_AttribValueResolveParams;
struct DW_AttribValueResolveParams
{ {
DW_Version version; String8 addr;
DW_Language language; String8 block;
U64 addr_size; // NOTE(rjf): size in bytes of containing compilation unit's addresses String8 data;
U64 containing_unit_info_off; // NOTE(rjf): containing compilation unit's offset into the .debug_info section String8 string;
U64 debug_addrs_base; // NOTE(rjf): containing compilation unit's offset into the .debug_addrs section (DWARF V5 ONLY) String8 exprloc;
U64 debug_rnglists_base; // NOTE(rjf): containing compilation unit's offset into the .debug_rnglists section (DWARF V5 ONLY) B8 flag;
U64 debug_str_offs_base; // NOTE(rjf): containing compilation unit's offset into the .debug_str_offsets section (DWARF V5 ONLY) S64 sdata;
U64 debug_loclists_base; // NOTE(rjf): containing compilation unit's offset into the .debug_loclists section (DWARF V5 ONLY) U64 udata;
}; U64 sec_offset;
U64 ref;
U64 strp_sup;
U64 xval;
U64 addrx;
U64 strx;
U64 rnglistx;
U64 ptr;
U64 implicit_const;
} DW_Form;
typedef struct DW_AttribValue DW_AttribValue; typedef struct DW_Attrib
struct DW_AttribValue
{
DW_SectionKind section;
U64 v[2];
};
typedef struct DW_Attrib DW_Attrib;
struct DW_Attrib
{ {
U64 info_off; U64 info_off;
U64 abbrev_off;
U64 abbrev_id; U64 abbrev_id;
DW_AttribKind attrib_kind; DW_AttribKind attrib_kind;
DW_FormKind form_kind; DW_FormKind form_kind;
DW_AttribClass value_class; DW_Form form;
DW_AttribValue form_value; } DW_Attrib;
};
typedef struct DW_AttribArray DW_AttribArray; typedef struct DW_AttribNode
struct DW_AttribArray
{ {
DW_Attrib *v; struct DW_AttribNode *next;
U64 count; DW_Attrib v;
}; } DW_AttribNode;
typedef struct DW_AttribNode DW_AttribNode; typedef struct DW_AttribList
struct DW_AttribNode
{
DW_AttribNode *next;
DW_Attrib attrib;
};
typedef struct DW_AttribList DW_AttribList;
struct DW_AttribList
{ {
DW_AttribNode *first; DW_AttribNode *first;
DW_AttribNode *last; DW_AttribNode *last;
U64 count; U64 count;
}; } DW_AttribList;
typedef struct DW_AttribListParseResult DW_AttribListParseResult; typedef struct DW_Tag
struct DW_AttribListParseResult
{ {
DW_AttribList attribs;
U64 max_info_off;
U64 max_abbrev_off;
};
////////////////////////////////
//~ rjf: Compilation Units + Accelerators
typedef struct DW_CompRoot DW_CompRoot;
struct DW_CompRoot
{
// NOTE(rjf): Header Data
U64 size;
DW_CompUnitKind kind;
DW_Version version;
U64 address_size;
U64 abbrev_off;
U64 info_off;
Rng1U64 tags_info_range;
DW_AbbrevTable abbrev_table;
// NOTE(rjf): [parsed from DWARF attributes] Offsets For More Info (DWARF V5 ONLY)
U64 rnglist_base; // NOTE(rjf): Offset into the .debug_rnglists section where this comp unit's data is.
U64 loclist_base; // NOTE(rjf): Offset into the .debug_loclists section where this comp unit's data is.
U64 addrs_base; // NOTE(rjf): Offset into the .debug_addr section where this comp unit's data is.
U64 stroffs_base; // NOTE(rjf): Offset into the .debug_str_offsets section where this comp unit's data is.
// NOTE(rjf): [parsed from DWARF attributes] General Info
String8 name;
String8 producer;
String8 compile_dir;
String8 external_dwo_name;
U64 dwo_id;
DW_Language language;
U64 name_case;
B32 use_utf8;
U64 line_off;
U64 low_pc;
U64 high_pc;
DW_AttribValue ranges_attrib_value;
U64 base_addr;
};
////////////////////////////////
//~ rjf: Tags
typedef struct DW_Tag DW_Tag;
struct DW_Tag
{
DW_Tag *next_sibling;
DW_Tag *first_child;
DW_Tag *last_child;
DW_Tag *parent;
Rng1U64 info_range;
Rng1U64 abbrev_range;
B32 has_children; B32 has_children;
U64 abbrev_id; U64 abbrev_id;
DW_TagKind kind; DW_TagKind kind;
U64 attribs_info_off;
U64 attribs_abbrev_off;
DW_AttribList attribs; DW_AttribList attribs;
};
typedef U32 DW_TagStubFlags;
enum
{
DW_TagStubFlag_HasObjectPointerArg = (1<<0),
DW_TagStubFlag_HasLocation = (1<<1),
DW_TagStubFlag_HasExternal = (1<<2),
DW_TagStubFlag_HasSpecification = (1<<3),
};
typedef struct DW_TagStub DW_TagStub;
struct DW_TagStub
{
U64 info_off; U64 info_off;
DW_TagKind kind; } DW_Tag;
DW_TagStubFlags flags;
U64 children_info_off;
U64 attribs_info_off;
U64 attribs_abbrev_off;
// NOTE(rjf): DW_Attrib_Specification is tacked onto definitions that typedef struct DW_TagNode
// are filling out more info about a "prototype". That attribute is a reference
// that points back at the declaration tag. The declaration tag has the
// DW_Attrib_Declaration attribute, which is sort of like the reverse
// of that, except there's no reference. So what we're doing here is just storing
// a reference on both, that point back to each other, so it's always easy to
// get from decl => spec, or from spec => decl.
//SYMS_SymbolID ref;
// NOTE(rjf): DW_Attrib_AbstractOrigin is tacked onto some definitions
// that are used to specify information more specific to inlining, while wanting
// to refer to an "abstract" function DIE, that is not specific to any inline
// sites. The DWARF generator will not duplicate information across these, so
// we will occasionally need to look at an abstract origin to get abstract
// information, like name/linkage-name/etc.
//SYMS_SymbolID abstract_origin;
U64 _unused_;
};
typedef struct DW_TagStubNode DW_TagStubNode;
struct DW_TagStubNode
{ {
DW_TagStubNode *next; DW_Tag tag;
DW_TagStub stub; struct DW_TagNode *sibling;
}; struct DW_TagNode *first_child;
struct DW_TagNode *last_child;
} DW_TagNode;
typedef struct DW_TagStubList DW_TagStubList; typedef struct DW_Loc
struct DW_TagStubList {
Rng1U64 range;
String8 expr;
} DW_Loc;
typedef struct DW_LocNode
{
DW_Loc v;
struct DW_LocNode *next;
} DW_LocNode;
typedef struct DW_LocList
{ {
DW_TagStubNode *first;
DW_TagStubNode *last;
U64 count; U64 count;
}; DW_LocNode *first;
DW_LocNode *last;
} DW_LocList;
//////////////////////////////// typedef struct DW_CompUnit
//~ rjf: Line Info VM Types
typedef struct DW_LineVMHeader DW_LineVMHeader;
struct DW_LineVMHeader
{ {
U64 unit_length; B32 relaxed;
U64 unit_opl; DW_Ext ext;
DW_CompUnitKind kind;
DW_Version version;
DW_Format format;
U64 address_size;
U64 abbrev_off;
Rng1U64 info_range;
U64 first_tag_info_off;
DW_AbbrevTable abbrev_table;
String8 abbrev_data;
DW_ListUnit *addr_lu;
DW_ListUnit *str_offsets_lu;
DW_ListUnit *rnglists_lu;
DW_ListUnit *loclists_lu;
U64 low_pc;
U64 dwo_id;
DW_Tag tag;
HashTable *tag_ht;
} DW_CompUnit;
typedef struct DW_TagTree
{
DW_TagNode *root;
U64 tag_count;
} DW_TagTree;
typedef struct DW_LineFile
{
String8 file_name;
U64 dir_idx;
U64 modify_time;
U64 file_size;
U128 md5_digest;
String8 source;
} DW_LineFile;
typedef struct DW_LineVMFileNode
{
struct DW_LineVMFileNode *next;
DW_LineFile file;
} DW_LineVMFileNode;
typedef struct DW_LineVMFileList
{
U64 node_count;
DW_LineVMFileNode *first;
DW_LineVMFileNode *last;
} DW_LineVMFileList;
typedef struct DW_LineVMFileArray
{
U64 count;
DW_LineFile *v;
} DW_LineVMFileArray;
typedef struct DW_LineVMHeader
{
Rng1U64 unit_range;
DW_Version version; DW_Version version;
U8 address_size; // Duplicates size from the compilation unit but is needed to support stripped exe that just have .debug_line and .debug_line_str. U8 address_size; // Duplicates size from the compilation unit but is needed to support stripped exe that just have .debug_line and .debug_line_str.
U8 segment_selector_size; U8 segment_selector_size;
U64 header_length; U64 header_length;
U64 program_off;
U8 min_inst_len; U8 min_inst_len;
U8 max_ops_for_inst; U8 max_ops_for_inst;
U8 default_is_stmt; U8 default_is_stmt;
@@ -325,12 +234,11 @@ struct DW_LineVMHeader
U8 opcode_base; U8 opcode_base;
U64 num_opcode_lens; U64 num_opcode_lens;
U8 *opcode_lens; U8 *opcode_lens;
String8Array dir_table; DW_LineVMFileArray dir_table;
DW_LineVMFileArray file_table; DW_LineVMFileArray file_table;
}; } DW_LineVMHeader;
typedef struct DW_LineVMState DW_LineVMState; typedef struct DW_LineVMState
struct DW_LineVMState
{ {
U64 address; // Address of a machine instruction. U64 address; // Address of a machine instruction.
U32 op_index; // This is used by the VLIW instructions to indicate index of operation inside the instruction. U32 op_index; // This is used by the VLIW instructions to indicate index of operation inside the instruction.
@@ -351,144 +259,195 @@ struct DW_LineVMState
// prepare stack for a function. // prepare stack for a function.
B32 prologue_end; B32 prologue_end;
B32 epilogue_begin; // NOTE(nick): Indicates that "address" points to section where function exits and unwinds stack. B32 epilogue_begin; // Indicates that "address" points to section where function exits and unwinds stack.
U64 isa; // NOTE(nick): Instruction set that is used. U64 isa; // Instruction set that is used.
U64 discriminator; // NOTE(nick): Arbitrary id that indicates to which block these instructions belong. U64 discriminator; // Arbitrary id that indicates to which block these instructions belong.
B32 end_sequence; // NOTE(nick): Indicates that "address" points to the first instruction in the instruction block that follows. B32 end_sequence; // Indicates that "address" points to the first instruction in the instruction block that follows.
} DW_LineVMState;
// NOTE(rjf): it looks like LTO might sometimes zero out high PC and low PCs, causing a typedef struct DW_Line
// swath of line info to map to a range starting at 0. This causes overlapping ranges
// which we do not want to report. So this B32 will turn on emission.
B32 busted_seq;
};
typedef struct DW_Line DW_Line;
struct DW_Line
{ {
U64 file_index; U64 file_index;
U32 line; U32 line;
U32 column; U32 column;
U64 voff; U64 address;
}; } DW_Line;
typedef struct DW_LineNode DW_LineNode; typedef struct DW_LineNode
struct DW_LineNode
{ {
DW_LineNode *next; struct DW_LineNode *next;
DW_Line v; DW_Line v;
}; } DW_LineNode;
typedef struct DW_LineSeqNode DW_LineSeqNode; typedef struct DW_LineSeqNode
struct DW_LineSeqNode
{ {
DW_LineSeqNode *next; struct DW_LineSeqNode *next;
U64 count; U64 count;
DW_LineNode *first; DW_LineNode *first;
DW_LineNode *last; DW_LineNode *last;
}; } DW_LineSeqNode;
typedef struct DW_LineTableParseResult DW_LineTableParseResult; typedef struct DW_LineTableParseResult
struct DW_LineTableParseResult
{ {
DW_LineVMHeader vm_header;
U64 seq_count; U64 seq_count;
DW_LineSeqNode *first_seq; DW_LineSeqNode *first_seq;
DW_LineSeqNode *last_seq; DW_LineSeqNode *last_seq;
}; } DW_LineTableParseResult;
//////////////////////////////// ////////////////////////////////
//~ rjf: .debug_pubnames and .debug_pubtypes // .debug_pubnames and .debug_pubtypes
typedef struct DW_PubStringsBucket DW_PubStringsBucket; typedef struct DW_PubStringsBucket
struct DW_PubStringsBucket
{ {
DW_PubStringsBucket *next; struct DW_PubStringsBucket *next;
String8 string; String8 string;
U64 info_off; U64 info_off;
U64 cu_info_off; U64 cu_info_off;
}; } DW_PubStringsBucket;
typedef struct DW_PubStringsTable DW_PubStringsTable; typedef struct DW_PubStringsTable
struct DW_PubStringsTable
{ {
U64 size; U64 size;
DW_PubStringsBucket **buckets; DW_PubStringsBucket **buckets;
}; } DW_PubStringsTable;
//////////////////////////////// typedef struct DW_Reference
//~ rjf: Basic Helpers {
DW_CompUnit *cu;
U64 info_off;
} DW_Reference;
// hasher
internal U64 dw_hash_from_string(String8 string); internal U64 dw_hash_from_string(String8 string);
//////////////////////////////// // deserial helpers
//~ Specific Based Range Helpers
#define dw_based_range_read_struct(base, range, offset, out) dw_based_range_read(base, range, offset, sizeof(*out), out) internal U64 str8_deserial_read_dwarf_packed_size(String8 string, U64 off, U64 *size_out);
internal U64 str8_deserial_read_dwarf_uint (String8 string, U64 off, DW_Format format, U64 *uint_out);
internal U64 str8_deserial_read_uleb128 (String8 string, U64 off, U64 *value_out);
internal U64 str8_deserial_read_sleb128 (String8 string, U64 off, S64 *value_out);
internal U64 str8_deserial_read_uleb128_array(Arena *arena, String8 string, U64 off, U64 count, U64 **arr_out);
internal U64 str8_deserial_read_sleb128_array(Arena *arena, String8 string, U64 off, U64 count, S64 **arr_out);
internal U64 dw_based_range_read(void *base, Rng1U64 range, U64 offset, U64 size, void *out); internal Rng1U64List dw_unit_ranges_from_data(Arena *arena, String8 data);
internal String8 dw_based_range_read_string(void *base, Rng1U64 range, U64 offset);
internal void* dw_based_range_ptr(void *base, Rng1U64 range, U64 offset);
internal void* dw_based_range_ptr_size(void *base, Rng1U64 range, U64 offset, U64 size);
internal U64 dw_based_range_read_uleb128(void *base, Rng1U64 range, U64 offset, U64 *out_value);
internal U64 dw_based_range_read_sleb128(void *base, Rng1U64 range, U64 offset, S64 *out_value);
internal U64 dw_based_range_read_length(void *base, Rng1U64 range, U64 offset, U64 *out_value);
internal U64 dw_based_range_read_abbrev_tag(void *base, Rng1U64 range, U64 offset, DW_Abbrev *out_abbrev);
internal U64 dw_based_range_read_abbrev_attrib_info(void *base, Rng1U64 range, U64 offset, DW_Abbrev *out_abbrev);
internal U64 dw_based_range_read_attrib_form_value(void *base, Rng1U64 range, U64 offset, DW_Mode mode, U64 address_size, DW_FormKind form_kind, U64 implicit_const, DW_AttribValue *form_value_out);
internal DW_Mode dw_mode_from_sec(DW_SectionArray *sections, DW_SectionKind kind); // list units
internal B32 dw_sec_is_present(DW_SectionArray *sections, DW_SectionKind kind);
internal void* dw_base_from_sec(DW_SectionArray *sections, DW_SectionKind kind);
internal Rng1U64 dw_range_from_sec(DW_SectionArray *sections, DW_SectionKind kind);
//////////////////////////////// internal U64 dw_read_list_unit_header_addr (String8 unit_data, DW_ListUnit *lu_out);
//~ rjf: Abbrev Table internal U64 dw_read_list_unit_header_str_offsets(String8 unit_data, DW_ListUnit *lu_out);
internal U64 dw_read_list_unit_header_list (String8 unit_data, DW_ListUnit *lu_out);
internal DW_AbbrevTable dw_make_abbrev_table(Arena *arena, DW_SectionArray *sections, U64 start_abbrev_off); internal DW_ListUnitInput dw_list_unit_input_from_input(Arena *arena, DW_Input *input);
internal U64 dw_offset_from_list_unit(DW_ListUnit *lu, U64 index);
internal U64 dw_addr_from_list_unit (DW_ListUnit *lu, U64 index);
// abbrev table
internal U64 dw_read_abbrev_tag (String8 data, U64 offset, DW_Abbrev *out_abbrev);
internal U64 dw_read_abbrev_attrib(String8 data, U64 offset, DW_Abbrev *out_abbrev);
internal DW_AbbrevTable dw_make_abbrev_table(Arena *arena, String8 abbrev_data, U64 start_abbrev_off);
internal U64 dw_abbrev_offset_from_abbrev_id(DW_AbbrevTable table, U64 abbrev_id); internal U64 dw_abbrev_offset_from_abbrev_id(DW_AbbrevTable table, U64 abbrev_id);
//////////////////////////////// // form and tag
//~ rjf: Miscellaneous DWARF Section Parsing
//- rjf: .debug_ranges (DWARF V4) internal U64 dw_read_form(String8 data, U64 off, DW_Version version, DW_Format unit_format, U64 address_size, DW_FormKind form_kind, U64 implicit_const, DW_Form *form_out);
internal Rng1U64List dw_v4_range_list_from_range_offset(Arena *arena, DW_SectionArray *sections, U64 addr_size, U64 comp_unit_base_addr, U64 range_off); internal U64 dw_read_tag (Arena *arena, String8 tag_data, U64 tag_off, U64 tag_base, DW_AbbrevTable abbrev_table, String8 abbrev_data, DW_Version version, DW_Format unit_format, U64 address_size, DW_Tag *tag_out);
internal U64 dw_read_tag_cu(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 info_off, DW_Tag *tag_out);
//- rjf: .debug_pubtypes + .debug_pubnames (DWARF V4) // attrib interp
internal DW_PubStringsTable dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_SectionArray *sections, DW_SectionKind section_kind);
//- rjf: .debug_str_offsets (DWARF V5) internal U64 dw_interp_sec_offset(DW_FormKind form_kind, DW_Form form);
internal U64 dw_v5_offset_from_offs_section_base_index(DW_SectionArray *sections, DW_SectionKind section, U64 base, U64 index); internal String8 dw_interp_exprloc (DW_FormKind form_kind, DW_Form form);
internal U128 dw_interp_const_u128(DW_FormKind form_kind, DW_Form form);
internal U64 dw_interp_const_u64 (DW_FormKind form_kind, DW_Form form);
internal U32 dw_interp_const_u32 (DW_FormKind form_kind, DW_Form form);
internal S64 dw_interp_const_s64 (DW_FormKind form_kind, DW_Form form);
internal S32 dw_interp_const_s32 (DW_FormKind form_kind, DW_Form form);
internal B32 dw_interp_flag (DW_FormKind form_kind, DW_Form form);
internal U64 dw_interp_address (U64 address_size, U64 base_addr, DW_ListUnit *addr_xlist, DW_FormKind form_kind, DW_Form form);
internal String8 dw_interp_block (DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form);
internal String8 dw_interp_string (DW_Input *input, DW_Format unit_format, DW_ListUnit *str_offsets, DW_FormKind form_kind, DW_Form form);
internal String8 dw_interp_line_ptr (DW_Input *input, DW_FormKind form_kind, DW_Form form);
internal DW_LineFile * dw_interp_file (DW_LineVMHeader *line_vm, DW_FormKind form_kind, DW_Form form);
internal DW_Reference dw_interp_ref (DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form);
internal DW_LocList dw_interp_loclist (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form);
internal Rng1U64List dw_interp_rnglist (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_FormKind form_kind, DW_Form form);
//- rjf: .debug_addr (DWARF V5) internal String8 dw_exprloc_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
internal U64 dw_v5_addr_from_addrs_section_base_index(DW_SectionArray *sections, DW_SectionKind section, U64 base, U64 index); internal U128 dw_const_u128_from_attrib_ptr(DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
internal U64 dw_const_u64_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
internal U32 dw_const_u32_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
internal S64 dw_const_s64_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
internal S32 dw_const_s32_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
internal B32 dw_flag_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
internal U64 dw_address_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
internal String8 dw_block_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
internal String8 dw_string_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
internal String8 dw_line_ptr_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
internal DW_LineFile * dw_file_from_attrib_ptr (DW_CompUnit *cu, DW_LineVMHeader *line_vm, DW_Attrib *attrib);
internal DW_Reference dw_ref_from_attrib_ptr (DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
internal DW_LocList dw_loclist_from_attrib_ptr (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
internal Rng1U64List dw_rnglist_from_attrib_ptr (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Attrib *attrib);
//- rjf: .debug_rnglists parsing (DWARF V5) internal String8 dw_exprloc_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
internal U64 dw_v5_sec_offset_from_rnglist_or_loclist_section_base_index(DW_SectionArray *sections, DW_SectionKind section_kind, U64 base, U64 index); internal U128 dw_const_u128_from_attrib(DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
internal Rng1U64List dw_v5_range_list_from_rnglist_offset(Arena *arena, DW_SectionArray *sections, DW_SectionKind section, U64 addr_size, U64 addr_section_base, U64 offset); internal U64 dw_const_u64_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
internal U32 dw_const_u32_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
internal B32 dw_flag_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
internal U64 dw_address_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
internal String8 dw_block_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
internal String8 dw_string_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
internal String8 dw_line_ptr_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
internal String8 dw_line_ptr_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
internal DW_LineFile * dw_file_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_LineVMHeader *line_vm, DW_Tag tag, DW_AttribKind kind);
internal DW_Reference dw_ref_from_attrib (DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
internal DW_LocList dw_loclist_from_attrib (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
internal Rng1U64List dw_rnglist_from_attrib (Arena *arena, DW_Input *input, DW_CompUnit *cu, DW_Tag tag, DW_AttribKind kind);
//////////////////////////////// // compile unit
//~ rjf: Attrib Value Parsing
internal DW_AttribValueResolveParams dw_attrib_value_resolve_params_from_comp_root(DW_CompRoot *root); internal DW_CompUnit dw_cu_from_info_off(Arena *arena, DW_Input *input, DW_ListUnitInput lu_input, U64 offset, B32 relaxed);
internal DW_AttribValue dw_attrib_value_from_form_value(DW_SectionArray *sections, DW_AttribValueResolveParams resolve_params, DW_FormKind form_kind, DW_AttribClass value_class, DW_AttribValue form_value); internal DW_TagTree dw_tag_tree_from_cu(Arena *arena, DW_Input *input, DW_CompUnit *cu);
internal String8 dw_string_from_attrib_value(DW_SectionArray *sections, DW_AttribValue value); internal HashTable * dw_make_tag_hash_table(Arena *arena, DW_TagTree tag_tree);
internal Rng1U64List dw_range_list_from_high_low_pc_and_ranges_attrib_value(Arena *arena, DW_SectionArray *sections, U64 address_size, U64 comp_unit_base_addr, U64 addr_section_base, U64 low_pc, U64 high_pc, DW_AttribValue ranges_value); internal DW_TagNode * dw_tag_node_from_info_off(DW_CompUnit *cu, U64 info_off);
//////////////////////////////// // line info
//~ rjf: Tag Parsing
internal DW_AttribListParseResult dw_parse_attrib_list_from_info_abbrev_offsets(Arena *arena, DW_SectionArray *sections, DW_Version ver, DW_Ext ext, DW_Language lang, U64 address_size, U64 info_off, U64 abbrev_off, B32 relaxed); internal U64 dw_read_line_file(String8 line_data,
internal DW_Tag* dw_tag_from_info_offset(Arena *arena, DW_SectionArray *sections, DW_AbbrevTable abbrev_table, DW_Version ver, DW_Ext ext, DW_Language lang, U64 address_size, U64 info_offset, B32 relaxed); U64 line_off,
internal DW_TagStub dw_stub_from_tag(DW_SectionArray *sections, DW_AttribValueResolveParams resolve_params, DW_Tag *tag); DW_Input *input,
DW_Version unit_version,
DW_Format unit_format,
DW_Ext ext,
U64 address_size,
DW_ListUnit *str_offsets,
U64 enc_count,
U64 *enc_arr,
DW_LineFile *line_file_out);
internal U64 dw_read_line_vm_header(Arena *arena,
String8 line_data,
U64 line_off,
DW_Input *input,
String8 cu_dir,
String8 cu_name,
U8 cu_address_size,
DW_ListUnit *cu_str_offsets,
DW_LineVMHeader *header_out);
//- rjf: line info
internal void dw_line_vm_reset(DW_LineVMState *state, B32 default_is_stmt); internal void dw_line_vm_reset(DW_LineVMState *state, B32 default_is_stmt);
internal void dw_line_vm_advance(DW_LineVMState *state, U64 advance, U64 min_inst_len, U64 max_ops_for_inst); internal void dw_line_vm_advance(DW_LineVMState *state, U64 advance, U64 min_inst_len, U64 max_ops_for_inst);
internal DW_LineSeqNode * dw_push_line_seq(Arena* arena, DW_LineTableParseResult *parsed_tbl); internal DW_LineSeqNode * dw_push_line_seq(Arena* arena, DW_LineTableParseResult *parsed_tbl);
internal DW_LineNode * dw_push_line(Arena *arena, DW_LineTableParseResult *tbl, DW_LineVMState *vm_state, B32 start_of_sequence); internal DW_LineNode * dw_push_line(Arena *arena, DW_LineTableParseResult *tbl, DW_LineVMState *vm_state, B32 start_of_sequence);
internal DW_LineTableParseResult dw_parsed_line_table_from_comp_root(Arena *arena, DW_SectionArray *sections, DW_CompRoot *root); internal String8 dw_path_from_file(Arena *arena, DW_LineVMHeader *vm, DW_LineFile *file);
internal U64 dw_read_line_file(void *line_base, Rng1U64 line_rng, U64 line_off, DW_Mode mode, DW_SectionArray *sections, DW_AttribValueResolveParams resolve_params, U8 address_size, U64 format_count, Rng1U64 *formats, DW_LineFile *line_file_out); internal String8 dw_path_from_file_idx(Arena *arena, DW_LineVMHeader *vm, U64 file_idx);
internal U64 dw_read_line_vm_header(Arena *arena, void *line_base, Rng1U64 line_rng, U64 line_off, DW_Mode mode, DW_SectionArray *sections, DW_AttribValueResolveParams resolve_params, String8 compile_dir, String8 unit_name, DW_LineVMHeader *header_out);
internal DW_LineTableParseResult dw_parsed_line_table_from_data(Arena *arena, String8 unit_data, DW_Input *input, String8 cu_dir, String8 cu_name, U8 cu_address_size, DW_ListUnit *cu_str_offsets);
// helper for .debug_pubtypes and .debug_pubnames
internal DW_PubStringsTable dw_v4_pub_strings_table_from_section_kind(Arena *arena, DW_Input *input, DW_SectionKind section_kind);
#endif // DWARF_PARSE_H #endif // DWARF_PARSE_H
+9 -1
View File
@@ -1,6 +1,11 @@
// Copyright (c) 2024 Epic Games Tools // Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
internal U64 dw_based_range_read(void *base, Rng1U64 range, U64 off, U64 size, void *out) { return 0; }
internal U64 dw_based_range_read_uleb128(void *base, Rng1U64 range, U64 off, U64 *out) { return 0; }
internal U64 dw_based_range_read_sleb128(void *base, Rng1U64 range, U64 off, S64 *out) { return 0; }
internal U64 dw_based_range_read_length(void *base, Rng1U64 range, U64 off, U64 *out) { return 0; }
//////////////////////////////// ////////////////////////////////
// x64 Unwind Function // x64 Unwind Function
@@ -148,7 +153,7 @@ dw_unwind_x64__apply_frame_rules(String8 raw_eh_frame,
// is this a roll-over CFA? // is this a roll-over CFA?
B32 is_roll_over_cfa = 0; B32 is_roll_over_cfa = 0;
if (reg_idx == DW_Reg_x64_Rsp) { if (reg_idx == DW_RegX64_Rsp) {
DW_CFIRegisterRule rule = row->cells[reg_idx].rule; DW_CFIRegisterRule rule = row->cells[reg_idx].rule;
if (rule == DW_CFIRegisterRule_Undefined || rule == DW_CFIRegisterRule_SameValue) { if (rule == DW_CFIRegisterRule_Undefined || rule == DW_CFIRegisterRule_SameValue) {
is_roll_over_cfa = 1; is_roll_over_cfa = 1;
@@ -410,6 +415,8 @@ dw_unwind_parse_pointer_x64(void *frame_base, Rng1U64 frame_range, DW_EhPtrCtx *
internal void internal void
dw_unwind_parse_cie_x64(void *base, Rng1U64 range, DW_EhPtrCtx *ptr_ctx, U64 off, DW_CIEUnpacked *cie_out) dw_unwind_parse_cie_x64(void *base, Rng1U64 range, DW_EhPtrCtx *ptr_ctx, U64 off, DW_CIEUnpacked *cie_out)
{ {
NotImplemented;
#if 0
MemoryZeroStruct(cie_out); MemoryZeroStruct(cie_out);
// get version // get version
@@ -521,6 +528,7 @@ dw_unwind_parse_cie_x64(void *base, Rng1U64 range, DW_EhPtrCtx *ptr_ctx, U64 off
cie_out->cfi_range.min = cfi_off; cie_out->cfi_range.min = cfi_off;
cie_out->cfi_range.max = cfi_off + cfi_size; cie_out->cfi_range.max = cfi_off + cfi_size;
} }
#endif
} }
internal void internal void
+143
View File
@@ -0,0 +1,143 @@
// Copyright (c) 2025 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: 32 => 64 bit conversions
internal ELF_Hdr64
elf_hdr64_from_hdr32(ELF_Hdr32 h32)
{
ELF_Hdr64 h64 = {0};
MemoryCopy(h64.e_ident, h32.e_ident, sizeof(h64.e_ident));
h64.e_type = h32.e_type;
h64.e_machine = h32.e_machine;
h64.e_version = h32.e_version;
h64.e_entry = (U64)h32.e_entry;
h64.e_phoff = (U64)h32.e_phoff;
h64.e_shoff = (U64)h32.e_shoff;
h64.e_flags = h32.e_flags;
h64.e_ehsize = h32.e_ehsize;
h64.e_phentsize = h32.e_phentsize;
h64.e_phnum = h32.e_phnum;
h64.e_shentsize = h32.e_shentsize;
h64.e_shnum = h32.e_shnum;
h64.e_shstrndx = h32.e_shstrndx;
return h64;
}
internal ELF_Shdr64
elf_shdr64_from_shdr32(ELF_Shdr32 h32)
{
ELF_Shdr64 h64 = {0};
h64.sh_name = h32.sh_name;
h64.sh_type = h32.sh_type;
h64.sh_flags = (U64)h32.sh_flags;
h64.sh_addr = (U64)h32.sh_addr;
h64.sh_offset = (U64)h32.sh_offset;
h64.sh_size = (U64)h32.sh_size;
h64.sh_link = h32.sh_link;
h64.sh_info = h32.sh_info;
h64.sh_addralign = (U64)h32.sh_addralign;
h64.sh_entsize = (U64)h32.sh_entsize;
return h64;
}
internal ELF_Phdr64
elf_phdr64_from_phdr32(ELF_Phdr32 h32)
{
ELF_Phdr64 h64 = {0};
h64.p_type = h32.p_type;
h64.p_flags = h32.p_flags;
h64.p_offset = (U64)h32.p_offset;
h64.p_vaddr = (U64)h32.p_vaddr;
h64.p_paddr = (U64)h32.p_paddr;
h64.p_filesz = (U64)h32.p_filesz;
h64.p_memsz = (U64)h32.p_memsz;
h64.p_align = (U64)h32.p_align;
return h64;
}
internal ELF_Dyn64
elf_dyn64_from_dyn32(ELF_Dyn32 h32)
{
ELF_Dyn64 h64 = {0};
h64.tag = (U64)h32.tag;
h64.val = (U64)h32.val;
return h64;
}
internal ELF_Sym64
elf_sym64_from_sym32(ELF_Sym32 sym32)
{
ELF_Sym64 sym64 = {0};
sym64.st_name = sym32.st_name;
sym64.st_value = sym32.st_value;
sym64.st_size = sym32.st_size;
sym64.st_info = sym32.st_info;
sym64.st_other = sym32.st_other;
sym64.st_shndx = sym32.st_shndx;
return sym64;
}
internal ELF_Rel64
elf_rel64_from_rel32(ELF_Rel32 rel32)
{
U32 sym = ELF32_R_SYM(rel32.r_info);
U32 type = ELF32_R_TYPE(rel32.r_info);
ELF_Rel64 rel64 = {0};
rel64.r_info = ELF64_R_INFO(sym, type);
rel64.r_offset = rel32.r_offset;
return rel64;
}
internal ELF_Rela64
elf_rela64_from_rela32(ELF_Rela32 rela32)
{
U32 sym = ELF32_R_SYM(rela32.r_info);
U32 type = ELF32_R_TYPE(rela32.r_info);
ELF_Rela64 rela64 = {0};
rela64.r_offset = rela32.r_info;
rela64.r_info = ELF64_R_INFO(sym, type);
rela64.r_addend = rela32.r_addend;
return rela64;
}
internal ELF_Chdr64
elf_chdr64_from_chdr32(ELF_Chdr32 chdr32)
{
ELF_Chdr64 chdr64 = {0};
chdr64.ch_type = chdr32.ch_type;
chdr64.ch_size = chdr32.ch_size;
chdr64.ch_addr_align = chdr32.ch_addr_align;
return chdr64;
}
////////////////////////////////
internal String8
elf_string_from_class(Arena *arena, ELF_Class v)
{
switch (v) {
case ELF_Class_None: return str8_lit("None");
case ELF_Class_32: return str8_lit("32Bit");
case ELF_Class_64: return str8_lit("64Bit");
}
return push_str8f(arena, "%#x", v);
}
////////////////////////////////
internal Arch
arch_from_elf_machine(ELF_MachineKind e_machine)
{
Arch arch = Arch_Null;
switch (e_machine) {
case ELF_MachineKind_None: arch = Arch_Null; break;
case ELF_MachineKind_AARCH64: arch = Arch_arm32; break;
case ELF_MachineKind_ARM: arch = Arch_arm32; break;
case ELF_MachineKind_386: arch = Arch_x86; break;
case ELF_MachineKind_X86_64: arch = Arch_x64; break;
default: NotImplemented; break;
}
return arch;
}
+996
View File
@@ -0,0 +1,996 @@
// Copyright (c) 2025 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef ELF_H
#define ELF_H
typedef U8 ELF_Class;
enum
{
ELF_Class_None = 0,
ELF_Class_32 = 1,
ELF_Class_64 = 2,
ELF_Class_Count = 3
};
typedef U8 ELF_OsAbi;
enum
{
ELF_OsAbi_None,
ELF_OsAbi_SYSV,
ELF_OsAbi_HPUX,
ELF_OsAbi_NETBSD,
ELF_OsAbi_GNU,
ELF_OsAbi_LINUX,
ELF_OsAbi_SOLARIS,
ELF_OsAbi_IRIX,
ELF_OsAbi_FREEBSD,
ELF_OsAbi_TRU64,
ELF_OsAbi_ARM = 97,
ELF_OsAbi_STANDALONE = 255,
};
typedef U8 ELF_Version;
enum
{
ELF_Version_None,
ELF_Version_Current,
};
typedef U16 ELF_MachineKind;
enum
{
ELF_MachineKind_None = 0,
ELF_MachineKind_M32 = 1,
ELF_MachineKind_SPARC = 2,
ELF_MachineKind_386 = 3,
ELF_MachineKind_68K = 4,
ELF_MachineKind_88K = 5,
ELF_MachineKind_IAMCU = 6,
ELF_MachineKind_860 = 7,
ELF_MachineKind_MIPS = 8,
ELF_MachineKind_S370 = 9,
ELF_MachineKind_MIPS_RS3_LE = 10,
// 11-14 reserved
ELF_MachineKind_PARISC = 15,
// 16 reserved
ELF_MachineKind_VPP500 = 17,
ELF_MachineKind_SPARC32PLUS = 18,
// nick: Sun's "v8plus"
ELF_MachineKind_INTEL960 = 19,
ELF_MachineKind_PPC = 20,
ELF_MachineKind_PPC64 = 21,
ELF_MachineKind_S390 = 22,
ELF_MachineKind_SPU = 23,
// 24-35 reserved
ELF_MachineKind_V800 = 36,
ELF_MachineKind_FR20 = 37,
ELF_MachineKind_RH32 = 38,
ELF_MachineKind_MCORE = 39,
ELF_MachineKind_ARM = 40,
ELF_MachineKind_SH = 42,
ELF_MachineKind_ALPHA = 41,
ELF_MachineKind_SPARCV9 = 43,
ELF_MachineKind_TRICORE = 44,
ELF_MachineKind_ARC = 45,
ELF_MachineKind_H8_300 = 46,
ELF_MachineKind_H8_300H = 47,
ELF_MachineKind_H8S = 48,
ELF_MachineKind_H8_500 = 49,
ELF_MachineKind_IA_64 = 50,
ELF_MachineKind_MIPS_X = 51,
ELF_MachineKind_COLDFILE = 52,
ELF_MachineKind_68HC12 = 53,
ELF_MachineKind_MMA = 54,
ELF_MachineKind_PCP = 55,
ELF_MachineKind_NCPU = 56,
ELF_MachineKind_NDR1 = 57,
ELF_MachineKind_STARCORE = 58,
ELF_MachineKind_ME16 = 59,
ELF_MachineKind_ST100 = 60,
ELF_MachineKind_TINYJ = 61,
ELF_MachineKind_X86_64 = 62,
ELF_MachineKind_AARCH64 = 183,
ELF_MachineKind_TI_C6000 = 140,
ELF_MachineKind_L1OM = 180,
ELF_MachineKind_K1OM = 181,
ELF_MachineKind_RISCV = 243,
ELF_MachineKind_S390_OLD = 0xA390,
};
typedef U8 ELF_Data;
enum
{
ELF_Data_None = 0,
ELF_Data_2LSB = 1,
ELF_Data_2MSB = 2,
};
typedef U32 ELF_PType;
enum
{
ELF_PType_Null = 0,
ELF_PType_Load = 1,
ELF_PType_Dynamic = 2,
ELF_PType_Interp = 3,
ELF_PType_Note = 4,
ELF_PType_ShLib = 5,
ELF_PType_PHdr = 6,
ELF_PType_Tls = 7,
ELF_PType_LoOs = 0x60000000,
ELF_PType_HiOs = 0x6fffffff,
ELF_PType_LowProc = 0x70000000,
ELF_PType_HighProc = 0x7fffffff,
// specific to Sun
ELF_PType_LowSunW = 0x6ffffffa,
ELF_PType_SunWBSS = 0x6ffffffb,
ELF_PType_GnuEHFrame = 0x6474E550,
ELF_PType_GnuStack = ELF_PType_LoOs + 0x474e550, // frame unwind information
ELF_PType_GnuRelro = ELF_PType_LoOs + 0x474e551, // stack flags
ELF_PType_GnuProperty = ELF_PType_LoOs + 0x474e552, // read-only after relocations
ELF_PType_SunEHFrame = ELF_PType_GnuEHFrame,
};
typedef U32 ELF_PFlag;
enum
{
ELF_PFlag_Exec = (1 << 0),
ELF_PFlag_Write = (1 << 1),
ELF_PFlag_Read = (1 << 2),
};
typedef U32 ELF_SectionCode;
enum
{
ELF_SectionCode_Null = 0,
ELF_SectionCode_ProgBits = 1,
ELF_SectionCode_Symtab = 2,
ELF_SectionCode_Strtab = 3,
ELF_SectionCode_Rela = 4,
ELF_SectionCode_Hash = 5,
ELF_SectionCode_Dynamic = 6,
ELF_SectionCode_Note = 7,
ELF_SectionCode_NoBits = 8,
ELF_SectionCode_Rel = 9,
ELF_SectionCode_Shlib = 10,
ELF_SectionCode_Dynsym = 11,
ELF_SectionCode_InitArray = 14,
ELF_SectionCode_FiniArray = 15, // Array of ptrs to init functions
ELF_SectionCode_PreinitArray = 16, // Array of ptrs to finish functions
ELF_SectionCode_Group = 17, // Array of ptrs to pre-init funcs
ELF_SectionCode_SymtabShndx = 18, // Section contains a section group
ELF_SectionCode_GNU_IncrementalInputs = 0x6fff4700, // Indices for SHN_XINDEX entries
ELF_SectionCode_GNU_Attributes = 0x6ffffff5, // Incremental build data
ELF_SectionCode_GNU_Hash = 0x6ffffff6, // Object attributes
ELF_SectionCode_GNU_LibList = 0x6ffffff7, // GNU style symbol hash table
ELF_SectionCode_SUNW_verdef = 0x6ffffffd,
ELF_SectionCode_SUNW_verneed = 0x6ffffffe, // Versions defined by file
ELF_SectionCode_SUNW_versym = 0x6fffffff, // Versions needed by file
// Symbol versions
ELF_SectionCode_GNU_verdef = ELF_SectionCode_SUNW_verdef,
ELF_SectionCode_GNU_verneed = ELF_SectionCode_SUNW_verneed,
ELF_SectionCode_GNU_versym = ELF_SectionCode_SUNW_versym,
ELF_SectionCode_Proc,
ELF_SectionCode_User,
};
typedef U32 ELF_SectionIndex;
enum
{
ELF_SectionIndex_Undef = 0, // Symbol with section index is undefined and must be resolved by the link editor
ELF_SectionIndex_Abs = 0xfff1, // Symbol has absolute value and wont change after relocations
ELF_SectionIndex_Common = 0xfff2, // This symbol indicates to linker to allocate the storage at address multiple of st_value
ELF_SectionIndex_LoReserve = 0xff00,
ELF_SectionIndex_HiReserve = 0xffff,
// Processor specific
ELF_SectionIndex_LoProc = ELF_SectionIndex_LoReserve,
ELF_SectionIndex_HiProc = 0xff1f,
// Reserved for OS
ELF_SectionIndex_LoOs = 0xff20,
ELF_SectionIndex_HiOs = 0xff3f,
ELF_SectionIndex_IA64_ASNI_Common = ELF_SectionIndex_LoProc,
ELF_SectionIndex_X8664_LCommon = 0xff02,
ELF_SectionIndex_MIPS_SCommon = 0xff03,
ELF_SectionIndex_TIC6X_Common = ELF_SectionIndex_LoReserve,
ELF_SectionIndex_MIPS_SUndefined = 0xff04,
};
typedef U32 ELF_SectionFlag;
enum
{
ELF_Shf_Write = (1 << 0),
ELF_Shf_Alloc = (1 << 1),
ELF_Shf_ExecInstr = (1 << 2),
ELF_Shf_Merge = (1 << 4),
ELF_Shf_Strings = (1 << 5),
ELF_Shf_InfoLink = (1 << 6),
ELF_Shf_LinkOrder = (1 << 7),
ELF_Shf_OsNonConforming = (1 << 8),
ELF_Shf_Group = (1 << 9),
ELF_Shf_Tls = (1 << 10),
ELF_Shf_Compressed = (1 << 11),
ELF_Shf_MaskOs_Shift = 16, ELF_Shf_MaskOs_Mask = 0xff,
ELF_Shf_AMD64Large = (1 << 28),
ELF_Shf_Ordered = (1 << 30),
ELF_Shf_Exclude = (1 << 31),
ELF_Shf_MaskProc_Shift = 28, ELF_Shf_MaskProc_Mask = 0xf,
};
#define ELF_SectionFlag_Extract_MaskOs(f) (U8)(((f) >> ELF_SectionFlag_MaskOs_Shift) & ELF_SectionFlag_MaskOs_Mask)
#define ELF_SectionFlag_Extract_MaskProc(f) (U8)(((f) >> ELF_SectionFlag_MaskProc_shift) & ELF_SectionFlag_MaskProc_Mask)
typedef U32 ELF_AuxType;
enum
{
ELF_AuxType_Null = 0,
ELF_AuxType_Phdr = 3, // program headers
ELF_AuxType_Phent = 4, // size of a program header
ELF_AuxType_Phnum = 5, // number of program headers
ELF_AuxType_Pagesz = 6, // system page size
ELF_AuxType_Base = 7, // interpreter base address
ELF_AuxType_Flags = 8,
ELF_AuxType_Entry = 9, // program entry point
ELF_AuxType_Uid = 11,
ELF_AuxType_Euid = 12,
ELF_AuxType_Gid = 13,
ELF_AuxType_Egid = 14,
ELF_AuxType_Platform = 15,
ELF_AuxType_Hwcap = 16,
ELF_AuxType_Clktck = 17,
ELF_AuxType_DCacheBSize = 19,
ELF_AuxType_ICacheBSize = 20,
ELF_AuxType_UCacheBSize = 21,
ELF_AuxType_IgnorePPC = 22,
ELF_AuxType_Secure = 23,
ELF_AuxType_BasePlatform = 24,
ELF_AuxType_Random = 25,
ELF_AuxType_Hwcap2 = 26, // addres to 16 random bytes
ELF_AuxType_ExecFn = 31,
ELF_AuxType_SysInfo = 32, // file name of executable
ELF_AuxType_SysInfoEhdr = 33,
ELF_AuxType_L1I_CacheSize = 40,
ELF_AuxType_L1I_CacheGeometry = 41,
ELF_AuxType_L1D_CacheSize = 42,
ELF_AuxType_L1D_CacheGeometry = 43,
ELF_AuxType_L2_CacheSize = 44,
ELF_AuxType_L2_CacheGeometry = 45,
ELF_AuxType_L3_CacheSize = 46,
ELF_AuxType_L3_CacheGeometry = 47,
};
typedef U32 ELF_DynTag;
enum
{
ELF_DynTag_Null = 0,
ELF_DynTag_Needed = 1,
ELF_DynTag_PltRelsz = 2,
ELF_DynTag_PltGot = 3,
ELF_DynTag_Hash = 4,
ELF_DynTag_Strtab = 5,
ELF_DynTag_Symtab = 6,
ELF_DynTag_Rela = 7,
ELF_DynTag_Relasz = 8,
ELF_DynTag_Relaent = 9,
ELF_DynTag_Strsz = 10,
ELF_DynTag_Syment = 11,
ELF_DynTag_Init = 12,
ELF_DynTag_Fini = 13,
ELF_DynTag_SoName = 14,
ELF_DynTag_RPath = 15,
ELF_DynTag_Symbolic = 16,
ELF_DynTag_Rel = 17,
ELF_DynTag_Relsz = 18,
ELF_DynTag_Relent = 19,
ELF_DynTag_Pltrel = 20,
ELF_DynTag_Debug = 21,
ELF_DynTag_TextRel = 22,
ELF_DynTag_JmpRel = 23,
ELF_DynTag_BindNow = 24,
ELF_DynTag_InitArray = 25,
ELF_DynTag_FiniArray = 26,
ELF_DynTag_InitArraysz = 27,
ELF_DynTag_FIniArraysz = 28,
ELF_DynTag_RunPath = 29,
ELF_DynTag_Flags = 30,
ELF_DynTag_PreInitArray = 32,
ELF_DynTag_PreInitArraysz = 33,
ELF_DynTag_SymtabShndx = 34,
ELF_DynTag_LoOs = 0x6000000D,
ELF_DynTag_HiOs = 0x6ffff000,
ELF_DynTag_ValRngLo = 0x6ffffd00,
ELF_DynTag_GNU_PreLinked = 0x6ffffdf5,
ELF_DynTag_GNU_Conflictsz = 0x6ffffdf6,
ELF_DynTag_GNU_LibListsz = 0x6ffffdf7,
ELF_DynTag_Checksum = 0x6ffffdf8,
ELF_DynTag_Pltpadsz = 0x6ffffdf9,
ELF_DynTag_Moveent = 0x6ffffdfa,
ELF_DynTag_Movesz = 0x6ffffdfb,
ELF_DynTag_Feature = 0x6ffffdfc,
ELF_DynTag_PosFlag_1 = 0x6ffffdfd,
ELF_DynTag_SymInSz = 0x6ffffdfe,
ELF_DynTag_SymInEnt = 0x6ffffdff,
ELF_DynTag_ValRngHi = ELF_DynTag_SymInEnt,
ELF_DynTag_AddrRngLo = 0x6ffffe00,
ELF_DynTag_GNU_Hash = 0x6ffffef5,
ELF_DynTag_TlsDescPlt = 0x6ffffef6,
ELF_DynTag_TlsDescGot = 0x6ffffef7,
ELF_DynTag_GNU_Conflict = 0x6ffffef8,
ELF_DynTag_GNU_LibList = 0x6ffffef9,
ELF_DynTag_Config = 0x6ffffefa,
ELF_DynTag_DepAudit = 0x6ffffefb,
ELF_DynTag_Audit = 0x6ffffefc,
ELF_DynTag_PltPad = 0x6ffffefd,
ELF_DynTag_MoveTab = 0x6ffffefe,
ELF_DynTag_SymInfo = 0x6ffffeff,
ELF_DynTag_AddrRngHi = ELF_DynTag_SymInfo,
ELF_DynTag_RelaCount = 0x6ffffff9,
ELF_DynTag_RelCount = 0x6ffffffa,
ELF_DynTag_Flags_1 = 0x6ffffffb,
ELF_DynTag_VerDef = 0x6ffffffc,
ELF_DynTag_VerDefNum = 0x6ffffffd,
ELF_DynTag_VerNeed = 0x6ffffffe,
ELF_DynTag_VerNeedNum = 0x6fffffff,
ELF_DynTag_VerSym = 0x6ffffff0,
ELF_DynTag_LoProc = 0x70000000,
ELF_DynTag_HiProc = 0x7fffffff,
};
typedef U32 ELF_DynFlag;
enum
{
ELF_DynFlag_Origin = (1 << 0),
ELF_DynFlag_Symbolic = (1 << 1),
ELF_DynFlag_TextTel = (1 << 2),
ELF_DynFlag_BindNow = (1 << 3),
ELF_DynFlag_StaticTls = (1 << 4),
};
typedef U32 ELF_DynFeatureFlag;
enum
{
ELF_DynFeatureFlag_ParInit = (1 << 0),
ELF_DynFeatureFlag_ConfExp = (1 << 1),
};
typedef U8 ELF_SymBind;
enum
{
// the same name may exists in multiple files without interfering with each other.
ELF_SymBind_Local = 0,
// Visible to all objects that are linked together.
ELF_SymBind_Global = 1,
// If there is a global symbol with identical name linker doesn't issue an error.
ELF_SymBind_Weak = 2,
ELF_SymBind_LoProc = 13,
ELF_SymBind_HiProc = 15,
};
typedef U8 ELF_SymType;
enum
{
ELF_SymType_NoType = 0,
// Type is not specified.
ELF_SymType_Object = 1,
// Symbol is associated with data object, such as a variable, an array, etc.
ELF_SymType_Func = 2,
// Symbol is associated with a function.
ELF_SymType_Section = 3,
// Symbol is used to relocate sections and normally have LOCAL binding.
ELF_SymType_File = 4,
// Gives name of the source file associated with object.
ELF_SymType_Common = 5,
ELF_SymType_Tls = 6,
ELF_SymType_LoProc = 13,
ELF_SymType_HiProc = 15,
};
typedef U8 ELF_SymVisibility;
enum
{
ELF_SymVisibility_Default = 0,
ELF_SymVisibility_Internal = 1,
ELF_SymVisibility_Hidden = 2,
ELF_SymVisibility_Protected = 3,
};
typedef U32 ELF_RelocI386;
enum
{
ELF_RelocI386_None = 0,
ELF_RelocI386_32 = 1,
ELF_RelocI386_PC32 = 2,
ELF_RelocI386_GOT32 = 3,
ELF_RelocI386_PLT32 = 4,
ELF_RelocI386_Copy = 5,
ELF_RelocI386_GlobDat = 6,
ELF_RelocI386_JumpSlot = 7,
ELF_RelocI386_Relative = 8,
ELF_RelocI386_GotOff = 9,
ELF_RelocI386_GotPc = 10,
ELF_RelocI386_32Plt = 11,
ELF_RelocI386_Tls_tpoff = 14,
ELF_RelocI386_Tls_ie = 15,
ELF_RelocI386_Tls_gotie = 16,
ELF_RelocI386_Tls_le = 17,
ELF_RelocI386_Tls_gd = 18,
ELF_RelocI386_Tls_ldm = 19,
ELF_RelocI386_16 = 20,
ELF_RelocI386_PC16 = 21,
ELF_RelocI386_8 = 22,
ELF_RelocI386_Pc8 = 23,
ELF_RelocI386_TlsGd32 = 24,
ELF_RelocI386_TlsGdPush = 25,
ELF_RelocI386_TlsGdCall = 26,
ELF_RelocI386_TlsGdPop = 27,
ELF_RelocI386_TlsLdm32 = 28,
ELF_RelocI386_TlsLdmPush = 29,
ELF_RelocI386_TlsLdmCall = 30,
ELF_RelocI386_TlsLdmPop = 31,
ELF_RelocI386_TlsLdo32 = 32,
ELF_RelocI386_TlsIe32 = 33,
ELF_RelocI386_TlsLe32 = 34,
ELF_RelocI386_TlsDtpmod32 = 35,
ELF_RelocI386_TlsDtpoff32 = 36,
ELF_RelocI386_TlsTpoff32 = 37,
// 38 is not taken
ELF_RelocI386_TlsGotDesc = 39,
ELF_RelocI386_TlsDescCall = 40,
ELF_RelocI386_TlsDesc = 41,
ELF_RelocI386_IRelative = 42,
ELF_RelocI386_Gotx32x = 43,
ELF_RelocI386_UsedByIntel200 = 200,
ELF_RelocI386_GNU_VTInherit = 250,
ELF_RelocI386_GNU_VTEntry = 251,
};
typedef U32 ELF_RelocX8664;
enum
{
ELF_RelocX8664_None = 0,
ELF_RelocX8664_64 = 1,
ELF_RelocX8664_Pc32 = 2,
ELF_RelocX8664_Got32 = 3,
ELF_RelocX8664_Plt32 = 4,
ELF_RelocX8664_Copy = 5,
ELF_RelocX8664_GlobDat = 6,
ELF_RelocX8664_JumpSlot = 7,
ELF_RelocX8664_Relative = 8,
ELF_RelocX8664_GotPcRel = 9,
ELF_RelocX8664_32 = 10,
ELF_RelocX8664_32S = 11,
ELF_RelocX8664_16 = 12,
ELF_RelocX8664_Pc16 = 13,
ELF_RelocX8664_8 = 14,
ELF_RelocX8664_Pc8 = 15,
ELF_RelocX8664_DtpMod64 = 16,
ELF_RelocX8664_DtpOff64 = 17,
ELF_RelocX8664_TpOff64 = 18,
ELF_RelocX8664_TlsGd = 19,
ELF_RelocX8664_TlsLd = 20,
ELF_RelocX8664_DtpOff32 = 21,
ELF_RelocX8664_GotTpOff = 22,
ELF_RelocX8664_TpOff32 = 23,
ELF_RelocX8664_Pc64 = 24,
ELF_RelocX8664_GotOff64 = 25,
ELF_RelocX8664_GotPc32 = 26,
ELF_RelocX8664_Got64 = 27,
ELF_RelocX8664_GotPcRel64 = 28,
ELF_RelocX8664_GotPc64 = 29,
ELF_RelocX8664_GotPlt64 = 30,
ELF_RelocX8664_PltOff64 = 31,
ELF_RelocX8664_Size32 = 32,
ELF_RelocX8664_Size64 = 33,
ELF_RelocX8664_GotPc32TlsDesc = 34,
ELF_RelocX8664_TlsDescCall = 35,
ELF_RelocX8664_TlsDesc = 36,
ELF_RelocX8664_IRelative = 37,
ELF_RelocX8664_Relative64 = 38,
ELF_RelocX8664_Pc32Bnd = 39,
ELF_RelocX8664_Plt32Bnd = 40,
ELF_RelocX8664_GotPcRelx = 41,
ELF_RelocX8664_RexGotPcRelx = 42,
ELF_RelocX8664_GNU_VTInherit = 250,
ELF_RelocX8664_GNU_VTEntry = 251,
};
typedef U32 ELF_ExternalVerFlag;
enum
{
ELF_ExternalVerFlag_Base = (1 << 0),
ELF_ExternalVerFlag_Weak = (1 << 1),
ELF_ExternalVerFlag_Info = (1 << 2),
};
typedef U32 ELF_NoteType;
enum
{
ELF_NoteType_GNU_Abi = 1,
ELF_NoteType_GNU_HwCap = 2,
ELF_NoteType_GNU_BuildId = 3,
ELF_NoteType_GNU_GoldVersion = 4,
ELF_NoteType_GNU_PropertyType0 = 5,
};
typedef U32 ELF_GnuABITag;
enum
{
ELF_GnuABITag_Linux = 0,
ELF_GnuABITag_Hurd = 1,
ELF_GnuABITag_Solaris = 2,
ELF_GnuABITag_FreeBsd = 3,
ELF_GnuABITag_NetBsd = 4,
ELF_GnuABITag_Syllable = 5,
ELF_GnuABITag_Nacl = 6,
};
typedef S32 ELF_GnuProperty;
enum
{
ELF_GnuProperty_LoProc = 0xc0000000,
// processor-specific range
ELF_GnuProperty_HiProc = 0xdfffffff,
ELF_GnuProperty_LoUser = 0xe0000000,
// application-specific range
ELF_GnuProperty_HiUser = 0xffffffff,
ELF_GnuProperty_StackSize = 1,
ELF_GnuProperty_NoCopyOnProtected = 2,
};
typedef U32 ELF_GnuPropertyX86Isa1;
enum
{
ELF_GnuPropertyX86Isa1_BaseLine = (1 << 0),
ELF_GnuPropertyX86Isa1_V2 = (1 << 1),
ELF_GnuPropertyX86Isa1_V3 = (1 << 2),
ELF_GnuPropertyX86Isa1_V4 = (1 << 3),
};
typedef U32 ELF_GnuPropertyX86Compat1Isa1;
enum
{
ELF_GnuPropertyX86Compat1Isa1_486 = (1 << 0),
ELF_GnuPropertyX86Compat1Isa1_586 = (1 << 1),
ELF_GnuPropertyX86Compat1Isa1_686 = (1 << 2),
ELF_GnuPropertyX86Compat1Isa1_SSE = (1 << 3),
ELF_GnuPropertyX86Compat1Isa1_SSE2 = (1 << 4),
ELF_GnuPropertyX86Compat1Isa1_SSE3 = (1 << 5),
ELF_GnuPropertyX86Compat1Isa1_SSSE3 = (1 << 6),
ELF_GnuPropertyX86Compat1Isa1_SSE4_1 = (1 << 7),
ELF_GnuPropertyX86Compat1Isa1_SSE4_2 = (1 << 8),
ELF_GnuPropertyX86Compat1Isa1_AVX = (1 << 9),
ELF_GnuPropertyX86Compat1Isa1_AVX2 = (1 << 10),
ELF_GnuPropertyX86Compat1Isa1_AVX512F = (1 << 11),
ELF_GnuPropertyX86Compat1Isa1_AVX512ER = (1 << 12),
ELF_GnuPropertyX86Compat1Isa1_AVX512PF = (1 << 13),
ELF_GnuPropertyX86Compat1Isa1_AVX512VL = (1 << 14),
ELF_GnuPropertyX86Compat1Isa1_AVX512DQ = (1 << 15),
ELF_GnuPropertyX86Compat1Isa1_AVX512BW = (1 << 16),
};
typedef U32 ELF_GnuPropertyX86Compat2Isa1;
enum
{
ELF_GnuPropertyX86Compat2Isa1_CMOVE = (1 << 0),
ELF_GnuPropertyX86Compat2Isa1_SSE = (1 << 1),
ELF_GnuPropertyX86Compat2Isa1_SSE2 = (1 << 2),
ELF_GnuPropertyX86Compat2Isa1_SSE3 = (1 << 3),
ELF_GnuPropertyX86Compat2Isa1_SSE4_1 = (1 << 4),
ELF_GnuPropertyX86Compat2Isa1_SSE4_2 = (1 << 5),
ELF_GnuPropertyX86Compat2Isa1_AVX = (1 << 6),
ELF_GnuPropertyX86Compat2Isa1_AVX2 = (1 << 7),
ELF_GnuPropertyX86Compat2Isa1_FMA = (1 << 8),
ELF_GnuPropertyX86Compat2Isa1_AVX512F = (1 << 9),
ELF_GnuPropertyX86Compat2Isa1_AVX512CD = (1 << 10),
ELF_GnuPropertyX86Compat2Isa1_AVX512ER = (1 << 11),
ELF_GnuPropertyX86Compat2Isa1_AVX512PF = (1 << 12),
ELF_GnuPropertyX86Compat2Isa1_AVX512VL = (1 << 13),
ELF_GnuPropertyX86Compat2Isa1_AVX512DQ = (1 << 14),
ELF_GnuPropertyX86Compat2Isa1_AVX512BW = (1 << 15),
ELF_GnuPropertyX86Compat2Isa1_AVX512_4FMAPS = (1 << 16),
ELF_GnuPropertyX86Compat2Isa1_AVX512_4VNNIW = (1 << 17),
ELF_GnuPropertyX86Compat2Isa1_AVX512_BITALG = (1 << 18),
ELF_GnuPropertyX86Compat2Isa1_AVX512_IFMA = (1 << 19),
ELF_GnuPropertyX86Compat2Isa1_AVX512_VBMI = (1 << 20),
ELF_GnuPropertyX86Compat2Isa1_AVX512_VBMI2 = (1 << 21),
ELF_GnuPropertyX86Compat2Isa1_AVX512_VNNI = (1 << 22),
ELF_GnuPropertyX86Compat2Isa1_AVX512_BF16 = (1 << 23),
};
typedef S32 ELF_GnuPropertyX86;
enum
{
ELF_GnuPropertyX86_Feature1And = 0xc0000002,
ELF_GnuPropertyX86_Feature2Used = 0xc0010001,
ELF_GnuPropertyX86_Isa1needed = 0xc0008002,
ELF_GnuPropertyX86_Isa2Needed = 0xc0008001,
ELF_GnuPropertyX86_Isa1Used = 0xc0010002,
ELF_GnuPropertyX86_Compat_isa_1_used = 0xc0000000,
ELF_GnuPropertyX86_Compat_isa_1_needed = 0xc0000001,
ELF_GnuPropertyX86_UInt32AndLo = ELF_GnuPropertyX86_Feature1And,
ELF_GnuPropertyX86_UInt32AndHi = 0xc0007fff,
ELF_GnuPropertyX86_UInt32OrLo = 0xc0008000,
ELF_GnuPropertyX86_UInt32OrHi = 0xc000ffff,
ELF_GnuPropertyX86_UInt32OrAndLo = 0xc0010000,
ELF_GnuPropertyX86_UInt32OrAndHi = 0xc0017fff,
};
typedef U32 ELF_GnuPropertyX86Feature1;
enum
{
ELF_GnuPropertyX86Feature1_Ibt = (1 << 0),
ELF_GnuPropertyX86Feature1_Shstk = (1 << 1),
ELF_GnuPropertyX86Feature1_LamU48 = (1 << 2),
ELF_GnuPropertyX86Feature1_LamU57 = (1 << 3),
};
typedef U32 ELF_GnuPropertyX86Feature2;
enum
{
ELF_GnuPropertyX86Feature2_X86 = (1 << 0),
ELF_GnuPropertyX86Feature2_X87 = (1 << 1),
ELF_GnuPropertyX86Feature2_MMX = (1 << 2),
ELF_GnuPropertyX86Feature2_XMM = (1 << 3),
ELF_GnuPropertyX86Feature2_YMM = (1 << 4),
ELF_GnuPropertyX86Feature2_ZMM = (1 << 5),
ELF_GnuPropertyX86Feature2_FXSR = (1 << 6),
ELF_GnuPropertyX86Feature2_XSAVE = (1 << 7),
ELF_GnuPropertyX86Feature2_XSAVEOPT = (1 << 8),
ELF_GnuPropertyX86Feature2_XSAVEC = (1 << 9),
ELF_GnuPropertyX86Feature2_TMM = (1 << 10),
ELF_GnuPropertyX86Feature2_MASK = (1 << 11),
};
#define ELF_HdrIs64Bit(e_ident) (e_ident[ELF_Identifier_Class] == ELF_Class_64)
#define ELF_HdrIs32Bit(e_ident) (e_ident[ELF_Identifier_Class] == ELF_Class_32)
typedef enum ELF_Identifier
{
ELF_Identifier_Mag0 = 0,
ELF_Identifier_Mag1 = 1,
ELF_Identifier_Mag2 = 2,
ELF_Identifier_Mag3 = 3,
ELF_Identifier_Class = 4,
ELF_Identifier_Data = 5,
ELF_Identifier_Version = 6,
ELF_Identifier_OsAbi = 7,
ELF_Identfiier_AbiBersion = 8,
ELF_Identifier_Max = 16,
} ELF_Identifier;
typedef U16 ELF_Type;
typedef enum ELF_TypeEnum
{
ELF_Type_None = 0,
ELF_Type_Rel = 1,
ELF_Type_Exec = 2,
ELF_Type_Dyn = 3,
ELF_Type_Core = 4,
ELF_Type_LoOs = 0xfe00,
ELF_Type_HiOs = 0xfeff,
ELF_Type_LoProc = 0xff00,
ELF_Type_HiProc = 0xffff,
} ELF_TypeEnum;
typedef struct ELF_Hdr64
{
U8 e_ident[ELF_Identifier_Max];
ELF_Type e_type;
ELF_MachineKind e_machine;
U32 e_version;
U64 e_entry;
U64 e_phoff;
U64 e_shoff;
U32 e_flags;
U16 e_ehsize;
U16 e_phentsize;
U16 e_phnum;
U16 e_shentsize;
U16 e_shnum;
U16 e_shstrndx;
} ELF_Hdr64;
typedef struct ELF_Hdr32
{
U8 e_ident[ELF_Identifier_Max];
ELF_Type e_type;
ELF_MachineKind e_machine;
U32 e_version;
U32 e_entry;
U32 e_phoff;
U32 e_shoff;
U32 e_flags;
U16 e_ehsize;
U16 e_phentsize;
U16 e_phnum;
U16 e_shentsize;
U16 e_shnum;
U16 e_shstrndx;
} ELF_Hdr32;
typedef struct ELF_Shdr64
{
U32 sh_name;
U32 sh_type;
U64 sh_flags;
U64 sh_addr;
U64 sh_offset;
U64 sh_size;
U32 sh_link;
U32 sh_info;
U64 sh_addralign;
U64 sh_entsize;
} ELF_Shdr64;
typedef struct ELF_Shdr32
{
U32 sh_name;
U32 sh_type;
U32 sh_flags;
U32 sh_addr;
U32 sh_offset;
U32 sh_size;
U32 sh_link;
U32 sh_info;
U32 sh_addralign;
U32 sh_entsize;
} ELF_Shdr32;
typedef struct ELF_Phdr64
{
U32 p_type;
U32 p_flags;
U64 p_offset;
U64 p_vaddr;
U64 p_paddr;
U64 p_filesz;
U64 p_memsz;
U64 p_align;
} ELF_Phdr64;
typedef struct ELF_Phdr32
{
U32 p_type;
U32 p_offset;
U32 p_vaddr;
U32 p_paddr;
U32 p_filesz;
U32 p_memsz;
U32 p_flags;
U32 p_align;
} ELF_Phdr32;
////////////////////////////////
// Auxiliary Vectors
// these appear in /proc/<pid>/auxv of a process, they are not in elf files
typedef struct ELF_Auxv32
{
U32 a_type;
U32 a_val;
} ELF_Auxv32;
typedef struct ELF_Auxv64
{
U64 a_type;
U64 a_val;
} ELF_Auxv64;
////////////////////////////////
// Dynamic Structures
// these appear in the virtual address space of a process, they are not in elf files
typedef struct ELF_Dyn32
{
U32 tag;
U32 val;
} ELF_Dyn32;
typedef struct ELF_Dyn64
{
U64 tag;
U64 val;
} ELF_Dyn64;
typedef struct ELF_LinkMap32
{
U32 base;
U32 name;
U32 ld;
U32 next;
} ELF_LinkMap32;
typedef struct ELF_LinkMap64
{
U64 base;
U64 name;
U64 ld;
U64 next;
} ELF_LinkMap64;
////////////////////////////////
// Imports and Exports
typedef struct
{
U32 st_name; // Holds index into files string table.
U32 st_value; // Depending on the context, this may be address, size, etc.
U32 st_size; // Data size in bytes. Zero when size is unknown.
U8 st_info; // Contains symbols type and binding.
U8 st_other; // Reserved for future use, currenly zero.
U16 st_shndx; // Section index to which symbol is relevant.
} ELF_Sym32;
typedef struct
{
U32 st_name;
U8 st_info;
U8 st_other;
U16 st_shndx;
U64 st_value;
U64 st_size;
} ELF_Sym64;
#define ELF_ST_INFO(b,t) (((b) << 4) + ((t) & 0xF))
#define ELF_ST_BIND(x) ((x) >> 4)
#define ELF_ST_TYPE(x) ((x) & 0xF)
#define ELF_ST_VISIBILITY(v) ((v) & 0x3)
typedef struct
{
U32 r_offset;
U32 r_info;
} ELF_Rel32;
typedef struct
{
U32 r_offset;
U32 r_info;
S32 r_addend;
} ELF_Rela32;
typedef struct
{
U64 r_offset;
U64 r_info;
} ELF_Rel64;
typedef struct
{
U64 r_offset;
U64 r_info;
S64 r_addend;
} ELF_Rela64;
#define ELF32_R_SYM(x) ((x) >> 8)
#define ELF32_R_TYPE(x) ((x) & 0xFF)
#define ELF64_R_INFO(s,t) (((U64)(s) << 32) | (U64)t)
#define ELF64_R_SYM(x) ((x) >> 32)
#define ELF64_R_TYPE(x) ((x) & 0xffffffff)
// This flag is set to indicate that symbol is not available outside shared object
#define ELF_EXTERNAL_VERSYM_HIDDEN 0x8000
#define ELF_EXTERNAL_VERSYM_MASK 0x7FFF
// Appears in .gnu.verdef (SHT_GNU_verdef)
typedef struct
{
U16 vd_version;
U16 vd_flags;
U16 vd_ndx;
U16 vd_cnt;
U32 vd_hash;
U32 vd_aux;
U32 vd_next;
} ELF_ExternalVerdef;
// Appears in .gnu.verdef (SHT_GNU_verdef)
typedef struct
{
U32 vda_name;
U32 vda_next;
} ELF_ExternalVerdaux;
// Appears in .gnu.verneed (SHT_GNU_verneed)
typedef struct
{
U16 vn_version;
U16 vn_cnt;
U32 vn_file;
U32 vn_aux;
U32 vn_next;
} ELF_ExternalVerneed;
// Appears in .gnu.verneed (SHT_GNU_verneed)
typedef struct
{
U32 vna_hash;
U16 vna_flags;
U16 vna_other;
U32 vna_name;
U32 vna_next;
} ELF_ExternalVernaux;
// Appears in .gnu.version (SHT_GNU_versym)
typedef struct
{
U16 vs_vers;
} ELF_ExternalVersym;
typedef struct
{
U32 name_size;
U32 desc_size;
U32 type;
// name + desc
// U8 data[1];
} ELF_Note;
////////////////////////////////
// Extensions
typedef U8 ELF_CompressType;
enum ELF_CompressTypeEnum
{
ELF_CompressType_None = 0,
ELF_CompressType_ZLib = 1,
ELF_CompressType_ZStd = 2,
ELF_CompressType_LoOs = 0x60000000,
ELF_CompressType_HiOs = 0x6fffffff,
ELF_CompressType_LoProc = 0x70000000,
ELF_CompressType_HiProc = 0x7fffffff,
};
typedef struct ELF_Chdr32
{
U32 ch_type;
U32 ch_size;
U32 ch_addr_align;
} ELF_Chdr32;
typedef struct ELF_Chdr64
{
U64 ch_type;
U64 ch_size;
U64 ch_addr_align;
} ELF_Chdr64;
////////////////////////////////
internal ELF_Hdr64 elf_hdr64_from_ehdr32(ELF_Hdr32 h32);
internal ELF_Shdr64 elf_shdr64_from_shdr32(ELF_Shdr32 h32);
internal ELF_Phdr64 elf_phdr64_from_phdr32(ELF_Phdr32 h32);
internal ELF_Dyn64 elf_dyn64_from_dyn32 (ELF_Dyn32 h32);
internal ELF_Sym64 elf_sym64_from_sym32 (ELF_Sym32 sym32);
internal ELF_Rel64 elf_rel64_from_rel32 (ELF_Rel32 rel32);
internal ELF_Rela64 elf_rela64_from_rela32(ELF_Rela32 rela32);
internal ELF_Chdr64 elf_chdr64_from_chdr32(ELF_Chdr32 chdr32);
////////////////////////////////
internal String8 elf_string_from_class(Arena *arena, ELF_Class v);
////////////////////////////////
internal Arch arch_from_elf_machine(ELF_MachineKind machine);
#endif // ELF_H
+143
View File
@@ -0,0 +1,143 @@
// Copyright (c) 2025 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal B32
elf_check_magic(String8 data)
{
U8 sig[ELF_Identifier_Max] = {0};
str8_deserial_read(data, 0, &sig[0], sizeof(sig), 1);
B32 is_magic_valid = (sig[ELF_Identifier_Mag0] == 0x7f && sig[ELF_Identifier_Mag1] == 'E' && sig[ELF_Identifier_Mag2] == 'L' && sig[ELF_Identifier_Mag3] == 'F');
return is_magic_valid;
}
internal ELF_BinInfo
elf_bin_from_data(String8 data)
{
ELF_Hdr64 hdr64 = {0};
Rng1U64 sh_name_range = rng_1u64(0,0);
if (elf_check_magic(data)) {
U8 sig[ELF_Identifier_Max] = {0};
str8_deserial_read(data, 0, &sig[0], sizeof(sig), 1);
switch (sig[ELF_Identifier_Class]) {
case ELF_Class_None: break;
case ELF_Class_32: {
ELF_Hdr32 hdr32 = {0};
U64 hdr_size = str8_deserial_read_struct(data, 0, &hdr32);
if (hdr_size == sizeof(hdr32)) {
hdr64 = elf_hdr64_from_hdr32(hdr32);
U64 shstr_off = hdr32.e_shoff + hdr32.e_shentsize*hdr32.e_shstrndx;
ELF_Shdr32 shdr = {0};
U64 shdr_size = str8_deserial_read_struct(data, shstr_off, &shdr);
if (shdr_size == sizeof(shdr)) {
sh_name_range = rng_1u64(shdr.sh_offset, shdr.sh_offset + shdr.sh_size);
}
}
} break;
case ELF_Class_64: {
U64 hdr_size = str8_deserial_read_struct(data, 0, &hdr64);
if (hdr_size == sizeof(hdr64)) {
U64 shstr_off = hdr64.e_shoff + hdr64.e_shentsize*hdr64.e_shstrndx;
ELF_Shdr64 shdr = {0};
U64 shdr_size = str8_deserial_read_struct(data, shstr_off, &shdr);
if (shdr_size == sizeof(shdr)) {
sh_name_range = rng_1u64(shdr.sh_offset, shdr.sh_offset + shdr.sh_size);
}
}
} break;
default: Assert(!"invalid elf header"); break;
}
}
ELF_BinInfo info = {0};
info.hdr = hdr64;
info.sh_name_range = sh_name_range;
return info;
}
internal ELF_Shdr64Array
elf_shdr64_array_from_bin(Arena *arena, String8 raw_data, ELF_Hdr64 *hdr)
{
Rng1U64 shdr_range = rng_1u64(hdr->e_shoff, hdr->e_shoff + hdr->e_shentsize*hdr->e_shnum);
String8 shdr_data = str8_substr(raw_data, shdr_range);
ELF_Shdr64Array result = {0};
result.count = hdr->e_shnum;
result.v = push_array(arena, ELF_Shdr64, hdr->e_shnum);
for(U64 shdr_idx = 0; shdr_idx < hdr->e_shnum; ++shdr_idx) {
switch (hdr->e_ident[ELF_Identifier_Class]) {
case ELF_Class_None: break;
case ELF_Class_32: {
ELF_Shdr32 shdr32 = {0};
str8_deserial_read_struct(shdr_data, shdr_idx * sizeof(ELF_Shdr32), &shdr32);
result.v[shdr_idx] = elf_shdr64_from_shdr32(shdr32);
} break;
case ELF_Class_64: {
str8_deserial_read_struct(shdr_data, shdr_idx * sizeof(ELF_Shdr64), &result.v[shdr_idx]);
} break;
default: InvalidPath; break;
}
}
return result;
}
internal String8
elf_name_from_shdr64(String8 raw_data, ELF_Hdr64 *hdr, Rng1U64 sh_name_range, ELF_Shdr64 *shdr)
{
String8 sh_names = str8_substr(raw_data, sh_name_range);
String8 name = {0};
str8_deserial_read_cstr(sh_names, shdr->sh_name, &name);
return name;
}
internal U64
elf_base_addr_from_bin(ELF_Hdr64 *hdr)
{
NotImplemented;
return 0;
}
internal B32
elf_parse_debug_link(String8 raw_data, ELF_BinInfo *elf, ELF_GnuDebugLink *debug_link_out)
{
Temp scratch = scratch_begin(0,0);
B32 is_debug_link_present = 0;
ELF_Shdr64Array sections = elf_shdr64_array_from_bin(scratch.arena, raw_data, &elf->hdr);
for (U64 i = 0; i < sections.count; ++i) {
ELF_Shdr64 *shdr = &sections.v[i];
String8 name = elf_name_from_shdr64(raw_data, &elf->hdr, elf->sh_name_range, shdr);
if (str8_match(name, str8_lit(".gnu_debuglink"), 0)) {
Rng1U64 raw_data_range = rng_1u64(shdr->sh_offset, shdr->sh_offset + shdr->sh_size);
String8 data = str8_substr(raw_data, raw_data_range);
String8 path = {0};
U32 checksum = 0;
{
U64 cursor = 0;
cursor += str8_deserial_read_cstr(data, cursor, &path);
cursor = AlignPow2(cursor, 4);
cursor += str8_deserial_read_struct(data, cursor, &checksum);
}
debug_link_out->path = path;
debug_link_out->checksum = checksum;
is_debug_link_present = 1;
break;
}
}
scratch_end(scratch);
return is_debug_link_present;
}
+36
View File
@@ -0,0 +1,36 @@
// Copyright (c) 2025 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef ELF_PARSE_H
#define ELF_PARSE_H
////////////////////////////////
typedef struct ELF_BinInfo
{
ELF_Hdr64 hdr;
Rng1U64 sh_name_range;
} ELF_BinInfo;
typedef struct ELF_Shdr64Array
{
U64 count;
ELF_Shdr64 *v;
} ELF_Shdr64Array;
typedef struct ELF_GnuDebugLink
{
String8 path;
U32 checksum;
} ELF_GnuDebugLink;
////////////////////////////////
internal B32 elf_check_magic(String8 data);
internal ELF_BinInfo elf_bin_from_data(String8 data);
internal ELF_Shdr64Array elf_shdr64_array_from_bin(Arena *arena, String8 raw_data, ELF_Hdr64 *hdr);
internal String8 elf_name_from_shdr64(String8 raw_data, ELF_Hdr64 *hdr, Rng1U64 sh_name_range, ELF_Shdr64 *shdr);
internal U64 elf_base_addr_from_bin(ELF_Hdr64 *hdr);
#endif // ELF_PARSE_H
+109 -100
View File
@@ -26,32 +26,32 @@ E_TypeKindTable:
{UChar8 "uchar8" 1 } {UChar8 "uchar8" 1 }
{UChar16 "uchar16" 2 } {UChar16 "uchar16" 2 }
{UChar32 "uchar32" 4 } {UChar32 "uchar32" 4 }
{U8 "U8" 1 } {U8 "uint8" 1 }
{U16 "U16" 2 } {U16 "uint16" 2 }
{U32 "U32" 4 } {U32 "uint32" 4 }
{U64 "U64" 8 } {U64 "uint64" 8 }
{U128 "U128" 16 } {U128 "uint128" 16 }
{U256 "U256" 32 } {U256 "uint256" 32 }
{U512 "U512" 64 } {U512 "uint512" 64 }
{S8 "S8" 1 } {S8 "int8" 1 }
{S16 "S16" 2 } {S16 "int16" 2 }
{S32 "S32" 4 } {S32 "int32" 4 }
{S64 "S64" 8 } {S64 "int64" 8 }
{S128 "S128" 16 } {S128 "int128" 16 }
{S256 "S256" 32 } {S256 "int256" 32 }
{S512 "S512" 64 } {S512 "int512" 64 }
{Bool "bool" 1 } {Bool "bool" 1 }
{F16 "F16" 2 } {F16 "float16" 2 }
{F32 "F32" 4 } {F32 "float32" 4 }
{F32PP "F32PP" 4 } {F32PP "float32PP" 4 }
{F48 "F48" 6 } {F48 "float48" 6 }
{F64 "F64" 8 } {F64 "float64" 8 }
{F80 "F80" 10 } {F80 "float80" 10 }
{F128 "F128" 16 } {F128 "float128" 16 }
{ComplexF32 "ComplexF32" 8 } {ComplexF32 "complex_float32" 8 }
{ComplexF64 "ComplexF64" 16 } {ComplexF64 "complex_float64" 16 }
{ComplexF80 "ComplexF80" 20 } {ComplexF80 "complex_float80" 20 }
{ComplexF128 "ComplexF128" 32 } {ComplexF128 "complex_float128" 32 }
{Modifier "modifier" 0 } {Modifier "modifier" 0 }
{Ptr "ptr" 0 } {Ptr "ptr" 0 }
{LRef "lref" 0 } {LRef "lref" 0 }
@@ -71,68 +71,75 @@ E_TypeKindTable:
{IncompleteEnum "enum" 0 } {IncompleteEnum "enum" 0 }
{Bitfield "bitfield" 0 } {Bitfield "bitfield" 0 }
{Variadic "variadic" 0 } {Variadic "variadic" 0 }
{Collection "collection" 0 } {Set "set" 0 }
{Lens "lens" 0 }
{LensSpec "lens_spec" 0 }
{MetaExpr "meta_expr" 0 }
{MetaDisplayName "meta_display_name" 0 }
{MetaDescription "meta_description" 0 }
} }
@table(name op_kind precedence string op_pre op_sep op_pos) @table(name op_kind precedence op_pre op_sep op_pos op_chain)
E_ExprKindTable: E_ExprKindTable:
{ {
{ Nil Null 0 "" "" "" "" } { Nil Null 0 "" "" "" "" }
{ Ref Null 0 "" "" "" "" } { Ref Null 0 "" "" "" "" }
{ ArrayIndex Null 0 "[]" "" "[" "]"} { ArrayIndex Null 0 "" "[" "]" "" }
{ MemberAccess Null 0 "." "" "." "" } { MemberAccess Null 0 "" "." "" "" }
{ Deref UnaryPrefix 2 "*" "*" "" "" } { Deref UnaryPrefix 2 "*" "" "" "" }
{ Address UnaryPrefix 2 "&" "&" "" "" } { Address UnaryPrefix 2 "&" "" "" "" }
{ Cast Null 1 "cast" "(" ")" "" } { Cast Null 1 "cast(" ")" "" "" }
{ Sizeof UnaryPrefix 1 "sizeof" "sizeof" "(" ")"} { Sizeof UnaryPrefix 1 "sizeof " "" "" "" }
{ Typeof UnaryPrefix 1 "typeof" "typeof" "(" ")"} { Typeof UnaryPrefix 1 "typeof " "" "" "" }
{ ByteSwap UnaryPrefix 1 "bswap" "bswap" "(" ")"} { ByteSwap UnaryPrefix 1 "bswap " "" "" "" }
{ Pos UnaryPrefix 2 "+" "+" "" "" } { Pos UnaryPrefix 2 "+" "" "" "" }
{ Neg UnaryPrefix 2 "-" "-" "" "" } { Neg UnaryPrefix 2 "-" "" "" "" }
{ LogNot UnaryPrefix 2 "!" "!" "" "" } { LogNot UnaryPrefix 2 "!" "" "" "" }
{ BitNot UnaryPrefix 2 "~" "~" "" "" } { BitNot UnaryPrefix 2 "~" "" "" "" }
{ Mul Binary 3 "*" "" "*" "" } { Mul Binary 3 "" " * " "" "" }
{ Div Binary 3 "/" "" "/" "" } { Div Binary 3 "" " / " "" "" }
{ Mod Binary 3 "%" "" "%" "" } { Mod Binary 3 "" " % " "" "" }
{ Add Binary 4 "+" "" "+" "" } { Add Binary 4 "" " + " "" "" }
{ Sub Binary 4 "-" "" "-" "" } { Sub Binary 4 "" " - " "" "" }
{ LShift Binary 5 "<<" "" "<<" "" } { LShift Binary 5 "" " << " "" "" }
{ RShift Binary 5 ">>" "" ">>" "" } { RShift Binary 5 "" " >> " "" "" }
{ Less Binary 6 "<" "" "<" "" } { Less Binary 6 "" " < " "" "" }
{ LsEq Binary 6 "<=" "" "<=" "" } { LsEq Binary 6 "" " <= " "" "" }
{ Grtr Binary 6 ">" "" ">" "" } { Grtr Binary 6 "" " > " "" "" }
{ GrEq Binary 6 ">=" "" ">=" "" } { GrEq Binary 6 "" " >= " "" "" }
{ EqEq Binary 7 "==" "" "==" "" } { EqEq Binary 7 "" " == " "" "" }
{ NtEq Binary 7 "!=" "" "!=" "" } { NtEq Binary 7 "" " != " "" "" }
{ BitAnd Binary 8 "&" "" "&" "" } { BitAnd Binary 8 "" " & " "" "" }
{ BitXor Binary 9 "^" "" "^" "" } { BitXor Binary 9 "" " ^ " "" "" }
{ BitOr Binary 10 "|" "" "|" "" } { BitOr Binary 10 "" " | " "" "" }
{ LogAnd Binary 11 "&&" "" "&&" "" } { LogAnd Binary 11 "" " && " "" "" }
{ LogOr Binary 12 "||" "" "||" "" } { LogOr Binary 12 "" " || " "" "" }
{ Ternary Null 0 "? " "" "?" ":"} { Ternary Null 0 "" " ? " "" " : "}
{ LeafBytecode Null 0 "bytecode" "" "" "" } { Call Null 15 "" "(" ")" ", "}
{ LeafMember Null 0 "member" "" "" "" }
{ LeafStringLiteral Null 0 "string_literal" "" "" "" }
{ LeafBool Null 0 "B32" "" "" "" }
{ LeafU64 Null 0 "U64" "" "" "" }
{ LeafF64 Null 0 "F64" "" "" "" }
{ LeafF32 Null 0 "F32" "" "" "" }
{ LeafIdent Null 0 "leaf_ident" "" "" "" }
{ LeafOffset Null 0 "leaf_offset" "" "" "" }
{ LeafFilePath Null 0 "leaf_filepath" "" "" "" }
{ TypeIdent Null 0 "type_ident" "" "" "" } { LeafBytecode Null 0 "" "" "" "" }
{ Ptr Null 0 "ptr" "" "" "" } { LeafStringLiteral Null 0 "" "" "" "" }
{ Array Null 0 "array" "" "" "" } { LeafU64 Null 0 "" "" "" "" }
{ Func Null 0 "function" "" "" "" } { LeafF64 Null 0 "" "" "" "" }
{ LeafF32 Null 0 "" "" "" "" }
{ LeafIdentifier Null 0 "" "" "" "" }
{ LeafOffset Null 0 "" "" "" "" }
{ LeafValue Null 0 "" "" "" "" }
{ LeafFilePath Null 0 "" "" "" "" }
{ Define Binary 13 "=" "" "=" "" } { TypeIdent Null 0 "" "" "" "" }
{ Ptr Null 0 "" "" "" "" }
{ Array Null 0 "" "" "" "" }
{ Func Null 0 "" "" "" "" }
{ Unsigned Null 0 "unsigned " "" "" "" }
{ Define Binary 13 "" " = " "" "" }
} }
@table(name display_string) @table(name display_string)
@@ -157,6 +164,12 @@ E_InterpretationCodeTable:
COUNT, COUNT,
} }
@data(String8)
e_token_kind_strings:
{
@expand(E_TokenKindTable a) `str8_lit_comp("$(a.name)")`
}
@enum E_TypeKind: @enum E_TypeKind:
{ {
@expand(E_TypeKindTable a) `$(a.name)`, @expand(E_TypeKindTable a) `$(a.name)`,
@@ -171,6 +184,18 @@ E_InterpretationCodeTable:
`LastSigned2 = E_TypeKind_S512`, `LastSigned2 = E_TypeKind_S512`,
`FirstIncomplete = E_TypeKind_IncompleteStruct`, `FirstIncomplete = E_TypeKind_IncompleteStruct`,
`LastIncomplete = E_TypeKind_IncompleteEnum`, `LastIncomplete = E_TypeKind_IncompleteEnum`,
`FirstMeta = E_TypeKind_MetaExpr`,
`LastMeta = E_TypeKind_MetaDescription`,
}
@data(String8) e_type_kind_basic_string_table:
{
@expand(E_TypeKindTable a) `str8_lit_comp("$(a.basic_string)")`;
}
@data(U8) e_type_kind_basic_byte_size_table:
{
@expand(E_TypeKindTable a) `$(a.basic_byte_size)`;
} }
@enum(U32) E_ExprKind: @enum(U32) E_ExprKind:
@@ -179,40 +204,24 @@ E_InterpretationCodeTable:
COUNT, COUNT,
} }
@enum E_InterpretationCode:
{
@expand(E_InterpretationCodeTable a) `$(a.name)`,
COUNT,
}
@data(String8)
e_token_kind_strings:
{
@expand(E_TokenKindTable a) `str8_lit_comp("$(a.name)")`
}
@data(String8) @data(String8)
e_expr_kind_strings: e_expr_kind_strings:
{ {
@expand(E_ExprKindTable a) `str8_lit_comp("$(a.name)")` @expand(E_ExprKindTable a) `str8_lit_comp("$(a.name)")`
} }
@data(E_OpInfo) e_expr_kind_op_info_table:
{
@expand(E_ExprKindTable a) `{ E_OpKind_$(a.op_kind), $(a.precedence), str8_lit_comp("$(a.op_pre)"), str8_lit_comp("$(a.op_sep)"), str8_lit_comp("$(a.op_pos)"), str8_lit_comp("$(a.op_chain)") }`
}
@enum E_InterpretationCode:
{
@expand(E_InterpretationCodeTable a) `$(a.name)`,
COUNT,
}
@data(String8) e_interpretation_code_display_strings: @data(String8) e_interpretation_code_display_strings:
{ {
@expand(E_InterpretationCodeTable a) `str8_lit_comp("$(a.display_string)")` @expand(E_InterpretationCodeTable a) `str8_lit_comp("$(a.display_string)")`
} }
@data(E_OpInfo) e_expr_kind_op_info_table:
{
@expand(E_ExprKindTable a) `{ E_OpKind_$(a.op_kind), $(a.precedence), str8_lit_comp("$(a.op_pre)"), str8_lit_comp("$(a.op_sep)"), str8_lit_comp("$(a.op_pos)") }`
}
@data(U8) e_kind_basic_byte_size_table:
{
@expand(E_TypeKindTable a) `$(a.basic_byte_size)`;
}
@data(String8) e_kind_basic_string_table:
{
@expand(E_TypeKindTable a) `str8_lit_comp("$(a.basic_string)")`;
}
-262
View File
@@ -1,262 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Bundled Evaluation Functions
internal E_Eval
e_eval_from_expr(Arena *arena, E_Expr *expr)
{
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr);
E_OpList oplist = e_oplist_from_irtree(arena, irtree.root);
String8 bytecode = e_bytecode_from_oplist(arena, &oplist);
E_Interpretation interp = e_interpret(bytecode);
E_Space zero_space = {0};
E_Space space = (MemoryMatchStruct(&zero_space, &irtree.space) ? e_interpret_ctx->primary_space : irtree.space);
E_Eval eval =
{
.value = interp.value,
.mode = irtree.mode,
.space = space,
.expr = expr,
.type_key = irtree.type_key,
.code = interp.code,
};
e_msg_list_concat_in_place(&eval.msgs, &irtree.msgs);
if(E_InterpretationCode_Good < eval.code && eval.code < E_InterpretationCode_COUNT)
{
e_msg(arena, &eval.msgs, E_MsgKind_InterpretationError, 0, e_interpretation_code_display_strings[eval.code]);
}
return eval;
}
internal E_Eval
e_eval_from_string(Arena *arena, String8 string)
{
E_TokenArray tokens = e_token_array_from_text(arena, string);
E_Parse parse = e_parse_expr_from_text_tokens(arena, string, &tokens);
E_Eval eval = e_eval_from_expr(arena, parse.expr);
e_msg_list_concat_in_place(&eval.msgs, &parse.msgs);
return eval;
}
internal E_Eval
e_autoresolved_eval_from_eval(E_Eval eval)
{
if(e_parse_ctx &&
e_interpret_ctx &&
e_parse_ctx->modules_count > 0 &&
e_interpret_ctx->module_base != 0 &&
(e_type_key_match(eval.type_key, e_type_key_basic(E_TypeKind_S64)) ||
e_type_key_match(eval.type_key, e_type_key_basic(E_TypeKind_U64)) ||
e_type_key_match(eval.type_key, e_type_key_basic(E_TypeKind_S32)) ||
e_type_key_match(eval.type_key, e_type_key_basic(E_TypeKind_U32))))
{
U64 vaddr = eval.value.u64;
U64 voff = vaddr - e_interpret_ctx->module_base[0];
RDI_Parsed *rdi = e_parse_ctx->primary_module->rdi;
RDI_Scope *scope = rdi_scope_from_voff(rdi, voff);
RDI_Procedure *procedure = rdi_procedure_from_voff(rdi, voff);
RDI_GlobalVariable *gvar = rdi_global_variable_from_voff(rdi, voff);
U32 string_idx = 0;
if(string_idx == 0) { string_idx = procedure->name_string_idx; }
if(string_idx == 0) { string_idx = gvar->name_string_idx; }
if(string_idx != 0)
{
eval.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, e_type_key_basic(E_TypeKind_Void), 0);
}
}
return eval;
}
internal E_Eval
e_dynamically_typed_eval_from_eval(E_Eval eval)
{
E_TypeKey type_key = eval.type_key;
E_TypeKind type_kind = e_type_kind_from_key(type_key);
if(e_type_state != 0 &&
e_interpret_ctx != 0 &&
e_interpret_ctx->space_read != 0 &&
e_interpret_ctx->module_base != 0 &&
type_kind == E_TypeKind_Ptr)
{
Temp scratch = scratch_begin(0, 0);
E_TypeKey ptee_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(type_key)));
E_TypeKind ptee_type_kind = e_type_kind_from_key(ptee_type_key);
if(ptee_type_kind == E_TypeKind_Struct || ptee_type_kind == E_TypeKind_Class)
{
E_Type *ptee_type = e_type_from_key(scratch.arena, ptee_type_key);
B32 has_vtable = 0;
for(U64 idx = 0; idx < ptee_type->count; idx += 1)
{
if(ptee_type->members[idx].kind == E_MemberKind_VirtualMethod)
{
has_vtable = 1;
break;
}
}
if(has_vtable)
{
U64 ptr_vaddr = eval.value.u64;
U64 addr_size = e_type_byte_size_from_key(e_type_unwrap(type_key));
U64 class_base_vaddr = 0;
U64 vtable_vaddr = 0;
if(e_space_read(eval.space, &class_base_vaddr, r1u64(ptr_vaddr, ptr_vaddr+addr_size)) &&
e_space_read(eval.space, &vtable_vaddr, r1u64(class_base_vaddr, class_base_vaddr+addr_size)))
{
Arch arch = e_type_state->ctx->primary_module->arch;
U32 rdi_idx = 0;
RDI_Parsed *rdi = 0;
U64 module_base = 0;
for(U64 idx = 0; idx < e_type_state->ctx->modules_count; idx += 1)
{
if(contains_1u64(e_type_state->ctx->modules[idx].vaddr_range, vtable_vaddr))
{
arch = e_type_state->ctx->modules[idx].arch;
rdi_idx = (U32)idx;
rdi = e_type_state->ctx->modules[idx].rdi;
module_base = e_type_state->ctx->modules[idx].vaddr_range.min;
break;
}
}
if(rdi != 0)
{
U64 vtable_voff = vtable_vaddr - module_base;
U64 global_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_GlobalVMap, vtable_voff);
RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, global_idx);
if(global_var->link_flags & RDI_LinkFlag_TypeScoped)
{
RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, global_var->container_idx);
RDI_TypeNode *type = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx);
E_TypeKey derived_type_key = e_type_key_ext(e_type_kind_from_rdi(type->kind), udt->self_type_idx, rdi_idx);
E_TypeKey ptr_to_derived_type_key = e_type_key_cons_ptr(arch, derived_type_key, 0);
eval.type_key = ptr_to_derived_type_key;
}
}
}
}
}
scratch_end(scratch);
}
return eval;
}
internal E_Eval
e_value_eval_from_eval(E_Eval eval)
{
ProfBeginFunction();
if(eval.mode == E_Mode_Offset)
{
E_TypeKey type_key = e_type_unwrap(eval.type_key);
E_TypeKind type_kind = e_type_kind_from_key(type_key);
if(type_kind == E_TypeKind_Array)
{
eval.mode = E_Mode_Value;
}
else
{
U64 type_byte_size = e_type_byte_size_from_key(type_key);
Rng1U64 value_vaddr_range = r1u64(eval.value.u64, eval.value.u64 + type_byte_size);
MemoryZeroStruct(&eval.value);
if(!e_type_key_match(type_key, e_type_key_zero()) &&
type_byte_size <= sizeof(E_Value) &&
e_space_read(eval.space, &eval.value, value_vaddr_range))
{
eval.mode = E_Mode_Value;
// rjf: mask&shift, for bitfields
if(type_kind == E_TypeKind_Bitfield && type_byte_size <= sizeof(U64))
{
Temp scratch = scratch_begin(0, 0);
E_Type *type = e_type_from_key(scratch.arena, type_key);
U64 valid_bits_mask = 0;
for(U64 idx = 0; idx < type->count; idx += 1)
{
valid_bits_mask |= (1ull<<idx);
}
eval.value.u64 = eval.value.u64 >> type->off;
eval.value.u64 = eval.value.u64 & valid_bits_mask;
eval.type_key = type->direct_type_key;
scratch_end(scratch);
}
// rjf: manually sign-extend
switch(type_kind)
{
default: break;
case E_TypeKind_Char8:
case E_TypeKind_S8: {eval.value.s64 = (S64)*((S8 *)&eval.value.u64);}break;
case E_TypeKind_Char16:
case E_TypeKind_S16: {eval.value.s64 = (S64)*((S16 *)&eval.value.u64);}break;
case E_TypeKind_Char32:
case E_TypeKind_S32: {eval.value.s64 = (S64)*((S32 *)&eval.value.u64);}break;
}
}
}
}
ProfEnd();
return eval;
}
internal E_Eval
e_element_eval_from_array_eval_index(E_Eval eval, U64 index)
{
E_Eval result = {0};
result.mode = eval.mode;
result.space = eval.space;
result.type_key = e_type_direct_from_key(eval.type_key);
result.code = eval.code;
result.msgs = eval.msgs;
U64 element_size = e_type_byte_size_from_key(result.type_key);
switch(eval.mode)
{
default:{}break;
case E_Mode_Value:
if(element_size <= sizeof(E_Value) &&
index < sizeof(E_Value)/element_size)
{
MemoryCopy((U8 *)(&result.value.u512[0]),
(U8 *)(&eval.value.u512[0]) + index*element_size,
element_size);
}break;
case E_Mode_Offset:
{
result.value.u64 = eval.value.u64 + element_size*index;
}break;
}
return result;
}
internal E_Eval
e_member_eval_from_eval_member_name(E_Eval eval, String8 member_name)
{
E_Eval result = {0};
{
E_Member member = e_type_member_from_key_name__cached(eval.type_key, member_name);
if(member.kind != E_MemberKind_Null)
{
result.mode = eval.mode;
result.space = eval.space;
result.type_key = member.type_key;
result.code = eval.code;
result.msgs = eval.msgs;
switch(eval.mode)
{
default:{}break;
case E_Mode_Value:
if(member.off < sizeof(eval.value))
{
U64 member_size = e_type_byte_size_from_key(member.type_key);
MemoryCopy((U8 *)(&result.value.u512[0]),
(U8 *)(&eval.value.u512[0]) + member.off,
Min(member_size, sizeof(eval.value) - member.off));
}break;
case E_Mode_Offset:
{
result.value.u64 = eval.value.u64 + member.off;
}break;
}
}
}
return result;
}
-33
View File
@@ -1,33 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef EVAL_BUNDLES_H
#define EVAL_BUNDLES_H
////////////////////////////////
//~ rjf: Bundled Evaluation Path Types
typedef struct E_Eval E_Eval;
struct E_Eval
{
E_Value value;
E_Mode mode;
E_Space space;
E_Expr *expr;
E_TypeKey type_key;
E_InterpretationCode code;
E_MsgList msgs;
};
////////////////////////////////
//~ rjf: Bundled Evaluation Functions
internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr);
internal E_Eval e_eval_from_string(Arena *arena, String8 string);
internal E_Eval e_autoresolved_eval_from_eval(E_Eval eval);
internal E_Eval e_dynamically_typed_eval_from_eval(E_Eval eval);
internal E_Eval e_value_eval_from_eval(E_Eval eval);
internal E_Eval e_element_eval_from_array_eval_index(E_Eval eval, U64 index);
internal E_Eval e_member_eval_from_eval_member_name(E_Eval eval, String8 member_name);
#endif // EVAL_BUNDLES_H
+1336 -8
View File
File diff suppressed because it is too large Load Diff
+1103 -6
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -6,4 +6,3 @@
#include "eval/eval_parse.c" #include "eval/eval_parse.c"
#include "eval/eval_ir.c" #include "eval/eval_ir.c"
#include "eval/eval_interpret.c" #include "eval/eval_interpret.c"
#include "eval/eval_bundles.c"
-1
View File
@@ -9,6 +9,5 @@
#include "eval/eval_parse.h" #include "eval/eval_parse.h"
#include "eval/eval_ir.h" #include "eval/eval_ir.h"
#include "eval/eval_interpret.h" #include "eval/eval_interpret.h"
#include "eval/eval_bundles.h"
#endif // EVAL_INC_H #endif // EVAL_INC_H
+63 -11
View File
@@ -4,21 +4,68 @@
//////////////////////////////// ////////////////////////////////
//~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) //~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs)
internal E_InterpretCtx *
e_selected_interpret_ctx(void)
{
return e_interpret_ctx;
}
internal void internal void
e_select_interpret_ctx(E_InterpretCtx *ctx) e_select_interpret_ctx(E_InterpretCtx *ctx, RDI_Parsed *primary_rdi, U64 ip_voff)
{ {
e_interpret_ctx = ctx; e_interpret_ctx = ctx;
// compute and apply frame base
if(primary_rdi != 0)
{
E_Interpretation frame_base = { .code = ~0 };
RDI_Procedure *proc = rdi_procedure_from_voff(primary_rdi, ip_voff);
for(U64 loc_block_idx = proc->frame_base_location_first; loc_block_idx < proc->frame_base_location_opl; loc_block_idx += 1)
{
RDI_LocationBlock *block = rdi_element_from_name_idx(primary_rdi, LocationBlocks, loc_block_idx);
if (block->scope_off_first <= ip_voff && ip_voff < block->scope_off_opl) {
U64 all_location_data_size = 0;
U8 *all_location_data = rdi_table_from_name(primary_rdi, LocationData, &all_location_data_size);
if(block->location_data_off + sizeof(RDI_LocationKind) <= all_location_data_size)
{
RDI_LocationKind loc_kind = *(RDI_LocationKind *)(all_location_data + block->location_data_off);
if(loc_kind == RDI_LocationKind_ValBytecodeStream || loc_kind == RDI_LocationKind_AddrBytecodeStream)
{
U8 *bytecode_ptr = all_location_data + block->location_data_off + sizeof(RDI_LocationKind);
U8 *bytecode_opl = all_location_data + all_location_data_size;
U64 bytecode_size = rdi_size_from_bytecode_stream(bytecode_ptr, bytecode_opl);
String8 bytecode = str8(bytecode_ptr, bytecode_size);
frame_base = e_interpret(bytecode);
}
else if(loc_kind != RDI_LocationKind_NULL)
{
NotImplemented;
}
}
break;
}
}
if(frame_base.code == E_InterpretationCode_Good)
{
*ctx->frame_base = frame_base.value.u64;
}
else
{
ctx->frame_base = 0;
}
}
} }
//////////////////////////////// ////////////////////////////////
//~ rjf: Space Reading Helpers //~ rjf: Space Reading Helpers
internal U64
e_space_gen(E_Space space)
{
U64 result = 0;
if(e_base_ctx->space_gen != 0)
{
result = e_base_ctx->space_gen(e_base_ctx->space_rw_user_data, space);
}
return result;
}
internal B32 internal B32
e_space_read(E_Space space, void *out, Rng1U64 range) e_space_read(E_Space space, void *out, Rng1U64 range)
{ {
@@ -58,7 +105,11 @@ e_interpret(String8 bytecode)
U64 stack_cap = 128; // TODO(rjf): scan bytecode; determine maximum stack depth U64 stack_cap = 128; // TODO(rjf): scan bytecode; determine maximum stack depth
E_Value *stack = push_array_no_zero(scratch.arena, E_Value, stack_cap); E_Value *stack = push_array_no_zero(scratch.arena, E_Value, stack_cap);
U64 stack_count = 0; U64 stack_count = 0;
E_Space selected_space = e_interpret_ctx->primary_space; E_Space selected_space = {0};
if(bytecode.size != 0)
{
selected_space = e_interpret_ctx->primary_space;
}
//- rjf: iterate bytecode & perform ops //- rjf: iterate bytecode & perform ops
U8 *ptr = bytecode.str; U8 *ptr = bytecode.str;
@@ -526,13 +577,13 @@ e_interpret(String8 bytecode)
case RDI_EvalOp_EqEq: case RDI_EvalOp_EqEq:
{ {
B32 result = MemoryMatchArray(svals[0].u512, svals[1].u512); B32 result = MemoryMatchArray(svals[0].u512.u64, svals[1].u512.u64);
nval.u64 = !!result; nval.u64 = !!result;
}break; }break;
case RDI_EvalOp_NtEq: case RDI_EvalOp_NtEq:
{ {
B32 result = MemoryMatchArray(svals[0].u512, svals[1].u512); B32 result = MemoryMatchArray(svals[0].u512.u64, svals[1].u512.u64);
nval.u64 = !result; nval.u64 = !result;
}break; }break;
@@ -767,7 +818,7 @@ e_interpret(String8 bytecode)
if(offset + bytes_to_read <= sizeof(E_Value)) if(offset + bytes_to_read <= sizeof(E_Value))
{ {
E_Value src_val = svals[1]; E_Value src_val = svals[1];
MemoryCopy(&nval.u512[0], (U8 *)(&src_val.u512[0]) + offset, bytes_to_read); MemoryCopy(&nval.u512.u64[0], (U8 *)(&src_val.u512.u64[0]) + offset, bytes_to_read);
} }
}break; }break;
@@ -812,6 +863,7 @@ e_interpret(String8 bytecode)
{ {
result.value = stack[0]; result.value = stack[0];
} }
result.space = selected_space;
scratch_end(scratch); scratch_end(scratch);
return result; return result;
} }
+2 -14
View File
@@ -4,21 +4,9 @@
#ifndef EVAL_INTERPRET_H #ifndef EVAL_INTERPRET_H
#define EVAL_INTERPRET_H #define EVAL_INTERPRET_H
////////////////////////////////
//~ rjf: Bytecode Interpretation Types
typedef struct E_Interpretation E_Interpretation;
struct E_Interpretation
{
E_Value value;
E_InterpretationCode code;
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Interpretation Context //~ rjf: Interpretation Context
typedef B32 E_SpaceRWFunction(void *user_data, E_Space space, void *out, Rng1U64 offset_range);
typedef struct E_InterpretCtx E_InterpretCtx; typedef struct E_InterpretCtx E_InterpretCtx;
struct E_InterpretCtx struct E_InterpretCtx
{ {
@@ -42,12 +30,12 @@ thread_static E_InterpretCtx *e_interpret_ctx = 0;
//////////////////////////////// ////////////////////////////////
//~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) //~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs)
internal E_InterpretCtx *e_selected_interpret_ctx(void); internal void e_select_interpret_ctx(E_InterpretCtx *ctx, RDI_Parsed *primary_rdi, U64 ip_voff);
internal void e_select_interpret_ctx(E_InterpretCtx *ctx);
//////////////////////////////// ////////////////////////////////
//~ rjf: Space Reading Helpers //~ rjf: Space Reading Helpers
internal U64 e_space_gen(E_Space space);
internal B32 e_space_read(E_Space space, void *out, Rng1U64 range); internal B32 e_space_read(E_Space space, void *out, Rng1U64 range);
internal B32 e_space_write(E_Space space, void *in, Rng1U64 range); internal B32 e_space_write(E_Space space, void *in, Rng1U64 range);
+1498 -394
View File
File diff suppressed because it is too large Load Diff
+108 -60
View File
@@ -5,83 +5,121 @@
#define EVAL_IR_H #define EVAL_IR_H
//////////////////////////////// ////////////////////////////////
//~ rjf: Bytecode Operation Types //~ rjf: Identifier Resolution Rule Types
enum typedef enum E_IdentifierResolutionPath
{ {
E_IRExtKind_Bytecode = RDI_EvalOp_COUNT, E_IdentifierResolutionPath_ParentExpr,
E_IRExtKind_SetSpace, E_IdentifierResolutionPath_ParentExprMember,
E_IRExtKind_COUNT E_IdentifierResolutionPath_ImplicitThisMember,
}; E_IdentifierResolutionPath_Local,
E_IdentifierResolutionPath_Globals,
E_IdentifierResolutionPath_ThreadLocals,
E_IdentifierResolutionPath_Procedures,
E_IdentifierResolutionPath_Types,
E_IdentifierResolutionPath_Registers,
E_IdentifierResolutionPath_RegisterAliases,
E_IdentifierResolutionPath_Constants,
E_IdentifierResolutionPath_Macros,
}
E_IdentifierResolutionPath;
typedef struct E_Op E_Op; typedef struct E_IdentifierResolutionRule E_IdentifierResolutionRule;
struct E_Op struct E_IdentifierResolutionRule
{ {
E_Op *next; E_IdentifierResolutionPath *paths;
RDI_EvalOp opcode; U64 count;
E_Value value;
String8 string;
};
typedef struct E_OpList E_OpList;
struct E_OpList
{
E_Op *first;
E_Op *last;
U64 op_count;
U64 encoded_size;
}; };
//////////////////////////////// ////////////////////////////////
//~ rjf: IR Tree Types //~ rjf: IR State
typedef struct E_IRNode E_IRNode; typedef struct E_IRCacheNode E_IRCacheNode;
struct E_IRNode struct E_IRCacheNode
{ {
E_IRNode *first; E_IRCacheNode *next;
E_IRNode *last; E_Expr *expr;
E_IRNode *next; E_IRNode *overridden_node;
RDI_EvalOp op; E_IRTreeAndType irtree;
String8 string;
E_Value value;
}; };
typedef struct E_IRTreeAndType E_IRTreeAndType; typedef struct E_IRCacheSlot E_IRCacheSlot;
struct E_IRTreeAndType struct E_IRCacheSlot
{ {
E_IRNode *root; E_IRCacheNode *first;
E_TypeKey type_key; E_IRCacheNode *last;
E_Mode mode;
E_Space space;
E_MsgList msgs;
}; };
//////////////////////////////// typedef struct E_IRState E_IRState;
//~ rjf: Parse Context struct E_IRState
typedef struct E_IRCtx E_IRCtx;
struct E_IRCtx
{ {
E_String2ExprMap *macro_map; Arena *arena;
U64 arena_eval_start_pos;
// rjf: ir context
E_IRCtx *ctx;
// rjf: unpacked ctx
RDI_Procedure *thread_ip_procedure;
// rjf: overridden irtree
E_IRTreeAndType *overridden_irtree;
B32 disallow_autohooks;
B32 disallow_chained_fastpaths;
// rjf: caches
E_UsedExprMap *used_expr_map;
E_TypeAutoHookCacheMap *type_auto_hook_cache_map;
U64 string_id_gen;
E_StringIDMap *string_id_map;
U64 ir_cache_slots_count;
E_IRCacheSlot *ir_cache_slots;
}; };
//////////////////////////////// ////////////////////////////////
//~ rjf: Globals //~ rjf: Globals
global read_only E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil}; E_IdentifierResolutionPath e_default_identifier_resolution_paths[] =
thread_static E_IRCtx *e_ir_ctx = 0; {
E_IdentifierResolutionPath_ParentExpr,
E_IdentifierResolutionPath_ParentExprMember,
E_IdentifierResolutionPath_ImplicitThisMember,
E_IdentifierResolutionPath_Local,
E_IdentifierResolutionPath_Globals,
E_IdentifierResolutionPath_ThreadLocals,
E_IdentifierResolutionPath_Procedures,
E_IdentifierResolutionPath_Types,
E_IdentifierResolutionPath_Registers,
E_IdentifierResolutionPath_RegisterAliases,
E_IdentifierResolutionPath_Constants,
E_IdentifierResolutionPath_Macros,
};
E_IdentifierResolutionRule e_default_identifier_resolution_rule =
{
e_default_identifier_resolution_paths,
ArrayCount(e_default_identifier_resolution_paths),
};
//////////////////////////////// E_IdentifierResolutionPath e_callable_identifier_resolution_paths[] =
//~ rjf: Expr Kind Enum Functions {
E_IdentifierResolutionPath_Macros,
internal RDI_EvalOp e_opcode_from_expr_kind(E_ExprKind kind); E_IdentifierResolutionPath_ParentExpr,
internal B32 e_expr_kind_is_comparison(E_ExprKind kind); E_IdentifierResolutionPath_ParentExprMember,
E_IdentifierResolutionPath_ImplicitThisMember,
//////////////////////////////// E_IdentifierResolutionPath_Local,
//~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) E_IdentifierResolutionPath_Globals,
E_IdentifierResolutionPath_ThreadLocals,
internal E_IRCtx *e_selected_ir_ctx(void); E_IdentifierResolutionPath_Procedures,
internal void e_select_ir_ctx(E_IRCtx *ctx); E_IdentifierResolutionPath_Types,
E_IdentifierResolutionPath_Registers,
E_IdentifierResolutionPath_RegisterAliases,
E_IdentifierResolutionPath_Constants,
};
E_IdentifierResolutionRule e_callable_identifier_resolution_rule =
{
e_callable_identifier_resolution_paths,
ArrayCount(e_callable_identifier_resolution_paths),
};
//////////////////////////////// ////////////////////////////////
//~ rjf: IR-ization Functions //~ rjf: IR-ization Functions
@@ -101,6 +139,7 @@ internal void e_irnode_push_child(E_IRNode *parent, E_IRNode *child);
//- rjf: ir subtree building helpers //- rjf: ir subtree building helpers
internal E_IRNode *e_irtree_const_u(Arena *arena, U64 v); internal E_IRNode *e_irtree_const_u(Arena *arena, U64 v);
internal E_IRNode *e_irtree_leaf_u128(Arena *arena, U128 u128);
internal E_IRNode *e_irtree_unary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, E_IRNode *c); internal E_IRNode *e_irtree_unary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, E_IRNode *c);
internal E_IRNode *e_irtree_binary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, E_IRNode *l, E_IRNode *r); internal E_IRNode *e_irtree_binary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, E_IRNode *l, E_IRNode *r);
internal E_IRNode *e_irtree_binary_op_u(Arena *arena, RDI_EvalOp op, E_IRNode *l, E_IRNode *r); internal E_IRNode *e_irtree_binary_op_u(Arena *arena, RDI_EvalOp op, E_IRNode *l, E_IRNode *r);
@@ -108,18 +147,27 @@ internal E_IRNode *e_irtree_conditional(Arena *arena, E_IRNode *c, E_IRNode *l,
internal E_IRNode *e_irtree_bytecode_no_copy(Arena *arena, String8 bytecode); internal E_IRNode *e_irtree_bytecode_no_copy(Arena *arena, String8 bytecode);
internal E_IRNode *e_irtree_string_literal(Arena *arena, String8 string); internal E_IRNode *e_irtree_string_literal(Arena *arena, String8 string);
internal E_IRNode *e_irtree_set_space(Arena *arena, E_Space space, E_IRNode *c); internal E_IRNode *e_irtree_set_space(Arena *arena, E_Space space, E_IRNode *c);
internal E_IRNode *e_irtree_mem_read_type(Arena *arena, E_Space space, E_IRNode *c, E_TypeKey type_key); internal E_IRNode *e_irtree_mem_read_type(Arena *arena, E_IRNode *c, E_TypeKey type_key);
internal E_IRNode *e_irtree_convert_lo(Arena *arena, E_IRNode *c, RDI_EvalTypeGroup out, RDI_EvalTypeGroup in); internal E_IRNode *e_irtree_convert_lo(Arena *arena, E_IRNode *c, RDI_EvalTypeGroup out, RDI_EvalTypeGroup in);
internal E_IRNode *e_irtree_trunc(Arena *arena, E_IRNode *c, E_TypeKey type_key); internal E_IRNode *e_irtree_trunc(Arena *arena, E_IRNode *c, E_TypeKey type_key);
internal E_IRNode *e_irtree_convert_hi(Arena *arena, E_IRNode *c, E_TypeKey out, E_TypeKey in); internal E_IRNode *e_irtree_convert_hi(Arena *arena, E_IRNode *c, E_TypeKey out, E_TypeKey in);
internal E_IRNode *e_irtree_resolve_to_value(Arena *arena, E_Space from_space, E_Mode from_mode, E_IRNode *tree, E_TypeKey type_key); internal E_IRNode *e_irtree_resolve_to_value(Arena *arena, E_Mode from_mode, E_IRNode *tree, E_TypeKey type_key);
//- rjf: expression poison checking
internal B32 e_expr_is_poisoned(E_Expr *expr);
internal void e_expr_poison(E_Expr *expr);
internal void e_expr_unpoison(E_Expr *expr);
//- rjf: top-level irtree/type extraction //- rjf: top-level irtree/type extraction
internal E_IRTreeAndType e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr); E_TYPE_ACCESS_FUNCTION_DEF(default);
internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_IdentifierResolutionRule *identifier_resolution_rule, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr);
//- rjf: irtree -> linear ops/bytecode //- rjf: irtree -> linear ops/bytecode
internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_OpList *out); internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out);
internal E_OpList e_oplist_from_irtree(Arena *arena, E_IRNode *root); internal E_OpList e_oplist_from_irtree(Arena *arena, E_IRNode *root);
internal String8 e_bytecode_from_oplist(Arena *arena, E_OpList *oplist); internal String8 e_bytecode_from_oplist(Arena *arena, E_OpList *oplist);
//- rjf: leaf-bytecode expression extensions
internal E_Expr *e_expr_irext_member_access(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtree, String8 member_name);
#endif // EVAL_IR_H #endif // EVAL_IR_H
+626 -1201
View File
File diff suppressed because it is too large Load Diff
+10 -213
View File
@@ -4,243 +4,40 @@
#ifndef EVAL_PARSE_H #ifndef EVAL_PARSE_H
#define EVAL_PARSE_H #define EVAL_PARSE_H
////////////////////////////////
//~ rjf: Generated Code
#include "generated/eval.meta.h"
////////////////////////////////
//~ rjf: Token Types
typedef struct E_Token E_Token;
struct E_Token
{
E_TokenKind kind;
Rng1U64 range;
};
typedef struct E_TokenChunkNode E_TokenChunkNode;
struct E_TokenChunkNode
{
E_TokenChunkNode *next;
E_Token *v;
U64 count;
U64 cap;
};
typedef struct E_TokenChunkList E_TokenChunkList;
struct E_TokenChunkList
{
E_TokenChunkNode *first;
E_TokenChunkNode *last;
U64 node_count;
U64 total_count;
};
typedef struct E_TokenArray E_TokenArray;
struct E_TokenArray
{
E_Token *v;
U64 count;
};
////////////////////////////////
//~ rjf: Expression Tree Types
typedef struct E_Expr E_Expr;
struct E_Expr
{
E_Expr *first;
E_Expr *last;
E_Expr *next;
E_Expr *prev;
E_Expr *ref;
void *location;
E_ExprKind kind;
E_Mode mode;
E_Space space;
E_TypeKey type_key;
E_Value value;
String8 string;
String8 bytecode;
};
////////////////////////////////
//~ rjf: Map Types
//- rjf: string -> num
typedef struct E_String2NumMapNode E_String2NumMapNode;
struct E_String2NumMapNode
{
E_String2NumMapNode *order_next;
E_String2NumMapNode *hash_next;
String8 string;
U64 num;
};
typedef struct E_String2NumMapNodeArray E_String2NumMapNodeArray;
struct E_String2NumMapNodeArray
{
E_String2NumMapNode **v;
U64 count;
};
typedef struct E_String2NumMapSlot E_String2NumMapSlot;
struct E_String2NumMapSlot
{
E_String2NumMapNode *first;
E_String2NumMapNode *last;
};
typedef struct E_String2NumMap E_String2NumMap;
struct E_String2NumMap
{
U64 slots_count;
U64 node_count;
E_String2NumMapSlot *slots;
E_String2NumMapNode *first;
E_String2NumMapNode *last;
};
//- rjf: string -> expr
typedef struct E_String2ExprMapNode E_String2ExprMapNode;
struct E_String2ExprMapNode
{
E_String2ExprMapNode *hash_next;
String8 string;
E_Expr *expr;
U64 poison_count;
};
typedef struct E_String2ExprMapSlot E_String2ExprMapSlot;
struct E_String2ExprMapSlot
{
E_String2ExprMapNode *first;
E_String2ExprMapNode *last;
};
typedef struct E_String2ExprMap E_String2ExprMap;
struct E_String2ExprMap
{
U64 slots_count;
E_String2ExprMapSlot *slots;
};
////////////////////////////////
//~ rjf: Parse Context
typedef struct E_ParseCtx E_ParseCtx;
struct E_ParseCtx
{
// rjf: instruction pointer info
U64 ip_vaddr;
U64 ip_voff;
E_Space ip_thread_space;
// rjf: modules
E_Module *modules;
U64 modules_count;
E_Module *primary_module;
// rjf: local identifier resolution maps
E_String2NumMap *regs_map;
E_String2NumMap *reg_alias_map;
E_String2NumMap *locals_map; // (within `rdis[rdis_primary_idx]`)
E_String2NumMap *member_map; // (within `rdis[rdis_primary_idx]`)
};
////////////////////////////////
//~ rjf: Parse Results
typedef struct E_Parse E_Parse;
struct E_Parse
{
E_Token *last_token;
E_Expr *expr;
E_MsgList msgs;
};
////////////////////////////////
//~ rjf: Globals
global read_only E_String2NumMap e_string2num_map_nil = {0};
global read_only E_String2ExprMap e_string2expr_map_nil = {0};
global read_only E_Expr e_expr_nil = {&e_expr_nil, &e_expr_nil, &e_expr_nil};
thread_static E_ParseCtx *e_parse_ctx = 0;
////////////////////////////////
//~ rjf: Basic Map Functions
//- rjf: string -> num
internal E_String2NumMap e_string2num_map_make(Arena *arena, U64 slot_count);
internal void e_string2num_map_insert(Arena *arena, E_String2NumMap *map, String8 string, U64 num);
internal U64 e_num_from_string(E_String2NumMap *map, String8 string);
internal E_String2NumMapNodeArray e_string2num_map_node_array_from_map(Arena *arena, E_String2NumMap *map);
internal int e_string2num_map_node_qsort_compare__num_ascending(E_String2NumMapNode **a, E_String2NumMapNode **b);
internal void e_string2num_map_node_array_sort__in_place(E_String2NumMapNodeArray *array);
//- rjf: string -> expr
internal E_String2ExprMap e_string2expr_map_make(Arena *arena, U64 slot_count);
internal void e_string2expr_map_insert(Arena *arena, E_String2ExprMap *map, String8 string, E_Expr *expr);
internal void e_string2expr_map_inc_poison(E_String2ExprMap *map, String8 string);
internal void e_string2expr_map_dec_poison(E_String2ExprMap *map, String8 string);
internal E_Expr *e_string2expr_lookup(E_String2ExprMap *map, String8 string);
////////////////////////////////
//~ rjf: Debug-Info-Driven Map Building Functions
internal E_String2NumMap *e_push_locals_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff);
internal E_String2NumMap *e_push_member_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff);
//////////////////////////////// ////////////////////////////////
//~ rjf: Tokenization Functions //~ rjf: Tokenization Functions
#define e_token_at_it(it, arr) (((it) < (arr)->v+(arr)->count) ? (*(it)) : e_token_zero()) #define e_token_at_it(it, arr) (((arr)->v <= (it) && (it) < (arr)->v+(arr)->count) ? (*(it)) : e_token_zero())
internal E_Token e_token_zero(void); internal E_Token e_token_zero(void);
internal void e_token_chunk_list_push(Arena *arena, E_TokenChunkList *list, U64 chunk_size, E_Token *token); internal void e_token_chunk_list_push(Arena *arena, E_TokenChunkList *list, U64 chunk_size, E_Token *token);
internal E_TokenArray e_token_array_from_chunk_list(Arena *arena, E_TokenChunkList *list); internal E_TokenArray e_token_array_from_chunk_list(Arena *arena, E_TokenChunkList *list);
internal E_TokenArray e_token_array_from_text(Arena *arena, String8 text); internal E_TokenArray e_token_array_from_text(Arena *arena, String8 text);
internal E_TokenArray e_token_array_make_first_opl(E_Token *first, E_Token *opl); internal E_TokenArray e_token_array_make_first_opl(E_Token *first, E_Token *opl);
////////////////////////////////
//~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs)
internal E_ParseCtx *e_selected_parse_ctx(void);
internal void e_select_parse_ctx(E_ParseCtx *ctx);
internal U32 e_parse_ctx_module_idx_from_rdi(RDI_Parsed *rdi);
//////////////////////////////// ////////////////////////////////
//~ rjf: Expression Tree Building Functions //~ rjf: Expression Tree Building Functions
internal E_Expr *e_push_expr(Arena *arena, E_ExprKind kind, void *location); internal E_Expr *e_push_expr(Arena *arena, E_ExprKind kind, Rng1U64 range);
internal void e_expr_insert_child(E_Expr *parent, E_Expr *prev, E_Expr *child); internal void e_expr_insert_child(E_Expr *parent, E_Expr *prev, E_Expr *child);
internal void e_expr_push_child(E_Expr *parent, E_Expr *child); internal void e_expr_push_child(E_Expr *parent, E_Expr *child);
internal void e_expr_remove_child(E_Expr *parent, E_Expr *child); internal void e_expr_remove_child(E_Expr *parent, E_Expr *child);
internal E_Expr *e_expr_ref(Arena *arena, E_Expr *ref); internal E_Expr *e_expr_ref(Arena *arena, E_Expr *ref);
internal E_Expr *e_expr_ref_addr(Arena *arena, E_Expr *rhs); internal E_Expr *e_expr_copy(Arena *arena, E_Expr *src);
internal E_Expr *e_expr_ref_member_access(Arena *arena, E_Expr *lhs, String8 member_name); internal void e_expr_list_push(Arena *arena, E_ExprList *list, E_Expr *expr);
internal E_Expr *e_expr_ref_array_index(Arena *arena, E_Expr *lhs, U64 index);
internal E_Expr *e_expr_ref_deref(Arena *arena, E_Expr *rhs);
internal E_Expr *e_expr_ref_cast(Arena *arena, E_TypeKey type_key, E_Expr *rhs);
internal E_Expr *e_expr_ref_bswap(Arena *arena, E_Expr *rhs);
//////////////////////////////// ////////////////////////////////
//~ rjf: Expression Tree -> String Conversions //~ rjf: Expression Tree -> String Conversions
internal void e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out); internal void e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8 parent_expr_string, String8List *out);
internal String8 e_string_from_expr(Arena *arena, E_Expr *expr); internal String8 e_string_from_expr(Arena *arena, E_Expr *expr, String8 parent_expr_string);
//////////////////////////////// ////////////////////////////////
//~ rjf: Parsing Functions //~ rjf: Parsing Functions
internal E_TypeKey e_leaf_type_from_name(String8 name); internal E_TypeKey e_leaf_type_from_name(String8 name);
internal E_TypeKey e_type_from_expr(E_Expr *expr); internal E_TypeKey e_type_key_from_expr(E_Expr *expr);
internal void e_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, E_String2ExprMap *map, E_Expr *expr); internal E_Parse e_push_type_parse_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens);
internal E_Parse e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens); internal E_Parse e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray tokens, S64 max_precedence, U64 max_chain_count);
internal E_Parse e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *tokens, S64 max_precedence); internal E_Parse e_push_parse_from_string(Arena *arena, String8 text);
internal E_Parse e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens);
internal E_Expr *e_parse_expr_from_text(Arena *arena, String8 text);
#endif // EVAL_PARSE_H #endif // EVAL_PARSE_H
+1487 -434
View File
File diff suppressed because it is too large Load Diff
+115 -256
View File
@@ -5,250 +5,37 @@
#define EVAL_TYPES_H #define EVAL_TYPES_H
//////////////////////////////// ////////////////////////////////
//~ rjf: Implicit Type Graph Key Types //~ rjf: Type Unwrapping
typedef enum E_TypeKeyKind typedef U32 E_TypeUnwrapFlags;
{
E_TypeKeyKind_Null,
E_TypeKeyKind_Basic,
E_TypeKeyKind_Ext,
E_TypeKeyKind_Cons,
E_TypeKeyKind_Reg,
E_TypeKeyKind_RegAlias,
}
E_TypeKeyKind;
typedef struct E_TypeKey E_TypeKey;
struct E_TypeKey
{
E_TypeKeyKind kind;
U32 u32[3];
// [0] -> E_TypeKind (Basic, Cons, Ext); Arch (Reg, RegAlias)
// [1] -> Type Index In RDI (Ext); Code (Reg, RegAlias); Type Index In Constructed (Cons)
// [2] -> RDI Index (Ext)
};
typedef struct E_TypeKeyNode E_TypeKeyNode;
struct E_TypeKeyNode
{
E_TypeKeyNode *next;
E_TypeKey v;
};
typedef struct E_TypeKeyList E_TypeKeyList;
struct E_TypeKeyList
{
E_TypeKeyNode *first;
E_TypeKeyNode *last;
U64 count;
};
////////////////////////////////
//~ rjf: Full Extracted Type Information Types
typedef enum E_MemberKind
{
E_MemberKind_Null,
E_MemberKind_DataField,
E_MemberKind_StaticData,
E_MemberKind_Method,
E_MemberKind_StaticMethod,
E_MemberKind_VirtualMethod,
E_MemberKind_VTablePtr,
E_MemberKind_Base,
E_MemberKind_VirtualBase,
E_MemberKind_NestedType,
E_MemberKind_Padding,
E_MemberKind_COUNT
}
E_MemberKind;
typedef U32 E_TypeFlags;
enum enum
{ {
E_TypeFlag_Const = (1<<0), E_TypeUnwrapFlag_Modifiers = (1<<0),
E_TypeFlag_Volatile = (1<<1), E_TypeUnwrapFlag_Pointers = (1<<1),
E_TypeFlag_External = (1<<2), E_TypeUnwrapFlag_Lenses = (1<<2),
E_TypeFlag_IsPlainText= (1<<3), E_TypeUnwrapFlag_Meta = (1<<3),
E_TypeFlag_IsCodeText = (1<<4), E_TypeUnwrapFlag_Enums = (1<<4),
E_TypeFlag_IsPathText = (1<<5), E_TypeUnwrapFlag_Aliases = (1<<5),
}; E_TypeUnwrapFlag_All = 0xffffffff,
E_TypeUnwrapFlag_AllDecorative = (E_TypeUnwrapFlag_All & ~E_TypeUnwrapFlag_Pointers)
typedef struct E_Member E_Member;
struct E_Member
{
E_MemberKind kind;
E_TypeKey type_key;
String8 name;
String8 pretty_name;
U64 off;
E_TypeKeyList inheritance_key_chain;
};
typedef struct E_MemberNode E_MemberNode;
struct E_MemberNode
{
E_MemberNode *next;
E_Member v;
};
typedef struct E_MemberList E_MemberList;
struct E_MemberList
{
E_MemberNode *first;
E_MemberNode *last;
U64 count;
};
typedef struct E_MemberArray E_MemberArray;
struct E_MemberArray
{
E_Member *v;
U64 count;
};
typedef struct E_EnumVal E_EnumVal;
struct E_EnumVal
{
String8 name;
U64 val;
};
typedef struct E_EnumValArray E_EnumValArray;
struct E_EnumValArray
{
E_EnumVal *v;
U64 count;
};
typedef struct E_Type E_Type;
struct E_Type
{
E_TypeKind kind;
E_TypeFlags flags;
String8 name;
U64 byte_size;
U64 count;
U32 off;
E_TypeKey direct_type_key;
E_TypeKey owner_type_key;
E_TypeKey *param_type_keys;
E_Member *members;
E_EnumVal *enum_vals;
};
////////////////////////////////
//~ rjf: Evaluation Context
//- rjf: constructed type cache types
typedef struct E_ConsTypeParams E_ConsTypeParams;
struct E_ConsTypeParams
{
Arch arch;
E_TypeKind kind;
E_TypeFlags flags;
String8 name;
E_TypeKey direct_key;
U64 count;
E_Member *members;
E_EnumVal *enum_vals;
};
typedef struct E_ConsTypeNode E_ConsTypeNode;
struct E_ConsTypeNode
{
E_ConsTypeNode *key_next;
E_ConsTypeNode *content_next;
E_TypeKey key;
E_ConsTypeParams params;
U64 byte_size;
};
typedef struct E_ConsTypeSlot E_ConsTypeSlot;
struct E_ConsTypeSlot
{
E_ConsTypeNode *first;
E_ConsTypeNode *last;
};
//- rjf: member lookup cache types
typedef struct E_MemberHashNode E_MemberHashNode;
struct E_MemberHashNode
{
E_MemberHashNode *next;
U64 member_idx;
};
typedef struct E_MemberHashSlot E_MemberHashSlot;
struct E_MemberHashSlot
{
E_MemberHashNode *first;
E_MemberHashNode *last;
};
typedef struct E_MemberCacheNode E_MemberCacheNode;
struct E_MemberCacheNode
{
E_MemberCacheNode *next;
E_TypeKey key;
E_MemberArray members;
U64 member_hash_slots_count;
E_MemberHashSlot *member_hash_slots;
};
typedef struct E_MemberCacheSlot E_MemberCacheSlot;
struct E_MemberCacheSlot
{
E_MemberCacheNode *first;
E_MemberCacheNode *last;
};
//- rjf: context parameterization
typedef struct E_TypeCtx E_TypeCtx;
struct E_TypeCtx
{
// rjf: instruction pointer info
U64 ip_vaddr;
U64 ip_voff; // (within `primary_module`)
// rjf: debug info
E_Module *modules;
U64 modules_count;
E_Module *primary_module;
};
//- rjf: stateful machine part of context (not provided by user)
typedef struct E_TypeState E_TypeState;
struct E_TypeState
{
Arena *arena;
U64 arena_eval_start_pos;
// rjf: evaluation context
E_TypeCtx *ctx;
// rjf: JIT-constructed types tables
U64 cons_id_gen;
U64 cons_content_slots_count;
U64 cons_key_slots_count;
E_ConsTypeSlot *cons_content_slots;
E_ConsTypeSlot *cons_key_slots;
// rjf: member cache table
U64 member_cache_slots_count;
E_MemberCacheSlot *member_cache_slots;
}; };
//////////////////////////////// ////////////////////////////////
//~ rjf: Globals //~ rjf: Globals
global read_only E_Member e_member_nil = {E_MemberKind_Null, zero_struct, {0}, {0}, 0, {0}}; global read_only E_Member e_member_nil = {E_MemberKind_Null};
global read_only E_Type e_type_nil = {E_TypeKind_Null}; global read_only E_Type e_type_nil = {E_TypeKind_Null};
thread_static E_TypeState *e_type_state = 0; E_TYPE_EXPAND_INFO_FUNCTION_DEF(default);
E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default);
E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity);
E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity);
global read_only E_TypeExpandRule e_type_expand_rule__default =
{
E_TYPE_EXPAND_INFO_FUNCTION_NAME(default),
E_TYPE_EXPAND_RANGE_FUNCTION_NAME(default),
E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity),
E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity),
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Type Kind Enum Functions //~ rjf: Type Kind Enum Functions
@@ -270,10 +57,11 @@ internal void e_member_list_push(Arena *arena, E_MemberList *list, E_Member *mem
internal E_MemberArray e_member_array_from_list(Arena *arena, E_MemberList *list); internal E_MemberArray e_member_array_from_list(Arena *arena, E_MemberList *list);
//////////////////////////////// ////////////////////////////////
//~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) //~ rjf: Enum Value Functions
internal E_TypeCtx *e_selected_type_ctx(void); internal void e_enum_val_list_push(Arena *arena, E_EnumValList *list, E_EnumVal *enum_val);
internal void e_select_type_ctx(E_TypeCtx *ctx); #define e_enum_val_list_push_new(arena, list, ...) e_enum_val_list_push((arena), (list), &(E_EnumVal){.val = 0, __VA_ARGS__})
internal E_EnumValArray e_enum_val_array_from_list(Arena *arena, E_EnumValList *list);
//////////////////////////////// ////////////////////////////////
//~ rjf: Type Operation Functions //~ rjf: Type Operation Functions
@@ -292,42 +80,113 @@ internal E_TypeKey e_type_key_cons_(E_ConsTypeParams *params);
#define e_type_key_cons(...) e_type_key_cons_(&(E_ConsTypeParams){.kind = E_TypeKind_Null, __VA_ARGS__}) #define e_type_key_cons(...) e_type_key_cons_(&(E_ConsTypeParams){.kind = E_TypeKind_Null, __VA_ARGS__})
//- rjf: constructed type construction helpers //- rjf: constructed type construction helpers
internal E_TypeKey e_type_key_cons_array(E_TypeKey element_type_key, U64 count); internal E_TypeKey e_type_key_cons_array(E_TypeKey element_type_key, U64 count, E_TypeFlags flags);
internal E_TypeKey e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key, E_TypeFlags flags); internal E_TypeKey e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key, U64 count, E_TypeFlags flags);
internal E_TypeKey e_type_key_cons_meta_expr(E_TypeKey type_key, String8 expr);
internal E_TypeKey e_type_key_cons_meta_display_name(E_TypeKey type_key, String8 name);
internal E_TypeKey e_type_key_cons_meta_description(E_TypeKey type_key, String8 desc);
internal E_TypeKey e_type_key_cons_base(Type *type); internal E_TypeKey e_type_key_cons_base(Type *type);
internal E_TypeKey e_type_key_file(void);
internal E_TypeKey e_type_key_folder(void);
//- rjf: basic type key functions //- rjf: basic type key functions
internal B32 e_type_key_match(E_TypeKey l, E_TypeKey r); internal B32 e_type_key_match(E_TypeKey l, E_TypeKey r);
//- rjf: key -> info extraction //- rjf: type key -> info extraction
internal U64 e_hash_from_type_key(E_TypeKey key); internal U64 e_hash_from_type(E_Type *type);
internal E_TypeKind e_type_kind_from_key(E_TypeKey key); internal E_TypeKind e_type_kind_from_key(E_TypeKey key);
internal U64 e_type_byte_size_from_key(E_TypeKey key); internal U64 e_type_byte_size_from_key(E_TypeKey key);
internal E_Type *e_type_from_key(Arena *arena, E_TypeKey key); internal E_Type *e_push_type_from_key(Arena *arena, E_TypeKey key);
internal E_TypeKey e_type_direct_from_key(E_TypeKey key);
internal E_TypeKey e_type_owner_from_key(E_TypeKey key);
internal E_TypeKey e_type_ptee_from_key(E_TypeKey key);
internal E_TypeKey e_type_unwrap_enum(E_TypeKey key);
internal E_TypeKey e_type_unwrap(E_TypeKey key);
internal E_TypeKey e_type_promote(E_TypeKey key);
internal B32 e_type_match(E_TypeKey l, E_TypeKey r);
internal E_Member *e_type_member_copy(Arena *arena, E_Member *src);
internal int e_type_qsort_compare_members_offset(E_Member *a, E_Member *b); internal int e_type_qsort_compare_members_offset(E_Member *a, E_Member *b);
internal E_MemberArray e_type_data_members_from_key(Arena *arena, E_TypeKey key); internal E_MemberArray e_type_data_members_from_key(Arena *arena, E_TypeKey key);
internal E_Member *e_type_member_from_array_name(E_MemberArray *members, String8 name); internal E_TypeExpandRule *e_expand_rule_from_type_key(E_TypeKey key);
//- rjf: type key traversal
internal E_TypeKey e_type_key_direct(E_TypeKey key);
internal E_TypeKey e_type_key_owner(E_TypeKey key);
internal E_TypeKey e_type_key_promote(E_TypeKey key);
internal E_TypeKey e_type_key_unwrap(E_TypeKey key, E_TypeUnwrapFlags flags);
//- rjf: type comparisons
internal B32 e_type_match(E_TypeKey l, E_TypeKey r);
//- rjf: type key -> string
internal void e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 prec, B32 skip_return); internal void e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 prec, B32 skip_return);
internal void e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 prec); internal void e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 prec);
internal String8 e_type_string_from_key(Arena *arena, E_TypeKey key); internal String8 e_type_string_from_key(Arena *arena, E_TypeKey key);
internal E_TypeKey e_default_expansion_type_from_key(E_TypeKey key);
//- rjf: type key data structures
internal void e_type_key_list_push(Arena *arena, E_TypeKeyList *list, E_TypeKey key);
internal E_TypeKeyList e_type_key_list_copy(Arena *arena, E_TypeKeyList *src);
//////////////////////////////// ////////////////////////////////
//~ rjf: Cache Lookups //~ rjf: Cache Lookups
internal E_Type *e_type_from_key(E_TypeKey key);
//- rjf: member lookups
internal E_MemberCacheNode *e_member_cache_node_from_type_key(E_TypeKey key); internal E_MemberCacheNode *e_member_cache_node_from_type_key(E_TypeKey key);
internal E_MemberArray e_type_data_members_from_key_filter__cached(E_TypeKey key, String8 filter);
internal E_MemberArray e_type_data_members_from_key__cached(E_TypeKey key); internal E_MemberArray e_type_data_members_from_key__cached(E_TypeKey key);
internal E_Member e_type_member_from_key_name__cached(E_TypeKey key, String8 name); internal E_Member e_type_member_from_key_name__cached(E_TypeKey key, String8 name);
//- rjf: enum val lookups
internal E_EnumValCacheNode *e_enum_val_cache_node_from_type_key(E_TypeKey key);
internal E_EnumValArray e_type_enum_vals_from_key_filter__cached(E_TypeKey key, String8 filter);
internal E_EnumValArray e_type_enum_vals_from_key__cached(E_TypeKey key);
internal E_EnumVal e_type_enum_val_from_key_name__cached(E_TypeKey key, String8 name);
////////////////////////////////
//~ rjf: (Built-In Type Hooks) Default Hooks
E_TYPE_EXPAND_INFO_FUNCTION_DEF(default);
E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default);
E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity);
E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity);
////////////////////////////////
//~ rjf: (Built-In Type Hooks) `rows` lens
E_TYPE_EXPAND_INFO_FUNCTION_DEF(rows);
E_TYPE_EXPAND_RANGE_FUNCTION_DEF(rows);
////////////////////////////////
//~ rjf: (Built-In Type Hooks) `sequence` lens
E_TYPE_EXPAND_INFO_FUNCTION_DEF(sequence);
E_TYPE_EXPAND_RANGE_FUNCTION_DEF(sequence);
////////////////////////////////
//~ rjf: (Built-In Type Hooks) `array` lens
E_TYPE_EXPAND_INFO_FUNCTION_DEF(array);
E_TYPE_EXPAND_RANGE_FUNCTION_DEF(array);
////////////////////////////////
//~ rjf: (Built-In Type Hooks) `slice` lens
E_TYPE_IREXT_FUNCTION_DEF(slice);
E_TYPE_ACCESS_FUNCTION_DEF(slice);
E_TYPE_EXPAND_INFO_FUNCTION_DEF(slice);
E_TYPE_EXPAND_RANGE_FUNCTION_DEF(slice);
////////////////////////////////
//~ rjf: (Built-In Type Hooks) `only`, `omit` lenses
E_TYPE_EXPAND_INFO_FUNCTION_DEF(only_and_omit);
E_TYPE_EXPAND_RANGE_FUNCTION_DEF(only_and_omit);
////////////////////////////////
//~ rjf: (Built-In Type Hooks) `folder` type
E_TYPE_EXPAND_INFO_FUNCTION_DEF(folder);
E_TYPE_EXPAND_RANGE_FUNCTION_DEF(folder);
E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(folder);
E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(folder);
////////////////////////////////
//~ rjf: (Built-In Type Hooks) `file` type
E_TYPE_IREXT_FUNCTION_DEF(file);
E_TYPE_ACCESS_FUNCTION_DEF(file);
E_TYPE_EXPAND_INFO_FUNCTION_DEF(file);
E_TYPE_EXPAND_RANGE_FUNCTION_DEF(file);
#endif // EVAL_TYPES_H #endif // EVAL_TYPES_H
+184 -172
View File
@@ -14,126 +14,72 @@ str8_lit_comp("CharLiteral"),
str8_lit_comp("Symbol"), str8_lit_comp("Symbol"),
}; };
String8 e_expr_kind_strings[48] = String8 e_type_kind_basic_string_table[61] =
{
str8_lit_comp("Nil"),
str8_lit_comp("Ref"),
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("Typeof"),
str8_lit_comp("ByteSwap"),
str8_lit_comp("Pos"),
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("LeafStringLiteral"),
str8_lit_comp("LeafBool"),
str8_lit_comp("LeafU64"),
str8_lit_comp("LeafF64"),
str8_lit_comp("LeafF32"),
str8_lit_comp("LeafIdent"),
str8_lit_comp("LeafOffset"),
str8_lit_comp("LeafFilePath"),
str8_lit_comp("TypeIdent"),
str8_lit_comp("Ptr"),
str8_lit_comp("Array"),
str8_lit_comp("Func"),
str8_lit_comp("Define"),
};
String8 e_interpretation_code_display_strings[11] =
{ {
str8_lit_comp(""), str8_lit_comp(""),
str8_lit_comp("Cannot divide by zero."), str8_lit_comp("void"),
str8_lit_comp("Invalid operation."), str8_lit_comp("HANDLE"),
str8_lit_comp("Invalid operation types."), str8_lit_comp("HRESULT"),
str8_lit_comp("Failed memory read."), str8_lit_comp("char8"),
str8_lit_comp("Failed register read."), str8_lit_comp("char16"),
str8_lit_comp("Invalid frame base address."), str8_lit_comp("char32"),
str8_lit_comp("Invalid module base address."), str8_lit_comp("uchar8"),
str8_lit_comp("Invalid thread-local storage base address."), str8_lit_comp("uchar16"),
str8_lit_comp("Insufficient evaluation machine stack space."), str8_lit_comp("uchar32"),
str8_lit_comp("Malformed bytecode."), str8_lit_comp("uint8"),
str8_lit_comp("uint16"),
str8_lit_comp("uint32"),
str8_lit_comp("uint64"),
str8_lit_comp("uint128"),
str8_lit_comp("uint256"),
str8_lit_comp("uint512"),
str8_lit_comp("int8"),
str8_lit_comp("int16"),
str8_lit_comp("int32"),
str8_lit_comp("int64"),
str8_lit_comp("int128"),
str8_lit_comp("int256"),
str8_lit_comp("int512"),
str8_lit_comp("bool"),
str8_lit_comp("float16"),
str8_lit_comp("float32"),
str8_lit_comp("float32PP"),
str8_lit_comp("float48"),
str8_lit_comp("float64"),
str8_lit_comp("float80"),
str8_lit_comp("float128"),
str8_lit_comp("complex_float32"),
str8_lit_comp("complex_float64"),
str8_lit_comp("complex_float80"),
str8_lit_comp("complex_float128"),
str8_lit_comp("modifier"),
str8_lit_comp("ptr"),
str8_lit_comp("lref"),
str8_lit_comp("rref"),
str8_lit_comp("array"),
str8_lit_comp("function"),
str8_lit_comp("method"),
str8_lit_comp("member_ptr"),
str8_lit_comp("struct"),
str8_lit_comp("class"),
str8_lit_comp("union"),
str8_lit_comp("enum"),
str8_lit_comp("typedef"),
str8_lit_comp("struct"),
str8_lit_comp("union"),
str8_lit_comp("class"),
str8_lit_comp("enum"),
str8_lit_comp("bitfield"),
str8_lit_comp("variadic"),
str8_lit_comp("set"),
str8_lit_comp("lens"),
str8_lit_comp("lens_spec"),
str8_lit_comp("meta_expr"),
str8_lit_comp("meta_display_name"),
str8_lit_comp("meta_description"),
}; };
E_OpInfo e_expr_kind_op_info_table[48] = U8 e_type_kind_basic_byte_size_table[61] =
{
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("["), str8_lit_comp("]") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("."), str8_lit_comp("") },
{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("*"), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("&"), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 1, str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp("") },
{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("sizeof"), str8_lit_comp("("), str8_lit_comp(")") },
{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("typeof"), str8_lit_comp("("), str8_lit_comp(")") },
{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("bswap"), str8_lit_comp("("), str8_lit_comp(")") },
{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("+"), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("-"), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("!"), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("~"), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("*"), str8_lit_comp("") },
{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("/"), str8_lit_comp("") },
{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("%"), str8_lit_comp("") },
{ E_OpKind_Binary, 4, str8_lit_comp(""), str8_lit_comp("+"), str8_lit_comp("") },
{ E_OpKind_Binary, 4, str8_lit_comp(""), str8_lit_comp("-"), str8_lit_comp("") },
{ E_OpKind_Binary, 5, str8_lit_comp(""), str8_lit_comp("<<"), str8_lit_comp("") },
{ E_OpKind_Binary, 5, str8_lit_comp(""), str8_lit_comp(">>"), str8_lit_comp("") },
{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp("<"), str8_lit_comp("") },
{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp("<="), str8_lit_comp("") },
{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(">"), str8_lit_comp("") },
{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(">="), str8_lit_comp("") },
{ E_OpKind_Binary, 7, str8_lit_comp(""), str8_lit_comp("=="), str8_lit_comp("") },
{ E_OpKind_Binary, 7, str8_lit_comp(""), str8_lit_comp("!="), str8_lit_comp("") },
{ E_OpKind_Binary, 8, str8_lit_comp(""), str8_lit_comp("&"), str8_lit_comp("") },
{ E_OpKind_Binary, 9, str8_lit_comp(""), str8_lit_comp("^"), str8_lit_comp("") },
{ E_OpKind_Binary, 10, str8_lit_comp(""), str8_lit_comp("|"), str8_lit_comp("") },
{ E_OpKind_Binary, 11, str8_lit_comp(""), str8_lit_comp("&&"), str8_lit_comp("") },
{ E_OpKind_Binary, 12, str8_lit_comp(""), str8_lit_comp("||"), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("?"), str8_lit_comp(":") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") },
};
U8 e_kind_basic_byte_size_table[56] =
{ {
0, 0,
0, 0,
@@ -191,66 +137,132 @@ U8 e_kind_basic_byte_size_table[56] =
0, 0,
0, 0,
0, 0,
0,
0,
0,
0,
0,
}; };
String8 e_kind_basic_string_table[56] = String8 e_expr_kind_strings[49] =
{
str8_lit_comp("Nil"),
str8_lit_comp("Ref"),
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("Typeof"),
str8_lit_comp("ByteSwap"),
str8_lit_comp("Pos"),
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("Call"),
str8_lit_comp("LeafBytecode"),
str8_lit_comp("LeafStringLiteral"),
str8_lit_comp("LeafU64"),
str8_lit_comp("LeafF64"),
str8_lit_comp("LeafF32"),
str8_lit_comp("LeafIdentifier"),
str8_lit_comp("LeafOffset"),
str8_lit_comp("LeafValue"),
str8_lit_comp("LeafFilePath"),
str8_lit_comp("TypeIdent"),
str8_lit_comp("Ptr"),
str8_lit_comp("Array"),
str8_lit_comp("Func"),
str8_lit_comp("Unsigned"),
str8_lit_comp("Define"),
};
E_OpInfo e_expr_kind_op_info_table[49] =
{
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("["), str8_lit_comp("]"), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("."), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("*"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("&"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 1, str8_lit_comp("cast("), str8_lit_comp(")"), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("sizeof "), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("typeof "), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_UnaryPrefix, 1, str8_lit_comp("bswap "), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("+"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("-"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("!"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("~"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp(" * "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp(" / "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp(" % "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 4, str8_lit_comp(""), str8_lit_comp(" + "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 4, str8_lit_comp(""), str8_lit_comp(" - "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 5, str8_lit_comp(""), str8_lit_comp(" << "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 5, str8_lit_comp(""), str8_lit_comp(" >> "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(" < "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(" <= "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(" > "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(" >= "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 7, str8_lit_comp(""), str8_lit_comp(" == "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 7, str8_lit_comp(""), str8_lit_comp(" != "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 8, str8_lit_comp(""), str8_lit_comp(" & "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 9, str8_lit_comp(""), str8_lit_comp(" ^ "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 10, str8_lit_comp(""), str8_lit_comp(" | "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 11, str8_lit_comp(""), str8_lit_comp(" && "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 12, str8_lit_comp(""), str8_lit_comp(" || "), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(" ? "), str8_lit_comp(""), str8_lit_comp(" : ") },
{ E_OpKind_Null, 15, str8_lit_comp(""), str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp(", ") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Null, 0, str8_lit_comp("unsigned "), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
{ E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp(" = "), str8_lit_comp(""), str8_lit_comp("") },
};
String8 e_interpretation_code_display_strings[11] =
{ {
str8_lit_comp(""), str8_lit_comp(""),
str8_lit_comp("void"), str8_lit_comp("Cannot divide by zero."),
str8_lit_comp("HANDLE"), str8_lit_comp("Invalid operation."),
str8_lit_comp("HRESULT"), str8_lit_comp("Invalid operation types."),
str8_lit_comp("char8"), str8_lit_comp("Failed memory read."),
str8_lit_comp("char16"), str8_lit_comp("Failed register read."),
str8_lit_comp("char32"), str8_lit_comp("Invalid frame base address."),
str8_lit_comp("uchar8"), str8_lit_comp("Invalid module base address."),
str8_lit_comp("uchar16"), str8_lit_comp("Invalid thread-local storage base address."),
str8_lit_comp("uchar32"), str8_lit_comp("Insufficient evaluation machine stack space."),
str8_lit_comp("U8"), str8_lit_comp("Malformed bytecode."),
str8_lit_comp("U16"),
str8_lit_comp("U32"),
str8_lit_comp("U64"),
str8_lit_comp("U128"),
str8_lit_comp("U256"),
str8_lit_comp("U512"),
str8_lit_comp("S8"),
str8_lit_comp("S16"),
str8_lit_comp("S32"),
str8_lit_comp("S64"),
str8_lit_comp("S128"),
str8_lit_comp("S256"),
str8_lit_comp("S512"),
str8_lit_comp("bool"),
str8_lit_comp("F16"),
str8_lit_comp("F32"),
str8_lit_comp("F32PP"),
str8_lit_comp("F48"),
str8_lit_comp("F64"),
str8_lit_comp("F80"),
str8_lit_comp("F128"),
str8_lit_comp("ComplexF32"),
str8_lit_comp("ComplexF64"),
str8_lit_comp("ComplexF80"),
str8_lit_comp("ComplexF128"),
str8_lit_comp("modifier"),
str8_lit_comp("ptr"),
str8_lit_comp("lref"),
str8_lit_comp("rref"),
str8_lit_comp("array"),
str8_lit_comp("function"),
str8_lit_comp("method"),
str8_lit_comp("member_ptr"),
str8_lit_comp("struct"),
str8_lit_comp("class"),
str8_lit_comp("union"),
str8_lit_comp("enum"),
str8_lit_comp("typedef"),
str8_lit_comp("struct"),
str8_lit_comp("union"),
str8_lit_comp("class"),
str8_lit_comp("enum"),
str8_lit_comp("bitfield"),
str8_lit_comp("variadic"),
str8_lit_comp("collection"),
}; };
C_LINKAGE_END C_LINKAGE_END
+16 -8
View File
@@ -74,7 +74,12 @@ E_TypeKind_IncompleteClass,
E_TypeKind_IncompleteEnum, E_TypeKind_IncompleteEnum,
E_TypeKind_Bitfield, E_TypeKind_Bitfield,
E_TypeKind_Variadic, E_TypeKind_Variadic,
E_TypeKind_Collection, E_TypeKind_Set,
E_TypeKind_Lens,
E_TypeKind_LensSpec,
E_TypeKind_MetaExpr,
E_TypeKind_MetaDisplayName,
E_TypeKind_MetaDescription,
E_TypeKind_COUNT, E_TypeKind_COUNT,
E_TypeKind_FirstBasic = E_TypeKind_Void, E_TypeKind_FirstBasic = E_TypeKind_Void,
E_TypeKind_LastBasic = E_TypeKind_ComplexF128, E_TypeKind_LastBasic = E_TypeKind_ComplexF128,
@@ -86,6 +91,8 @@ E_TypeKind_FirstSigned2 = E_TypeKind_S8,
E_TypeKind_LastSigned2 = E_TypeKind_S512, E_TypeKind_LastSigned2 = E_TypeKind_S512,
E_TypeKind_FirstIncomplete = E_TypeKind_IncompleteStruct, E_TypeKind_FirstIncomplete = E_TypeKind_IncompleteStruct,
E_TypeKind_LastIncomplete = E_TypeKind_IncompleteEnum, E_TypeKind_LastIncomplete = E_TypeKind_IncompleteEnum,
E_TypeKind_FirstMeta = E_TypeKind_MetaExpr,
E_TypeKind_LastMeta = E_TypeKind_MetaDescription,
} E_TypeKind; } E_TypeKind;
typedef U32 E_ExprKind; typedef U32 E_ExprKind;
@@ -124,20 +131,21 @@ E_ExprKind_BitOr,
E_ExprKind_LogAnd, E_ExprKind_LogAnd,
E_ExprKind_LogOr, E_ExprKind_LogOr,
E_ExprKind_Ternary, E_ExprKind_Ternary,
E_ExprKind_Call,
E_ExprKind_LeafBytecode, E_ExprKind_LeafBytecode,
E_ExprKind_LeafMember,
E_ExprKind_LeafStringLiteral, E_ExprKind_LeafStringLiteral,
E_ExprKind_LeafBool,
E_ExprKind_LeafU64, E_ExprKind_LeafU64,
E_ExprKind_LeafF64, E_ExprKind_LeafF64,
E_ExprKind_LeafF32, E_ExprKind_LeafF32,
E_ExprKind_LeafIdent, E_ExprKind_LeafIdentifier,
E_ExprKind_LeafOffset, E_ExprKind_LeafOffset,
E_ExprKind_LeafValue,
E_ExprKind_LeafFilePath, E_ExprKind_LeafFilePath,
E_ExprKind_TypeIdent, E_ExprKind_TypeIdent,
E_ExprKind_Ptr, E_ExprKind_Ptr,
E_ExprKind_Array, E_ExprKind_Array,
E_ExprKind_Func, E_ExprKind_Func,
E_ExprKind_Unsigned,
E_ExprKind_Define, E_ExprKind_Define,
E_ExprKind_COUNT, E_ExprKind_COUNT,
} E_ExprKindEnum; } E_ExprKindEnum;
@@ -160,11 +168,11 @@ E_InterpretationCode_COUNT,
C_LINKAGE_BEGIN C_LINKAGE_BEGIN
extern String8 e_token_kind_strings[6]; extern String8 e_token_kind_strings[6];
extern String8 e_expr_kind_strings[48]; extern String8 e_type_kind_basic_string_table[61];
extern U8 e_type_kind_basic_byte_size_table[61];
extern String8 e_expr_kind_strings[49];
extern E_OpInfo e_expr_kind_op_info_table[49];
extern String8 e_interpretation_code_display_strings[11]; extern String8 e_interpretation_code_display_strings[11];
extern E_OpInfo e_expr_kind_op_info_table[48];
extern U8 e_kind_basic_byte_size_table[56];
extern String8 e_kind_basic_string_table[56];
C_LINKAGE_END C_LINKAGE_END
@@ -1,127 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Built-In View Rules
//
// @view_rule_info
//
// NOTE(rjf): View rules are subtle in that they may impact any subset of the
// eval visualization pipeline. The "array" view rule, for example, functions
// by tweaking the type of an eval from `X *` to `X (*)[N]` (where N is
// computed from whatever expression is specified by the view rule). The "list"
// view rule, on the other hand, does not require any changes to the actual
// eval nor its type - instead, it follows an alternative path in constructing
// "viz blocks", and then constructing "viz rows" from those blocks. Compare
// these to the simpler 'dec', 'bin', or 'oct' rules, which simply tweak the
// radix used when stringizing numbers, which is something that only occurs in
// single-line eval stringization building.
//
// As such, each view rule specification has a mask, which determines which
// stages it may be used for. For a given view rule specification, if the bit
// corresponding to a particular eval stage is set, then that view rule spec-
// -ification also includes a hook which can be called from that stage.
//
// Below is a list of the stages in the eval visualization pipeline, as well as
// abbreviations which are used in the tables.
//
// expr resolution, "xp" -> provides a chance for a view rule to make
// modifications to expression trees that it is
// applied to
//
// viz block prod, "vb" -> given a resolved eval, produce a list of non-
// windowed "viz blocks", which correspond to one or
// many contiguous rows in a watch-window-style UI.
// one level of expanded struct members, with no sub-
// expansions, would be one viz block. if one of those
// members - in the middle - were expanded too, then
// it would require three viz blocks - one for the
// members before the sub-expansion, one for the
// sub expansion members, and one for the members
// after, and so on. this is done recursively.
//
// viz row prod, "vr" -> given a list of viz blocks, a windowed list of viz
// rows may be produced. each of these rows has info
// for building actual UI in e.g. a watch window -
// whether or not the row can be expanded, whether or
// not the row's value can be edited, what the edit-
// able string is for a row, what the display string
// is for a row, what the expression string is for a
// row, what the type is for a row, and so on.
//
// line stringize, "ls" -> this is the stage used to produce display strings
// in the "viz row prod" stage, as well as basically
// any time UI needs to display the result of an eval
// in a single line. this also occurs recursively,
// descending into members & elements as needed,
// constrained by # of available pixels and font size
// and so on.
//
// row ui build, "ru" -> finally, after the previous stages are completed,
// ui can finally be built according to all of the
// per-row information produced. this is the stage
// where view rules can insert their own arbitrary ui
// on a per-row basis.
//
// view ui build, "vu" -> view rules which want to supply more sophisticated
// visualizers have the ability to provide full
// arbitrary UI hooks, which can either be produced
// in a minified form via watch views, or via a
// standalone tab.
//
// 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:
//
// inherited, "ih" -> is this view rule included, or not included, in
// child expansions?
//
// expandable, "ex" -> does this view rule force the ability to expand
// an expression, even if traditional analysis of type
// info would not allow expansion?
//
// Not all of these stages are specified at this layer, however, since the
// "df_core" layer is for the non-graphical core debugger features. So the
// information pertaining to the eval visualization pipeline stages which
// do require graphical subsystems (e.g. UI, fonts, rendering) are specified
// in the "df_gfx" layer.
//
// For any view rules in this layer which also have graphical features, they
// are specified in both tables under the same name.
@table(coverage_check name name_lower string ih ex xr xe display_name docs schema description)
EV_ViewRuleTable:
{
{x Default default "default" - - - x "Default" - "" "" }
{x Array array "array" - - x - "Array" x "x:{expr}" "Specifies that a pointer points to N elements, rather than only 1." }
{x List list "list" - - - x "Array" x "x:{expr}" "Specifies that a pointer points to N elements, rather than only 1." }
{x Slice slice "slice" - - x - "Slice" x "" "Specifies that a pointer within a struct, also containing an integer, points to the number of elements encoded by the integer." }
{x ByteSwap bswap "bswap" x - x - "Byte Swap" x "" "Specifies that all integral evaluations should be byte-swapped, such that their endianness is reversed." }
{x Cast cast "cast" - - x - "Cast" x "x:{type}" "Specifies that the expression to which the view rule is applied should be casted to the provided type." }
{x Wrap wrap "wrap" - - x - "Wrap" x "x:{expr}" "Specifies that the expression should be wrapped with the view-rule-specified expression, which will refer to the original expression as `$expr`." }
{x Only only "only" x - x - "Only" x "" "Specifies that only the provided member names should be shown in user-defined-type expansions." }
{x Omit omit "omit" x - x - "Omit" x "" "Specifies that the provided member names should not be shown in user-defined-type expansions." }
{x Bin bin "bin" x - - - "Display In Binary" x "" "Specifies that all numeric values should be shown in base 2 (binary)." }
{x Oct oct "oct" x - - - "Display In Octal" x "" "Specifies that all numeric values should be shown in base 8 (octal)." }
{x Dec dec "dec" x - - - "Display In Decimal" x "" "Specifies that all numeric values should be shown in base 10 (decimal)." }
{x Hex hex "hex" x - - - "Display In Hexadecimal" x "" "Specifies that all numeric values should be shown in base 16 (hexadecimal)." }
{x NoAddress no_addr "no_addr" x - - - "Omit Addresses" x "" "Specifies that addresses should be omitted from visualizations, if possible." }
}
@enum EV_ViewRuleKind:
{
@expand(EV_ViewRuleTable a) `$(a.name)`,
COUNT,
}
@gen
{
@expand(EV_ViewRuleTable a) `$(a.xr == "x" -> "EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(" .. a.name_lower .. ");")`;
@expand(EV_ViewRuleTable a) `$(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(" .. a.name_lower .. ");")`;
@expand(EV_ViewRuleTable a) `$(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(" .. a.name_lower .. ");")`;
}
@data(EV_ViewRuleInfo) @c_file ev_builtin_view_rule_info_table:
{
@expand(EV_ViewRuleTable a)
```{str8_lit_comp("$(a.string)"), (EV_ViewRuleInfoFlag_Inherited*$(a.ih == "x"))|(EV_ViewRuleInfoFlag_Expandable*$(a.ex == "x")), $(a.xr == "x" -> "EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME("..a.name_lower..")") $(a.xr != "x" -> "EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity)"), $(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME("..a.name_lower..")") $(a.xe != "x" -> "EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil)"), $(a.xe == "x" -> "EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME("..a.name_lower..")") $(a.xe != "x" -> "EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil)"), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) }```;
}
@@ -1,557 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: View Rule Tree Info Extraction Helpers
internal U64
ev_base_offset_from_eval(E_Eval eval)
{
if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(eval.type_key)))
{
eval = e_value_eval_from_eval(eval);
}
return eval.value.u64;
}
internal E_Value
ev_value_from_params(MD_Node *params)
{
Temp scratch = scratch_begin(0, 0);
String8 expr = md_string_from_children(scratch.arena, params);
E_Eval eval = e_eval_from_string(scratch.arena, expr);
E_Eval value_eval = e_value_eval_from_eval(eval);
scratch_end(scratch);
return value_eval.value;
}
internal E_TypeKey
ev_type_key_from_params(MD_Node *params)
{
Temp scratch = scratch_begin(0, 0);
String8 expr = md_string_from_children(scratch.arena, params);
E_TokenArray tokens = e_token_array_from_text(scratch.arena, expr);
E_Parse parse = e_parse_type_from_text_tokens(scratch.arena, expr, &tokens);
E_TypeKey type_key = e_type_from_expr(parse.expr);
scratch_end(scratch);
return type_key;
}
internal E_Value
ev_value_from_params_key(MD_Node *params, String8 key)
{
Temp scratch = scratch_begin(0, 0);
MD_Node *key_node = md_child_from_string(params, key, 0);
String8 expr = md_string_from_children(scratch.arena, key_node);
E_Eval eval = e_eval_from_string(scratch.arena, expr);
E_Eval value_eval = e_value_eval_from_eval(eval);
scratch_end(scratch);
return value_eval.value;
}
internal Rng1U64
ev_range_from_eval_params(E_Eval eval, MD_Node *params)
{
Temp scratch = scratch_begin(0, 0);
U64 size = ev_value_from_params_key(params, str8_lit("size")).u64;
E_TypeKey type_key = e_type_unwrap(eval.type_key);
E_TypeKind type_kind = e_type_kind_from_key(type_key);
E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(eval.type_key));
E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key);
if(size == 0 && e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct ||
direct_type_kind == E_TypeKind_Union ||
direct_type_kind == E_TypeKind_Class ||
direct_type_kind == E_TypeKind_Array))
{
size = e_type_byte_size_from_key(e_type_direct_from_key(e_type_unwrap(eval.type_key)));
}
if(size == 0 && eval.mode == E_Mode_Offset && (type_kind == E_TypeKind_Struct ||
type_kind == E_TypeKind_Union ||
type_kind == E_TypeKind_Class ||
type_kind == E_TypeKind_Array))
{
size = e_type_byte_size_from_key(e_type_unwrap(eval.type_key));
}
if(size == 0)
{
size = 16384;
}
Rng1U64 result = {0};
result.min = ev_base_offset_from_eval(eval);
result.max = result.min + size;
scratch_end(scratch);
return result;
}
internal Arch
ev_arch_from_eval_params(E_Eval eval, MD_Node *params)
{
Arch arch = Arch_Null;
MD_Node *arch_node = md_child_from_string(params, str8_lit("arch"), 0);
String8 arch_kind_string = arch_node->first->string;
if(str8_match(arch_kind_string, str8_lit("x64"), StringMatchFlag_CaseInsensitive))
{
arch = Arch_x64;
}
return arch;
}
////////////////////////////////
//~ rjf: default
typedef struct EV_DefaultExpandAccel EV_DefaultExpandAccel;
struct EV_DefaultExpandAccel
{
E_MemberArray members;
E_EnumValArray enum_vals;
U64 array_count;
B32 array_need_extra_deref;
B32 is_ptr2ptr;
};
EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(default)
{
Temp scratch = scratch_begin(&arena, 1);
U64 total_row_count = 0;
EV_DefaultExpandAccel *accel = push_array(arena, EV_DefaultExpandAccel, 1);
////////////////////////////
//- rjf: unpack expression type info
//
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr);
E_TypeKey type_key = e_type_unwrap(irtree.type_key);
E_TypeKind type_kind = e_type_kind_from_key(type_key);
E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(type_key));
E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key);
////////////////////////////
//- rjf: structs/unions/classes -> expansions generate rows for all members
//
if((type_kind == E_TypeKind_Struct ||
type_kind == E_TypeKind_Union ||
type_kind == E_TypeKind_Class) ||
(e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct ||
direct_type_kind == E_TypeKind_Union ||
direct_type_kind == E_TypeKind_Class)))
{
E_TypeKey struct_type_key = e_type_kind_is_pointer_or_ref(type_kind) ? direct_type_key : type_key;
accel->members = e_type_data_members_from_key__cached(struct_type_key);
total_row_count = accel->members.count;
}
////////////////////////////
//- rjf: enums -> expansions generate rows for all members
//
else if(type_kind == E_TypeKind_Enum ||
(e_type_kind_is_pointer_or_ref(type_kind) && direct_type_kind == E_TypeKind_Enum))
{
E_Type *type = e_type_from_key(arena, e_type_kind_is_pointer_or_ref(type_kind) ? direct_type_key : type_key);
accel->enum_vals.v = type->enum_vals;
accel->enum_vals.count = type->count;
total_row_count = accel->enum_vals.count;
}
////////////////////////////
//- rjf: arrays -> expansions generate rows for all elements
//
else if(type_kind == E_TypeKind_Array ||
(e_type_kind_is_pointer_or_ref(type_kind) && direct_type_kind == E_TypeKind_Array))
{
B32 need_extra_deref = e_type_kind_is_pointer_or_ref(type_kind);
E_Expr *array_expr = need_extra_deref ? e_expr_ref_deref(arena, expr) : expr;
E_Type *type = e_type_from_key(arena, need_extra_deref ? direct_type_key : type_key);
total_row_count = type->count;
accel->array_count = type->count;
accel->array_need_extra_deref = need_extra_deref;
}
////////////////////////////
//- rjf: pointer-to-pointer -> expansions generate dereference
//
else if(e_type_kind_is_pointer_or_ref(type_kind) && e_type_kind_is_pointer_or_ref(direct_type_kind))
{
total_row_count = 1;
accel->is_ptr2ptr = 1;
}
////////////////////////////
//- rjf: package result
//
EV_ExpandInfo result = {0};
{
result.user_data = accel;
result.row_count = total_row_count;
}
scratch_end(scratch);
return result;
}
EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(default)
{
EV_DefaultExpandAccel *accel = (EV_DefaultExpandAccel *)user_data;
EV_ExpandRangeInfo result = {0};
U64 needed_row_count = dim_1u64(idx_range);
////////////////////////////
//- rjf: fill with members
//
if(accel->members.count != 0)
{
E_MemberArray *members = &accel->members;
result.row_exprs_count = Min(needed_row_count, members->count);
result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count);
result.row_strings = push_array(arena, String8, result.row_exprs_count);
result.row_view_rules = push_array(arena, String8, result.row_exprs_count);
result.row_members = push_array(arena, E_Member *, result.row_exprs_count);
for EachIndex(row_expr_idx, result.row_exprs_count)
{
E_Member *member = &members->v[idx_range.min + row_expr_idx];
result.row_exprs[row_expr_idx] = e_expr_ref_member_access(arena, expr, member->name);
result.row_members[row_expr_idx] = member;
}
}
////////////////////////////
//- rjf: fill with enum vals
//
else if(accel->enum_vals.count != 0)
{
E_EnumValArray *enumvals = &accel->enum_vals;
result.row_exprs_count = Min(needed_row_count, enumvals->count);
result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count);
result.row_strings = push_array(arena, String8, result.row_exprs_count);
result.row_view_rules = push_array(arena, String8, result.row_exprs_count);
result.row_members = push_array(arena, E_Member *, result.row_exprs_count);
for EachIndex(row_expr_idx, result.row_exprs_count)
{
E_EnumVal *enumval = &enumvals->v[idx_range.min + row_expr_idx];
result.row_exprs[row_expr_idx] = e_expr_ref_member_access(arena, expr, enumval->name);
result.row_members[row_expr_idx] = &e_member_nil;
}
}
////////////////////////////
//- rjf: fill with array indices
//
else if(accel->array_count != 0)
{
E_Expr *array_expr = accel->array_need_extra_deref ? e_expr_ref_deref(arena, expr) : expr;
result.row_exprs_count = Min(needed_row_count, accel->array_count);
result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count);
result.row_strings = push_array(arena, String8, result.row_exprs_count);
result.row_view_rules = push_array(arena, String8, result.row_exprs_count);
result.row_members = push_array(arena, E_Member *, result.row_exprs_count);
for EachIndex(row_expr_idx, result.row_exprs_count)
{
result.row_exprs[row_expr_idx] = e_expr_ref_array_index(arena, array_expr, idx_range.min + row_expr_idx);
result.row_members[row_expr_idx] = &e_member_nil;
}
}
////////////////////////////
//- rjf: fill with ptr-to-ptr deref
//
else if(accel->is_ptr2ptr)
{
result.row_exprs_count = 1;
result.row_exprs = push_array(arena, E_Expr *, result.row_exprs_count);
result.row_strings = push_array(arena, String8, result.row_exprs_count);
result.row_view_rules = push_array(arena, String8, result.row_exprs_count);
result.row_members = push_array(arena, E_Member *, result.row_exprs_count);
result.row_exprs[0] = e_expr_ref_deref(arena, expr);
result.row_members[0] = &e_member_nil;
}
return result;
}
////////////////////////////////
//~ rjf: "array"
EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(array)
{
Temp scratch = scratch_begin(&arena, 1);
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr);
E_TypeKey type_key = irtree.type_key;
E_TypeKind type_kind = e_type_kind_from_key(type_key);
if(e_type_kind_is_pointer_or_ref(type_kind))
{
E_Value count = ev_value_from_params(params);
E_TypeKey element_type_key = e_type_ptee_from_key(type_key);
E_TypeKey array_type_key = e_type_key_cons_array(element_type_key, count.u64);
E_TypeKey ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, array_type_key, 0);
expr = e_expr_ref_cast(arena, ptr_type_key, expr);
}
scratch_end(scratch);
return expr;
}
////////////////////////////////
//~ rjf: "list"
EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(list)
{
EV_ExpandInfo info = {0};
return info;
}
EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(list)
{
EV_ExpandRangeInfo info = {0};
return info;
}
////////////////////////////////
//~ rjf: "slice"
EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(slice)
{
Temp scratch = scratch_begin(&arena, 1);
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr);
E_TypeKind type_kind = e_type_kind_from_key(irtree.type_key);
if(type_kind == E_TypeKind_Struct || type_kind == E_TypeKind_Class)
{
// rjf: unpack members
E_MemberArray members = e_type_data_members_from_key__cached(irtree.type_key);
// rjf: choose base pointer & count members
E_Member *base_ptr_member = 0;
E_Member *count_member = 0;
for(U64 idx = 0; idx < members.count; idx += 1)
{
E_Member *member = &members.v[idx];
E_TypeKey member_type = e_type_unwrap(member->type_key);
E_TypeKind member_type_kind = e_type_kind_from_key(member_type);
if(count_member == 0 && e_type_kind_is_integer(member_type_kind))
{
count_member = member;
}
if(base_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind))
{
base_ptr_member = &members.v[idx];
}
if(count_member != 0 && base_ptr_member != 0)
{
break;
}
}
// rjf: evaluate count member, determine count
U64 count = 0;
if(count_member != 0)
{
E_Expr *count_member_expr = e_expr_ref_member_access(scratch.arena, expr, count_member->name);
E_Eval count_member_eval = e_eval_from_expr(scratch.arena, count_member_expr);
E_Eval count_member_value_eval = e_value_eval_from_eval(count_member_eval);
count = count_member_value_eval.value.u64;
}
// rjf: generate new struct slice type
E_TypeKey slice_type_key = zero_struct;
if(base_ptr_member != 0 && count_member != 0)
{
String8 struct_name = e_type_string_from_key(scratch.arena, irtree.type_key);
E_TypeKey element_type_key = e_type_ptee_from_key(base_ptr_member->type_key);
E_TypeKey array_type_key = e_type_key_cons_array(element_type_key, count);
E_TypeKey sized_base_ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, array_type_key, 0);
E_MemberList slice_type_members = {0};
e_member_list_push(scratch.arena, &slice_type_members, count_member);
e_member_list_push(scratch.arena, &slice_type_members, &(E_Member){.kind = E_MemberKind_DataField, .type_key = sized_base_ptr_type_key, .name = base_ptr_member->name, .pretty_name = base_ptr_member->pretty_name, .off = base_ptr_member->off});
E_MemberArray slice_type_members_array = e_member_array_from_list(scratch.arena, &slice_type_members);
slice_type_key = e_type_key_cons(.arch = e_type_state->ctx->primary_module->arch,
.kind = E_TypeKind_Struct,
.name = struct_name,
.members = slice_type_members_array.v,
.count = slice_type_members_array.count);
}
// rjf: generate new expression tree - addr of struct, cast-to-ptr, deref
if(base_ptr_member != 0 && count_member != 0)
{
expr = e_expr_ref_addr(arena, expr);
expr = e_expr_ref_cast(arena, e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, slice_type_key, 0), expr);
expr = e_expr_ref_deref(arena, expr);
}
}
scratch_end(scratch);
return expr;
}
////////////////////////////////
//~ rjf: "bswap"
EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(bswap)
{
expr = e_expr_ref_bswap(arena, expr);
return expr;
}
////////////////////////////////
//~ rjf: "cast"
EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(cast)
{
E_TypeKey type_key = ev_type_key_from_params(params);
expr = e_expr_ref_cast(arena, type_key, expr);
return expr;
}
////////////////////////////////
//~ rjf: "wrap"
EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(wrap)
{
String8 wrap_string = md_string_from_children(arena, params);
E_Expr *wrap_expr = e_parse_expr_from_text(arena, wrap_string);
E_Expr *new_root_expr = wrap_expr;
if(wrap_expr != &e_expr_nil)
{
Temp scratch = scratch_begin(&arena, 1);
typedef struct Task Task;
struct Task
{
Task *next;
E_Expr *parent;
E_Expr *expr;
};
Task start_task = {0, &e_expr_nil, wrap_expr};
Task *first_task = &start_task;
Task *last_task = first_task;
for(Task *t = first_task; t != 0; t = t->next)
{
if(t->expr->kind == E_ExprKind_LeafIdent && str8_match(t->expr->string, str8_lit("$expr"), 0))
{
E_Expr *original_expr_ref = e_expr_ref(arena, expr);
if(t->parent != &e_expr_nil)
{
e_expr_insert_child(t->parent, t->expr, original_expr_ref);
e_expr_remove_child(t->parent, t->expr);
}
else
{
new_root_expr = original_expr_ref;
}
}
else for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next)
{
Task *task = push_array(scratch.arena, Task, 1);
SLLQueuePush(first_task, last_task, task);
task->parent = t->expr;
task->expr = child;
}
}
scratch_end(scratch);
}
return new_root_expr;
}
////////////////////////////////
//~ rjf: "only"
EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(only)
{
Temp scratch = scratch_begin(&arena, 1);
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr);
E_TypeKey type_key = irtree.type_key;
E_TypeKind type_kind = e_type_kind_from_key(type_key);
E_TypeKey direct_type_key = e_type_direct_from_key(type_key);
E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key);
B32 is_ptr = e_type_kind_is_pointer_or_ref(type_kind);
E_TypeKey struct_type_key = is_ptr ? direct_type_key : type_key;
E_TypeKind struct_type_kind = is_ptr ? direct_type_kind : type_kind;
if(struct_type_kind == E_TypeKind_Struct ||
struct_type_kind == E_TypeKind_Union ||
struct_type_kind == E_TypeKind_Class)
{
E_MemberArray current_members = e_type_data_members_from_key__cached(struct_type_key);
E_MemberList new_members = {0};
for MD_EachNode(node, params->first)
{
for EachIndex(idx, current_members.count)
{
if(str8_match(node->string, current_members.v[idx].name, 0))
{
e_member_list_push(scratch.arena, &new_members, &current_members.v[idx]);
break;
}
}
}
E_MemberArray new_members_array = e_member_array_from_list(scratch.arena, &new_members);
E_TypeKey new_type = {0};
if(new_members_array.count == 1 && new_members_array.v[0].off == 0)
{
new_type = new_members_array.v[0].type_key;
}
else
{
String8 struct_name = e_type_string_from_key(scratch.arena, struct_type_key);
new_type = e_type_key_cons(.kind = E_TypeKind_Struct, .name = struct_name, .members = new_members_array.v, .count = new_members_array.count);
}
if(!is_ptr)
{
expr = e_expr_ref_addr(arena, expr);
}
expr = e_expr_ref_cast(arena, e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, new_type, 0), expr);
if(!is_ptr)
{
expr = e_expr_ref_deref(arena, expr);
}
}
scratch_end(scratch);
return expr;
}
////////////////////////////////
//~ rjf: "omit"
EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(omit)
{
Temp scratch = scratch_begin(&arena, 1);
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr);
E_TypeKey type_key = irtree.type_key;
E_TypeKind type_kind = e_type_kind_from_key(type_key);
E_TypeKey direct_type_key = e_type_direct_from_key(type_key);
E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key);
B32 is_ptr = e_type_kind_is_pointer_or_ref(type_kind);
E_TypeKey struct_type_key = is_ptr ? direct_type_key : type_key;
E_TypeKind struct_type_kind = is_ptr ? direct_type_kind : type_kind;
if(struct_type_kind == E_TypeKind_Struct ||
struct_type_kind == E_TypeKind_Union ||
struct_type_kind == E_TypeKind_Class)
{
E_MemberArray current_members = e_type_data_members_from_key__cached(struct_type_key);
E_MemberList new_members = {0};
for EachIndex(idx, current_members.count)
{
B32 include = 1;
for MD_EachNode(node, params->first)
{
if(str8_match(node->string, current_members.v[idx].name, 0))
{
include = 0;
break;
}
}
if(include)
{
e_member_list_push(scratch.arena, &new_members, &current_members.v[idx]);
}
}
E_MemberArray new_members_array = e_member_array_from_list(scratch.arena, &new_members);
E_TypeKey new_type = {0};
String8 struct_name = e_type_string_from_key(scratch.arena, struct_type_key);
new_type = e_type_key_cons(.kind = E_TypeKind_Struct, .name = struct_name, .members = new_members_array.v, .count = new_members_array.count);
if(!is_ptr)
{
expr = e_expr_ref_addr(arena, expr);
}
expr = e_expr_ref_cast(arena, e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, new_type, 0), expr);
if(!is_ptr)
{
expr = e_expr_ref_deref(arena, expr);
}
}
scratch_end(scratch);
return expr;
}
@@ -1,17 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef EVAL_VISUALIZATION_BUILTIN_VIEW_RULES_H
#define EVAL_VISUALIZATION_BUILTIN_VIEW_RULES_H
////////////////////////////////
//~ rjf: View Rule Tree Info Extraction Helpers
internal U64 ev_base_offset_from_eval(E_Eval eval);
internal E_Value ev_value_from_params(MD_Node *params);
internal E_TypeKey ev_type_key_from_params(MD_Node *params);
internal E_Value ev_value_from_params_key(MD_Node *params, String8 key);
internal Rng1U64 ev_range_from_eval_params(E_Eval eval, MD_Node *params);
internal Arch ev_arch_from_eval_params(E_Eval eval, MD_Node *params);
#endif // EVAL_VISUALIZATION_BUILTIN_VIEW_RULES_H
File diff suppressed because it is too large Load Diff
+119 -186
View File
@@ -75,31 +75,7 @@ struct EV_View
}; };
//////////////////////////////// ////////////////////////////////
//~ rjf: View Rule Instance Types //~ rjf: Expansion Rule Types
typedef struct EV_ViewRule EV_ViewRule;
struct EV_ViewRule
{
MD_Node *root;
};
typedef struct EV_ViewRuleNode EV_ViewRuleNode;
struct EV_ViewRuleNode
{
EV_ViewRuleNode *next;
EV_ViewRule v;
};
typedef struct EV_ViewRuleList EV_ViewRuleList;
struct EV_ViewRuleList
{
EV_ViewRuleNode *first;
EV_ViewRuleNode *last;
U64 count;
};
////////////////////////////////
//~ rjf: View Rule Info Types
typedef struct EV_ExpandInfo EV_ExpandInfo; typedef struct EV_ExpandInfo EV_ExpandInfo;
struct EV_ExpandInfo struct EV_ExpandInfo
@@ -111,82 +87,46 @@ struct EV_ExpandInfo
B32 rows_default_expanded; B32 rows_default_expanded;
}; };
typedef struct EV_ExpandRangeInfo EV_ExpandRangeInfo; #define EV_EXPAND_RULE_INFO_FUNCTION_SIG(name) EV_ExpandInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr)
struct EV_ExpandRangeInfo #define EV_EXPAND_RULE_INFO_FUNCTION_NAME(name) ev_expand_rule_info__##name
{ #define EV_EXPAND_RULE_INFO_FUNCTION_DEF(name) internal EV_EXPAND_RULE_INFO_FUNCTION_SIG(EV_EXPAND_RULE_INFO_FUNCTION_NAME(name))
U64 row_exprs_count; typedef EV_EXPAND_RULE_INFO_FUNCTION_SIG(EV_ExpandRuleInfoHookFunctionType);
String8 *row_strings;
String8 *row_view_rules;
E_Expr **row_exprs;
E_Member **row_members;
};
#define EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_SIG(name) E_Expr *name(Arena *arena, E_Expr *expr, MD_Node *params) typedef struct EV_ExpandRule EV_ExpandRule;
#define EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(name) ev_view_rule_expr_resolution__##name struct EV_ExpandRule
#define EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_SIG(EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(name))
#define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(name) EV_ExpandInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params)
#define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(name) ev_view_rule_expr_expand_info__##name
#define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(name))
#define EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_SIG(name) EV_ExpandRangeInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data)
#define EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(name) ev_view_rule_expr_expand_range_info__##name
#define EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(name))
#define EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_SIG(name) U64 name(U64 num, void *user_data)
#define EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(name) ev_view_rule_expr_expand_id_from_num_##name
#define EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(name))
#define EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_SIG(name) U64 name(U64 id, void *user_data)
#define EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(name) ev_view_rule_expr_expand_num_from_id_##name
#define EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(name))
typedef EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_SIG(EV_ViewRuleExprResolutionHookFunctionType);
typedef EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(EV_ViewRuleExprExpandInfoHookFunctionType);
typedef EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_SIG(EV_ViewRuleExprExpandRangeInfoHookFunctionType);
typedef EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_SIG(EV_ViewRuleExprExpandIDFromNumHookFunctionType);
typedef EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_SIG(EV_ViewRuleExprExpandNumFromIDHookFunctionType);
typedef U32 EV_ViewRuleInfoFlags; // NOTE(rjf): see @view_rule_info
enum
{
EV_ViewRuleInfoFlag_Inherited = (1<<0),
EV_ViewRuleInfoFlag_Expandable = (1<<1),
};
typedef struct EV_ViewRuleInfo EV_ViewRuleInfo;
struct EV_ViewRuleInfo
{ {
String8 string; String8 string;
EV_ViewRuleInfoFlags flags; EV_ExpandRuleInfoHookFunctionType *info;
EV_ViewRuleExprResolutionHookFunctionType *expr_resolution;
EV_ViewRuleExprExpandInfoHookFunctionType *expr_expand_info;
EV_ViewRuleExprExpandRangeInfoHookFunctionType *expr_expand_range_info;
EV_ViewRuleExprExpandIDFromNumHookFunctionType *expr_expand_id_from_num;
EV_ViewRuleExprExpandIDFromNumHookFunctionType *expr_expand_num_from_id;
}; };
typedef struct EV_ViewRuleInfoNode EV_ViewRuleInfoNode; typedef struct EV_ExpandRuleNode EV_ExpandRuleNode;
struct EV_ViewRuleInfoNode struct EV_ExpandRuleNode
{ {
EV_ViewRuleInfoNode *next; EV_ExpandRuleNode *next;
EV_ViewRuleInfo v; EV_ExpandRule v;
}; };
typedef struct EV_ViewRuleInfoSlot EV_ViewRuleInfoSlot; typedef struct EV_ExpandRuleSlot EV_ExpandRuleSlot;
struct EV_ViewRuleInfoSlot struct EV_ExpandRuleSlot
{ {
EV_ViewRuleInfoNode *first; EV_ExpandRuleNode *first;
EV_ViewRuleInfoNode *last; EV_ExpandRuleNode *last;
}; };
typedef struct EV_ViewRuleInfoTable EV_ViewRuleInfoTable; typedef struct EV_ExpandRuleTable EV_ExpandRuleTable;
struct EV_ViewRuleInfoTable struct EV_ExpandRuleTable
{ {
EV_ViewRuleInfoSlot *slots; EV_ExpandRuleSlot *slots;
U64 slots_count; U64 slots_count;
}; };
typedef struct EV_ExpandRuleTagPair EV_ExpandRuleTagPair;
struct EV_ExpandRuleTagPair
{
EV_ExpandRule *rule;
E_Expr *tag;
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Blocks //~ rjf: Blocks
@@ -206,18 +146,17 @@ struct EV_Block
// rjf: split index, relative to parent's space // rjf: split index, relative to parent's space
U64 split_relative_idx; U64 split_relative_idx;
// rjf: expression / visualization info // rjf: evaluation info
String8 string; String8 string;
E_Expr *expr; E_Eval eval;
EV_ViewRuleList *view_rules; String8 filter;
EV_ViewRuleInfo *expand_view_rule_info; E_TypeExpandInfo type_expand_info;
MD_Node *expand_view_rule_params; E_TypeExpandRule *type_expand_rule;
void *expand_view_rule_info_user_data; EV_ExpandInfo viz_expand_info;
EV_ExpandRule *viz_expand_rule;
// rjf: expansion info // rjf: expansion info
U64 row_count; U64 row_count;
B32 single_item;
B32 rows_default_expanded;
}; };
typedef struct EV_BlockTree EV_BlockTree; typedef struct EV_BlockTree EV_BlockTree;
@@ -256,66 +195,32 @@ struct EV_BlockRangeList
typedef struct EV_Row EV_Row; typedef struct EV_Row EV_Row;
struct EV_Row struct EV_Row
{ {
EV_Row *next;
// rjf: block hierarchy info
EV_Block *block; EV_Block *block;
EV_Key key; EV_Key key;
// rjf: row size/scroll info
U64 visual_size; U64 visual_size;
String8 edit_string;
E_Eval eval;
};
typedef struct EV_WindowedRowNode EV_WindowedRowNode;
struct EV_WindowedRowNode
{
EV_WindowedRowNode *next;
U64 visual_size_skipped; U64 visual_size_skipped;
U64 visual_size_chopped; U64 visual_size_chopped;
EV_Row row;
// rjf: expression / visualization info
String8 string;
E_Expr *expr;
E_Member *member;
EV_ViewRuleList *view_rules;
}; };
typedef struct EV_WindowedRowList EV_WindowedRowList; typedef struct EV_WindowedRowList EV_WindowedRowList;
struct EV_WindowedRowList struct EV_WindowedRowList
{ {
EV_Row *first; EV_WindowedRowNode *first;
EV_Row *last; EV_WindowedRowNode *last;
U64 count; U64 count;
U64 count_before_visual; U64 count_before_visual;
U64 count_before_semantic; U64 count_before_semantic;
}; };
////////////////////////////////
//~ rjf: Automatic Type -> View Rule Map Types
typedef struct EV_AutoViewRuleNode EV_AutoViewRuleNode;
struct EV_AutoViewRuleNode
{
EV_AutoViewRuleNode *next;
E_TypeKey key;
String8 view_rule;
B32 is_required;
};
typedef struct EV_AutoViewRuleSlot EV_AutoViewRuleSlot;
struct EV_AutoViewRuleSlot
{
EV_AutoViewRuleNode *first;
EV_AutoViewRuleNode *last;
U64 count;
};
typedef struct EV_AutoViewRuleTable EV_AutoViewRuleTable;
struct EV_AutoViewRuleTable
{
EV_AutoViewRuleSlot *slots;
U64 slots_count;
};
////////////////////////////////
//~ rjf: Generated Code
#include "generated/eval_visualization.meta.h"
//////////////////////////////// ////////////////////////////////
//~ rjf: String Generation Types //~ rjf: String Generation Types
@@ -324,34 +229,74 @@ enum
{ {
EV_StringFlag_ReadOnlyDisplayRules = (1<<0), EV_StringFlag_ReadOnlyDisplayRules = (1<<0),
EV_StringFlag_PrettyNames = (1<<1), EV_StringFlag_PrettyNames = (1<<1),
EV_StringFlag_DisableAddresses = (1<<2),
EV_StringFlag_DisableStrings = (1<<3),
EV_StringFlag_DisableChars = (1<<4),
EV_StringFlag_DisableStringQuotes = (1<<5),
};
typedef struct EV_StringParams EV_StringParams;
struct EV_StringParams
{
EV_StringFlags flags;
U32 radix;
U32 min_digits;
U8 digit_group_separator;
String8 filter;
B32 limit_strings;
U64 limit_strings_size;
};
typedef struct EV_StringIterTask EV_StringIterTask;
struct EV_StringIterTask
{
EV_StringIterTask *next;
EV_StringParams params;
E_Eval eval;
U64 idx;
S32 depth;
B32 redirect_to_sets_and_structs;
void *user_data;
};
typedef struct EV_StringIter EV_StringIter;
struct EV_StringIter
{
EV_StringIterTask *top_task;
EV_StringIterTask *free_task;
}; };
//////////////////////////////// ////////////////////////////////
//~ rjf: Nil/Identity View Rule Hooks //~ rjf: Nil/Identity View Rule Hooks
EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(identity); EV_EXPAND_RULE_INFO_FUNCTION_DEF(nil);
EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(nil);
EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(nil);
EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity);
EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity);
//////////////////////////////// ////////////////////////////////
//~ rjf: Globals //~ rjf: Globals
global read_only EV_ViewRuleInfo ev_nil_view_rule_info = global read_only EV_ExpandRule ev_nil_expand_rule =
{ {
{0}, {0},
EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil),
};
thread_static EV_ExpandRuleTable *ev_view_rule_info_table = 0;
global read_only EV_Block ev_nil_block =
{
&ev_nil_block,
&ev_nil_block,
&ev_nil_block,
&ev_nil_block,
&ev_nil_block,
{0},
0, 0,
EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), {0},
EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), {{0}, {0}, {0}, &e_expr_nil, &e_irnode_nil},
EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), {0},
EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), {0},
EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity), &e_type_expand_rule__default,
{0},
&ev_nil_expand_rule,
}; };
thread_static EV_ViewRuleInfoTable *ev_view_rule_info_table = 0;
global read_only EV_ViewRuleList ev_nil_view_rule_list = {0};
thread_static EV_AutoViewRuleTable *ev_auto_view_rule_table = 0;
global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, &e_expr_nil, &ev_nil_view_rule_list, &ev_nil_view_rule_info};
//////////////////////////////// ////////////////////////////////
//~ rjf: Key Functions //~ rjf: Key Functions
@@ -367,6 +312,7 @@ internal U64 ev_hash_from_key(EV_Key key);
//~ rjf: Type Info Helpers //~ rjf: Type Info Helpers
//- rjf: type info -> expandability/editablity //- rjf: type info -> expandability/editablity
internal E_TypeKey ev_expansion_type_from_key(E_TypeKey type_key);
internal B32 ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode); internal B32 ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode);
internal B32 ev_type_key_is_editable(E_TypeKey type_key); internal B32 ev_type_key_is_editable(E_TypeKey type_key);
@@ -387,54 +333,37 @@ internal void ev_key_set_view_rule(EV_View *view, EV_Key key, String8 view_rule_
//////////////////////////////// ////////////////////////////////
//~ rjf: View Rule Info Table Building / Selection / Lookups //~ rjf: View Rule Info Table Building / Selection / Lookups
internal void ev_view_rule_info_table_push(Arena *arena, EV_ViewRuleInfoTable *table, EV_ViewRuleInfo *info); internal void ev_expand_rule_table_push(Arena *arena, EV_ExpandRuleTable *table, EV_ExpandRule *info);
internal void ev_view_rule_info_table_push_builtins(Arena *arena, EV_ViewRuleInfoTable *table); #define ev_expand_rule_table_push_new(arena, table, ...) ev_expand_rule_table_push((arena), (table), &(EV_ExpandRule){__VA_ARGS__})
internal void ev_select_view_rule_info_table(EV_ViewRuleInfoTable *table); internal void ev_select_expand_rule_table(EV_ExpandRuleTable *table);
internal EV_ViewRuleInfo *ev_view_rule_info_from_string(String8 string); internal EV_ExpandRule *ev_expand_rule_from_string(String8 string);
internal EV_ExpandRule *ev_expand_rule_from_type_key(E_TypeKey type_key);
////////////////////////////////
//~ rjf: Automatic Type -> View Rule Table Building / Selection / Lookups
internal void ev_auto_view_rule_table_push_new(Arena *arena, EV_AutoViewRuleTable *table, E_TypeKey type_key, String8 view_rule, B32 is_required);
internal void ev_select_auto_view_rule_table(EV_AutoViewRuleTable *table);
internal EV_ViewRuleList *ev_auto_view_rules_from_type_key(Arena *arena, E_TypeKey type_key, B32 gather_required, B32 gather_optional);
////////////////////////////////
//~ rjf: View Rule Instance List Building
internal void ev_view_rule_list_push_tree(Arena *arena, EV_ViewRuleList *list, MD_Node *root);
internal void ev_view_rule_list_push_string(Arena *arena, EV_ViewRuleList *list, String8 string);
internal EV_ViewRuleList *ev_view_rule_list_from_string(Arena *arena, String8 string);
internal EV_ViewRuleList *ev_view_rule_list_from_expr_fastpaths(Arena *arena, String8 string);
internal EV_ViewRuleList *ev_view_rule_list_from_inheritance(Arena *arena, EV_ViewRuleList *src);
internal EV_ViewRuleList *ev_view_rule_list_copy(Arena *arena, EV_ViewRuleList *src);
internal void ev_view_rule_list_concat_in_place(EV_ViewRuleList *dst, EV_ViewRuleList **src);
////////////////////////////////
//~ rjf: Expression Resolution (Dynamic Overrides, View Rule Application)
internal E_Expr *ev_resolved_from_expr(Arena *arena, E_Expr *expr, EV_ViewRuleList *view_rules);
//////////////////////////////// ////////////////////////////////
//~ rjf: Block Building //~ rjf: Block Building
internal EV_BlockTree ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules); internal EV_BlockTree ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval root_eval);
internal EV_BlockTree ev_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string, EV_ViewRuleList *view_rules);
internal U64 ev_depth_from_block(EV_Block *block); internal U64 ev_depth_from_block(EV_Block *block);
//////////////////////////////// ////////////////////////////////
//~ rjf: Block Coordinate Spaces //~ rjf: Block Coordinate Spaces
internal U64 ev_block_id_from_num(EV_Block *block, U64 num);
internal U64 ev_block_num_from_id(EV_Block *block, U64 id);
internal EV_BlockRangeList ev_block_range_list_from_tree(Arena *arena, EV_BlockTree *block_tree); internal EV_BlockRangeList ev_block_range_list_from_tree(Arena *arena, EV_BlockTree *block_tree);
internal EV_BlockRange ev_block_range_from_num(EV_BlockRangeList *block_ranges, U64 num); internal EV_BlockRange ev_block_range_from_num(EV_BlockRangeList *block_ranges, U64 num);
internal EV_Key ev_key_from_num(EV_BlockRangeList *block_ranges, U64 num); internal EV_Key ev_key_from_num(EV_BlockRangeList *block_ranges, U64 num);
internal U64 ev_num_from_key(EV_BlockRangeList *block_ranges, EV_Key key); internal U64 ev_num_from_key(EV_BlockRangeList *block_ranges, EV_Key key);
internal U64 ev_vnum_from_num(EV_BlockRangeList *block_ranges, U64 num);
internal U64 ev_num_from_vnum(EV_BlockRangeList *block_ranges, U64 vidx);
//////////////////////////////// ////////////////////////////////
//~ rjf: Row Building //~ rjf: Row Building
internal EV_WindowedRowList ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 filter, EV_BlockRangeList *block_ranges, Rng1U64 visible_range); internal EV_WindowedRowList ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, EV_BlockRangeList *block_ranges, Rng1U64 vnum_range);
internal String8 ev_expr_string_from_row(Arena *arena, EV_Row *row, EV_StringFlags flags); internal EV_Row *ev_row_from_num(Arena *arena, EV_View *view, EV_BlockRangeList *block_ranges, U64 num);
internal EV_WindowedRowList ev_rows_from_num_range(Arena *arena, EV_View *view, EV_BlockRangeList *block_ranges, Rng1U64 num_range);
internal B32 ev_eval_is_expandable(E_Eval eval);
internal B32 ev_row_is_expandable(EV_Row *row); internal B32 ev_row_is_expandable(EV_Row *row);
internal B32 ev_row_is_editable(EV_Row *row); internal B32 ev_row_is_editable(EV_Row *row);
@@ -445,7 +374,11 @@ internal B32 ev_row_is_editable(EV_Row *row);
internal String8 ev_string_from_ascii_value(Arena *arena, U8 val); internal String8 ev_string_from_ascii_value(Arena *arena, U8 val);
internal String8 ev_string_from_hresult_facility_code(U32 code); internal String8 ev_string_from_hresult_facility_code(U32 code);
internal String8 ev_string_from_hresult_code(U32 code); internal String8 ev_string_from_hresult_code(U32 code);
internal String8 ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, U32 min_digits, E_Eval eval); internal String8 ev_string_from_simple_typed_eval(Arena *arena, EV_StringParams *params, E_Eval eval);
internal String8 ev_escaped_from_raw_string(Arena *arena, String8 raw); internal String8 ev_escaped_from_raw_string(Arena *arena, String8 raw);
//- rjf: tree stringification iterator
internal EV_StringIter *ev_string_iter_begin(Arena *arena, E_Eval eval, EV_StringParams *params);
internal B32 ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string);
#endif // EVAL_VISUALIZATION_CORE_H #endif // EVAL_VISUALIZATION_CORE_H
@@ -2,4 +2,3 @@
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
#include "eval_visualization_core.c" #include "eval_visualization_core.c"
#include "eval_visualization_builtin_view_rules.c"
@@ -5,6 +5,5 @@
#define EVAL_VISUALIZATION_INC_H #define EVAL_VISUALIZATION_INC_H
#include "eval_visualization_core.h" #include "eval_visualization_core.h"
#include "eval_visualization_builtin_view_rules.h"
#endif // EVAL_VISUALIZATION_INC_H #endif // EVAL_VISUALIZATION_INC_H
@@ -1,26 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
//- GENERATED CODE
C_LINKAGE_BEGIN
EV_ViewRuleInfo ev_builtin_view_rule_info_table[14] =
{
{str8_lit_comp("default"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(default) , EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(default) , EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) },
{str8_lit_comp("array"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(array) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) },
{str8_lit_comp("list"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(list) , EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(list) , EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) },
{str8_lit_comp("slice"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(slice) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) },
{str8_lit_comp("bswap"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(bswap) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) },
{str8_lit_comp("cast"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(cast) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) },
{str8_lit_comp("wrap"), (EV_ViewRuleInfoFlag_Inherited*0)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(wrap) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) },
{str8_lit_comp("only"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(only) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) },
{str8_lit_comp("omit"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(omit) , EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) },
{str8_lit_comp("bin"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) },
{str8_lit_comp("oct"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) },
{str8_lit_comp("dec"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) },
{str8_lit_comp("hex"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) },
{str8_lit_comp("no_addr"), (EV_ViewRuleInfoFlag_Inherited*1)|(EV_ViewRuleInfoFlag_Expandable*0), EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil), EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity) },
};
C_LINKAGE_END
@@ -1,39 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
//- GENERATED CODE
#ifndef EVAL_VISUALIZATION_META_H
#define EVAL_VISUALIZATION_META_H
typedef enum EV_ViewRuleKind
{
EV_ViewRuleKind_Default,
EV_ViewRuleKind_Array,
EV_ViewRuleKind_List,
EV_ViewRuleKind_Slice,
EV_ViewRuleKind_ByteSwap,
EV_ViewRuleKind_Cast,
EV_ViewRuleKind_Wrap,
EV_ViewRuleKind_Only,
EV_ViewRuleKind_Omit,
EV_ViewRuleKind_Bin,
EV_ViewRuleKind_Oct,
EV_ViewRuleKind_Dec,
EV_ViewRuleKind_Hex,
EV_ViewRuleKind_NoAddress,
EV_ViewRuleKind_COUNT,
} EV_ViewRuleKind;
EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(array);
EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(slice);
EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(bswap);
EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(cast);
EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(wrap);
EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(only);
EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(omit);
EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(default);
EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(list);
EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(default);
EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(list);
#endif // EVAL_VISUALIZATION_META_H

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