Author SHA1 Message Date
Nikita Smith f792da5d31 manifest... 2024-10-18 16:53:30 -07:00
Ryan Fleury 1344270b5a adjust versions 2024-10-18 16:40:25 -07:00
Ryan Fleury c03844fb1a fix build, make icon unique to raddbg 2024-10-18 16:32:49 -07:00
Nikita Smith d04e86c007 rename merged manifest 2024-10-18 16:23:51 -07:00
Ryan Fleury 669574df5a fix incorrect ordering of inline sites & concrete frames in call stack view 2024-10-18 16:07:25 -07:00
Nikita Smith 3aa4b2ea03 fix udt resolution & emit correct null type 2024-10-18 16:01:17 -07:00
Nikita Smith 2f5e55d52f switch check typo 2024-10-18 16:01:17 -07:00
Nikita Smith 14ad67d59a assign correct file path node to source file
* disabled debug check for sortness too while I'm here
2024-10-18 16:01:17 -07:00
Nikita Smith b2bdb893a0 print file path node idx 2024-10-18 16:01:17 -07:00
Ryan Fleury 98dfedfff5 limit the amount of line info visualization voff gathering; otherwise we can just spend tons of time gathering inline site voffs forever... 2024-10-18 15:16:34 -07:00
Ryan Fleury 1f633a029c skip redundant expansion tasks in eval viz block tree build 2024-10-18 13:58:24 -07:00
Ryan Fleury b3d6b2913e fix enum value committing 2024-10-18 13:47:51 -07:00
Ryan Fleury 53c624a27c respect view rule radix in enum evaluations 2024-10-18 13:37:14 -07:00
Ryan Fleury 1865c33704 specify collection qualifier for collection tabs; do not resolve to anything else 2024-10-18 13:32:29 -07:00
Ryan Fleury e17a089564 fix incorrect 0 member (should be nil) 2024-10-18 12:14:40 -07:00
Ryan Fleury eb9212b6f7 fix string cmd query params 2024-10-18 12:00:13 -07:00
Nikita Smith 0ac090cab2 delete unused files 2024-10-18 11:07:00 -07:00
Nikita Smith 7827e1b1c7 fix bounds check condition in assert 2024-10-18 11:07:00 -07:00
Nikita Smith 36f3924160 don't allocate .reloc section when there are no pages 2024-10-18 11:05:51 -07:00
Nikita Smith 00dd4ad6ec check if subsystem was specified 2024-10-18 11:05:01 -07:00
Nikita Smith 7f7f7f2873 reserve space for null string 2024-10-18 11:03:46 -07:00
Nikita Smith c8a5fc4806 Changed debug directory parser to handle multiple entries. Added
parser for RDI debug info entry. Changed debug info lookup order so
debugger tries to load path specified in exe first and if debug info
is missing then debugger will do heuristic searches.
2024-10-17 18:51:35 -07:00
Nikita Smith 652dcafbbf demon helper for reading cstrings 2024-10-17 18:46:59 -07:00
Ryan Fleury 72f987533c Merge branch 'dev' of https://github.com/EpicGames/raddebugger into dev 2024-10-17 16:50:50 -07:00
Ryan Fleury 5fd835c4d4 note 2024-10-17 16:50:25 -07:00
Nikita Smith c50d9276ba build inline lines accels 2024-10-17 16:25:54 -07:00
Nikita Smith 1214cb0968 dumper for CodeView inline sites 2024-10-17 16:25:54 -07:00
Nikita Smith 3099759c0b stringizers for inline site range kind 2024-10-17 16:25:54 -07:00
Nikita Smith 95d31f5608 fix off-by-one in inline site decode 2024-10-17 16:25:54 -07:00
Ryan Fleury 687323fc2e fix soft-halt with thread freezes; fix disabling/tooltips of top-bar controls 2024-10-17 16:12:31 -07:00
Ryan Fleury 51dce36ede notes 2024-10-17 14:51:41 -07:00
Ryan Fleury b61f4d550f Merge branch 'dev' of https://github.com/EpicGames/raddebugger into dev 2024-10-17 14:51:28 -07:00
Ryan Fleury d8d8762869 adjust entity rows in watch views to use single-click for select, double-click for their primary operation, and add in operation for breakpoints/watch-pins 2024-10-17 14:51:07 -07:00
Nikita Smith d2db4542cb check type server signature against signature in obj 2024-10-17 14:05:34 -07:00
Ryan Fleury 7adf08cc7b parameterize string eval commit path by whether or not the surrounding ui expects the string to be manually escaped or not by the user (it is not in the case of things like the meta-entity views) 2024-10-17 12:57:53 -07:00
Ryan Fleury a202999655 fix over-ambitious thread selection in frontend 2024-10-17 12:43:32 -07:00
Ryan Fleury ae3a43c694 fix file-path-parameterized commands w/ ipc 2024-10-17 12:32:20 -07:00
Ryan Fleury 2f7434cd92 always use pending-file when doing a file switch 2024-10-17 12:29:06 -07:00
Ryan Fleury b02c67bfa6 close stdout/stderr/stdin handles 2024-10-17 12:20:03 -07:00
Ryan Fleury 992be37801 fix unclamped-by-line token ranges in code slice widget mouse -> token path 2024-10-17 12:13:32 -07:00
Ryan Fleury 4727a01b9f fix kill/halt button & text 2024-10-17 12:01:02 -07:00
Ryan Fleury e376ad8113 stdout/stderr/stdin file path overrides for targets 2024-10-17 11:25:47 -07:00
Ryan Fleury 23ad094a68 allow escaped-identifier lookup for type names 2024-10-17 10:46:14 -07:00
Nikita Smith 2b407b5861 changed write file to accept 1MiB blocks to improve file write speed on windows 2024-10-16 22:27:46 -07:00
Nikita Smith 79390f4a95 align msf pages on page size 2024-10-16 22:27:46 -07:00
Nikita Smith aedfb556be fix aligned arena push 2024-10-16 22:27:46 -07:00
Ryan Fleury 78039c86a0 include no_addr in view rule system for docs/inheritance rules 2024-10-16 15:41:21 -07:00
Ryan Fleury 186e8cbabe shift disasm view to rounding/sizing equally 2024-10-16 14:58:13 -07:00
Ryan Fleury 5ec0a0e406 fix incorrect inline site baking 2024-10-16 14:29:08 -07:00
Martins MozeikoandRyan Fleury 9c016004c2 Setup symbol path in win32 exception handler to the .exe folder
Otherwise it was trying lookup .pdb files only in the current folder,
as that is how .exe's are built (/pdbaltpath). This change now makes
exception handler to load .pdb from the same folder as where .exe is.
2024-10-16 14:13:26 -07:00
Ryan Fleury 9c1f8ef37b file name disambiguation for tab titles 2024-10-16 14:12:21 -07:00
Ryan Fleury 938af75efb normalize paths when doing file-path <-> eval string 2024-10-16 13:33:47 -07:00
Ryan Fleury 38173a7154 adjust pointer visualization; don't follow 0 pointers, go back to showing address first; adjust find-code-location snapping rule to only require a disasm snap / focus if no file location is specified 2024-10-16 13:23:10 -07:00
Ryan Fleury 74ee3b9850 option to rdi_from_pdb for deterministic generation; omits non-intrinsic, build-dependent information 2024-10-16 12:47:10 -07:00
Ryan Fleury 2edb65b5bd fix remaining non-determinism in pdb -> rdi generation! 2024-10-16 12:07:02 -07:00
Nikita Smith 9e6aa8506f README.md tweaks 2024-10-16 10:48:51 -07:00
Nikita Smith 648fa7cdab update hash in config 2024-10-16 10:23:53 -07:00
Nikita Smith 6612f4a32d hash image only when we have debug info building 2024-10-16 10:15:16 -07:00
Ryan Fleury e65bc121ed more work on pdb -> rdi determinism; almost done hitting all of the issues... 2024-10-16 08:52:27 -07:00
Ryan Fleury e1575f815c Merge branch 'dev' of https://github.com/EpicGames/raddebugger into dev 2024-10-15 18:05:14 -07:00
Ryan Fleury 0b50d8718e oops - reenable 2024-10-15 18:05:05 -07:00
Ryan Fleury 4671458e8e further debugging / logging / work on tester, trynig to get to the bottom of nondeterministic rdi generation 2024-10-15 17:41:18 -07:00
Nikita Smith bb86072dfa updated git actions 2024-10-15 17:32:21 -07:00
Nikita Smith d5988d0066 updated README 2024-10-15 17:26:50 -07:00
Nikita Smith 932df7bf68 linker 2024-10-15 17:25:22 -07:00
Nikita Smith 0cf553e39a minor fixes 2024-10-15 17:24:29 -07:00
Nikita Smith 1bcd66329f factored parser code out of pdb 2024-10-15 16:28:51 -07:00
Nikita Smith c3e2e2e91b factored parser code out of msf 2024-10-15 16:28:47 -07:00
Nikita Smith c34d7e2062 added missing LF_ENDPRECOMP type, fixed case for S_OBJNAME symbol,
merged leaf id kinds into main leaf enum, renamed public flags enum,
removed type dependency on PDB string table and PDB coff section array
2024-10-15 16:24:29 -07:00
Nikita Smith b1d6ebf77b added masm language enum and type kind count 2024-10-15 16:20:18 -07:00
Nikita Smith 9535652cfb define null path style 2024-10-15 16:19:27 -07:00
Nikita Smith 3ae1d8e401 bunch of tiny tweaks and changes from internal repo 2024-10-15 16:18:43 -07:00
Nikita Smith 7e98df22d7 temp arena change that lets us bypass memory decommits 2024-10-15 14:43:36 -07:00
Ryan Fleury 65b5176468 allocate extra slot for nil in global vmap baking; was causing overwrites of keys/markers before! 2024-10-15 12:42:43 -07:00
Ryan Fleury e61dfd793a stdout redirection support in os command line launch helper; do rdi dumps in determinism test 2024-10-15 12:20:25 -07:00
Ryan Fleury 97abec11a2 begin setting up tester for automated tests 2024-10-15 11:46:07 -07:00
Ryan Fleury b223a61cad tweaks & language fix 2024-10-15 10:17:37 -07:00
Ryan Fleury 94fb5056c2 resolve ptr-addition integer to value 2024-10-15 10:07:10 -07:00
Ryan Fleury 88dced7d2a notes 2024-10-15 09:00:54 -07:00
Ryan Fleury e92543d3f8 round to 4K rather than 16K boundaries for starting disasm address 2024-10-14 21:46:03 -07:00
Ryan Fleury 078cbf6afd fix incorrect auto disasm starting address 2024-10-14 20:56:25 -07:00
Martins MozeikoandRyan Fleury 3d34a26205 avx512 register support in codeview -> rdi conversion 2024-10-14 20:54:26 -07:00
Ryan Fleury cc2848feb9 visualize temporary targets, provide path to move to project; final notes & readme adjustments 2024-10-14 16:25:31 -07:00
Ryan Fleury 5c861d5a10 temporary hack to fix serialization/deserialization of symbol breakpoints 2024-10-14 15:54:11 -07:00
Ryan Fleury 78e99d4094 temporary hack to fix over-ambitious project filtering 2024-10-14 15:45:15 -07:00
Ryan Fleury 18f72dd5ea fix cases where empty/busted config was not being properly reset; a few other small fixes & notes; disabling linked list helper tooltip until it's back in 2024-10-14 15:33:35 -07:00
Ryan Fleury eadd49072a restart path, breakpoint vaddr editing path 2024-10-14 15:10:44 -07:00
Ryan Fleury 1bf01c790b ctrl entity lister; fix up entity parameter commands / lister interaction 2024-10-14 15:01:35 -07:00
Ryan Fleury 6fcdce4e0f default expansion in eval visualization; apply to scheduler tree 2024-10-14 14:21:12 -07:00
Ryan Fleury 6a297113c5 more work on new scheduler 2024-10-14 13:36:17 -07:00
Ryan Fleury 9169c14e24 dead code elimination 2024-10-14 11:04:28 -07:00
Ryan Fleury e2722e45c8 new go-to-file-path implementation, in go-to-name command 2024-10-14 11:03:51 -07:00
Ryan Fleury 59abb3750d switch-to-partner file implementation 2024-10-14 10:43:48 -07:00
Ryan Fleury 4f33162d8c new switch implementation with per-project recent files 2024-10-14 10:35:00 -07:00
Ryan Fleury d87704c91f decay arrays to pointers when doing pointer-array comparisons; begin gathering recent file history into project state; prefer larger src/disasm panels when finding a new location; do not over-ambitiously hold top-level frame scopes for dbgi/fzy - stop before per-frame sleep 2024-10-14 10:20:27 -07:00
Ryan Fleury 89f47df0e2 wrap view rule, for wrapping an expression with a containing expression 2024-10-14 09:17:29 -07:00
Ryan Fleury 68fa006e53 basic entity right click menu for name/condition editing 2024-10-14 08:44:18 -07:00
Ryan Fleury a365d23acf do not apply invalid auto view rules: 2024-10-14 08:21:21 -07:00
Ryan Fleury 1c269286df auto view rules 2024-10-14 08:19:42 -07:00
Ryan Fleury 8a1dd578a7 sketch out ptr graph building data structures 2024-10-13 20:14:59 -07:00
Ryan Fleury adb8d5237c stub out linked list view rule in new eval viz system; sketch out pointer graph cache layer, for pointer chasing & building graphs asynchronously, for use in the linked list viewer & other future visualizers 2024-10-13 20:07:39 -07:00
Ryan Fleury 000970758a dead code elimination; bp hit count reset on initial-step-into fix; notes 2024-10-13 19:32:09 -07:00
Ryan Fleury ba0e4ea0c5 fix cross-module global evaluation with new multi-module-capable eval system 2024-10-13 19:25:42 -07:00
Ryan Fleury b45462c740 cache control entity meta evals, do not reconstruct on every single meta ctrl eval space read 2024-10-13 18:11:20 -07:00
Ryan Fleury ff589d2e55 digits view rule 2024-10-13 16:39:16 -07:00
Ryan Fleury 2a44f1df60 tweaks 2024-10-13 15:16:54 -07:00
Ryan Fleury 165170ba2b Merge branch 'dev' of https://github.com/EpicGames/raddebugger into dev 2024-10-11 17:26:56 -07:00
Ryan Fleury 9aefc68177 more work on full scheduler view 2024-10-11 17:23:41 -07:00
Nikita Smith 3f88b83fdb pe: added helpers for image checksum debug directory, and entry point names 2024-10-11 16:15:55 -07:00
Ryan Fleury 7724c7f7d3 begin setting up view rules for scheduler tree 2024-10-11 16:01:40 -07:00
Ryan Fleury e86190a3d3 Merge branch 'dev' of https://github.com/EpicGames/raddebugger into dev 2024-10-11 15:14:50 -07:00
Ryan Fleury fc1c00c8f5 fix array value string generation to account for type modifiers 2024-10-11 15:14:46 -07:00
Ryan Fleury 193d6726c6 adjust control thread single-step path to be a bit more robust to malformed requests 2024-10-11 15:09:08 -07:00
Nikita Smith ab9804860c base: bug fix large pages commit code path 2024-10-11 13:50:08 -07:00
Ryan Fleury 4091f5e0c0 rich unwind -> callstack, defined by ctrl layer, so we can begin floating meta evaluation cache to ctrl layer 2024-10-11 11:46:25 -07:00
Ryan Fleury 4757c4dafd switch reg cmd name parameterization from using general string slot, to its own dedicated slot, so that the string can be used 2024-10-11 10:38:28 -07:00
Ryan Fleury f44c94c3ca bring-to-front command 2024-10-11 10:23:18 -07:00
Ryan Fleury b9f931a749 guard against name collisions in call stack root expression; need to explicitly resolve against debugger-defined names 2024-10-10 15:34:31 -07:00
Ryan Fleury 79b2bcf37a fix incorrect alignment assumption in arena 2024-10-10 15:11:22 -07:00
Ryan Fleury 01eb655d19 fix memory view 2024-10-10 14:37:46 -07:00
Ryan Fleury 51b8dbaab0 fix incorrect registers view with new eval viz expansion system 2024-10-10 14:06:52 -07:00
Ryan Fleury 578d8d64a0 correctly apply path maps in engine; correctly set disasm mode in source/disasm views 2024-10-10 13:43:45 -07:00
Ryan Fleury 546c817d34 proper file path map application in source code line info visualization & thread/bp mapping; fix incorrect base vaddr in disasm view post-visualization pass 2024-10-10 13:33:50 -07:00
Ryan Fleury 2bf5c9c9a4 docs & fix for -q 2024-10-10 13:04:16 -07:00
Ryan Fleury f6502f476b quit-after-success flag 2024-10-10 12:57:26 -07:00
Ryan Fleury 0d50157239 fixes with path map application; further completeness of file drop completion menu; fix of set-next-statement 2024-10-10 12:03:11 -07:00
Ryan Fleury ba5f2021f6 file path map application in go-to-code-location path 2024-10-10 11:45:38 -07:00
Ryan Fleury 8336aa71ad fix incorrect deletion flags set for file path map entities 2024-10-10 11:23:29 -07:00
Ryan Fleury 903995f85e file path map building & ui 2024-10-10 11:13:11 -07:00
Ryan Fleury 0c6912ed78 sketch out meta-evaluation for file path maps; have an extra drop-completion ui step when drag/dropping exes, so you can easily drag/drop exes from explorer and add them as targets (the likely common case), but also allowing viewing them with the memory viewer 2024-10-10 09:03:38 -07:00
Ryan Fleury 5933708bdb fix cacheline boundary visualization & other various fixes in eval / eval viz 2024-10-10 08:13:58 -07:00
Ryan Fleury 9c5d9caa32 pass over help menu; typeof in eval 2024-10-10 07:44:26 -07:00
Ryan Fleury 848b26bbd9 fixes / jank pass 2024-10-10 07:13:47 -07:00
Ryan Fleury 0359998a8b do not send statically-disqualified conditional breakpoints to control thread - if they are only controlled by static values or by evaluations on ui-thread-controlled-or-defined state, we can eliminate them from the control thread's concerns 2024-10-09 16:38:34 -07:00
Ryan Fleury 883f1ee1cb eliminate path for frontend to communicate meta evaluation info to ctrl thread - that can't be how it works, since control thread entities change during a demon_run, and thus the control thread needs to recompute meta evaluations for its entities on-the-fly 2024-10-09 16:26:04 -07:00
Ryan Fleury 07c781a4f6 jank reduction & completeness pass 2024-10-09 16:24:29 -07:00
Ryan Fleury ac19591df6 source view reset bugfix; bp hit count reset bugfix (should happen on launch-of-new-session, not after process has started, since we can now evaluate breakpoints on the control thread) 2024-10-09 16:07:00 -07:00
Ryan Fleury 564b8ea753 don't use checkbox icon for what is really a radio button 2024-10-09 15:26:12 -07:00
Ryan Fleury 73555a2486 shift+click to toggle bps 2024-10-09 15:17:39 -07:00
Ryan Fleury 1758292074 pipe breakpoint-condition-touched meta-evaluations to control thread; allow evaluation of meta-evaluations in conditional breakpoints 2024-10-09 15:07:54 -07:00
Ryan Fleury d0e0e35fb5 fix first-time startup not being parameterized by startup window 2024-10-09 14:25:28 -07:00
Ryan Fleury 8e5ebc2d75 memory view fixups for new visualization systems; breakpoint editing work 2024-10-09 13:58:41 -07:00
Ryan Fleury bd87c109b5 extend autocompletion lister to support path autocompletion; use in cases where a watch window view is editing a path-tagged type 2024-10-09 11:18:46 -07:00
Ryan Fleury b960935315 only apply file paths to registers in text visualizers if they are explicitly evaluated - otherwise line info will be correlated to non-source-files 2024-10-08 21:37:45 -07:00
Ryan Fleury dc32a9eb01 leave stubs for go-to-disasm & go-to-source commands 2024-10-08 17:12:45 -07:00
Ryan Fleury 8d0267395a fix go-to-source 2024-10-08 17:08:02 -07:00
Ryan Fleury 05045c8db0 increase hash store history limit; fix incorrectly skipping important go-to-code-location commands 2024-10-08 17:02:49 -07:00
Ryan Fleury aea1999af0 further fixes to implicit disasm parameterization 2024-10-08 16:28:36 -07:00
Ryan Fleury 6bcc316b42 adjust non-parameterized disassembly rules to fit expected behavior better; if user runs 'go to address', or 'go to disassembly', a non-parameterized disassembly view will adjust to a 'temporary look' address, but will reset back to the thread's address upon a new run. this fits generally expected behavior - for stable looks at arbitrary addresses, that is when you would just want to use the watch window & use the disassembly view rule on a specific parameter expression. 2024-10-08 16:19:11 -07:00
Ryan Fleury 8cdf264f4d fix only/omit rules to apply to pointers-to-structs in the same way they apply to regular structs 2024-10-08 15:46:17 -07:00
Ryan Fleury 91aedd5888 be a bit less careful with disabled animation delay 2024-10-08 15:33:52 -07:00
Ryan Fleury 870df1191b jank reduction & flow fix pass, after all of the last month's changes 2024-10-08 15:32:34 -07:00
Ryan Fleury 8708b27bff bps view work 2024-10-08 11:52:43 -07:00
Ryan Fleury c6b44f6afa bp hit counts reset; cell-granularity deletions path for watch windows 2024-10-08 11:25:16 -07:00
Ryan Fleury 6be9c71ea9 first pass at meta entity eval commits; breakpoint editing, target editing, watch pin editing 2024-10-07 21:22:22 -07:00
Ryan Fleury 3720634a62 scroll output to bottom by default (not yet configurable) 2024-10-07 17:45:57 -07:00
Ryan Fleury 534a727b7c unminimize on exception hit 2024-10-07 17:33:10 -07:00
Ryan Fleury 32ce2e110b auto-resolution of derived class ptrs 2024-10-07 17:06:40 -07:00
Ryan Fleury 58114b72f4 move member lookup paths to using eval type member cache 2024-10-07 16:26:43 -07:00
Ryan Fleury 54bb225704 lock expand operations in the watch view via the expandability detection - do not just try expanding 2024-10-07 16:13:36 -07:00
Ryan Fleury 3f19c45dd3 fix enums not working for simple integer operations in eval 2024-10-07 16:04:03 -07:00
Ryan Fleury cf46ce7712 codebase readme pass 2024-10-07 15:59:39 -07:00
Ryan Fleury 23ed5c8f5f allow 'only' view rule to determine sort-order of members in constructed type info 2024-10-07 14:50:41 -07:00
Ryan Fleury c7ce08fd71 fix clang builds 2024-10-07 14:43:31 -07:00
Ryan Fleury 7114a20e66 apply expr view rule fast paths properly 2024-10-07 14:22:31 -07:00
Ryan Fleury 95dd544871 top-level text editing mode state, so that textual keys can be used for hotkeys, but just become disabled when text editing is actually happening 2024-10-07 13:54:30 -07:00
Ryan Fleury 084ef67583 fix implicit source code location parameterization w.r.t. disassembly & code file cursors; also fix output view state 2024-10-07 13:40:08 -07:00
Ryan Fleury 71cdc0eab8 watch pins 2024-10-07 13:10:54 -07:00
Ryan Fleury fa46a52600 stop double-escaping font config paths 2024-10-07 12:50:38 -07:00
Ryan Fleury a2f1be3aa9 fix view rule state retention across reloads 2024-10-07 12:47:17 -07:00
Ryan Fleury 9ed5134843 fix watch reordering, to be more flexible to how entities are arranged w.r.t. rows (add-new-rows at top) 2024-10-07 11:52:53 -07:00
Ryan Fleury 232f955786 breakpoints, watch pins 2024-10-06 13:35:41 -07:00
Ryan Fleury 6a1c36b212 use more basic default epsilon assumption 2024-10-04 11:51:12 -07:00
Ryan Fleury 71ff183dc4 move over to new rich hover system for all entity tooltips 2024-10-03 09:34:47 -07:00
Ryan Fleury 8b8acf64d6 more work on universal rich hover / ctx menu systems 2024-10-02 12:02:49 -07:00
Ryan Fleury 487c7c9938 show rich hover tooltips when dragging/dropping as well 2024-10-01 15:44:37 -07:00
Ryan Fleury d978f56250 thread rich hover 2024-10-01 13:48:11 -07:00
Ryan Fleury 5f32b0710e more work on modules view; show debug info loading status 2024-10-01 12:36:41 -07:00
Ryan Fleury 911f9ef97b make meta & eval type system a bit richer to express plain text vs. code text vs. path text 2024-10-01 12:04:40 -07:00
Ryan Fleury 685cb4a3b8 further work on expanding main watch path to support various string styling/visualizing mechanisms, used ad-hoc before; more work on scheduler 2024-10-01 11:43:57 -07:00
Ryan Fleury dae0d602f9 modules view pass 2024-10-01 10:42:31 -07:00
Ryan Fleury ac5c65ebdd fix busted next/prev tab operations on panels with single tab 2024-10-01 10:02:37 -07:00
Ryan Fleury 04815b4265 continue work on ctrl entity visualization in watch views & further progress on new scheduler 2024-10-01 09:36:29 -07:00
Ryan Fleury 152cc709ce work on ctrl entity buttons in watch views 2024-09-30 17:07:50 -07:00
Ryan Fleury 57d01355a1 create pre-filtered types for meta evals; all of the same underlying data transforms are on a single meta-eval data bundle, but now each type of meta eval entity is exposed via a tighter type to the ui & eval system 2024-09-30 16:03:55 -07:00
Ryan Fleury fcedcab57c begin work on scheduler view requirements 2024-09-30 15:08:05 -07:00
Ryan Fleury 3fb8b83324 mostly done with all of the special machinery for entity views via watch windows 2024-09-30 14:12:55 -07:00
Ryan Fleury 5d76b58acd targets view: ensure ctrl+click for selection, ensure proper target parameterization of engine commands 2024-09-30 09:40:39 -07:00
Ryan Fleury 2e13b221ac do not attempt to form implicit member lookup expressions if initial map failed 2024-09-27 17:03:18 -07:00
Ryan Fleury 64e5d60f38 eliminate adjusted frame base check, which was causing incorrect unwinds in some cases 2024-09-27 16:57:23 -07:00
Ryan Fleury ce72af8b59 fix inclusion of symbolized addresses in editable eval visualization strings 2024-09-27 16:30:01 -07:00
Ryan Fleury 086ca98181 callstack unwind selection in watch window-ified callstack view 2024-09-27 16:27:55 -07:00
Ryan Fleury fe59fab3da progress on callstack view replacement 2024-09-27 15:48:36 -07:00
Ryan Fleury 52b2cbc17a selection in targets view 2024-09-27 14:46:22 -07:00
Ryan Fleury 7362f8ef60 always focus window on stop events; further watch view progress 2024-09-27 14:25:32 -07:00
Ryan Fleury cab01431be more watch view work 2024-09-27 13:41:17 -07:00
Ryan Fleury 771883c56c another checkpoint in fixing up the watch window for replacing targets/scheduler/etc 2024-09-27 13:15:10 -07:00
Ryan Fleury b6b188b67b begin work on full targets view replacement in new watch / eval viz systems 2024-09-27 11:02:37 -07:00
Ryan Fleury ecaa2c55c0 eliminate all old eval visualization block/row code 2024-09-27 10:29:55 -07:00
Ryan Fleury 45226e8a81 begin eliminating old block/row code in eval visualization 2024-09-27 10:26:30 -07:00
Ryan Fleury 0073b2b045 fix correct application of top-level view rules in block tree build 2024-09-27 10:12:44 -07:00
Ryan Fleury 3d781f847e fix expansion rule picking 2024-09-27 10:08:49 -07:00
Ryan Fleury 4b7e6d7113 fixes for variable size rows in new eval visualization structures / integration 2024-09-27 10:04:56 -07:00
Ryan Fleury 3fa98eb0e7 begin moving all visualizer view rules to new eval visualization block system 2024-09-26 17:00:32 -07:00
Ryan Fleury 60f65d30e2 populate entity deletions more urgently in watch viiew 2024-09-26 16:24:47 -07:00
Ryan Fleury 007efe29eb fix incorrect multi-select deletion behavior 2024-09-26 16:21:45 -07:00
Ryan Fleury bbac451de4 fix a few small issues with insertion/deletion of new watch rows 2024-09-26 16:15:03 -07:00
Ryan Fleury 73c37b4d8b correct collection editing/deletion/reordering/etc. with new watch visualization system 2024-09-26 16:08:35 -07:00
Ryan Fleury 2fdfeec467 always keep collections in filtered watch views; add add-new-row capability to watch collection expansion & hook up with expansion ids 2024-09-26 15:36:22 -07:00
Ryan Fleury d314a12698 eliminate possibility for recursive watch window builds; correctly sort child expansion keys before iteration, if needed, for non-identity-based id schemes (debug info tables, frontend entities, etc.); further fixes & integration 2024-09-26 15:26:28 -07:00
Ryan Fleury 07f978ac41 further integration work & expanded support; generalized paths for entity reordering in watch views 2024-09-26 14:37:13 -07:00
Ryan Fleury 338fabd9d0 more block tree / eval visualization integration work with watch views 2024-09-26 13:13:30 -07:00
Ryan Fleury 715bd36965 fix table cursor snapping 2024-09-26 12:24:13 -07:00
Ryan Fleury 198246eb52 more integration work, of new block tree eval visualization structure w/ watch views 2024-09-26 12:05:01 -07:00
Ryan Fleury e705907ec0 checkpoint in moving existing watch views to new block-tree visualization structure 2024-09-26 08:09:22 -07:00
Ryan Fleury 2fb0eb0eb1 sketch out basic coordinate space conversions for new block tree / block range list structures; num -> key; key -> row; num -> containing block range; etc. 2024-09-25 16:53:54 -07:00
Ryan Fleury 48b10411bc eliminate old weld-together path for block tree walk & windowed row list build 2024-09-25 16:37:11 -07:00
Ryan Fleury d6f6ec83da unweld windowed row list generation from block tree walk; write new path which relies on caller-prepped block range list 2024-09-25 16:36:43 -07:00
Ryan Fleury df2bc62563 extend eval visualization view rule hooks to support view-rule-defined (id <-> number) mapping; used for id-based state keys, but an immediate-mode ordering (e.g. sorted/filtered debug info tables); can be used in the future for sorted types/arrays/etc., while preserving expansion/view rule state. also, pull out the block tree -> list(block*range) walk, since it is going to be useful in multiple places 2024-09-25 16:32:48 -07:00
Ryan Fleury f2ecb3d898 expand info & expansion range query hook implementation, for all currently supported view rules 2024-09-25 15:59:42 -07:00
Ryan Fleury a1ceb5fa3b on second thought... merging both view rule expansion *header* info generation, and windowed range queries into an expanded block, into the same hook, is really limiting & wrong - so split back to two hooks, one stage is just informing the expansion space, the next provides per-row information within an expanded block with range-based queries 2024-09-25 15:17:39 -07:00
Ryan Fleury a87c032305 fix a few details in new eval visualization block tree generation algorithm; fix row generation; start fitting new system into hover eval as a first test 2024-09-25 13:17:17 -07:00
Ryan Fleury 9c3d2cd5ab eval visualization: first pass of new tree-ified block building, which preserves the hierarchy of the eval visualization path, as well as relies on only a single view rule hook; first pass of windowed row list production, given that block tree build; also still just uses the single hook 2024-09-25 12:23:50 -07:00
Ryan Fleury c976154284 eval: add cache for type data member gathering & member lookup; eval_visualization: sketch out new hook organization which has single hook for both view rule expansion info, + expansion expr production, in a single combined path (the two often require the same information so it is maybe a good idea to combine them - if not, it will be easy to separate into two stages (expand + expr-child production), but basically just trying to get view rules out of 'block production', and more into just providing the information that actually varies per view rule 2024-09-25 09:34:23 -07:00
Ryan Fleury fcfd446c5e watch ui tweaks 2024-09-24 16:58:10 -07:00
Ryan Fleury d2c9fdcf0b notes 2024-09-24 13:27:59 -07:00
Ryan Fleury 2f9121171c eliminate dead code, after this pass 2024-09-24 13:24:23 -07:00
Ryan Fleury fbfaf1c747 strip out root buttons idea; fix up pretty member names 2024-09-24 11:06:31 -07:00
Ryan Fleury 64f763162f adjust font provider rasterization bounds to prevent off-by-one cutoffs 2024-09-24 07:23:44 -07:00
Ryan Fleury 629ddec458 begin sketching out watch-window-driven scheduler replacement 2024-09-23 17:41:26 -07:00
Ryan Fleury 5690a9e19b further enriching of codebase type info & eval type info to encode code-contents of pointers, pretty names for members; further progress on improving watch views to support all needed features for replacing all table uis 2024-09-23 16:45:18 -07:00
Ryan Fleury 508d11c8d8 further progress on targets view replacement; split collection views into several types 2024-09-23 16:06:01 -07:00
Ryan Fleury bfe6f655be more work on watch view to replace all old uis 2024-09-23 14:26:27 -07:00
Ryan Fleury f728614e0b eliminate watch view fill kind; extend rtti & eval type system with 'external' pointers, for e.g. meta-space vaddr u64s pointing into an address space; begin sketching out paths for mutational rows in watch collections, use to add 'add target' fastpath in targets collection evaluations 2024-09-23 10:57:43 -07:00
Ryan Fleury ebaad35813 fix filter passthrough & fix double-application of view rules in some cases 2024-09-20 17:19:13 -07:00
Ryan Fleury 8babd89f47 modules view, watch window style 2024-09-20 17:04:53 -07:00
Ryan Fleury 066f5f6cf2 add correct inheritance rules for oct, hex, dec, bin, only, omit view rules 2024-09-20 16:24:09 -07:00
Ryan Fleury c98db01b63 replace watch view fill kind with top-level expression & view rule; collection macro for watches; reintroduce only/omit, with new expr-macro-based eval visualization system; remove root-expression-generation from expansion block generation, since it makes things a bit more complicated 2024-09-20 16:15:29 -07:00
Ryan Fleury a1debd9219 targets, breakpoints, watch pins, etc. collections; fix . access on enum types; add more information to meta evaluations 2024-09-20 13:49:27 -07:00
Ryan Fleury 432e70caf6 begin sketching out 'collections', which are the formal mechanism in the eval/eval-viz systems for visualizing synthetic structures/arrays/trees produced by the debugger, rather than ad-hocing / hardwiring the correct ev-block production for each kind of view - the views can still stay, but this is an important feature for other cases 2024-09-20 12:04:13 -07:00
Ryan Fleury bbd86449d8 fix ghost auto-view-rule text visualization to calculate auto view rule from raw type expression rather than post-view-rule-applied one 2024-09-19 16:07:14 -07:00
Ryan Fleury 454764b9f6 set up auto view rule table in frontend thread; visualize auto-view-rules as ghosted text in watch views 2024-09-19 15:29:08 -07:00
Ryan Fleury 05ec402a8e make eval visualization system robust to absence of auto view rule table 2024-09-19 15:23:55 -07:00
Ryan Fleury df4d18aa5c sketch out type-based auto-view-rule in eval visualization system 2024-09-19 15:22:47 -07:00
Ryan Fleury cc61df0c7b lazily-evaluate meta evaluations on an as-needed basis - with callstacks in particular it is just too expensive to do all threads every frame up-front 2024-09-19 14:38:24 -07:00
Ryan Fleury 7bec50db75 type-info-table-driven pointer rebasing for meta evals; add callstack info to entity meta evals 2024-09-19 14:04:40 -07:00
Ryan Fleury 0e993c5e7a eliminate old ctx menu paths 2024-09-19 11:36:34 -07:00
Ryan Fleury 16ba8a98cf shift source ctx menu to universal ctx menu path 2024-09-19 11:33:23 -07:00
Ryan Fleury 1e8413797a shift tab ctx menu into universal ctx menu 2024-09-19 11:27:55 -07:00
Ryan Fleury ca8fdd1d6e progress on universal ctx menu 2024-09-19 11:22:08 -07:00
Ryan Fleury 714c736530 eliminate old manual serialization code for meta evals in ctrl msgs 2024-09-18 17:01:59 -07:00
Ryan Fleury 7c41fc11e0 fix up issues with user <-> ctrl thread communication 2024-09-18 16:21:22 -07:00
Ryan Fleury 546e6e695f eliminate ad-hoc meta eval info type tables; switch to base layer meta type info; do first pass of shifting serialization of meta evals to meta type info driven system 2024-09-18 15:57:01 -07:00
Ryan Fleury 7e5759ed03 finish first pass sketching out basic base-layer-defined codebase type info & serialization/deserialization path with basic pointer cases 2024-09-18 14:52:39 -07:00
Ryan Fleury 9ae3b2eb92 base layer defined type info tables experiment - can ideally be used as a more whole solution for the ctrl meta eval info stuff 2024-09-17 17:52:23 -07:00
Ryan Fleury 85a07be1ac generate meta tables for meta evaluations; use to table-drive ctrl msg serialization, deserialization, meta eval type info generation, and info <-> serialized eval path 2024-09-17 15:43:39 -07:00
Ryan Fleury 3de6331a8e notes for 0.9.12 2024-09-17 14:17:04 -07:00
Ryan Fleury 487637aaaa fix while-loading command processing in text views 2024-09-17 14:05:40 -07:00
Ryan Fleury e825c0f5b5 keep 64mb reserve size default if possible with large pages enabling 2024-09-17 13:46:11 -07:00
Ryan Fleury 5dd89f350d --large_pages option; allow dynamic override of arena defaults 2024-09-17 13:41:56 -07:00
Ryan Fleury 4d41c32586 plug in fuzzy searching system to autocompletion lister; can now autocomplete procedures, types, globals in watch window 2024-09-17 11:52:33 -07:00
Ryan Fleury a368d04e3b checkpoint on new universal drag/drop stuff 2024-09-17 11:26:13 -07:00
Ryan Fleury ca9ee9a658 checkpoint in new universal regs-based rich hover / context menu / drag-drop systems 2024-09-17 11:05:43 -07:00
Ryan Fleury 8ce7626099 fix run-to-line & run-to-address (was accidentally zeroing extra_bps) 2024-09-16 18:09:19 -07:00
Ryan Fleury d66703a044 filter commands in views by view rather than window/panel 2024-09-16 17:57:48 -07:00
Ryan Fleury fa64116048 notes 2024-09-16 17:54:53 -07:00
Ryan Fleury cff6222863 additional small fixes 2024-09-16 17:48:39 -07:00
Ryan Fleury 515724f264 small fixes 2024-09-16 17:43:38 -07:00
Ryan Fleury a7ca8dd0a0 sketch out thread color events & client-driven thread color state, plug thread colors back into ui 2024-09-16 17:37:50 -07:00
Ryan Fleury 35659a4525 checkpoint on new drag/drop system; eliminate old drag/drop payload, just use regs like everything else 2024-09-16 17:25:21 -07:00
Ryan Fleury 4b382777e9 fix debug engine incorrectly using visual run state to soft halt, when ctrl thread did not necessarily report it was running; was leading to 'phantom halts'; other small fixes, dead code elimination, and begin sketching out proper cross-window drag/drop 2024-09-16 17:09:41 -07:00
Ryan Fleury 3cf27169b6 fix view snapping in frame selection & disasm 2024-09-16 16:25:02 -07:00
Ryan Fleury ba647a0b1d fix open-tab path; fix pending-file setup 2024-09-16 16:13:40 -07:00
Ryan Fleury 2f86e289a4 get all view code off of explicit view parameterization; merge row value cell ui hook with regular view ui hook 2024-09-16 15:59:01 -07:00
Ryan Fleury 9899efe93c merge view rules & view specs entirely; simplify graphical view rules down to single hook 2024-09-16 14:44:28 -07:00
Ryan Fleury 84f685803d fix set-space ir extension instruction; expand ctrlbits to u16, so that it can encode modern register sized decodes 2024-09-16 11:59:06 -07:00
Ryan Fleury c00fede4f1 fill out meta eval info system in frontend; get eval back up and running 2024-09-16 11:51:55 -07:00
Ryan Fleury adc9e0e512 begin sketching out meta eval info, to allow for debugger meta evaluations on both ctrl thread & on ui thread - e.g. breakpoint hit count evaluation in conditional bps 2024-09-16 10:36:22 -07:00
Ryan Fleury 17d062934e dead code elimination 2024-09-16 10:13:28 -07:00
Ryan Fleury e8c8df9c6e eliminate setup hook for views 2024-09-16 09:53:24 -07:00
Ryan Fleury 23a5c9eb44 eliminate view cmds hook; just use ui hook 2024-09-16 09:45:54 -07:00
Ryan Fleury 3c262fccf3 adjust top-level rd_frame structure to allow N cycles (rather than 1) of [rd cmds], [d tick] per frame; fix a few ctrl thread driving issues in dbg engine 2024-09-15 12:46:03 -07:00
Ryan Fleury 114ebfa27b adjust raddbg command queue to have two phases; first phase, r/w, core gets chance to push extra commands & consume them immediately same-frame; views get second phase, read-only, where they can consume all commands, but when they push new commands, those are distributed back at the top of the chain, where the core gets first chance 2024-09-15 09:47:37 -07:00
Ryan Fleury 7a1811fb71 begin eliminating setup hook for views 2024-09-14 08:12:26 -07:00
Ryan Fleury f396a88bac mdesk layer extensions for mutable tree manipulations 2024-09-13 17:16:42 -07:00
Ryan Fleury 4b526db0dd organization pass & straightening some things out before entity simplification/replacement 2024-09-13 16:12:55 -07:00
Ryan Fleury 8ffc9f4a9b more progress on entity simplification; df -> rd; eliminate dbg_frontend distinction from raddbg layer 2024-09-13 15:55:58 -07:00
Ryan Fleury 48ae9b6973 move rest of cfg-related stuff into frontend 2024-09-13 14:51:07 -07:00
Ryan Fleury 793ad8fe1e new view rule table definition in df, merging graphical view rules & views totally 2024-09-13 13:39:40 -07:00
Ryan Fleury 7cd1d175de deduplicate string escaping paths in eval/cfg/etc 2024-09-13 12:08:22 -07:00
Ryan Fleury 306f8d84c5 remainder of entity code -> df; exception code filters -> df 2024-09-13 11:59:46 -07:00
Ryan Fleury 573bad8487 entity from d -> df 2024-09-13 11:46:17 -07:00
Ryan Fleury 9b66a9c60e fix df/ctrl kind mismatch 2024-09-13 11:26:53 -07:00
Ryan Fleury 96b5f82964 run-to-line/address porting from old df_entity-based behavior 2024-09-13 11:21:13 -07:00
Ryan Fleury 6b758f08fa eliminate dead code; port breakpoint hit counting to frontend; begin floating entity code into frontend, prepping for simplification/replacement 2024-09-13 10:48:40 -07:00
Ryan Fleury 7fb711b07c eliminate more dead code 2024-09-13 10:41:42 -07:00
Ryan Fleury c8a892ad8f eliminate d_entity-based module mapping code; all of this is done via ctrl systems now 2024-09-13 10:39:32 -07:00
Ryan Fleury f9c541ea7b eliminate regs concept from engine; eliminate more d_entity mirroring ctrl_entity 2024-09-13 10:26:34 -07:00
Ryan Fleury 2dfa3dae42 snap-to-thread if none selected in frontend; fix soft halt logic to match old logic; fix ctrl entity store alloc gen on release 2024-09-12 17:10:39 -07:00
Ryan Fleury f13806b19f another checkpoint in moving previously engine-controlled behavior to frontend, and getting engine completely off d_entities 2024-09-12 16:51:48 -07:00
Ryan Fleury 71cb03f3be checkpoint in getting off of d_entities and onto ctrl_entities for frontend paths, including thread selection & df_regs 2024-09-12 16:30:26 -07:00
Ryan Fleury 3641c212b2 begin floating thread/frame selection mechanisms into frontend and out of engine 2024-09-12 14:58:48 -07:00
Ryan Fleury 638140ab87 another checkpoint, moving d_regs -> df_regs; eliminating more state & responsibilities from dbg_engine 2024-09-12 14:10:41 -07:00
Ryan Fleury 65ed1f0997 another checkpoint - eliminate cmd specs from engine, move all dynamic command definition things into frontend 2024-09-12 12:11:00 -07:00
Ryan Fleury 472e73137d checkpoint 2024-09-11 18:25:48 -07:00
Ryan Fleury 2f299e087a fix busted stepping mechanism 2024-09-11 17:44:30 -07:00
Ryan Fleury c8efacf707 split engine from frontend cmd structure; use to begin fixing/hardening engine commands and decoupling them from frontend complications 2024-09-11 17:42:34 -07:00
Ryan Fleury deef05d0d2 extend eval space size to allow u128 key for hash store & related cache keys, + some extra metadata determined by user (user-defined kind & extra u64) 2024-09-11 17:11:33 -07:00
Ryan Fleury 26fb91d539 fix top-level frontend exit logic; eliminate path -> entity code, since we are totally off filesystem entities 2024-09-11 16:25:02 -07:00
Ryan Fleury f59694fcfb float cfg from engine -> frontend; more elimination of dead code in engine 2024-09-11 15:40:11 -07:00
Ryan Fleury f4726eee0a eliminate old eval viz code in engine 2024-09-11 15:22:51 -07:00
Ryan Fleury cc2b5138b0 more dead code elimination & simplification & floating from engine -> frontend 2024-09-11 15:04:12 -07:00
Ryan Fleury e7b4912e4a eliminate more dead code in engine 2024-09-11 14:35:30 -07:00
Ryan Fleury af5825c89a move interaction register stack into frontend layer 2024-09-11 14:24:16 -07:00
Ryan Fleury be6458690f ctrl layer defined handle system, to replace machine-id/demon-handle pairs used everywhere by users 2024-09-11 14:01:38 -07:00
Ryan Fleury e6872cb71e eliminate all old debug engine eval visualization code; we're now moved over to the new more standalone eval viz codebase layer 2024-09-10 17:22:24 -07:00
Ryan Fleury 20aba085cd oops 2024-09-10 17:14:10 -07:00
Ryan Fleury 299ea04539 port debugger frontend to using eval visualization layer, over old debug engine code 2024-09-10 17:10:48 -07:00
Ryan Fleury bb50e88141 eval_visualization layer: builtin view rules, porting of more debug engine code over 2024-09-10 16:14:11 -07:00
Ryan Fleury e989da4087 float down dbg engine eval visualization stuff into formal codebase layer which just builds on top of eval 2024-09-10 15:46:05 -07:00
Ryan Fleury d3bf9cbb53 eliminate now-unnecessary config writing mechanism 2024-09-10 14:11:54 -07:00
Ryan Fleury d35bc56f8f further coalesce all frontend command processing into top-level frame path; have frontend commands for all possible engine commands 2024-09-10 14:01:06 -07:00
Ryan Fleury 9e7ce6a6c7 do not bake in this parameters in static methods 2024-09-10 13:51:59 -07:00
Ryan Fleury 09db3aacd0 formally split dbg engine/frontend commands; float entity operations & all ui-related operations up to frontend layer, keep engine to small set of control operations (we are trying to get the engine out of the mix in managing entity state) 2024-09-10 11:37:01 -07:00
Ryan Fleury 6534bff5d0 eliminate state delta history experiment codef 2024-09-10 07:24:33 -07:00
Ryan Fleury baaa853c7f dead code & unnecessary helper elimination 2024-09-08 16:49:27 -07:00
Ryan Fleury 8831781af4 reorder top-level frame structure; frontend gets chance first 2024-09-08 14:28:06 -07:00
Ryan Fleury dfe0c17b89 oops; fix incorrect usage of thread instead of process entity 2024-09-08 13:16:57 -07:00
Ryan Fleury 6cf0c7ee92 promote thread freeze state to ctrl entity tree; communicate via msgs for user -> ctrl, and communicate entity state changes back via events for ctrl -> user 2024-09-08 13:09:52 -07:00
Ryan Fleury fee500578a get trap net generation off of d_entities and onto ctrl entities; decouple debug engine stepping/running from d_entities 2024-09-08 10:50:00 -07:00
Ryan Fleury 43b83b56f1 float eval system preparation to frontend & out of engine 2024-09-08 10:30:05 -07:00
Ryan Fleury 9b95e60894 feed flattened breakpoints into ctrl message instead of entities 2024-09-08 10:26:14 -07:00
Ryan Fleury 2272b4a14c eliminate d_ctrl_run helper intermediate; switch to using simplified passdown types for breakpoints, rather than entities, in ctrl run parameterization 2024-09-08 10:23:32 -07:00
Ryan Fleury 6b172396f5 eliminate messages - too early for that change; eliminate many usage sites of d_ctrl_run; focus all ctrl thread driving code into one spot 2024-09-08 10:12:10 -07:00
Ryan Fleury 2cc81baffa sketch out simplified input types for engine; port over animation cache from reverted changes 2024-09-08 09:44:39 -07:00
Ryan Fleury a204018e94 Revert "checkpoint on pass to majorly simplify debug frontend state, and eliminate df entities, and move from cmds -> msgs"
This reverts commit 06a685221a.
2024-09-07 14:50:27 -07:00
Ryan Fleury 3ed8f4af98 Revert "begin sketching out live cfg mutation code, as replacement for frontend entity tree formation/mutation"
This reverts commit c8c9c7ea27.
2024-09-07 14:48:47 -07:00
Ryan Fleury 5ffab0439b Revert "more msgs -> cmds & df entity elimination progress"
This reverts commit 9968c6e491.
2024-09-07 14:48:42 -07:00
Ryan Fleury cccbd265ff Revert "another checkpoint in big df entity elimination pass"
This reverts commit f8fd32e328.
2024-09-07 14:48:34 -07:00
Ryan Fleury 6180da1b0f Revert "yet another checkpoint"
This reverts commit 5ad8d523ba.
2024-09-07 14:48:29 -07:00
Ryan Fleury 30766f93ae Revert "checkpoint"
This reverts commit 3631de648b.
2024-09-07 14:48:21 -07:00
Ryan Fleury 3631de648b checkpoint 2024-09-07 13:37:35 -07:00
Ryan Fleury 5ad8d523ba yet another checkpoint 2024-09-05 19:19:00 -07:00
Ryan Fleury f8fd32e328 another checkpoint in big df entity elimination pass 2024-09-04 15:50:59 -07:00
Ryan Fleury 9968c6e491 more msgs -> cmds & df entity elimination progress 2024-09-03 16:50:16 -07:00
Ryan Fleury c8c9c7ea27 begin sketching out live cfg mutation code, as replacement for frontend entity tree formation/mutation 2024-09-03 15:20:04 -07:00
Ryan Fleury 06a685221a checkpoint on pass to majorly simplify debug frontend state, and eliminate df entities, and move from cmds -> msgs 2024-09-03 12:46:30 -07:00
Ryan Fleury 6b02c8a7d6 more progress on converting cmds codepaths -> msgs codepaths 2024-09-01 16:20:26 -07:00
Ryan Fleury 06f65857db more progress in df cmds -> msgs 2024-09-01 15:49:06 -07:00
Ryan Fleury 6ead03ac17 strip out update/render/repaint window cruft; promote layer per-tick APIs to base layer 2024-09-01 09:00:58 -07:00
Ryan Fleury 98840c73d8 finish initial pass over df msgs 2024-09-01 08:39:18 -07:00
Ryan Fleury 45d3702c5b further progress on cmds -> msgs in debug frontend 2024-08-31 09:02:42 -07:00
Ryan Fleury 2696c96f75 continue coalescing df frame 2024-08-31 07:36:53 -07:00
Ryan Fleury 7645d00392 eliminate more cruft in engine/frontend layers; sketch out new frontend msg processing loop 2024-08-30 18:08:29 -07:00
Ryan Fleury 7004994b25 sketch out msg processing loop, to replace cmd processing loop, in dbg engine 2024-08-30 17:52:45 -07:00
Ryan Fleury 8770a43678 set up scaffolding for dbg engine/frontendm sgs 2024-08-30 15:24:35 -07:00
Ryan Fleury 533fd0041f begin flattening d/df tick paths 2024-08-30 14:10:12 -07:00
Ryan Fleury 2ceff4293f begin eliminating begin/end frame concept in debug engine, and moving to single debug engine tick 2024-08-30 12:24:47 -07:00
Ryan Fleury 13f2de6e88 d regs -> mdesk 2024-08-30 10:07:56 -07:00
Ryan Fleury ecf9cd1dab fix markup vsnprintf fwd declare warning 2024-08-30 09:33:54 -07:00
Ryan Fleury b0d10d457e notes 2024-08-29 17:14:50 -07:00
Ryan Fleury e1806d2d61 notes 2024-08-29 17:02:26 -07:00
Ryan Fleury facf0dafe6 move remaining per-window cmds to top-level 2024-08-29 16:29:10 -07:00
Ryan Fleury 37f771ae9b begin moving all frontend command processing into top-level layer, rather than doing it per-window 2024-08-29 16:24:15 -07:00
Ryan Fleury 84bc078e9f watch commands -> core layer 2024-08-29 15:54:10 -07:00
Ryan Fleury df777a4c07 eliminate old code slice cruft 2024-08-29 13:39:53 -07:00
Ryan Fleury e81fbe4bf2 eliminate old code; organization pass over dbg frontend 2024-08-29 13:37:28 -07:00
Ryan Fleury 9932a30ef9 entity parameter tree equipment; architecture -> arch 2024-08-29 13:16:50 -07:00
Ryan Fleury df6150c811 always produce inheritance child cfg tables for each viz block 2024-08-29 12:48:54 -07:00
Ryan Fleury 719c453bfc eliminate old type 2024-08-29 11:57:57 -07:00
Ryan Fleury 0f4d2cfbc1 entity name -> string 2024-08-29 11:48:55 -07:00
Ryan Fleury bb553b4ec0 eliminate manual notification of entity / panel mutations for soft halts & config changes; just compute a hash of all run parameterization state every time you run, and every frame, and if they change, soft halt refresh 2024-08-29 11:34:29 -07:00
Ryan Fleury 9bba4f224c ctrl flow analysis -> dasm layer 2024-08-29 10:58:16 -07:00
Ryan Fleury 5907783a2e d_interact_regs -> d_regs 2024-08-29 10:54:54 -07:00
Ryan Fleury 4944652331 introduce debug engine entity kinds for windows/panels/tabs, to begin process of formally moving all view parameterizations to watch entities; eliminate redundant passthrough of window/panel parameters 2024-08-29 10:49:35 -07:00
Ryan Fleury e9304b5eff parameter tree editing in tab right-click menu 2024-08-28 17:54:49 -07:00
Ryan Fleury 61a264e20c fix empty language option in autocompletion lister 2024-08-28 17:22:27 -07:00
Ryan Fleury 4439aab721 split more frontend-only information from debug engine core definitions 2024-08-28 17:14:59 -07:00
Ryan Fleury 1c62787758 dbg_gfx -> dbg_frontend; fix force-confirm commands; more naming passes 2024-08-28 16:59:21 -07:00
Ryan Fleury 269abf661f switch to simplified debug engine command interface; rely on interact registers, rather than explicit pass-down, for contextually-obvious parameters 2024-08-28 16:47:05 -07:00
Ryan Fleury e3dc29d7ae push_cmd__root -> push_cmd 2024-08-28 15:37:55 -07:00
Ryan Fleury cb25e261e4 eliminate all cmd param slot marking 2024-08-28 15:37:03 -07:00
Ryan Fleury 818c5a9160 eliminate dependence on 'command parameter slots' 2024-08-28 15:34:46 -07:00
Ryan Fleury c60809f02b df -> dbg_engine and dbg_gfx layers; df (core) -> d 2024-08-28 15:16:55 -07:00
Ryan Fleury ca4b602b28 f -> fnt 2024-08-28 13:45:54 -07:00
Ryan Fleury 83542d4010 re-slice views code; begin prepping for view rules / views being organized together 2024-08-28 13:38:49 -07:00
Ryan Fleury 01236ca3b9 make all view, core view rule, and gfx view rule names completely consistent, use the name as the unique key among all tables 2024-08-28 13:11:00 -07:00
Ryan Fleury 31810bb221 fix incorrect lifetime of cfg table trees 2024-08-28 12:01:19 -07:00
Ryan Fleury 22c4336375 finish trimming old view rule code; get 3d geometry viewer back in good shape and integrated as a full view 2024-08-28 11:36:44 -07:00
Ryan Fleury 5ff9e47f8a fix loading in transient views 2024-08-27 17:18:42 -07:00
Ryan Fleury d956f7a266 view rule table notes 2024-08-27 16:46:19 -07:00
Ryan Fleury 0c2502c89f partway through fixing regressions of color view rule 2024-08-27 16:35:15 -07:00
Ryan Fleury be93968c8d fix incorrect resource kind string table; fix incorrect usage of resource kind table when doing texture format lookups in bitmap view 2024-08-27 15:48:27 -07:00
Ryan Fleury 32ac4f10bb support loading overlay in transient views; fix incorrect transient view state caching when view parameters change 2024-08-27 15:23:19 -07:00
Ryan Fleury 59360f770c file drop support 2024-08-27 14:49:57 -07:00
Ryan Fleury 32fcc6d34c expand pending file view to actually analyze files a bit before picking appropriate viewer; for now just do code if text, memory if not 2024-08-27 14:27:14 -07:00
Ryan Fleury 645db07493 add memory view rule; adjust memory view to appropriately use eval parameterizations, so that it can be used as a view rule correctly 2024-08-27 13:47:38 -07:00
Ryan Fleury 4b75145ec0 only consider non-queried disassembly views in general-purpose find-code-locationp ath 2024-08-27 13:08:32 -07:00
Ryan Fleury e59e014b2b shift disassembly view to being usable as a view rule too; arbitrary disassembly view parameterization 2024-08-27 13:00:21 -07:00
Ryan Fleury 08652e8b0a cast view rule 2024-08-27 11:46:54 -07:00
Ryan Fleury 511e81b188 eliminate eval resolution stage; we can just use expr resolution stage for everything 2024-08-27 11:39:46 -07:00
Ryan Fleury 90273e7a2e bswap view rule 2024-08-27 11:37:27 -07:00
Ryan Fleury cf7b664ab2 bswap expression & ir 2024-08-27 11:35:45 -07:00
Ryan Fleury accc77e03e eliminate type resolution eval viz stage (can just be done via the expr resolution stage, which is more powerful); fix elements expansion for non-pointers 2024-08-27 11:17:05 -07:00
Ryan Fleury 5b29f0db47 new expr resolution eval visualization stage; use to implement array & slice view rules 2024-08-27 11:04:22 -07:00
Ryan Fleury a97c8bd070 fix new param tree generation; stop string viz for padding members; fix relative file path serialization in new cfg saving path 2024-08-27 09:13:28 -07:00
Ryan Fleury 6a8c110b83 remove old cursor/mark decls 2024-08-26 16:15:28 -07:00
Ryan Fleury c97c351508 move cursor/mark state out of being hardcoded in view, and into param tree 2024-08-26 16:13:50 -07:00
Ryan Fleury 567aea2b15 new view serialized/deserialized params storage 2024-08-26 15:55:12 -07:00
Ryan Fleury 895c4dd199 fix press detection in watch view canvases 2024-08-26 15:16:23 -07:00
Ryan Fleury 3691b59af3 set up system for per-view param tree mutations; fix duplicate param key serialization 2024-08-26 15:13:53 -07:00
Ryan Fleury ec16f59a1e fix incorrect usage of new ui events pump 2024-08-26 14:34:24 -07:00
Ryan Fleury c16e21db71 eliminate dead code 2024-08-26 14:27:51 -07:00
Ryan Fleury 1de57557b5 get off cfg node duplicates of mdesk trees; use md trees for params consistently across view rules, tabs, etc. 2024-08-26 14:26:23 -07:00
Ryan Fleury aed18eb71c eliminate string-from-state function for view specs - we will be doing everything via the cfg tree; clean up & fix view titles for all of the different visualizer circumstances; do general path for serializing cfg trees for each view 2024-08-26 11:26:34 -07:00
Ryan Fleury 14f617db85 begin eliminating separate hook system for view rule uis; shift over to regular views, so there is just one codepath for all visualizers; move ui to event pump system, with permissions stack, so that callers of sub-ui-codepaths can mask off event consumption as needed 2024-08-26 09:56:47 -07:00
Ryan Fleury 74471e4b8d fix tab title rules; fix watch keyboard navigation with new dynamic columns 2024-08-26 06:12:42 -07:00
Ryan Fleury 43eac9f332 add entity labels to macro map 2024-08-23 16:28:09 -07:00
Ryan Fleury 729a4aa1f9 first step to collapsing separate view parameterization path, and just having views be parameterized by evaluation strings 2024-08-23 16:17:19 -07:00
Ryan Fleury e395ef42a1 eval system syntax for opaque id evaluations 2024-08-23 14:45:48 -07:00
Ryan Fleury 8ae8e2f943 extend file streaming cache to support range-based file stream queries; begin plugging in file stream queries as alternative to ctrl stream queries; further bugfixes & unification in eval system 2024-08-23 12:29:52 -07:00
Ryan Fleury ff922fa087 fix expandability/block/row building for block ui view rules 2024-08-22 17:11:12 -07:00
Ryan Fleury 47462f4789 first pass at filesystem evaluation in eval system 2024-08-22 16:55:07 -07:00
Ryan Fleury 341f9c6cf7 introduce resolution qualifiers to evaluation syntax, to specifically denote resolution to registers, locals, types, etc., or file paths 2024-08-22 15:56:43 -07:00
Ryan Fleury b7cc2e8d93 entity evaluation committing; checkbox view rule; per-column view rules in watch views 2024-08-22 15:28:13 -07:00
Ryan Fleury acd7435553 collapse register mode into being a thread space, unify process/thread/debugger read/write paths, keep differences in core eval read/write paths 2024-08-22 14:50:27 -07:00
Ryan Fleury a7cf64d5e2 extend watch view column parameterization; further progress on replacing entity views with watch views 2024-08-22 12:01:53 -07:00
Ryan Fleury 1848acd47e eliminate eval assumption of single architecture; equip each eval module with an architecture; use to correctly specify the debugger process architecture; do initial pass of debugger space evaluation 2024-08-21 12:55:50 -07:00
Ryan Fleury 1ec62b40ae reverse decision to show inheritance type prefix in member names, because I forgot that C++ STL / other codebase types are completely insane; go back to showing inheritance info as a tooltip 2024-08-21 11:24:52 -07:00
Ryan Fleury 70fa90bb87 fix incorrect os_window_first_paint rules 2024-08-20 17:07:59 -07:00
Ryan Fleury c77d61fb4c ellipses for unfinished arrays/structs in eval single-line visualization 2024-08-20 16:33:08 -07:00
Ryan Fleury 4611ddb536 eval value array indexing; type-only evaluation of array indexing and member accesses; various fixes 2024-08-20 16:13:01 -07:00
Ryan Fleury 156a94b286 string/char literal escaping in eval 2024-08-20 14:57:23 -07:00
Ryan Fleury b5b6f61811 fix various edge cases in visualizer paths 2024-08-20 14:48:25 -07:00
Ryan Fleury 67a719f2c6 fix parse error visualization; fix invalid cases in eval expression parser 2024-08-20 14:12:40 -07:00
Ryan Fleury c896d05afc relocate entity; fix incorrect eval mode for procedures view; fix incorrect evaluation of callstack frames in new callstack view 2024-08-20 13:53:54 -07:00
Ryan Fleury b44a5db97f further progress on cleaned up eval watch system; visual fixes/improvements in hover eval 2024-08-20 13:41:36 -07:00
Ryan Fleury 408b689245 eliminate old eval/eval-viz paths 2024-08-20 12:06:02 -07:00
Ryan Fleury 639239d758 convert all eval visualization paths to incrementally building expression trees, rather than using final eval bundles; ensure all evaluation paths, in various circumstances (single line viz, row viz), go through exactly the same path; deduplicate single-row-expr evaluation paths 2024-08-20 12:04:23 -07:00
Ryan Fleury be2daf570a checkpoint on eval / eval-viz simplification pass 2024-08-19 11:26:28 -07:00
Ryan Fleury 9f593f9971 callstack frame selection in watch views 2024-08-16 16:17:50 -07:00
Ryan Fleury 04b38eb405 more progress on new expanded watch path; mostly feature convergent for procedures & callstack 2024-08-16 15:28:16 -07:00
Ryan Fleury 2d1adaf932 watch view feature parity for error visualization 2024-08-16 13:00:02 -07:00
Ryan Fleury d749a5e965 progress on single path for building all cells in watch window, reaching feature parity with old watch windows 2024-08-16 12:49:35 -07:00
Ryan Fleury 25f30f6a72 begin pass to make watch view columns dynamic; will use to specialize watch views for the new expanded set of purposes it has 2024-08-16 11:49:10 -07:00
Ryan Fleury 6bdaf9b4df plug watch pins into new watch-driven ui 2024-08-15 15:12:58 -07:00
Ryan Fleury 82fcc9ed4d evaluate breakpoints in per-breakpoint space, rather than a top-level space for all of the debugger entities 2024-08-15 14:57:16 -07:00
Ryan Fleury 01cf3d39f1 further progress on using the upgraded eval system; sketch out replacement breakpoints & callstack views, which are just specializations of watch window 2024-08-15 14:34:47 -07:00
Ryan Fleury 8b5be64507 fix primary module selection in multi-process scenarios 2024-08-15 12:23:08 -07:00
Ryan Fleury 20bde07c46 fix ir generation for set-space opcode 2024-08-15 12:16:00 -07:00
Ryan Fleury b98a75e056 switch eval memory reads -> more generalized space reads; apply to register reads as well 2024-08-15 11:55:22 -07:00
Ryan Fleury 59c01a73af pipe through space information through eval compiler/interpreter 2024-08-15 11:21:52 -07:00
Ryan Fleury a0d91862a7 bundle per-module info in eval system; use all modules in all processes in ctrl layer evaluations; further sketching out of space info 2024-08-15 10:04:52 -07:00
Ryan Fleury ed75b253f7 notes on 'eval space'; first step to evaluating debugger-space things 2024-08-14 16:26:47 -07:00
Ryan Fleury 857bf44001 converge watch pin / breakpoint commands & mapping, without file entity structure 2024-08-14 15:41:18 -07:00
Ryan Fleury 94791e62ff eliminate old serialization/deserialization paths 2024-08-14 15:27:36 -07:00
Ryan Fleury 52f4474cc8 legacy config exe key for targets 2024-08-14 15:27:01 -07:00
Ryan Fleury 4a2aaf650a add legacy config deserialization paths, for old config files 2024-08-14 15:25:11 -07:00
Ryan Fleury bb9e5057d7 fix go-to-location path to adjust for no file entities; write single deserialization path for all entities, instead of handwritten special casedo nes 2024-08-14 15:08:48 -07:00
Ryan Fleury 33fe9ba485 formally support hresult codes as distinct from handles in debug info & visualization 2024-08-14 13:48:09 -07:00
Ryan Fleury a9f4a11c0a fix run-to-line and run-to-address for new breakpoint entity setup 2024-08-14 12:39:34 -07:00
Ryan Fleury afdb0e5b2e remove addr-mode assumption for string visualizing; eliminate entity deleted flag 2024-08-14 12:26:53 -07:00
Ryan Fleury 728120690d ptr/array-value comparison path in eval 2024-08-14 11:29:45 -07:00
Ryan Fleury 918895c091 small string evaluation; strings as values in eval 2024-08-14 10:49:56 -07:00
Ryan Fleury eac1672c4e begin sketching out eval paths for small string operations 2024-08-13 16:16:55 -07:00
Ryan Fleury 07c4e6ee87 evaluation compiler debug tooltip visualizer 2024-08-13 15:41:01 -07:00
Ryan Fleury c64d207d4d finish sketching out complex synthetic type construction; tear out unneeded leaf external evaluation (we can just use the macro map & separate address spaces); sketch out scaffolding for a thread evaluation type 2024-08-13 13:40:14 -07:00
Ryan Fleury a1605acb7b correct procedural struct/union byte size calculation in eval types 2024-08-13 13:07:13 -07:00
Ryan Fleury 0eff5aca06 extend constructed types in eval system to support procedural construction of structs/unions/enums; can be used for synthetic evals in debugger frontend & ctrl layer 2024-08-13 13:04:05 -07:00
Ryan Fleury 6d30455e76 further progress on eliminating file entities; further entity simplification; set up external identifier resolution map for evaluating 'meta' variables; sketch out generalized entity serialization path 2024-08-13 11:39:25 -07:00
Ryan Fleury 057d4d485e begin entity simplification pass; begin eliminating frontend file system entity cache; build new path-based file override systems, instead of relying on the entity tree 2024-08-12 17:06:59 -07:00
Ryan Fleury 86f45ce5e7 do not assume valid identifier maps if location info is not present 2024-08-12 09:26:44 -07:00
Ryan Fleury 77edf0d8da further progress on undo 2024-08-09 12:11:14 -07:00
Ryan Fleury e506d8389c strip out old undo/redo scaffolding 2024-08-09 10:19:29 -07:00
Ryan Fleury a541ca50d9 rdi_from_pdb: robustify to malformed/unexpected pdb characteristics; df: display errors with inline code better; eval: fix incorrect assumption of addr mode being required for member access operators 2024-08-09 09:27:18 -07:00
Ryan Fleury eda3d6f8b5 fix incorrect assumption of 0 slot -> primary rdi; fixes mistyped locals 2024-08-08 15:56:38 -07:00
Ryan Fleury 896f84369b ues correct unwound registers for eval context 2024-08-08 15:32:18 -07:00
Ryan Fleury 18237a1464 eliminate old architecture info tables 2024-08-07 16:48:20 -07:00
Ryan Fleury 6563cb9e2c split command lister-omission to being either included in ui lists, and included in lower level ipc driving documentation 2024-08-07 15:17:27 -07:00
Ryan Fleury 6a886e096e fix ternary operators in eval; fix incorrect oplist concatentation path 2024-08-07 13:10:41 -07:00
Ryan Fleury 607442b92a fix member lookup rules in new eval ir tree builder 2024-08-07 08:22:22 -07:00
Ryan Fleury fee31daa55 fix system processes lister 2024-08-06 15:08:41 -07:00
Ryan Fleury 44fb75228a fix incorrect symbol name font in symbol lister tooltips 2024-08-06 14:12:18 -07:00
Ryan Fleury ba095129e6 fix incorrect index space usage in debug-info-wide tables 2024-08-06 14:05:39 -07:00
Ryan Fleury a4978e75a3 eliminate separate helper for eval viz block list building 2024-08-06 14:01:30 -07:00
Ryan Fleury 5a682e5888 split eval systems, to decouple types/exprs/parsing (debug info dependent), from irization (macro map dependent), from interpretation (completely independent of the former two stages & all their dependencies) 2024-08-06 13:57:48 -07:00
Ryan Fleury c1cea82ae7 eliminate old eval/type-graph layers 2024-08-06 10:20:37 -07:00
Ryan Fleury e951d788ed fix watch window snap to cursor; begin introducing string literals into eval 2024-08-06 10:19:10 -07:00
Ryan Fleury 615a05e423 fix watch window snap-to-cursor rules; fix eval path for command parameter filling 2024-08-06 09:22:03 -07:00
Ryan Fleury 24d398e3c0 fix resolution to address value in array case; reintroduce macro map building (but this time it is frontend-wide rather than locked to a watch window) 2024-08-06 08:58:30 -07:00
Ryan Fleury 26f75fe7c1 shift watch view expressions from being a watch view implementation detail to being a top-level entity 2024-08-06 08:39:52 -07:00
Ryan Fleury 784a77bdff be a bit more forgiving in eval interpreter, to allow for graceful type (and thus empty bytecode) evaluation 2024-08-06 07:15:03 -07:00
Ryan Fleury ebaf83172f eliminate mid-frame calls into full update step via os_window_first_paint; pull up outside regular frontend frame boundaries; fixes incorrect per-frame dbgi scope usage 2024-08-06 07:07:44 -07:00
Ryan Fleury 3e6b8a3c66 first pass at converting frontend over to using new eval system 2024-08-05 17:05:43 -07:00
Ryan Fleury ba45dd161d complete eval2 first pass 2024-07-30 13:50:27 -07:00
Ryan Fleury d2c363ada2 eval2; ir tree compiler pass, type operations pass 2024-07-30 13:40:24 -07:00
Ryan Fleury 87b9b833d1 multi-module eval; new eval vm 2024-07-29 16:40:36 -07:00
Ryan Fleury ff90223dcb multi-module eval: type graph; eval parser 2024-07-29 16:23:13 -07:00
Ryan Fleury 3a61a0363b fix built exes to refer to their pdbs relatively, so that relocated builds can still locate pdbs relatively; eliminate old unused targets; simplify project.4coder 2024-07-29 11:38:15 -07:00
Ryan Fleury 6bef60b306 begin sketching out new eval layer upgrade, to support (a) many modules, (b) string operations, (c) many address spaces (?) 2024-07-26 16:56:21 -07:00
Ryan Fleury 23da2f8901 always serialize tab filters, if filtering is possible 2024-07-26 16:13:26 -07:00
Ryan Fleury 361be3f6e8 actually fix clang 2024-07-26 15:02:41 -07:00
Ryan Fleury f7dd96a5d1 fix clang 2024-07-26 14:58:17 -07:00
Ryan Fleury 333d9d9eb3 strip out unneeded info from df entities; raddbg_markup windows thread names 2024-07-26 14:52:11 -07:00
Ryan Fleury e80dc54aa7 fix inline frame snapping rules 2024-07-26 12:08:21 -07:00
Ryan Fleury 78d07b8d80 up-one-frame & down-one-frame commands for new rich unwind structure 2024-07-26 11:45:10 -07:00
Ryan Fleury e637ffa523 fix incorrect inline depth check 2024-07-26 11:24:08 -07:00
Ryan Fleury b18e437337 git normalize all files 2024-07-26 11:13:47 -07:00
Ryan Fleury c13833f74f fix line info voff baking; default selected inline frame depth to being shallowest; rework rich unwind to not lose concrete/inline frame structured info 2024-07-26 11:09:55 -07:00
Ryan Fleury 1d87c34dca fix big growth path in arena; make rdi parse code slightly more robust to malformed rdis 2024-07-26 08:37:13 -07:00
Ryan Fleury 1f89d4de9e do not overly-ambitiously hold debug info access scopes in ctrl thread run loop 2024-07-25 10:40:35 -07:00
Ryan Fleury b555655f3a fix incorrect chain size computation in new arena push implementation 2024-07-25 10:33:40 -07:00
Ryan Fleury e48baf9666 begin some work on extending rich hovering; working towards correllating rich hover info from everywhere, to everywhere; memory view <-> source view <-> bitmap viewer <-> watch window <-> etc. 2024-07-23 17:15:00 -07:00
Ryan Fleury ccf8504dd1 switch ctrl flow analysis etc. to zydis from udis86; unify disassembling path in dasm_cache layer, use single instruction decode path in frontend for ctrl flow analysis; use in dasm cache layer for disassembly textualization 2024-07-23 16:23:29 -07:00
Ryan Fleury 926b5e3546 apply linux notes from martins; simplify build.sh; simplify some linux layer code; fix incorrect linux api usage; get gcc builds up and running 2024-07-23 14:31:10 -07:00
Ryan Fleury e0b67f0ecb initial integration of zydis into dasm cache layer 2024-07-23 14:30:26 -07:00
Ryan Fleury 72c940d2b3 project.4coder 2024-07-23 08:45:10 -07:00
NikitaandRyan Fleury e18e136f82 fixed line number binary search for last range in line number map 2024-07-23 08:44:08 -07:00
Martins MozeikoandRyan Fleury ce7c8d5244 avx512 registers & fixes for getting & setting x64 context 2024-07-23 08:43:35 -07:00
Henry GoschützandRyan Fleury 14759e49e9 Fixed a typo. 2024-07-23 08:33:33 -07:00
Ryan Fleury d143fec0d1 fix mmap error case 2024-07-18 14:45:16 -07:00
Ryan Fleury 4835264059 stub out linux demon; linux font provider; begin work, get windows/events up and running in os_gfx 2024-07-18 13:37:22 -07:00
Ryan Fleury ec9c68f55e start work on raddbg building 2024-07-16 17:23:08 -07:00
Ryan Fleury de131b0c18 add rdi_dump to build.sh 2024-07-16 16:51:20 -07:00
Ryan Fleury fdd6c20c78 add cli utilities to build.sh 2024-07-16 16:49:49 -07:00
Ryan Fleury d5338c05f2 os_core: fix file tree iteration 2024-07-16 16:44:05 -07:00
Ryan Fleury d0d9327236 update metagen base/os & entry point 2024-07-16 16:09:53 -07:00
Ryan Fleury d82b54597f os_core: linux port of condition variables 2024-07-16 16:01:23 -07:00
Ryan Fleury 90065e535f os_core: linux port for shared memory, system info, process info, safe call, guid, mutexes, threads 2024-07-16 15:25:19 -07:00
Ryan Fleury b3f69f30ad os_core: linux port for file maps, file iters 2024-07-16 14:11:37 -07:00
Ryan Fleury 3cc51038df os_core: linux port for memory, thread info, filesystem apis 2024-07-16 13:24:54 -07:00
Ryan Fleury 1b74fb0760 simplification pass over os core layer; simplification pass over base arena; set up build.sh; stub out new spot for linux os core 2024-07-15 17:23:01 -07:00
Ryan Fleury 6447a2a993 notes 2024-07-15 10:41:03 -07:00
Ryan Fleury 2539e2ef45 full pass over ui to centralize text rasterization settings by font slot 2024-07-15 10:40:42 -07:00
Ryan Fleury 45656194f4 fix some text spacing issues after text rendering pass 2024-07-15 09:55:30 -07:00
Ryan Fleury 3bb8dc9089 adjust hover eval focus rules; require manual interaction to focus 2024-07-15 09:39:56 -07:00
Ryan Fleury ebbf927fc1 fix interaction register propagation rules on unfocused windows (still propagate if window was last focused) 2024-07-15 09:28:12 -07:00
Ryan Fleury 044e78bea2 fix incorrect scratch usage in new code view ui build path 2024-07-15 09:07:02 -07:00
Ryan Fleury d78afc5000 reintroduce out-of-date file warning 2024-07-04 09:56:44 -07:00
Ryan Fleury aed9a285f5 fix misuse of inactive panel overlay 2024-07-02 16:07:29 -07:00
Ryan Fleury f03d0fb974 correctly apply deserialized window settings 2024-06-28 17:36:44 -07:00
Ryan Fleury 80690d7b20 notes 2024-06-28 16:07:39 -07:00
Ryan Fleury 843749c8ae ui for editing multiple keybindings per command 2024-06-28 16:07:05 -07:00
Ryan Fleury 38090b6273 extend font provider backend with ability to independently toggle hinting & full anti-aliasing; fix up ui text measurement/placement; introduce per-window settings for adjusting font rendering parameters 2024-06-28 15:31:27 -07:00
Ryan Fleury b0259b7a49 visual cleanup / fixes 2024-06-28 09:47:55 -07:00
Ryan Fleury f7b97b302f fix visual issues in completion behavior of autocomplete lister 2024-06-28 09:42:38 -07:00
Ryan Fleury f2a7103461 watch-expr-at-mouse command 2024-06-28 09:14:58 -07:00
Ryan Fleury d1c0bf5fe2 fix add-tab button corners/placement with max-side tabs 2024-06-28 09:02:08 -07:00
Ryan Fleury 8ca67ff892 fix possible incorrect panel being used in commands fired from tab right-click menu 2024-06-27 14:24:45 -07:00
Ryan Fleury 13aa41910e default settings categories to closed 2024-06-27 13:17:44 -07:00
Ryan Fleury c05ceedfcb fix clang build 2024-06-26 18:12:27 -07:00
Ryan Fleury 5e093a9b4c notes 2024-06-26 17:54:54 -07:00
Ryan Fleury 08bc2b0a79 fix up color config remapping table 2024-06-26 17:48:28 -07:00
Ryan Fleury 4ebc38d9f9 fill theme presets for new theme color codes 2024-06-26 17:39:40 -07:00
Ryan Fleury 5e2c6b5107 setting view categories 2024-06-26 15:47:28 -07:00
Ryan Fleury 7584890edd theme presets in new settings view 2024-06-26 15:16:41 -07:00
Ryan Fleury 4bbf64de7e first pass at new settings view 2024-06-26 15:00:45 -07:00
Ryan Fleury e10bef9d2b fix function breakpoints using hit-count as voff; pass over entity ref buttons in various uis; go-to-location with address values in watch views 2024-06-26 12:05:56 -07:00
Ryan Fleury 1229a50c68 eliminate txti layer 2024-06-26 11:09:58 -07:00
Ryan Fleury 6e2353d302 eliminate margin from output 2024-06-26 11:01:51 -07:00
Ryan Fleury 3d272a598b complete convergence of new disasm view, which uses the core code view path 2024-06-26 10:57:49 -07:00
Ryan Fleury dbdf6e7c02 eliminate old duplicative disasm path; use same code view path 2024-06-26 10:44:24 -07:00
Ryan Fleury 0904de74de eliminate old duplicative code/output views 2024-06-26 10:07:26 -07:00
Ryan Fleury e3077cf6f5 pick-file path for new code view 2024-06-26 10:06:16 -07:00
Ryan Fleury 9ad52d25b5 more progress on top-level interaction-register-based cursor commands, getting more out of unified source view 2024-06-26 10:02:26 -07:00
Ryan Fleury c2ddffd424 set up interaction register push/pops for windows & views; use to implement top-level cursor-breakpoint operations; more convergence with new unified src view path 2024-06-26 09:21:51 -07:00
Ryan Fleury 7d351d03c5 txt: split symbol tokens in language lexers to defaultly do single-char symbols unless in special cases; this resolves weird indirection-size-change code label displays 2024-06-26 07:37:52 -07:00
Ryan Fleury 2e12b1485a some light mode fixes, light mode theme preset re-filled 2024-06-25 17:53:39 -07:00
Ryan Fleury 653eb08d43 set up interaction register stack 2024-06-25 17:21:59 -07:00
Ryan Fleury 9be3c2affc sketch out 'interaction registers'; fix bp hit count tracking 2024-06-25 17:02:43 -07:00
Ryan Fleury 6fa8af5e1a checkpoint on unified code ctx menu & all of its operations 2024-06-25 16:31:31 -07:00
Ryan Fleury 010d5609c6 checkpoint in first pass at new unified code view impl.; start setting up unified top-level code ctx menu 2024-06-25 12:00:50 -07:00
Ryan Fleury d12c5ec2e8 first pass at mutable text layer, which allows debugger-produced/controlled buffers to be fed into text visualization systems; start pulling out code view into single path, which will be used for disassembly/source/output 2024-06-25 11:09:02 -07:00
Ryan Fleury c10ac170a8 config settings, for top-level toggles or simple numeric parameters; use to mask off animations, background blurs, and so on; use to control tab width 2024-06-25 09:09:10 -07:00
Ryan Fleury 7a185f9560 auto-fill ctrl+f query from selection; fix single-cell copy/paste in watch views; tweaks/fixes 2024-06-25 08:04:00 -07:00
Ryan Fleury 0d581694e6 notes; tweaks; fixes 2024-06-24 16:35:23 -07:00
Ryan Fleury b4b8f5f0ab fix some escape-to-cancel & context menu behavior; notes 2024-06-24 16:14:06 -07:00
Ryan Fleury 15d42027e7 adjust memory view for new ui palettes & themes 2024-06-24 15:39:12 -07:00
Ryan Fleury 883aa2d1de fix binding ui interaction with group keys 2024-06-24 15:34:56 -07:00
Ryan Fleury 586b3e3072 fix incorrect margin measurement in output view 2024-06-24 15:32:50 -07:00
Ryan Fleury 2588bbcd12 notes 2024-06-24 15:25:22 -07:00
Ryan Fleury 0a5cc5df6f ui: group key, for menu-bar-style interactions, where you have several distinct boxes, but want one interaction to continuously flow between them 2024-06-24 15:23:56 -07:00
Ryan Fleury ff32449ba2 adjust rich hover info in source/disasm view to be less noisy; require hovering over line number margin, rather than always displaying it for whatever line the mouse is over 2024-06-24 15:14:13 -07:00
Ryan Fleury 614954b7ef checkpoint on palettes, fix source view overlay margin building/drawing 2024-06-24 14:46:16 -07:00
Ryan Fleury 31c671e3f5 more progress on simplifying/condensing new theme colors 2024-06-24 14:08:28 -07:00
Ryan Fleury 6d75d6b63b simplification/consolidation pass over theme colors 2024-06-24 11:59:19 -07:00
Ryan Fleury 4d2b524400 notes, ui pass tweaks 2024-06-23 23:21:18 -07:00
Ryan Fleury 16863b1f5a fix run-list size calculation, accounting for advance vs. end pad 2024-06-22 20:29:38 -07:00
Ryan Fleury f9abb397f3 adjust px offset -> byte offset path for new text measuring fixes 2024-06-22 20:19:24 -07:00
Ryan Fleury db5a7d4be2 adjust title bar 2024-06-22 16:12:53 -07:00
Ryan Fleury 6ac870dac0 improvements in text layout, focus visualization, smooth text rasterization for icons; checkpoint in ui visuals pass 2024-06-22 15:58:40 -07:00
Ryan Fleury 5f23820f9d checkpoint on ui/palettes/visuals pass 2024-06-21 22:06:40 -07:00
Ryan Fleury fc77844452 color scheme -> palette; fix eval/watch views after cleanup; make more progress on new palette system 2024-06-21 09:49:51 -07:00
Ryan Fleury 3b27abd5c7 first pass at new theme color table, scheme-based ui color specification 2024-06-20 15:28:48 -07:00
Ryan Fleury ce1f54a931 notes 2024-06-20 09:06:35 -07:00
Ryan Fleury c60d3aab22 mouse-driven ui path for query completion; show-in-explorer ui for tab ctx menu 2024-06-20 08:02:01 -07:00
Ryan Fleury b76c605eba sort locals by debug info order; still likely not sufficient for all the options, but at least marginally better & introduces the sorting path 2024-06-20 07:35:59 -07:00
Ryan Fleury 6eef8c3e16 rdi_format_parse: prefer line info idxs with file coordinates in line mapping helper 2024-06-19 13:27:34 -07:00
Ryan Fleury b5b5aca691 log win32 demon resume code 2024-06-19 12:07:08 -07:00
Ryan Fleury 435877824a oh NO... never mind... mystery solved... be VERY CAREFUL ABOUT STATE MACHINES! fixes incorrect non-resets of win32 demon 'exception not handled' state, which was buggily leading to DBG_EXCEPTION_NOT_HANDLED being passed to ContinueDebugEvent 2024-06-19 11:56:47 -07:00
Ryan Fleury 3327d73373 notes on memory-execution-exception spoof implementation situation, and toggles to switch to old behavior, for later investigation 2024-06-19 11:32:44 -07:00
Ryan Fleury 376a7c48a5 pass over logging, include a lot of extra info in ctrl thread log; demon abstraction for target-process memory allocation/protection; switch spoofs to being in allocated page, rather than at bogus address 2024-06-19 11:12:21 -07:00
Ryan Fleury f6eec680bc adjust single stepping rule to be robust to non-single-step events; this is still not what the issue is pertaining to the stepping bug... 2024-06-18 17:19:17 -07:00
Ryan Fleury 41fd224956 log ctrl events on user thread; do not use cached register block reading path for ctrl stepping machine, as it must not prematurely update cache for all readers, since runs are not complete 2024-06-18 12:07:46 -07:00
Ryan Fleury c794d896c9 oops - fix logging for trap net 2024-06-18 10:59:35 -07:00
Ryan Fleury 1a8b39ad9d fix builds github workflow for new build names 2024-06-18 10:56:41 -07:00
Ryan Fleury a8891b3ca4 fix rdi_from_dwarf build 2024-06-18 10:55:54 -07:00
Ryan Fleury ada1b8dfe2 log final trap net 2024-06-18 10:51:29 -07:00
Ryan Fleury 9461e79268 adjust build script to warn if valid build target was not specified 2024-06-18 10:46:50 -07:00
Ryan Fleury 4fc5b61676 also disable overly-ambitious cursor centering in memory view 2024-06-18 10:28:49 -07:00
Ryan Fleury 6cc1dfb39a trap net generation logging; log markers 2024-06-18 10:14:54 -07:00
Ryan Fleury d44f098e84 disallow override detection with nil overrides 2024-06-17 13:06:23 -07:00
Ryan Fleury 749821dd27 adjust unwind loop to be robust to noop-unwind-steps that would otherwise result in infinite unwind loops 2024-06-17 12:14:10 -07:00
Ryan Fleury 6ad94978ce correctly adjust dbgi timestamp in ctrl entity store, upon debug info changes 2024-06-17 10:55:17 -07:00
Ryan Fleury bc5d0b1888 fix rich hover reset behavior 2024-06-17 10:18:41 -07:00
Ryan Fleury 3c2c98b08a rdi_make: fix incorrect line table count calculation 2024-06-17 10:08:11 -07:00
Ryan Fleury 31d7be8f8a tweak snap-to-cursor behavior when dragging 2024-06-17 09:42:12 -07:00
Ryan Fleury 0b3e3228d1 rdi_from_pdb: fix incorrect bounds checks on procedure frameproc lookup for local location info 2024-06-17 09:34:27 -07:00
Ryan Fleury 794f212501 dasm address consistency 2024-06-14 14:17:26 -07:00
Ryan Fleury 723c7c5d4d further tightening up of win32 demon run path; take a few fastpaths on x64; speeds up conditional breakpoints 2024-06-14 09:50:33 -07:00
Ryan Fleury fb9824dc24 remove unnecessary ctrl log flushes, which seriously bloated the ctrl thread running path 2024-06-14 07:57:46 -07:00
Ryan Fleury 933b4c90de fix rdi_format_parse and rdi_breakpad_from_pdb build 2024-06-13 17:12:31 -07:00
Ryan Fleury 5349838633 rdi: producer name in top-level-info 2024-06-13 16:55:47 -07:00
Ryan Fleury f655758060 extend tooltips & stringization of callstacks with rich unwind info 2024-06-13 16:48:27 -07:00
Ryan Fleury fa4d0bc262 ctrl: break debug string events apart if needed; enforce size cap on serialized ctrl events 2024-06-13 16:24:54 -07:00
Ryan Fleury 3c39a88abf correctly transform saved relative project paths to absolute project paths on config deserialization 2024-06-13 15:52:11 -07:00
Ryan Fleury fb6689a74d always report debug string events earlier in queue 2024-06-13 15:28:56 -07:00
Ryan Fleury a5e29f65f6 Merge branch 'inline_merge' of https://github.com/EpicGamesExt/raddebugger into inline_merge 2024-06-13 15:20:35 -07:00
Ryan Fleury b6f50cc4be intersect line voff ranges across all overlapping line tables when mapping voffs to line info; fixes inline stepping 2024-06-13 15:18:29 -07:00
Ryan Fleury b47b22bdce correct thread -> src mapping, given inline info 2024-06-13 15:18:29 -07:00
Ryan Fleury 41e99bd2f6 proper inline frame unwind selection & storage & command parameterization 2024-06-13 15:18:29 -07:00
Ryan Fleury 2c7d15de59 pull out 'rich unwind' gathering path, which takes a 'concrete unwind'
and produces a full unwind with debug-info-derived inline frames
2024-06-13 15:18:29 -07:00
Ryan Fleury bf2d5640fa go back to per-inline-site line tables; eliminate call location for inline tables; these can be encoded via parent line tables; wire up parsed line tables to inline site production from symbol conversion phase 2024-06-13 15:18:29 -07:00
Ryan Fleury 1880eca295 do not assume non-empty name map bakes 2024-06-13 15:18:29 -07:00
Ryan Fleury 59a20a5574 fix missing line chunks in inline line table parsing 2024-06-13 15:18:29 -07:00
Ryan Fleury 852ff5f054 oops! 2024-06-13 15:18:29 -07:00
Ryan Fleury ac3d7be4de look up into inline site info in call stack view; display both concrete & inline frames 2024-06-13 15:18:29 -07:00
Ryan Fleury 07b56a920c parse inline site scope ranges in symbol conversion pass 2024-06-13 15:18:29 -07:00
Ryan Fleury 1cc829512f fix disasm cmd/ui discrepancy 2024-06-13 15:18:29 -07:00
Ryan Fleury dafbe32e85 adjust line info lookup apis to be range-based, with a first-and-shallowest-only helper 2024-06-13 15:18:29 -07:00
Ryan Fleury 2419a00b11 fix cases where decorative disasm lines were being confused with non-decorative 2024-06-13 15:18:29 -07:00
Ryan Fleury 6e9b2bd107 extend rdi line info lookups with depth; fix bad panel deref in target view cmds 2024-06-13 15:18:29 -07:00
Ryan Fleury 123232ab32 correctly apply procedure base voffs in inline line info parsing 2024-06-13 15:18:29 -07:00
Ryan Fleury 1dbc37fe1f eliminate per-inline-site line tables; merge inline site line info with unit's line table 2024-06-13 15:18:29 -07:00
Ryan Fleury 4c10967cec merged line table sort experiments 2024-06-13 15:18:29 -07:00
Ryan Fleury e543abd478 rdi_from_pdb: next checkpoint on inline line table parsing/conversion 2024-06-13 15:18:29 -07:00
Ryan Fleury 3b94fa55fb rdi_from_pdb: inline binary annotations parsing 2024-06-13 15:18:29 -07:00
Ryan Fleury 3b6d8cb761 rdi_from_pdb: sketch out unified inlinee parsing/gathering path in units conversion task 2024-06-13 15:18:29 -07:00
Ryan Fleury a73cde2864 codeview c13 inlinee lines info parsing, lookup in inline site parsing path 2024-06-13 15:18:29 -07:00
Ryan Fleury fe12f2fdf9 inline site info extraction 2024-06-13 15:18:29 -07:00
Ryan Fleury c80555c49d rdi_make, rdi_from_pdb, rdi_dump: sketch out the building (no parsing/filling yet), dumping, and baking/serializing of inline sites 2024-06-13 15:18:29 -07:00
Ryan Fleury a3f411ddd4 more progress on rdi parsing library high-level composite helpers; update breakpad_from_pdb to new format/maker changes 2024-06-13 15:18:29 -07:00
Ryan Fleury 084cabad39 pass over high level composite rdi parsing helpers 2024-06-13 15:18:29 -07:00
Ryan Fleury 64d7bae845 rdi_make: eliminate old baking/serializing code 2024-06-13 15:18:29 -07:00
Ryan Fleury 93d5bab41c eliminate base node idx from per-node info; nodes can be stored all relative to their name map's base indices, and this is naturally applied on lookup, no need to bake it in 2024-06-13 15:18:29 -07:00
Ryan Fleury 772bc37504 fix fuzzy search layer for new table extraction code 2024-06-13 15:18:29 -07:00
Ryan Fleury 2ff0abb91e rdi_make, rdi_from_pdb: complete next pass over new serialization/compression interface, including for new top-level-only name map data sections; eliminate determinism issues from string map build (task dispatch was busted) 2024-06-13 15:18:28 -07:00
Ryan Fleury b05cfa4b24 checkpoint on new baking implementation 2024-06-13 15:18:28 -07:00
Ryan Fleury 379885421e rdi make: xfer over per-name-map building path 2024-06-13 15:18:28 -07:00
Ryan Fleury 809a888ce7 rdi make: first pass at new baking paths 2024-06-13 15:18:28 -07:00
Ryan Fleury 9dadd3ed3c sketch out new rdi make baking codepaths 2024-06-13 15:18:28 -07:00
Ryan Fleury d0d1e7d7e6 sketch out artifact types for new rdi baking pass 2024-06-13 15:18:28 -07:00
Ryan Fleury 10ead2f999 rdi: first pass of eliminating remainder of non-top-level sections; simplification/cleanup of rdi parsing layer 2024-06-13 15:18:28 -07:00
Ryan Fleury 550e8a0451 set up inline site info building scaffolding 2024-06-13 15:18:28 -07:00
Ryan Fleury 7495096e05 fix baking of joined line tables 2024-06-13 15:18:28 -07:00
Ryan Fleury 7e85335f3b move per-source-file line maps to top-level sections, and move source line -> voff maps to separate top-level info table 2024-06-13 15:18:28 -07:00
Ryan Fleury 3ad6197b88 eliminate old per-unit line info code 2024-06-13 15:18:28 -07:00
Ryan Fleury 81b45f1a2f do not broadcast unnecessarily in task system kickoff 2024-06-13 15:18:28 -07:00
Ryan Fleury 44868c0e85 rdi, rdi_make, rdi_from_pdb, rdi_dump, df, dasm, etc: extract line tables from per-unit data sections, have top-level line info tables with units referring to line tables, and line tables just referring to sub-ranges of top-level sections; fix off-by-one string index in rdi generation 2024-06-13 15:18:28 -07:00
Ryan Fleury f7ce1b73bc introduce separate rdi table element types for isolated line tables & inline sites 2024-06-13 15:18:28 -07:00
Ryan Fleury a4a0452d0c fix project.4coder 2024-06-13 15:18:28 -07:00
Ryan Fleury 45090de3fb appease clang 2024-06-13 15:18:28 -07:00
Ryan Fleury 6824ffddc0 intersect line voff ranges across all overlapping line tables when mapping voffs to line info; fixes inline stepping 2024-06-13 15:17:12 -07:00
Ryan Fleury dc34cdb59a correct thread -> src mapping, given inline info 2024-06-13 15:04:12 -07:00
Ryan Fleury 98290ff29b proper inline frame unwind selection & storage & command parameterization 2024-06-13 14:58:18 -07:00
Ryan Fleury 5a24649a31 pull out 'rich unwind' gathering path, which takes a 'concrete unwind'
and produces a full unwind with debug-info-derived inline frames
2024-06-13 11:28:38 -07:00
Ryan Fleury 97a96cfdd4 go back to per-inline-site line tables; eliminate call location for inline tables; these can be encoded via parent line tables; wire up parsed line tables to inline site production from symbol conversion phase 2024-06-13 10:41:19 -07:00
Ryan Fleury e25c3044b0 do not assume non-empty name map bakes 2024-06-10 15:59:19 -07:00
Ryan Fleury af80e1bfc8 fix missing line chunks in inline line table parsing 2024-06-10 15:42:50 -07:00
Ryan Fleury 6488e2d5e2 oops! 2024-06-10 15:26:02 -07:00
Ryan Fleury 649932cce0 look up into inline site info in call stack view; display both concrete & inline frames 2024-06-10 15:06:25 -07:00
Ryan Fleury dd5cc89483 parse inline site scope ranges in symbol conversion pass 2024-06-10 14:36:00 -07:00
Ryan Fleury 8a6837c553 fix disasm cmd/ui discrepancy 2024-06-10 13:33:32 -07:00
Ryan Fleury a009473557 adjust line info lookup apis to be range-based, with a first-and-shallowest-only helper 2024-06-10 13:28:08 -07:00
Ryan Fleury c18c02a37e fix cases where decorative disasm lines were being confused with non-decorative 2024-06-10 13:23:32 -07:00
Ryan Fleury c61f820aef extend rdi line info lookups with depth; fix bad panel deref in target view cmds 2024-06-10 12:34:22 -07:00
Ryan Fleury 5c8c1a89e3 correctly apply procedure base voffs in inline line info parsing 2024-06-10 11:35:31 -07:00
Ryan Fleury 61630f4cf9 eliminate per-inline-site line tables; merge inline site line info with unit's line table 2024-06-10 11:26:54 -07:00
Ryan Fleury 21b439e7e5 merged line table sort experiments 2024-06-10 11:12:21 -07:00
Ryan Fleury 4888f90f7f rdi_from_pdb: next checkpoint on inline line table parsing/conversion 2024-06-10 09:45:41 -07:00
Ryan Fleury 6f92fe971a rdi_from_pdb: inline binary annotations parsing 2024-06-10 09:18:05 -07:00
Ryan Fleury cfd2380caa rdi_from_pdb: sketch out unified inlinee parsing/gathering path in units conversion task 2024-06-07 17:22:45 -07:00
Ryan Fleury 07d56ee27c codeview c13 inlinee lines info parsing, lookup in inline site parsing path 2024-06-07 16:40:21 -07:00
Ryan Fleury 334bd3b06f inline site info extraction 2024-06-07 15:22:53 -07:00
Ryan Fleury a14a2f34f5 rdi_make, rdi_from_pdb, rdi_dump: sketch out the building (no parsing/filling yet), dumping, and baking/serializing of inline sites 2024-06-07 14:54:13 -07:00
Ryan Fleury 9dcb5a209a more progress on rdi parsing library high-level composite helpers; update breakpad_from_pdb to new format/maker changes 2024-06-07 13:45:26 -07:00
Ryan Fleury 300b14ffb4 pass over high level composite rdi parsing helpers 2024-06-07 11:45:18 -07:00
Ryan Fleury 8c63478d9b rdi_make: eliminate old baking/serializing code 2024-06-07 11:17:48 -07:00
Ryan Fleury 8f03fb0cc5 eliminate base node idx from per-node info; nodes can be stored all relative to their name map's base indices, and this is naturally applied on lookup, no need to bake it in 2024-06-07 11:17:11 -07:00
Ryan Fleury b48fcea28a fix fuzzy search layer for new table extraction code 2024-06-07 11:07:58 -07:00
Ryan Fleury 431884dce8 rdi_make, rdi_from_pdb: complete next pass over new serialization/compression interface, including for new top-level-only name map data sections; eliminate determinism issues from string map build (task dispatch was busted) 2024-06-07 11:03:00 -07:00
Ryan Fleury d931aed462 checkpoint on new baking implementation 2024-06-06 17:13:44 -07:00
Ryan Fleury 2c4c9e9d75 rdi make: xfer over per-name-map building path 2024-06-06 16:50:02 -07:00
Ryan Fleury 11978904e1 rdi make: first pass at new baking paths 2024-06-06 16:47:33 -07:00
Ryan Fleury 8d99f4859b sketch out new rdi make baking codepaths 2024-06-06 16:06:50 -07:00
Ryan Fleury 6e84c078a8 sketch out artifact types for new rdi baking pass 2024-06-06 15:37:27 -07:00
Ryan Fleury 14034c8bea rdi: first pass of eliminating remainder of non-top-level sections; simplification/cleanup of rdi parsing layer 2024-06-06 14:37:22 -07:00
Ryan Fleury 0a88e08dee Merge branch 'dev' of https://github.com/EpicGamesExt/raddebugger into inline_merge 2024-06-05 18:06:47 -07:00
Ryan Fleury c04a97f991 eval: fix enum type unwrapping; unwrap enum types on array indexing 2024-06-05 18:06:09 -07:00
Ryan Fleury 0b35224cf8 set up inline site info building scaffolding 2024-06-04 17:04:53 -07:00
Ryan Fleury 3f50169fee fix baking of joined line tables 2024-06-04 15:46:51 -07:00
Ryan Fleury ebd5cf9e47 move per-source-file line maps to top-level sections, and move source line -> voff maps to separate top-level info table 2024-06-04 13:33:38 -07:00
Ryan Fleury f7e67a80c9 eliminate old per-unit line info code 2024-06-03 16:45:33 -07:00
Ryan Fleury 063975693d do not broadcast unnecessarily in task system kickoff 2024-06-03 16:25:37 -07:00
Ryan Fleury 44fbbc24ee rdi, rdi_make, rdi_from_pdb, rdi_dump, df, dasm, etc: extract line tables from per-unit data sections, have top-level line info tables with units referring to line tables, and line tables just referring to sub-ranges of top-level sections; fix off-by-one string index in rdi generation 2024-06-03 15:32:14 -07:00
Ryan Fleury fcb839b788 introduce separate rdi table element types for isolated line tables & inline sites 2024-06-02 21:22:01 -07:00
Ryan Fleury 139d00e660 Merge branch 'dev' of https://github.com/EpicGamesExt/raddebugger into inline_merge 2024-06-02 18:24:30 -07:00
Ryan Fleury 41afe1af64 Merge branch 'dev' of https://github.com/EpicGamesExt/raddebugger 2024-06-02 18:23:38 -07:00
Ryan Fleury 3927d333ae remove unnecessary and sometimes unsupported win_noexcept keyword 2024-06-02 18:22:51 -07:00
Ryan Fleury 8438faca06 fix project.4coder 2024-06-01 21:09:44 -07:00
Ryan Fleury 061abb4545 appease clang 2024-06-01 21:09:36 -07:00
Ryan Fleury 011c980646 fix project.4coder 2024-06-01 21:09:10 -07:00
Ryan Fleury 26626c3946 appease clang 2024-06-01 21:09:06 -07:00
Ryan Fleury 281849b4e8 fix project.4coder 2024-06-01 21:06:28 -07:00
Ryan Fleury d3f7bef2b7 appease clang 2024-06-01 21:06:22 -07:00
Ryan Fleury ab5259a3d3 Merge branch 'inline_merge' of https://github.com/EpicGamesExt/raddebugger into inline_merge 2024-06-01 19:25:33 -07:00
Ryan Fleury 57da328c2a d3d11 render backend c++ -> c; raddbg build c++ -> c 2024-06-01 19:24:47 -07:00
Ryan Fleury ebc19ded62 font provider dwrite c++ -> c 2024-06-01 19:24:47 -07:00
Ryan Fleury aff3da8256 move font provider directwrite backend to using martins' auto-generated dwrite c declarations, get it almost off C++ entirely 2024-06-01 19:24:47 -07:00
Ryan Fleury c1764cee07 adjust builds to new rdi library setup 2024-06-01 19:24:46 -07:00
Ryan Fleury cc58703185 reorganize generated & handwritten library (relocatable) rad debug info format files; separate from codebase-local tools for managing or internally including the libraries 2024-06-01 19:24:46 -07:00
Ryan Fleury 6a57555882 lld no_aslr 2024-06-01 19:24:46 -07:00
Ryan Fleury cdf0b67354 clean up metaprogram multiline string line endings; fix rdi_from_pdb build 2024-06-01 19:24:46 -07:00
Ryan Fleury 45f69b6f98 further progress on metacode-driven generation of rdi headers; metaprogram xlist generation; getting rdi_dump up-to-speed 2024-06-01 19:24:46 -07:00
Ryan Fleury 47df50b6dc generation folder output override in metaprogram 2024-06-01 19:24:46 -07:00
Ryan Fleury f50b54cff7 complete metacodification of rdi format info into tables 2024-06-01 19:24:46 -07:00
Ryan Fleury 8492693df2 initial pass of moving rdi definitions to metacode tables 2024-06-01 19:24:45 -07:00
Nikita SmithandRyan Fleury 652a9b5cee codeview: inline binary annot format and decode helpers 2024-06-01 19:23:59 -07:00
Ryan Fleury 7f87f89aa8 rdi_dump: stringize source file's path 2024-06-01 19:22:30 -07:00
Nikita SmithandRyan Fleury 92b3356526 codeview: struct defs for $$INLINEE_LINES 2024-06-01 19:22:30 -07:00
Nikita SmithandRyan Fleury 98486f0795 codeview: new sub-section types 2024-06-01 19:22:29 -07:00
Ryan Fleury 729a5a9392 clean up & merge inline binary annotation decoders 2024-06-01 19:22:29 -07:00
Nikita SmithandRyan Fleury ffa802f583 codeview: inline binary annot format and decode helpers 2024-06-01 19:22:29 -07:00
Ryan Fleury b192e38d12 d3d11 render backend c++ -> c; raddbg build c++ -> c 2024-06-01 19:21:43 -07:00
Ryan Fleury 3c0831ec09 font provider dwrite c++ -> c 2024-06-01 18:21:29 -07:00
Ryan Fleury 02e1b8cf00 move font provider directwrite backend to using martins' auto-generated dwrite c declarations, get it almost off C++ entirely 2024-06-01 18:20:13 -07:00
Ryan Fleury 448baf68a8 adjust builds to new rdi library setup 2024-06-01 12:07:55 -07:00
Ryan Fleury 82c1badcdc reorganize generated & handwritten library (relocatable) rad debug info format files; separate from codebase-local tools for managing or internally including the libraries 2024-06-01 12:05:51 -07:00
Ryan Fleury 01a21af955 lld no_aslr 2024-06-01 11:57:44 -07:00
Ryan Fleury a8b02f9791 clean up metaprogram multiline string line endings; fix rdi_from_pdb build 2024-06-01 11:30:51 -07:00
Ryan Fleury 2c9a6f996d fix zero expression child nodes, commonly produced via partially typed expressions 2024-06-01 10:58:49 -07:00
Ryan Fleury d66bbdc6a7 further progress on metacode-driven generation of rdi headers; metaprogram xlist generation; getting rdi_dump up-to-speed 2024-06-01 10:16:38 -07:00
Ryan Fleury de56231f4a generation folder output override in metaprogram 2024-05-31 17:29:25 -07:00
Ryan Fleury 35c1c463c8 complete metacodification of rdi format info into tables 2024-05-31 17:16:54 -07:00
Ryan Fleury 59e71eb5cc drive iteration in win32 file system api; fix some root-level behaviors of file browser 2024-05-31 12:20:14 -07:00
Ryan Fleury d3adfdeced deduplicate debug string event generation; log ctrl messages 2024-05-31 11:17:59 -07:00
Ryan Fleury ed8731c093 correctly handle copy path in new multicursor-able watch view controls 2024-05-31 10:47:46 -07:00
Ryan Fleury 6d4b4b1526 time-based exit path for demon win32 event consumption loop, to not overly-aggressively-buffer things 2024-05-30 07:10:21 -07:00
Ryan Fleury 9fbcd1ec36 Merge branch 'dev' 2024-05-30 07:06:53 -07:00
Ryan Fleury da54fd1217 majorly improve outputdebugstring performance 2024-05-30 07:06:29 -07:00
Ryan Fleury 34bba95839 import todo notes from awkwardly aggressive user feedback 2024-05-29 21:25:47 -07:00
Ryan Fleury 89fd718a8c Merge branch 'dev' of https://github.com/EpicGamesExt/raddebugger into inline_merge 2024-05-29 12:35:49 -07:00
Ryan Fleury 89c8f84498 more tweaks with new double-margin; do not try to display non-printable ascii characters in watch 2024-05-29 12:25:03 -07:00
Ryan Fleury c426818364 draw line between priority & catchall marging 2024-05-29 11:53:48 -07:00
Ryan Fleury 62fa397e29 split code slice margin into two parts - priority, and catchall. priority for selected thread so it is always necessarily visible, and catchall for other threads, breakpoints, watch pins, etc. also tweak targets view behavior to prioritize selection as the common path, and to make checkboxes less idiosyncratic 2024-05-29 11:51:04 -07:00
Ryan Fleury 0e179f3844 fix clips, occlusion, for ui-tree-wide truncated text tooltips 2024-05-29 10:56:46 -07:00
Ryan Fleury f808e8ae29 adjust force-contain on tooltips; we don't want it for drag/drop, we do for tooltips, so use active interaction as a proxy 2024-05-29 10:43:14 -07:00
Ryan Fleury 8f446d1f9a pass over callstack view to display function type info and properly display richer/weirder C++ symbol names 2024-05-29 10:36:22 -07:00
Ryan Fleury e073ff3218 more notes on the multithreaded access violation stuff! 2024-05-29 08:31:24 -07:00
Ryan Fleury 2512d07c72 correctly roll-back late-hits for int3s 2024-05-29 08:08:44 -07:00
Ryan Fleury f65cf5436e fix code off -> instruction idx lookup - fixes busted instruction pointer drawing in disassembly view 2024-05-29 08:03:06 -07:00
Ryan Fleury 5778e75d66 oops - do not zero unwind cache node after adding it, zero it before adding it 2024-05-28 21:45:14 -07:00
Ryan Fleury 08750c2318 initial pass of moving rdi definitions to metacode tables 2024-05-28 21:31:56 -07:00
Ryan Fleury 9a5a3b9296 Merge remote-tracking branch 'refs/remotes/origin/inline_merge' into inline_merge 2024-05-28 07:41:31 -07:00
Ryan Fleury cab8bdaf38 rdi_dump: stringize source file's path 2024-05-28 07:37:19 -07:00
Nikita SmithandRyan Fleury afb7aba039 codeview: struct defs for $$INLINEE_LINES 2024-05-28 07:37:19 -07:00
Nikita SmithandRyan Fleury 0750570081 codeview: new sub-section types 2024-05-28 07:37:18 -07:00
Ryan Fleury 86a9934016 clean up & merge inline binary annotation decoders 2024-05-28 07:37:18 -07:00
Nikita SmithandRyan Fleury f14686c6fb codeview: inline binary annot format and decode helpers 2024-05-28 07:37:18 -07:00
Ryan Fleury e80008cb7e do not animate disasm load when running 2024-05-28 07:34:10 -07:00
Ryan Fleury 68d3f17ecb do not snap-to-thread on soft-halts 2024-05-28 07:30:54 -07:00
Ryan Fleury e541fce2bc fix non-enumeration of 0 tex2dfmt 2024-05-28 06:13:14 -07:00
Ryan Fleury 6a32c197fa rdi_dump: stringize source file's path 2024-05-28 06:10:43 -07:00
Nikita SmithandRyan Fleury eea3c6b53c codeview: struct defs for $$INLINEE_LINES 2024-05-28 06:10:43 -07:00
Nikita SmithandRyan Fleury d2f9bdeefb codeview: new sub-section types 2024-05-28 06:10:43 -07:00
Ryan Fleury c767f03f32 clean up & merge inline binary annotation decoders 2024-05-28 06:10:43 -07:00
Nikita SmithandRyan Fleury db737941d8 codeview: inline binary annot format and decode helpers 2024-05-28 06:10:43 -07:00
Ryan Fleury 8319850666 fix precision tab alignment issue 2024-05-28 06:10:12 -07:00
Ryan Fleury d04ee598b2 use lower level unwinding path with more generous time allowance, rather than passive cache query, for step-out 2024-05-26 14:35:57 -07:00
Ryan Fleury 15f5894c60 choose debug info key timestamps from debug info path, rather than module timestamp; the module should be allowed to be newer 2024-05-26 13:25:03 -07:00
Ryan Fleury 05c751a61a fix filesystem lister names 2024-05-26 12:47:47 -07:00
Ryan Fleury dd7cce2c3a some progress on the bitmap view rule 2024-05-24 21:20:44 -07:00
Ryan Fleury b1e1752229 oops 2024-05-24 17:19:46 -07:00
Ryan Fleury bddc9c97d9 get rdi_dump off dbgi layer, actually, super bad idea; just dedup decompression code 2024-05-24 17:18:31 -07:00
Ryan Fleury 325474fc49 Merge remote-tracking branch 'refs/remotes/origin/dev' into dev 2024-05-24 16:35:09 -07:00
Ryan Fleury 50d401e4ce formalize tab size in all ui codepaths, per-box; pick 4*columnsize by default in text views 2024-05-24 16:34:42 -07:00
Ryan Fleury 1dbbd351d7 formalize tab size in all ui codepaths, per-box; pick 4*columnsize by default in text views 2024-05-24 16:33:30 -07:00
Casey MuratoriandRyan Fleury 1161c4adbb Added line that got left out when I tried to commit this the first time. 2024-05-24 16:10:40 -07:00
Casey MuratoriandRyan Fleury 320a307e90 Dynamically linked SetThreadDescription to avoid requiring latest SDK/kernel version on Windows 2024-05-24 16:10:40 -07:00
Casey MuratoriandRyan Fleury f835158071 Added call to the build.bat so that rc can be redirected as a batch file 2024-05-24 16:10:40 -07:00
Ryan Fleury f214b7d5f2 eliminate tab picker ui 2024-05-24 15:17:36 -07:00
Ryan Fleury d716159faf feed base column & tab width through all font rendering paths; use temporary constants 2024-05-24 15:12:40 -07:00
Ryan Fleury 5074b7f62e expand f_push_run_from_... to basing its tab-advance logic on what base column it is starting at - currently assume this is 0, basically doing the most naive tab alignment version that will work for leading spaces but for nothing else, and also assume 4-space tab width for now 2024-05-24 14:40:07 -07:00
Martins MozeikoandRyan Fleury fd982d38fc Fixes bad resource usage in rendering
D3D11 is quite strict about how resources are supposed to be used - read/write & CPU access.
This changes Tex2DKind and BufferKind into one uniform ResourceKind (because it's the same thing really).

And it is more strict about usage:
1) Static is not allowed to update, resource is immutable, data provided at creation
2) Dynamic allows CPU to update GPU resource occasionally via UpdateSubresource
3) Stream allows CPU to update GPU resource often via Map/Unmap (currently unused)
2024-05-24 14:04:42 -07:00
Ryan Fleury 7e0611e7f1 recent projects history & opener 2024-05-24 14:03:07 -07:00
Ryan Fleury fd7085b690 do not settle for empty unwinds 2024-05-24 13:37:31 -07:00
Ryan Fleury 5f76fcfb6b filter panel tabs by project, if applicable; move all tab controls & so on to working based on this filtering mechanism 2024-05-24 13:33:47 -07:00
Ryan Fleury 9e778b30b6 begin tracking per-tab project info; fix dasm cache request dequeue incorrect cv broadcast 2024-05-24 12:58:54 -07:00
Ryan Fleury 15a1f81545 profile -> project 2024-05-24 12:35:51 -07:00
Ryan Fleury f7ad44a0d7 fix new-file query completion 2024-05-24 12:16:30 -07:00
Ryan Fleury 9349ac9e72 eliminate weird rollback/re-adjust rules for threads hitting int3s - rollback should only ever happen for temporary traps, e.g. user breakpoints or stepping. the fact that the thread shows *after* the trap later is a visualization issue, not a functionality issue 2024-05-24 08:20:10 -07:00
Ryan Fleury 489ae56223 fix moduleless unwinding and find-threads without debug info 2024-05-23 16:17:31 -07:00
Ryan Fleury 35b97d9c20 process name on stop-reason strings 2024-05-23 15:38:51 -07:00
Ryan Fleury bafc2170ca do not consume passthrough --s in command line parser 2024-05-23 15:21:53 -07:00
Ryan Fleury 6837d8d71a move rdi_dump over to dbgi layer 2024-05-23 15:16:53 -07:00
Ryan Fleury 35c599dea3 raddbgi -> rdi 2024-05-23 15:09:53 -07:00
Ryan Fleury dc5dda3f71 visualize handle basic types 2024-05-23 14:47:42 -07:00
Ryan Fleury fdfee37228 oops - only d3d11 flush on resize 2024-05-23 14:45:32 -07:00
Ryan Fleury ece414c575 prioritize title-bar-client-areas over built-in window borders; expand top bar rect a bit to ensure edge of window coverage 2024-05-23 14:40:23 -07:00
Ryan Fleury f431ac7f80 rewrite ipc communication; do ipc message reception on separate thread, wake up main thread; fix various robustness issues. do not necessarily initialize slower-to-initialize layers in conversion/ipc instances 2024-05-23 14:34:01 -07:00
Ryan Fleury e850f6fc93 c++ module extensions 2024-05-23 12:39:14 -07:00
Ryan Fleury 68a9802357 re-implement keyboard-driven path for opening dedicated view rule tabs 2024-05-23 11:36:51 -07:00
Ryan Fleury 905d04ab0b adjust disasm window limits; too often hitting non-read-only memory 2024-05-23 11:34:23 -07:00
Ryan Fleury bc40d1c0b0 rewrite frontend unwind cache to always preserve stale results until a new unwind successfully completes 2024-05-23 11:16:34 -07:00
Ryan Fleury f26b4c3b06 eliminate path-tree-based keying of debug info on frontend; use dbgi-layer-defined debug info keys, which can be more robust to changes to the same debug info path across time (e.g. during hot reloads 2024-05-23 10:30:23 -07:00
Ryan Fleury 68a92e910a eliminate old dbgi layer 2024-05-23 08:26:16 -07:00
Ryan Fleury 1621dc0637 correct nil rdi top-level-info 2024-05-23 07:54:28 -07:00
Ryan Fleury 21fcfd28a4 appease clang 2024-05-23 07:38:30 -07:00
Ryan Fleury 4a3d439c44 adjust symbol lister to apply to all loaded debug infos, rather than just the selected thread's debug info 2024-05-23 07:34:24 -07:00
Ryan Fleury 30f8e1675e new multi-dbgi-capable fuzzy search layer first pass 2024-05-23 07:01:34 -07:00
Ryan Fleury c17072053b adjust d3d11 resize path 2024-05-22 15:27:39 -07:00
Ryan Fleury a5e2235fc6 fix deadlocks on di_close contending with passive scoped dbgi access 2024-05-22 11:54:27 -07:00
Ryan Fleury 0160d05e8a further tweaks to mule_peb_trample 2024-05-22 11:39:23 -07:00
Ryan Fleury 7a4e939886 fix incorrectly referring to root entity for debug info if missing; fix thread register cache issues; fix new dbgi layer issues 2024-05-22 11:13:08 -07:00
Ryan Fleury b33559b081 tweaks to mule_peb_trample 2024-05-21 12:40:21 -07:00
Ryan Fleury b74db17375 peb trampling mule 2024-05-21 11:29:19 -07:00
Ryan Fleury a019115b95 get ctrl and debug frontend layers onto new pdb-path-based debug info loader layer; sketch out standalone fuzzy search layer, to replace old dbgi searching functionality; shift all debug frontend code from referring to debug info via 'binaries' to referring to debug info via 'dbgis', just file entities at the location of o.g. debug info 2024-05-21 10:08:28 -07:00
Ryan Fleury b9ac104276 begin stitching new dbgi layer usage code into ctrl layer; keep track of per-module preferred pdb paths via event-synchronized ctrl entity tree; still need conversion 2024-05-20 17:15:11 -07:00
Ryan Fleury 6e41bdf11b first pass at loader portion of new dbgi layer replacement; set up ctrl entity for per-module debug info selection path info 2024-05-20 16:28:52 -07:00
Ryan Fleury 49eb834e2b eliminate old unwind code 2024-05-20 12:58:02 -07:00
Ryan Fleury fd6befecc3 get tls address calculation off of binary parsing path; do based on in-process memory 2024-05-20 12:55:20 -07:00
Ryan Fleury 5342fab86b bugfix in new unwinder; applying stack ptr read & unwind when doing epilog unwinds 2024-05-20 11:12:29 -07:00
Ryan Fleury 9919ac59bb move module image info parse / cache management to ctrl thread, directly tie to module lifetime as ctrl thread sees it; reduce load from each unwind 2024-05-20 10:58:45 -07:00
Ryan Fleury 2d1fcd7475 fix some unwanted frontend unwind cache behavior; fix staleness calculation in ctrl process memory cache 2024-05-20 08:23:41 -07:00
Ryan Fleury 393fb9e5f2 eliminate old unwinder usage code; more regression fixing 2024-05-17 15:07:21 -07:00
Ryan Fleury 301cf6b7ac regression fixes, better integration, and tightening up the new unwinder 2024-05-17 14:15:11 -07:00
Ryan Fleury 578a56d231 further progress on new unwinder 2024-05-16 17:12:37 -07:00
Ryan Fleury 33ab26dfb3 begin porting unwinder to ctrl layer, just built purely on in-process memory, and getting completely off of parsed binary image artifacts 2024-05-16 15:39:57 -07:00
Ryan Fleury 8901dd30ec eliminate old pending entity code; do not build missing entity interface if data is actually present (but frontend cache still suggests missing) 2024-05-16 10:35:56 -07:00
Ryan Fleury e1a5d131c8 fix clang... sigh 2024-05-15 15:41:03 -07:00
Ryan Fleury 55c1674ec6 notes 2024-05-15 13:38:38 -07:00
Ryan Fleury 364a2160af correctly register jit debugger exe; collect jit_debug_info into dmn win32; notes 2024-05-15 13:25:20 -07:00
Ryan Fleury 56afe8ca60 watch window reordering 2024-05-15 11:57:46 -07:00
Ryan Fleury 6e039430a5 mouse controls for new watch window editing mechanism 2024-05-15 11:22:05 -07:00
Ryan Fleury f1af166fd4 expand ui events to contain semantic 'controls' info, to eliminate most hardcoded escs/returns/f2s/etc; formalize these things as proper commands; keyboard-driven expansions; other various fixes 2024-05-15 10:53:26 -07:00
Ryan Fleury 03844d81d2 further progress on watch window pass; multi-cursor, multi-selection, autocomplete lister, etc 2024-05-15 09:26:16 -07:00
Ryan Fleury aa73e62240 fix clang 2024-05-14 16:31:34 -07:00
Ryan Fleury 16de33245c first half of first pass at multi-cursor watch window 2024-05-14 16:25:24 -07:00
Ryan Fleury f8b688096a fix crash on tpi-less pdbs 2024-05-14 11:39:18 -07:00
Ryan Fleury 4dd1f6f579 eval watch -> watch; prep for more organized event-driven editing path for watch windows, beginning of multi-selection support 2024-05-14 10:33:03 -07:00
Ryan Fleury 58b8ed8974 floating line-nums/margins in source & disasm views, when horizontally scrolled 2024-05-14 09:07:44 -07:00
Ryan Fleury ac9a908464 automatically support insert-based copy/paste shortcuts 2024-05-14 08:27:59 -07:00
Ryan Fleury 5d459d9b7a skip/chop whitespace on launch parameters 2024-05-14 08:23:28 -07:00
Ryan Fleury 3085482e34 expand base layer logging mechanism with bucketing info; make one bucket for passive log collection, another for user-facing errors; always consume user errors at the top-level and display; use user-error mechanism to communicate bad 32-bit app launches from demon 2024-05-14 08:10:02 -07:00
Ryan Fleury 6c200a59cd bugfixes for new autocompletion system 2024-05-14 07:50:13 -07:00
Ryan Fleury 362bcbcda5 fix clang 2024-05-13 16:28:13 -07:00
Ryan Fleury 897949d33a notes 2024-05-13 16:27:15 -07:00
Ryan Fleury 70479e0399 fix autocompletion query word calculation 2024-05-13 16:26:54 -07:00
Ryan Fleury 90fc289ef0 extend autocompletion lister parameter detection, based on cursor position; feed through view rule parameters; correctly support cursor position with multi-arguments, regardless of which argument the cursor is on 2024-05-13 16:19:32 -07:00
Ryan Fleury 7c0f92ab3d sketch out view rule schemas; use them to determine autocompletion lister flags via partial parse of view rule input & matching to cursor; expand autocompletion lister to support lists of various things used in view rule arguments 2024-05-13 15:45:35 -07:00
Ryan Fleury 036d94fff0 autocompletion lister improvements - completions now can be used for sub-expression parts 2024-05-13 14:24:28 -07:00
Ryan Fleury 37dd5cea2d oops - this was not dead code! 2024-05-13 13:11:34 -07:00
Ryan Fleury 05f2cde2ee fix clang 2024-05-13 13:10:49 -07:00
Ryan Fleury e59d71893b bugfix copying & other accidental event consumption issues with new ui events 2024-05-13 12:57:45 -07:00
Ryan Fleury e41eb9430f finish pass to convert everything over to ui events, eliminate nav actions; intermix os events & ui event production with commands 2024-05-13 11:48:42 -07:00
Ryan Fleury 58192b8356 move all ui/df codepaths onto new ui event consumption, rather than os/nav events in parallel 2024-05-13 10:33:30 -07:00
Ryan Fleury 38e38eaf3b sketch out ui event type, to unify type & stream for text ops, nav actions, and all other user inputs 2024-05-13 07:48:48 -07:00
Ryan Fleury 9f89735b01 preserve jeff notes from emails - put into todo list 2024-05-12 14:11:08 -07:00
Ryan Fleury 4cb0073909 stop non-x64 builds with less cryptic errors 2024-05-10 16:32:01 -07:00
Ryan Fleury 6fb8db4d3d getting started view improvements 2024-05-10 10:15:10 -07:00
Ryan Fleury 123276a1c6 choose compact layout by default with smaller monitor size 2024-05-10 09:59:23 -07:00
Ryan Fleury 6e8753f1e1 formalize more compact panel layout 2024-05-10 09:56:06 -07:00
Ryan Fleury dda0e012bf support getting started view in default panel layout 2024-05-10 09:35:03 -07:00
Ryan Fleury 6660446bdd auto-close panels if final tabs are closed; simplify empty panel view, move 'helper' stuff to dedicated 'getting started' tab 2024-05-10 08:48:42 -07:00
Nikita SmithandRyan Fleury ef175baae4 fix chained unwind info count 2024-05-10 08:47:25 -07:00
Ryan Fleury f45ea18f24 full line bounds check in intermixed dasm 2024-05-01 05:13:17 -07:00
Ryan Fleury 4aeb6d7d03 notes 2024-04-30 11:38:02 -07:00
Ryan Fleury ed0ec4b34d last fixes, improvements, & split operation coverage for new tab drag/drop system 2024-04-30 11:14:24 -07:00
Ryan Fleury 2e971f9e39 do not force contain tooltip if it is above some threshold - otherwise it can occlude important ui 2024-04-30 10:02:50 -07:00
Ryan Fleury d65c263266 new/fixed panel animation 2024-04-30 09:41:57 -07:00
Ryan Fleury cd9437534c remove old animation method for panel pcts; since panels are often rearranged in a hierarchy, having pcts being based on parent rectangle (as opposed to the root rectangle) is unstable and often looks bad 2024-04-30 09:17:00 -07:00
Ryan Fleury 3b2656675e root-level non-split-axis splits; less noisy tab drag/drop ui 2024-04-30 05:39:34 -07:00
Ryan Fleury b4dab84235 always resolve to address mode evaluation when doing a member access 2024-04-29 18:13:50 -07:00
Ryan Fleury 2fc34ffb3d further coverage of split-drop drag/drop sites, for splitting options at non-leaf-panels 2024-04-29 12:17:03 -07:00
Ryan Fleury d419c6e15c formal drop-hot mechanism in ui core; further cleanup/fixes in drop-split combined operation ui 2024-04-29 11:06:18 -07:00
Ryan Fleury 15a2e708a0 hook up new combined move-tab-and-split ui with actual operation; auto-close panels which have their last tab dragged away; etc 2024-04-29 06:15:43 -07:00
Ryan Fleury 5a84fe4949 first half of pass to enable combined, standard split+movetab drag/drop fast-paths; just visualizations, next need the combo mutations 2024-04-28 18:51:57 -07:00
Ryan Fleury 9177299488 improve tab drag/drop 2024-04-28 17:29:41 -07:00
Ryan Fleury b6eb13761f fix breakpad_from_pdb build; robustify to typeless global vars 2024-04-25 11:53:23 -07:00
Ryan Fleury 67eede7513 hot-reloading for dasm_cache, in case of filesystem changes; file stream layer -> expose filesystem-wide generation number, for very coarse-grained generation number to gracefully depend on filesystem changes passively 2024-04-25 09:37:16 -07:00
Ryan Fleury f4ea9e66b0 bugfix on-demand process-dependent breakpoint resolution path & user breakpoint hit logic in stepping machine; more logging 2024-04-25 08:59:00 -07:00
Ryan Fleury 0dbde584bd jump destination symbol name visualization in disassembly 2024-04-23 19:12:58 -07:00
Ryan Fleury 579e3e9637 adjust source code intermixing symbol 2024-04-23 14:01:11 -07:00
Ryan Fleury 425626a275 first pass over mixed-mode disassembly 2024-04-23 13:52:44 -07:00
Ryan Fleury 5b87c2b64a bundle disassembly parameterizations into single dasm params type; extend with exe path & base address, to begin using debug info in the disassembly pass itself 2024-04-23 12:37:53 -07:00
Ryan Fleury 879e649d0e more frontend logging 2024-04-23 10:07:59 -07:00
Ryan Fleury 15e9dec60a fix incorrect entity destruction logging 2024-04-23 10:04:05 -07:00
Ryan Fleury ec13092a35 ui thread logging; more ctrl thread logging 2024-04-23 09:57:17 -07:00
Ryan Fleury 757cd9b9d2 correct createfile params for appending 2024-04-23 08:34:32 -07:00
Ryan Fleury 856c59a949 set up ctrl thread log scopes; ditch ctrl -> user log stuff, just make each log site in control of exporting to a separate file 2024-04-18 15:09:43 -07:00
Ryan Fleury 62d1c6b130 scoped log gathering; communicate ctrl logs -> user via events 2024-04-18 14:48:03 -07:00
Ryan Fleury b995909997 sketch out logging stub, to begin marking up debugger layers with logging - high level stuff still wip 2024-04-17 14:32:09 -07:00
Ryan Fleury a954317500 fix new issues with confirmation popup & top bar 2024-04-17 12:41:49 -07:00
Ryan Fleury b307d3bbed fix top bar issues 2024-04-17 11:50:38 -07:00
Ryan Fleury 8890284f97 zig lexing (syntax highlighting & hover-on-eval) 2024-04-17 11:36:01 -07:00
Ryan Fleury b41e762393 jai syntax highlighting & hover-eval support 2024-04-17 11:12:05 -07:00
Ryan Fleury 72e8ae6e30 actually do redraw on resize - need that win32 window class style.. 2024-04-17 09:58:03 -07:00
Ryan Fleury 9f4aade2e1 stepping fast-paths in top bar 2024-04-17 09:47:36 -07:00
Ryan Fleury 27fef06b6c remove unnecessary window class styles 2024-04-17 09:19:00 -07:00
Ryan Fleury 572fad1f03 first pass at custom window border 2024-04-17 08:46:21 -07:00
Ryan Fleury c31847f785 improve min sampling when applying transforms in ui 2024-04-13 12:18:01 -07:00
Ryan Fleury 9719688bb3 improve query visualization in tabs; don't collapse title before query string 2024-04-13 11:46:55 -07:00
Ryan Fleury a6bed27dff errr, reverse last change 2024-04-10 13:37:32 -07:00
Ryan Fleury b7a14aa41c explicitly show error if decoding line machine code or line info fails 2024-04-10 13:36:52 -07:00
Ryan Fleury 56bc399fd5 initial pass for compression in converter; decompression in debuggerdbgi layer 2024-04-10 09:33:55 -07:00
Ryan Fleury d560f8c734 fix backslash escaping rules in cfg serialization; fix small scrolling (e.g. from trackpad) often being truncated to having no effect; fixed hanging when set-thread-name specifies a non-readable address 2024-04-09 07:37:53 -07:00
Ryan Fleury 36b50981ff fix conditional breakpoints, post demon2/ctrl passes 2024-04-05 11:38:14 -07:00
Ryan Fleury 32114c3215 begin cleanup/naming pass over view rules 2024-04-05 10:17:38 -07:00
Ryan Fleury a8ece647c1 simplify and remove temporary polish from minified bitmap viewer 2024-04-02 15:31:02 -07:00
Ryan Fleury e0879ac569 stub out graph view rule 2024-04-02 15:18:16 -07:00
Ryan Fleury 0eb8216ea0 first pass at dedicated bitmap tab view, & all the machinery of going from watch window w/ view rule -> dedicated ui 2024-04-02 14:33:17 -07:00
Ryan Fleury cd1a0a4cb5 tab query serialization/deserialization; only enable for view rule defined view specs 2024-04-02 10:42:31 -07:00
Ryan Fleury 1b95eacd08 stub out visualizer tab view hooks for bitmap, geo, text, disasm viewers; pass down cfg node trees for open-tab command; visualize query string in tab titles 2024-04-02 10:35:19 -07:00
Ryan Fleury 546c544ae0 eliminate eval-viewer view - instead we can have the gfx view rule spec table optionally define tab view specs itself, and those can be separately registered from the sort of 'base' tab views. then we can map from gfx-view-rule -> dedicated-tab-view-spec 2024-04-02 10:16:53 -07:00
Ryan Fleury 3ea67dd7cf eliminate old disasm layer initialization 2024-04-01 15:09:41 -07:00
Ryan Fleury 52295e5e06 first pass at view rule lookup cache... this might not be the right thing here 2024-04-01 14:48:48 -07:00
Ryan Fleury 63123d69d1 set up auto view rule entities, serialization, & editor ui, for automatically mapping specific types to specific view rules 2024-04-01 14:30:48 -07:00
Ryan Fleury 835eae208a extend eval viz pipeline with split between edit/display expression strings per-block and per-row. this allows reconstruction of the string that would lead to the same eval as a row (even if it is auto-generated by e.g. expanding a root-level row; also allow -- to extend eval expressions with passthrough text, used for view rules 2024-04-01 13:56:07 -07:00
Ryan Fleury cfb34ec560 C++ namespace examples 2024-04-01 11:11:27 -07:00
Ryan Fleury c45b12cfac only export executable name, not full cmdline specified path in converter 2024-04-01 10:25:27 -07:00
Ryan Fleury 7c0ce2ab54 fix incorrect skip-to-end in new pdb -> raddbgi converter member parsing, in some cases (particularly noticeable in C++ structs with vtable members) 2024-03-30 19:44:20 -07:00
Ryan Fleury 693d20ec1a fix incorrect generation of modifier flags, container types, and out-of-order pointer/modifier types in new pdb -> raddbgi converter. fixes many 'nil type' issues, missing this ptr, etc. 2024-03-30 19:29:16 -07:00
Ryan Fleury a6db711f2d quick fix to not omit opl line records in breakpad_from_pdb 2024-03-29 15:53:18 -07:00
523 changed files with 323077 additions and 164663 deletions
+8 -6
View File
@@ -21,10 +21,12 @@ jobs:
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 raddbg msvc debug || exit /b 1
call build raddbgi_from_pdb msvc debug || exit /b 1 call build rdi_from_pdb msvc debug || exit /b 1
call build raddbgi_from_dwarf msvc debug || exit /b 1 call build rdi_from_dwarf msvc debug || exit /b 1
call build raddbgi_dump msvc debug || exit /b 1 call build rdi_dump msvc debug || exit /b 1
call build raddbg clang debug || exit /b 1 call build raddbg clang debug || exit /b 1
call build raddbgi_from_pdb clang debug || exit /b 1 call build rdi_from_pdb clang debug || exit /b 1
call build raddbgi_from_dwarf clang debug || exit /b 1 call build rdi_from_dwarf clang debug || exit /b 1
call build raddbgi_dump 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
+151 -107
View File
@@ -17,29 +17,23 @@ with any information you can gather, like dump files (along with the build you
used), instructions to reproduce, test executables, and so on. used), instructions to reproduce, test executables, and so on.
You can download pre-built binaries for the debugger You can download pre-built binaries for the debugger
[here](https://github.com/EpicGames/raddebugger/releases). [here](https://github.com/EpicGamesExt/raddebugger/releases).
The RAD Debugger project aims to simplify the debugger by simplifying and The RAD Debugger project aims to simplify the debugger by simplifying and
unifying the underlying debug info format. In that pursuit we've built unifying the underlying debug info format. In that pursuit we've built the RAD
the RADDBGI debug info format, which is what the debugger parses and uses. To Debug Info (RDI) format, which is what the debugger parses and uses. To work
work with existing toolchains, we convert PDB (and eventually PE/ELF files with existing toolchains, we convert PDB (and eventually PE/ELF files with
with embedded DWARF) into the RADDBGI format on-demand. This conversion process embedded DWARF) into the RDI format on-demand.
is currently an unoptimized reference version. Nevertheless it's still quite
fast for smaller PDB files (in many cases faster than many other programs
simply deserialize the PDBs). It is much slower for much larger projects at the
moment, but we expect this will vastly improve overtime.
The RADDBGI format is currently specified in code, in the files within the The RDI format is currently specified in code, in the files within the
`src/lib_raddbgi_format` folder. The other relevant folders for working with `src/lib_rdi_format` folder. The other relevant folders for working with the
the format are: format are:
- `lib_raddbgi_make`: The "RAD Debug Info Make" library, for making RADDBGI - `lib_rdi_make`: The "RAD Debug Info Make" library, for making RDI debug info.
debug info. - `rdi_from_pdb`: Our PDB-to-RDI converter. Can be used as a helper codebase
- `raddbgi_from_pdb`: Our PDB-to-RADDBGI converter. Can be used as a helper layer, or built as an executable with a command line interface frontend.
codebase layer, or built as an executable with a command line interface - `rdi_from_dwarf`: Our in-progress DWARF-to-RDI converter.
frontend. - `rdi_dump`: Our RDI textual dumping utility.
- `raddbgi_from_dwarf`: Our in-progress DWARF-to-RADDBGI converter.
- `raddbgi_dump`: Our RADDBGI textual dumping utility.
## Development Setup Instructions ## Development Setup Instructions
@@ -96,13 +90,12 @@ 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... 299 files found searching C:\devel\raddebugger/src... 309 files found
parsing metadesk... 12 metadesk files parsed parsing metadesk... 15 metadesk files parsed
gathering tables... 37 tables found gathering tables... 96 tables found
generating layer code... generating layer code...
raddbg.cpp 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
@@ -126,18 +119,6 @@ there are still cases where the debugger has not been tested, and so there are
still issues. So, we feel that the top priority is eliminating these issues, still issues. So, we feel that the top priority is eliminating these issues,
such that the debugging experience is rock solid. such that the debugging experience is rock solid.
Additionally, the debug info conversion process is not fast (nor wide) enough
to support extremely large projects. This is for two reasons: (a) the
PDB-to-RADDBGI converter is an unoptimized reference implementation, and (b)
the debugger learns of new modules (and thus which PDBs to load) in a
serially-dependent way (this is necessarily the case for correct debugging
results). We expect that the conversion process' performance can be massively
improved, and also that some heuristics can be used to begin converting PDBs
to RADDBGIs before the debugger knows those PDBs are needed, thus ensuring the
associated RADDBGI files are ready instantaneously when the associated modules
are finally loaded by the debugger. Improving this situation is a major part of
this phase, as it will make the debugger much more usable for large projects.
### Local x64 Linux Debugging Phase ### Local x64 Linux Debugging Phase
The next priority for the project is to take the rock solid x64 Windows The next priority for the project is to take the rock solid x64 Windows
@@ -152,11 +133,10 @@ The major parts of this phase are:
- Porting the `src/demon` layer to implement the Demon local process control - Porting the `src/demon` layer to implement the Demon local process control
abstraction API. abstraction API.
- Porting the `src/unwind` layer to support x64 ELF unwinding (currently, there - Implementing an x64 ELF Linux unwinder in the `src/ctrl` layer.
is only an x64 PE unwinding implementation). - Creating a DWARF-to-RDI converter (in the same way that we've built a
- Creating a DWARF-to-RADDBGI converter (in the same way that we've built a PDB-to-RDI converter). A partial implementation of this is in
PDB-to-RADDBGI converter). A partial implementation of this is in `src/rdi_from_dwarf`.
`src/raddbgi_from_dwarf`.
- Porting the `src/render` layer to implement all of the rendering features the - Porting the `src/render` layer to implement all of the rendering features the
frontend needs on a Linux-compatible API (the backend used on Windows is D3D11). frontend needs on a Linux-compatible API (the backend used on Windows is D3D11).
- Porting the `src/font_provider` layer to a Linux-compatible font - Porting the `src/font_provider` layer to a Linux-compatible font
@@ -178,6 +158,45 @@ like remote debugging, porting to different architectures, further improving
the debugger's features (like improving the visualization engine), and so on. the debugger's features (like improving the visualization engine), and so on.
But for now, we're mostly focused on those first two phases. But for now, we're mostly focused on those first two phases.
---
# The RAD Linker
The RAD Linker is a new performance linker for generating x64 PE/COFF binaries. It is designed to be very fast when creating gigantic executables. It generates standard PDB files for debugging, but it can also optionally create RAD Debugger debug info too (useful for huge executables that otherwise create broken PDBs that overflow internal 32-bit tables).
The RAD Linker is primarily optimized to handle huge linking projects - in our test cases (where debug info is multiple gigabytes), we see 50% faster link times.
The command line syntax is fully compatible with MSVC and you can get a full list of implemented switches from `/help`.
Our current designed-for use case for the linker is to help with the compile-debug cycle of huge projects. We don't yet have support for dead-code-elimination or link-time-optimizations, but these features are on the road map.
By default, the RAD linker spawns as many threads as there are cores, so if you plan to run multiple linkers in parallel, you can limit the number of thread workers via `/rad_workers`.
We also have support for large memory pages, which, when enabled, reduce link time by
another 25%. To link with large pages, you need to explicitly request them via `/rad_large_pages`. Large pages are off by default, since Windows support for large pages is a bit buggy - we recommend they only be used in Docker or VM images where the environment is reset after each link. In a standard Windows environment, using large pages otherwise will fragment memory quickly forcing a reboot. We are working on a Linux port of the linker that will be able to build with large pages robustly.
## Short Term Roadmap
- Porting linker to Linux (for Windows executables, just running on Linux).
- Debug info features
- Get DWARF debug info converter up-and-running.
- Smooth out rough edges in RADDBGI builder.
- Improve build speed further (especially for tiny and mid sizes projects).
- Other features to come
- Dead-code-elimination via `/opt:ref`.
- Link Time Optimizations with the help of clang (we won't support LTCG from MSVC compiler since it is undocumented).
## To build the RAD Linker
- Setup development environment, [see](#Development-Setup-Instructions)
- Run `build radlink release` or if you have clang installed `build radlink release clang`. We favor latter option for better code generation.
If build was successful linker executable is placed in `build` folder under `radlink.exe`.
## Benchmarks
![AMD Ryzen Threadripper PRO 3995WX 64-Cores, 256 GiB RAM (Windows x64)](https://github.com/user-attachments/assets/39d95fdf-9f0b-45d3-9fb8-90d8ac624168)
---
## Top-Level Directory Descriptions ## Top-Level Directory Descriptions
- `data`: Small binary files which are used when building, either to embed - `data`: Small binary files which are used when building, either to embed
@@ -188,7 +207,8 @@ After setting up the codebase and building, the following directories will
also exist: also exist:
- `build`: All build artifacts. Not checked in to version control. - `build`: All build artifacts. Not checked in to version control.
- `local`: Local files, used for local build configuration input files. - `local`: Local files, used for local build configuration input files. Not
checked in to version control.
## Codebase Introduction ## Codebase Introduction
@@ -218,7 +238,7 @@ so in other words, layers are arranged into a directed acyclic graph.
A few layers are built to be used completely independently from the rest of the A few layers are built to be used completely independently from the rest of the
codebase, as libraries in other codebases and projects. As such, these layers do codebase, as libraries in other codebases and projects. As such, these layers do
not depend on any other layers in the codebase. The folders which contain these not depend on any other layers in the codebase. The folders which contain these
layers are prefixed with `lib_`, like `lib_raddbgi_format`. layers are prefixed with `lib_`, like `lib_rdi_format`.
A list of the layers in the codebase and their associated namespaces is below: A list of the layers in the codebase and their associated namespaces is below:
- `base` (no namespace): Universal, codebase-wide constructs. Strings, math, - `base` (no namespace): Universal, codebase-wide constructs. Strings, math,
@@ -232,55 +252,70 @@ A list of the layers in the codebase and their associated namespaces is below:
processes. Runs in lockstep with attached processes. When it runs, attached processes. Runs in lockstep with attached processes. When it runs, attached
processes are halted. When attached processes are running, it is halted. processes are halted. When attached processes are running, it is halted.
Driven by a debugger frontend on another thread. Driven by a debugger frontend on another thread.
- `dasm` (`DASM_`): An asynchronous disassembly decoder and cache. Users ask for - `dasm_cache` (`DASM_`): An asynchronous disassembly decoder and cache. Users
disassembly for a particular virtual address range in a process, and threads ask for disassembly for some data, with a particular architecture, and other
implemented in this layer decode and cache the disassembly for that range. various parameters, and threads implemented in this layer decode and cache the
- `dbgi` (`DBGI_`): An asynchronous debug info loader and cache. Loads debug disassembly for that data with those parameters.
info stored in the RADDBGI format. Users ask for debug info for a particular - `dbgi` (`DI_`): An asynchronous debug info loader and cache. Loads debug info
executable, and on separate threads, this layer loads the associated debug stored in the RDI format. Users ask for debug info for a particular path, and
info file. If necessary, it will launch a separate conversion process to on separate threads, this layer loads the associated debug info file. If
convert original debug info into the RADDBGI format. necessary, it will launch a separate conversion process to convert original
- `demon` (`DEMON_`): An abstraction layer for local-machine, low-level process debug info into the RDI format.
- `dbg_engine` (`D_`): Implements the core debugger system, without any
graphical components. This contains top-level logic for things like stepping,
launching, freezing threads, mid-run breakpoint addition, some caching layers,
and so on.
- `demon` (`DMN_`): An abstraction layer for local-machine, low-level process
control. The abstraction is used to provide a common interface for process control. The abstraction is used to provide a common interface for process
control on target platforms. Used to implement part of `ctrl`. control on target platforms. Used to implement part of `ctrl`.
- `df/core` (`DF_`): The debugger's non-graphical frontend. Implements a - `draw` (`DR_`): Implements a high-level graphics drawing API for the
debugger "entity cache" (where "entities" include processes, threads, modules, debugger's purposes, using the underlying `render` abstraction layer. Provides
breakpoints, source files, targets, and so on). Implements a command loop high-level APIs for various draw commands, but takes care of batching them,
for driving process control, which is used to implement stepping commands and and so on.
user breakpoints. Implements extractors and caches for various entity-related - `eval` (`E_`): Implements a compiler for an expression language built for
data, like full thread unwinds and local variable maps. Also implements core evaluation of variables, registers, types, and more, from debugger-attached
building blocks for evaluation and evaluation visualization. processes, debug info, debugger state, and files. Broken into several phases
- `df/gfx` (`DF_`): The debugger's graphical frontend. Builds on top of mostly corresponding to traditional compiler phases - lexer, parser,
`df/core` to provide all graphical features, including windows, panels, all type-checker, IR generation, and IR evaluation.
of the various debugger interfaces, and evaluation visualization. - `eval_visualization` (`EV_`): Implements the core non-graphical evaluation
- `draw` (`D_`): Implements a high-level graphics drawing API for the debugger's visualization engine, which can be used to visualize evaluations (provided by
purposes, using the underlying `render` abstraction layer. Provides high-level the `eval` layer) in a number of ways. Implements core data structures and
APIs for various draw commands, but takes care of batching them, and so on. transforms for the `Watch` view.
- `eval` (`EVAL_`): Implements a compiler for an expression language built for - `file_stream` (`FS_`): Provides asynchronous file loading, storing the
evaluation of variables, registers, and so on from debugger-attached processes artifacts inside of the cache implemented by the `hash_store` layer, and
and/or debug info. Broken into several phases mostly corresponding to hot-reloading the contents of files when they change. Allows callers to map
traditional compiler phases - lexer, parser, type-checker, IR generation, and file paths to data hashes, which can then be used to obtain the file's data.
IR evaluation. - `font_cache` (`FNT_`): Implements a cache of rasterized font data, both in
- `font_cache` (`F_`): Implements a cache of rasterized font data, both in CPU- CPU-side data for text shaping, and in GPU texture atlases for rasterized
side data for text shaping, and in GPU texture atlases for rasterized glyphs. glyphs. All cache information is sourced from the `font_provider` abstraction
All cache information is sourced from the `font_provider` abstraction layer. layer.
- `font_provider` (`FP_`): An abstraction layer for various font file decoding - `font_provider` (`FP_`): An abstraction layer for various font file decoding
and font rasterization backends. and font rasterization backends.
- `fuzzy_search` (`FZY_`): Provides a fuzzy searching engine for doing
large, asynchronous fuzzy searches. Used by the debugger for implementing
things like the symbol lister or the `Procedures` view, which search across
all loaded debug info records, using fuzzy matching rules.
- `geo_cache` (`GEO_`): Implements an asynchronously-filled cache for GPU - `geo_cache` (`GEO_`): Implements an asynchronously-filled cache for GPU
geometry data, filled by data sourced in the `hash_store` layer's cache. Used geometry data, filled by data sourced in the `hash_store` layer's cache. Used
for asynchronously preparing data for memory visualization in the debugger. for asynchronously preparing data for visualization.
- `hash_store` (`HS_`): Implements a cache for general data blobs, keyed by a - `hash_store` (`HS_`): Implements a cache for general data blobs, keyed by a
128-bit hash of the data. Used as a general data store by other layers. 128-bit hash of the data. Also implements a 128-bit key cache on top, where
the keys refer to a unique identity, associated with a 128-bit hash, where the
hash may change across time. Used as a general data store by other layers.
- `lib_raddbg_markup` (`RADDBG_`): Standalone library for marking up user - `lib_raddbg_markup` (`RADDBG_`): Standalone library for marking up user
programs to work with various features in the `raddbg` debugger. Does not programs to work with various features in the debugger. Does not depend on
depend on `base`, and can be independently relocated to other codebases. `base`, and can be independently relocated to other codebases.
- `lib_raddbgi_make` (`RDIM_`): Standalone library for constructing RADDBGI - `lib_rdi_format` (`RDI_`): Standalone library which defines the core RDI types
debug info data. Does not depend on `base`, and can be independently relocated and helper functions for reading and writing the RDI debug info file format.
Does not depend on `base`, and can be independently relocated to other
codebases.
- `lib_rdi_make` (`RDIM_`): Standalone library for constructing RDI debug info
data. Does not depend on `base`, and can be independently relocated
to other codebases. to other codebases.
- `lib_raddbgi_format` (`RDI_`): Standalone library which defines the core - `mdesk` (`MD_`): Code for parsing Metadesk files (stored as `.mdesk`), which
RADDBGI types and helper functions for reading and writing the RADDBGI debug is the JSON-like (technically a JSON superset) text format used for the
info file format. Does not depend on `base`, and can be independently debugger's user and project configuration files, view rules, and metacode,
relocated to other codebases. which is parsed and used to generate code with the `metagen` layer.
- `metagen` (`MG_`): A metaprogram which is used to generate primarily code and - `metagen` (`MG_`): A metaprogram which is used to generate primarily code and
data tables. Consumes Metadesk files, stored with the extension `.mdesk`, and data tables. Consumes Metadesk files, stored with the extension `.mdesk`, and
generates C code which is then included by hand-written C code. Currently, it generates C code which is then included by hand-written C code. Currently, it
@@ -298,6 +333,9 @@ A list of the layers in the codebase and their associated namespaces is below:
- `msf` (`MSF_`): Code for parsing and/or writing the MSF file format. - `msf` (`MSF_`): Code for parsing and/or writing the MSF file format.
- `mule` (no namespace): Test executables for battle testing debugger - `mule` (no namespace): Test executables for battle testing debugger
functionality. functionality.
- `mutable_text` (`MTX_`): Implements an asynchronously-filled-and-mutated
cache for text buffers which are mutated across time. In the debugger, this is
used to implement the `Output` view.
- `natvis` (no namespace): NatVis files for type visualization of the codebase's - `natvis` (no namespace): NatVis files for type visualization of the codebase's
types in other debuggers. types in other debuggers.
- `os/core` (`OS_`): An abstraction layer providing core, non-graphical - `os/core` (`OS_`): An abstraction layer providing core, non-graphical
@@ -306,20 +344,28 @@ A list of the layers in the codebase and their associated namespaces is below:
- `os/gfx` (`OS_`): An abstraction layer, building on `os/core`, providing - `os/gfx` (`OS_`): An abstraction layer, building on `os/core`, providing
graphical operating system features under an abstract API, which is graphical operating system features under an abstract API, which is
implemented per-target-operating-system. implemented per-target-operating-system.
- `os/socket` (`OS_`): An abstraction layer, building on `os/core`, providing - `path` (`PATH_`): Small helpers for manipulating file path strings.
networking operating system features under an abstract API, which is
implemented per-target-operating-system.
- `pdb` (`PDB_`): Code for parsing and/or writing the PDB file format. - `pdb` (`PDB_`): Code for parsing and/or writing the PDB file format.
- `pe` (`PE_`): Code for parsing and/or writing the PE (Portable Executable) - `pe` (`PE_`): Code for parsing and/or writing the PE (Portable Executable)
file format. file format.
- `raddbg` (no namespace): The layer which ties everything together for the main - `raddbg` (`RD_`): The layer which ties everything together for the main
graphical debugger. Not much "meat", just drives `df`, implements command line graphical debugger. Implements the debugger's graphical frontend, all of the
options, and so on. debugger-specific UI, the debugger executable's command line interface, and
- `raddbgi_from_pdb` (`P2R_`): Our implementation of PDB-to-RADDBGI conversion. all of the built-in visualizers.
- `raddbgi_from_dwarf` (`D2R_`): Our in-progress implementation of - `rdi_breakpad_from_pdb` (`P2B_`): Our implementation, using the codebase's RDI
DWARF-to-RADDBGI conversion. technology, for extracting information from PDBs and generating Breakpad text
- `raddbgi_dump` (`RADDBGIDUMP_`): A dumper utility program for dumping dumps.
textualizations of RADDBGI debug info files. - `rdi_dump` (no namespace): A dumper utility program for dumping
textualizations of RDI debug info files.
- `rdi_format` (no namespace): A layer which includes the `lib_rdi_format` layer
and bundles it with codebase-specific helpers, to easily include the library
in codebase programs, and have it be integrated with codebase constructs.
- `rdi_from_dwarf` (`D2R_`): Our in-progress implementation of DWARF-to-RDI
conversion.
- `rdi_from_pdb` (`P2R_`): Our implementation of PDB-to-RDI conversion.
- `rdi_make` (no namespace): A layer which includes the `lib_rdi_make` layer and
bundles it with codebase-specific helpers, to easily include the library in
codebase programs, and have it be integrated with codebase constructs.
- `regs` (`REGS_`): Types, helper functions, and metadata for registers on - `regs` (`REGS_`): Types, helper functions, and metadata for registers on
supported architectures. Used in reading/writing registers in `demon`, or in supported architectures. Used in reading/writing registers in `demon`, or in
looking up register metadata. looking up register metadata.
@@ -328,21 +374,19 @@ A list of the layers in the codebase and their associated namespaces is below:
level drawing API - this layer is strictly for minimally abstracting on an level drawing API - this layer is strictly for minimally abstracting on an
as-needed basis. Higher level drawing features are implemented in the `draw` as-needed basis. Higher level drawing features are implemented in the `draw`
layer. layer.
- `scratch` (no namespace): Scratch space for small and transient test or sample - `scratch` (no namespace): Scratch space for small and transient test programs.
programs. - `task_system` (`TS_`): Implements a system for kicking off asynchronous tasks
and obtaining artifacts from those tasks once they've completed.
- `texture_cache` (`TEX_`): Implements an asynchronously-filled cache for GPU - `texture_cache` (`TEX_`): Implements an asynchronously-filled cache for GPU
texture data, filled by data sourced in the `hash_store` layer's cache. Used texture data, filled by data sourced in the `hash_store` layer's cache. Used
for asynchronously preparing data for memory visualization in the debugger. for asynchronously preparing data for visualization.
- `txti` (`TXTI_`): Machinery for asynchronously-loaded, asynchronously hot- - `text_cache` (`TXT_`): Implements an asynchronously-filled cache for textual
reloaded, asynchronously parsed, and asynchronously mutated source code files. analysis data (tokens, line ranges, and so on), filled by data sourced in the
Used by the debugger to visualize source code files. Users ask for text lines, `hash_store` layer's cache. Used for asynchronously preparing data for
tokens, and metadata, and it is prepared on background threads. visualization (like for the source code viewer).
- `type_graph` (`TG_`): Code for analyzing and navigating type structures from - `third_party` (no namespace): External code from other projects, which some
RADDBGI debug info files, with the additional capability of constructing layers in the codebase depend on. All external code is included and built
synthetic types *not* found in debug info. Used in `eval` and for various directly within the codebase.
visualization features.
- `ui` (`UI_`): Machinery for building graphical user interfaces. Provides a - `ui` (`UI_`): Machinery for building graphical user interfaces. Provides a
core immediate mode hierarchical user interface data structure building core immediate mode hierarchical user interface data structure building
API, and has helper layers for building some higher-level widgets. API, and has helper layers for building some higher-level widgets.
- `unwind` (`UNW_`): Code for generating unwind information from threads, for
supported operating systems and architectures.
+43 -23
View File
@@ -4,18 +4,18 @@ cd /D "%~dp0"
:: --- Usage Notes (2024/1/10) ------------------------------------------------ :: --- Usage Notes (2024/1/10) ------------------------------------------------
:: ::
:: This is a central build script for the RAD Debugger project. It takes a list :: This is a central build script for the RAD Debugger project, for use in
:: of simple alphanumeric-only arguments which control (a) what is built, (b) :: Windows development environments. It takes a list of simple alphanumeric-
:: which compiler & linker are used, and (c) extra high-level build options. By :: only arguments which control (a) what is built, (b) which compiler & linker
:: default, if no options are passed, then the main "raddbg" graphical debugger :: are used, and (c) extra high-level build options. By default, if no options
:: is built. :: are passed, then the main "raddbg" graphical debugger is built.
:: ::
:: Below is a non-exhaustive list of possible ways to use the script: :: Below is a non-exhaustive list of possible ways to use the script:
:: `build raddbg` :: `build raddbg`
:: `build raddbg clang` :: `build raddbg clang`
:: `build raddbg release` :: `build raddbg release`
:: `build raddbg asan telemetry` :: `build raddbg asan telemetry`
:: `build raddbgi_from_pdb` :: `build rdi_from_pdb`
:: ::
:: For a full list of possible build targets and their build command lines, :: For a full list of possible build targets and their build command lines,
:: search for @build_targets in this file. :: search for @build_targets in this file.
@@ -34,6 +34,7 @@ if "%release%"=="1" set debug=0 && echo [release mode]
if "%msvc%"=="1" set clang=0 && echo [msvc compile] if "%msvc%"=="1" set clang=0 && echo [msvc compile]
if "%clang%"=="1" set msvc=0 && echo [clang compile] if "%clang%"=="1" set msvc=0 && echo [clang compile]
if "%~1"=="" echo [default mode, assuming `raddbg` build] && set raddbg=1 if "%~1"=="" echo [default mode, assuming `raddbg` build] && set raddbg=1
if "%~1"=="release" if "%~2"=="" echo [default mode, assuming `raddbg` build] && set raddbg=1
:: --- Unpack Command Line Build Arguments ------------------------------------ :: --- Unpack Command Line Build Arguments ------------------------------------
set auto_compile_flags= set auto_compile_flags=
@@ -42,24 +43,27 @@ if "%asan%"=="1" set auto_compile_flags=%auto_compile_flags% -fsanitize=add
:: --- 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
set clang_common= -I..\src\ -I..\local\ -gcodeview -fdiagnostics-absolute-paths -Wall -Wno-unknown-warning-option -Wno-missing-braces -Wno-unused-function -Wno-writable-strings -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-register -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion -Xclang -flto-visibility-public-std -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf set clang_common= -I..\src\ -I..\local\ -gcodeview -fdiagnostics-absolute-paths -Wall -Wno-unknown-warning-option -Wno-missing-braces -Wno-unused-function -Wno-writable-strings -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-register -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion -Wno-compare-distinct-pointer-types -Wno-initializer-overrides -Wno-incompatible-pointer-types-discards-qualifiers -Xclang -flto-visibility-public-std -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf -ferror-limit=10000
set cl_debug= call cl /Od /DBUILD_DEBUG=1 %cl_common% %auto_compile_flags% set cl_debug= call cl /Od /Ob1 /DBUILD_DEBUG=1 %cl_common% %auto_compile_flags%
set cl_release= call cl /O2 /DBUILD_DEBUG=0 %cl_common% %auto_compile_flags% set cl_release= call cl /O2 /DBUILD_DEBUG=0 %cl_common% %auto_compile_flags%
set clang_debug= call clang -g -O0 -DBUILD_DEBUG=1 %clang_common% %auto_compile_flags% set clang_debug= call clang -g -O0 -DBUILD_DEBUG=1 %clang_common% %auto_compile_flags%
set clang_release= call clang -g -O2 -DBUILD_DEBUG=0 %clang_common% %auto_compile_flags% set clang_release= call clang -g -O2 -DBUILD_DEBUG=0 %clang_common% %auto_compile_flags%
set cl_link= /link /MANIFEST:EMBED /INCREMENTAL:NO /natvis:"%~dp0\src\natvis\base.natvis" logo.res set cl_link= /link /MANIFEST:EMBED /INCREMENTAL:NO /natvis:"%~dp0\src\natvis\base.natvis" /pdbaltpath:%%%%_PDB%%%%
set clang_link= -fuse-ld=lld -Xlinker /MANIFEST:EMBED -Xlinker /natvis:"%~dp0\src\natvis\base.natvis" logo.res set clang_link= -fuse-ld=lld -Xlinker /MANIFEST:EMBED -Xlinker /natvis:"%~dp0\src\natvis\base.natvis" -Xlinker /pdbaltpath:%%%%_PDB%%%%
set cl_out= /out: set cl_out= /out:
set clang_out= -o set clang_out= -o
:: --- Per-Build Settings ----------------------------------------------------- :: --- Per-Build Settings -----------------------------------------------------
set link_dll=-DLL set link_dll=-DLL
set link_icon=logo.res
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
if "%clang%"=="1" set EHsc= if "%clang%"=="1" set EHsc=
if "%msvc%"=="1" set rc=rc.exe if "%msvc%"=="1" set no_aslr=/DYNAMICBASE:NO
if "%clang%"=="1" set rc=llvm-rc.exe if "%clang%"=="1" set no_aslr=-Wl,/DYNAMICBASE:NO
if "%msvc%"=="1" set rc=call rc
if "%clang%"=="1" set rc=call llvm-rc
:: --- Choose Compile/Link Lines ---------------------------------------------- :: --- Choose Compile/Link Lines ----------------------------------------------
if "%msvc%"=="1" set compile_debug=%cl_debug% if "%msvc%"=="1" set compile_debug=%cl_debug%
@@ -96,17 +100,26 @@ if not "%no_meta%"=="1" (
:: --- Build Everything (@build_targets) -------------------------------------- :: --- Build Everything (@build_targets) --------------------------------------
pushd build pushd build
if "%raddbg%"=="1" %compile% %gfx% ..\src\raddbg\raddbg_main.cpp %compile_link% %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 "%raddbgi_from_pdb%"=="1" %compile% ..\src\raddbgi_from_pdb\raddbgi_from_pdb_main.c %compile_link% %out%raddbgi_from_pdb.exe || exit /b 1 if "%radlink%"=="1" set didbuild=1 && %compile% ..\src\linker\lnk.c %compile_link% %out%radlink.exe || exit /b 1
if "%raddbgi_from_dwarf%"=="1" %compile% ..\src\raddbgi_from_dwarf\raddbgi_from_dwarf.c %compile_link% %out%raddbgi_from_dwarf.exe || exit /b 1 if "%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 "%raddbgi_dump%"=="1" %compile% ..\src\raddbgi_dump\raddbgi_dump_main.c %compile_link% %out%raddbgi_dump.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 "%raddbgi_breakpad_from_pdb%"=="1" %compile% ..\src\raddbgi_breakpad_from_pdb\raddbgi_breakpad_from_pdb_main.c %compile_link% %out%raddbgi_breakpad_from_pdb.exe || exit /b 1 if "%rdi_dump%"=="1" set didbuild=1 && %compile% ..\src\rdi_dump\rdi_dump_main.c %compile_link% %out%rdi_dump.exe || exit /b 1
if "%ryan_scratch%"=="1" %compile% ..\src\scratch\ryan_scratch.c %compile_link% %out%ryan_scratch.exe || exit /b 1 if "%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 "%cpp_tests%"=="1" %compile% ..\src\scratch\i_hate_c_plus_plus.cpp %compile_link% %out%cpp_tests.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 "%look_at_raddbg%"=="1" %compile% ..\src\scratch\look_at_raddbg.c %compile_link% %out%look_at_raddbg.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 "%mule_main%"=="1" del vc*.pdb mule*.pdb && %compile_release% %only_compile% ..\src\mule\mule_inline.cpp && %compile_release% %only_compile% ..\src\mule\mule_o2.cpp && %compile_debug% %EHsc% ..\src\mule\mule_main.cpp ..\src\mule\mule_c.c mule_inline.obj mule_o2.obj %compile_link% %out%mule_main.exe || exit /b 1 if "%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 "%mule_module%"=="1" %compile% ..\src\mule\mule_module.cpp %compile_link% %link_dll% %out%mule_module.dll || 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_hotload%"=="1" %compile% ..\src\mule\mule_hotload_main.c %compile_link% %out%mule_hotload.exe & %compile% ..\src\mule\mule_hotload_module_main.c %compile_link% %link_dll% %out%mule_hotload_module.dll || exit /b 1 if "%mule_module%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_module.cpp %compile_link% %link_dll% %out%mule_module.dll || exit /b 1
if "%mule_hotload%"=="1" set didbuild=1 && %compile% ..\src\mule\mule_hotload_main.c %compile_link% %out%mule_hotload.exe & %compile% ..\src\mule\mule_hotload_module_main.c %compile_link% %link_dll% %out%mule_hotload_module.dll || exit /b 1
if "%mule_peb_trample%"=="1" (
set didbuild=1
if exist mule_peb_trample.exe move mule_peb_trample.exe mule_peb_trample_old_%random%.exe
if exist mule_peb_trample_new.pdb move mule_peb_trample_new.pdb mule_peb_trample_old_%random%.pdb
if exist mule_peb_trample_new.rdi move mule_peb_trample_new.rdi mule_peb_trample_old_%random%.rdi
%compile% ..\src\mule\mule_peb_trample.c %compile_link% %out%mule_peb_trample_new.exe || exit /b 1
move mule_peb_trample_new.exe mule_peb_trample.exe
)
popd popd
:: --- Unset ------------------------------------------------------------------ :: --- Unset ------------------------------------------------------------------
@@ -117,3 +130,10 @@ set compile_link=
set out= set out=
set msvc= set msvc=
set debug= set debug=
set release=
:: --- Warn On No Builds ------------------------------------------------------
if "%didbuild%"=="" (
echo [WARNING] no valid build target specified; must use build target names as arguments to this script, like `build raddbg` or `build rdi_from_pdb`.
exit /b 1
)
+74
View File
@@ -0,0 +1,74 @@
#!/bin/bash
set -eu
cd "$(dirname "$0")"
# --- Unpack Arguments --------------------------------------------------------
for arg in "$@"; do declare $arg='1'; done
if [ ! -v gcc ]; then clang=1; fi
if [ ! -v release ]; then debug=1; fi
if [ -v debug ]; then echo "[debug mode]"; fi
if [ -v release ]; then echo "[release mode]"; fi
if [ -v clang ]; then compiler="${CC:-clang}"; echo "[clang compile]"; fi
if [ -v gcc ]; then compiler="${CC:-gcc}"; echo "[gcc compile]"; fi
# --- Unpack Command Line Build Arguments -------------------------------------
auto_compile_flags=''
# --- Compile/Link Line Definitions -------------------------------------------
clang_common='-I../src/ -I../local/ -g -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_release="$compiler -g -O2 -DBUILD_DEBUG=0 ${clang_common} ${auto_compile_flags}"
clang_link="-lpthread -lm -lrt -ldl"
clang_out="-o"
gcc_common='-I../src/ -I../local/ -g -Wno-unknown-warning-option -Wall -Wno-missing-braces -Wno-unused-function -Wno-attributes -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-compare-distinct-pointer-types -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf'
gcc_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${gcc_common} ${auto_compile_flags}"
gcc_release="$compiler -g -O2 -DBUILD_DEBUG=0 ${gcc_common} ${auto_compile_flags}"
gcc_link="-lpthread -lm -lrt -ldl"
gcc_out="-o"
# --- Per-Build Settings ------------------------------------------------------
link_dll="-fPIC"
link_os_gfx="-lX11 -lXext"
# --- Choose Compile/Link Lines -----------------------------------------------
if [ -v gcc ]; then compile_debug="$gcc_debug"; fi
if [ -v gcc ]; then compile_release="$gcc_release"; fi
if [ -v gcc ]; then compile_link="$gcc_link"; fi
if [ -v gcc ]; then out="$gcc_out"; fi
if [ -v clang ]; then compile_debug="$clang_debug"; fi
if [ -v clang ]; then compile_release="$clang_release"; fi
if [ -v clang ]; then compile_link="$clang_link"; fi
if [ -v clang ]; then out="$clang_out"; fi
if [ -v debug ]; then compile="$compile_debug"; fi
if [ -v release ]; then compile="$compile_release"; fi
# --- Prep Directories --------------------------------------------------------
mkdir -p build
mkdir -p local
# --- Build & Run Metaprogram -------------------------------------------------
if [ -v no_meta ]; then echo "[skipping metagen]"; fi
if [ ! -v no_meta ]
then
cd build
$compile_debug ../src/metagen/metagen_main.c $compile_link $out metagen
./metagen
cd ..
fi
# --- Build Everything (@build_targets) ---------------------------------------
cd build
if [ -v raddbg ]; then didbuild=1 && $compile ../src/raddbg/raddbg_main.c $compile_link $link_os_gfx $out raddbg; 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_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 ryan_scratch ]; then didbuild=1 && $compile ../src/scratch/ryan_scratch.c $compile_link $link_os_gfx $out ryan_scratch; fi
cd ..
# --- Warn On No Builds -------------------------------------------------------
if [ ! -v didbuild ]
then
echo "[WARNING] no valid build target specified; must use build target names as arguments to this script, like \`./build.sh raddbg\` or \`./build.sh rdi_from_pdb\`."
exit 1
fi
+37 -115
View File
@@ -45,130 +45,52 @@ load_paths =
commands = commands =
{ {
.rjf_f1 = //- rjf: fkey command slots (change locally but do not commit)
{ .f1 = { .win = "build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.win = "build raddbg telemetry", .f2 = { .win = "build rdi_from_pdb", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.linux = "", .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, },
.out = "*compilation*",
.footer_panel = true, //- rjf: local target builds
.save_dirty_files = true, .build_raddbg = { .win = "build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.cursor_at_end = false, .build_rdi_from_pdb = { .win = "build rdi_from_pdb", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
}, .build_rdi_from_dwarf = { .win = "build rdi_from_dwarf", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.rjf_f2 = .build_rdi_dump = { .win = "build rdi_dump", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
{ .build_rdi_breakpad_from_pdb = { .win = "build rdi_breakpad_from_pdb", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.win = "build raddbgi_from_pdb telemetry release", .build_ryan_scratch = { .win = "build ryan_scratch", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.linux = "", .build_mule_main = { .win = "build mule_main", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.out = "*compilation*", .build_mule_module = { .win = "build mule_module", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.footer_panel = true, .build_mule_hotload = { .win = "build mule_hotload", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.save_dirty_files = true, .build_mule_peb_trample = { .win = "build mule_peb_trample", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.cursor_at_end = false,
}, //- rjf: wsl target builds
.rjf_f3 = .build_raddbg_wsl = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
{ .build_rdi_from_pdb_wsl = { .win = "wsl ./build.sh rdi_from_pdb", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --profile:local_dev.raddbg_profile && popd", .build_rdi_from_dwarf_wsl = { .win = "wsl ./build.sh rdi_from_dwarf", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.linux = "", .build_rdi_dump_wsl = { .win = "wsl ./build.sh rdi_dump", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.out = "*compilation*", .build_rdi_breakpad_from_pdb_wsl = { .win = "wsl ./build.sh rdi_breakpad_from_pdb", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.footer_panel = true, .build_ryan_scratch_wsl = { .win = "wsl ./build.sh ryan_scratch", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.save_dirty_files = true, .build_mule_main_wsl = { .win = "wsl ./build.sh mule_main", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.cursor_at_end = false, .build_mule_module_wsl = { .win = "wsl ./build.sh mule_module", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
}, .build_mule_hotload_wsl = { .win = "wsl ./build.sh mule_hotload", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.rjf_f4 = .build_mule_peb_trample_wsl = { .win = "wsl ./build.sh mule_peb_trample", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
{
.win = "build raddbgi_from_pdb release telemetry && pushd build && raddbgi_from_pdb.exe --exe:UnrealEditorFortnite.exe --pdb:UnrealEditorFortnite.pdb --out:UnrealEditorFortnite.raddbgi --capture && popd", //- rjf: local target runs
.linux = "", .run_raddbg = { .win = "pushd build && raddbg.exe && popd", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.out = "*compilation*",
.footer_panel = true,
.save_dirty_files = true,
.cursor_at_end = false,
},
.rjf_f5 =
{
.win = "pushd build && raddbgi_from_pdb.exe --exe:raddbg.exe --pdb:raddbg.pdb --out:raddbg.raddbg --capture && popd",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
.save_dirty_files = true,
.cursor_at_end = false,
},
.build_raddbg =
{
.win = "build raddbg",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
.save_dirty_files = true,
.cursor_at_end = false,
},
.build_raddbg_release_telemetry =
{
.win = "build raddbg release telemetry",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
.save_dirty_files = true,
.cursor_at_end = false,
},
.build_raddbgi_from_pdb =
{
.win = "build raddbgi_from_pdb",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
.save_dirty_files = true,
.cursor_at_end = false,
},
.build_raddbgi_dump =
{
.win = "build raddbgi_dump",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
.save_dirty_files = true,
.cursor_at_end = false,
},
.build_mule_main =
{
.win = "build mule_main",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
.save_dirty_files = true,
.cursor_at_end = false,
},
.build_ryan_scratch =
{
.win = "build ryan_scratch",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
.save_dirty_files = true,
.cursor_at_end = false,
},
.run_raddbg =
{
.win = "pushd build && raddbg.exe && popd",
.linux = "",
.out = "*compilation*",
.footer_panel = true,
.save_dirty_files = true,
.cursor_at_end = false,
},
}; };
fkey_command = fkey_command =
{ {
.F1 = "build_raddbg", .F1 = "f1",
.F3 = "run_raddbg", .F2 = "f2",
.F3 = "f3",
}; };
fkey_command_override = fkey_command_override =
{ {
.rjf = .rjf =
{ {
.F1 = "rjf_f1", .F1 = "f1",
.F2 = "rjf_f2", .F2 = "f2",
.F3 = "rjf_f3", .F3 = "f3",
.F4 = "rjf_f4",
.F5 = "rjf_f5",
}, },
}; };
+167 -222
View File
@@ -2,172 +2,175 @@
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
//////////////////////////////// ////////////////////////////////
// Implementation //~ rjf: Arena Functions
//- rjf: arena creation/destruction
internal Arena * internal Arena *
arena_alloc__sized(U64 init_res, U64 init_cmt) arena_alloc_(ArenaParams *params)
{ {
ProfBeginFunction(); // rjf: round up reserve/commit sizes
Assert(ARENA_HEADER_SIZE < init_cmt && init_cmt <= init_res); U64 reserve_size = params->reserve_size;
U64 commit_size = params->commit_size;
void *memory = 0; if(params->flags & ArenaFlag_LargePages)
U64 res = 0;
U64 cmt = 0;
B32 large_pages = os_large_pages_enabled();
if(large_pages)
{ {
U64 page_size = os_large_page_size(); reserve_size = AlignPow2(reserve_size, os_get_system_info()->large_page_size);
res = AlignPow2(init_res, page_size); commit_size = AlignPow2(commit_size, os_get_system_info()->large_page_size);
#if OS_WINDOWS
cmt = res;
#else
cmt = AlignPow2(init_cmt, page_size);
#endif
memory = os_reserve_large(res);
if(!os_commit_large(memory, cmt))
{
memory = 0;
os_release(memory, res);
}
} }
else else
{ {
U64 page_size = os_page_size(); reserve_size = AlignPow2(reserve_size, os_get_system_info()->page_size);
res = AlignPow2(init_res, page_size); commit_size = AlignPow2(commit_size, os_get_system_info()->page_size);
cmt = AlignPow2(init_cmt, page_size); }
memory = os_reserve(res);
if(!os_commit(memory, cmt)) // rjf: reserve/commit initial block
void *base = params->optional_backing_buffer;
if(base == 0)
{ {
memory = 0; if(params->flags & ArenaFlag_LargePages)
os_release(memory, res); {
base = os_reserve_large(reserve_size);
os_commit_large(base, commit_size);
}
else
{
base = os_reserve(reserve_size);
os_commit(base, commit_size);
} }
} }
Arena *arena = (Arena*)memory; // rjf: panic on arena creation failure
if(arena) #if OS_FEATURE_GRAPHICAL
if(Unlikely(base == 0))
{ {
AsanPoisonMemoryRegion(memory, cmt); os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure."));
AsanUnpoisonMemoryRegion(memory, ARENA_HEADER_SIZE); os_abort(1);
arena->prev = 0; }
#endif
// rjf: extract arena header & fill
Arena *arena = (Arena *)base;
arena->current = arena; arena->current = arena;
arena->flags = params->flags;
arena->cmt_size = (U32)params->commit_size;
arena->res_size = params->reserve_size;
arena->base_pos = 0; arena->base_pos = 0;
arena->pos = ARENA_HEADER_SIZE; arena->pos = ARENA_HEADER_SIZE;
arena->cmt = cmt; arena->cmt = commit_size;
arena->res = res; arena->res = reserve_size;
arena->align = 8; #if ARENA_FREE_LIST
arena->grow = 1; arena->free_size = 0;
arena->large_pages = large_pages; arena->free_last = 0;
} #endif
AsanPoisonMemoryRegion(base, commit_size);
ProfEnd(); AsanUnpoisonMemoryRegion(base, ARENA_HEADER_SIZE);
return arena;
}
internal Arena *
arena_alloc(void)
{
ProfBeginFunction();
U64 init_res, init_cmt;
if (os_large_pages_enabled()) {
init_res = ARENA_RESERVE_SIZE_LARGE_PAGES;
init_cmt = ARENA_COMMIT_SIZE_LARGE_PAGES;
} else {
init_res = ARENA_RESERVE_SIZE;
init_cmt = ARENA_COMMIT_SIZE;
}
Arena *arena = arena_alloc__sized(init_res, init_cmt);
ProfEnd();
return arena; return arena;
} }
internal void internal void
arena_release(Arena *arena) arena_release(Arena *arena)
{ {
for (Arena *node = arena->current, *prev = 0; node != 0; node = prev) { for(Arena *n = arena->current, *prev = 0; n != 0; n = prev)
prev = node->prev; {
os_release(node, node->res); prev = n->prev;
os_release(n, n->res);
} }
} }
internal U64 //- rjf: arena push/pop core functions
arena_huge_push_threshold(void)
{
U64 reserve_size = os_large_pages_enabled() ? ARENA_RESERVE_SIZE_LARGE_PAGES : ARENA_RESERVE_SIZE;
U64 threshold = (reserve_size - ARENA_HEADER_SIZE) / 2 + 1;
return threshold;
}
internal void * internal void *
arena_push__impl(Arena *arena, U64 size) arena_push(Arena *arena, U64 size, U64 align)
{ {
Arena *current = arena->current; Arena *current = arena->current;
U64 pos_mem = AlignPow2(current->pos, arena->align); U64 pos_pre = AlignPow2(current->pos, align);
U64 pos_new = pos_mem + size; U64 pos_pst = pos_pre + size;
if (current->res < pos_new && arena->grow) { // rjf: chain, if needed
Arena *new_block; if(current->res < pos_pst && !(arena->flags & ArenaFlag_NoChain))
// normal growth path
if (size < arena_huge_push_threshold()) {
new_block = arena_alloc();
}
// huge growth path
else {
U64 new_block_size = size + ARENA_HEADER_SIZE;
new_block = arena_alloc__sized(new_block_size, new_block_size);
}
if (new_block) {
new_block->base_pos = current->base_pos + current->res;
SLLStackPush_N(arena->current, new_block, prev);
current = new_block;
pos_mem = AlignPow2(current->pos, current->align);
pos_new = pos_mem + size;
}
}
if (current->cmt < pos_new) {
U64 cmt_new_aligned, cmt_new_clamped, cmt_new_size;
B32 is_cmt_ok;
if (current->large_pages) {
cmt_new_aligned = AlignPow2(pos_new, ARENA_COMMIT_SIZE_LARGE_PAGES);
cmt_new_clamped = ClampTop(cmt_new_aligned, current->res);
cmt_new_size = cmt_new_clamped - current->cmt;
is_cmt_ok = os_commit_large((U8*)current + current->cmt, cmt_new_size);
} else {
cmt_new_aligned = AlignPow2(pos_new, ARENA_COMMIT_SIZE);
cmt_new_clamped = ClampTop(cmt_new_aligned, current->res);
cmt_new_size = cmt_new_clamped - current->cmt;
is_cmt_ok = os_commit((U8*)current + current->cmt, cmt_new_size);
}
if (is_cmt_ok) {
current->cmt = cmt_new_clamped;
}
}
void *memory = 0;
if (current->cmt >= pos_new) {
memory = (U8*)current + pos_mem;
current->pos = pos_new;
AsanUnpoisonMemoryRegion(memory, size);
}
#if OS_FEATURE_GRAPHICAL
if(Unlikely(memory == 0))
{ {
os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure.")); Arena *new_block = 0;
os_exit_process(1);
#if ARENA_FREE_LIST
Arena *prev_block;
for(new_block = arena->free_last, prev_block = 0; new_block != 0; prev_block = new_block, new_block = new_block->prev)
{
if(new_block->res >= AlignPow2(size, align))
{
if(prev_block)
{
prev_block->prev = new_block->prev;
}
else
{
arena->free_last = new_block->prev;
}
arena->free_size -= new_block->res_size;
AsanUnpoisonMemoryRegion((U8*)new_block + ARENA_HEADER_SIZE, new_block->res_size - ARENA_HEADER_SIZE);
break;
}
} }
#endif #endif
return memory; if(new_block == 0)
{
U64 res_size = current->res_size;
U64 cmt_size = current->cmt_size;
if(size + ARENA_HEADER_SIZE > res_size)
{
res_size = AlignPow2(size + ARENA_HEADER_SIZE, align);
cmt_size = AlignPow2(size + ARENA_HEADER_SIZE, align);
}
new_block = arena_alloc(.reserve_size = res_size,
.commit_size = cmt_size,
.flags = current->flags);
new_block->base_pos = current->base_pos + current->res;
SLLStackPush_N(arena->current, new_block, prev);
}
current = new_block;
pos_pre = AlignPow2(current->pos, align);
pos_pst = pos_pre + size;
}
// rjf: commit new pages, if needed
if(current->cmt < pos_pst)
{
U64 cmt_pst_aligned = pos_pst + current->cmt_size-1;
cmt_pst_aligned -= cmt_pst_aligned%current->cmt_size;
U64 cmt_pst_clamped = ClampTop(cmt_pst_aligned, current->res);
U64 cmt_size = cmt_pst_clamped - current->cmt;
U8 *cmt_ptr = (U8 *)current + current->cmt;
if(current->flags & ArenaFlag_LargePages)
{
os_commit_large(cmt_ptr, cmt_size);
}
else
{
os_commit(cmt_ptr, cmt_size);
}
current->cmt = cmt_pst_clamped;
}
// rjf: push onto current block
void *result = 0;
if(current->cmt >= pos_pst)
{
result = (U8 *)current+pos_pre;
current->pos = pos_pst;
AsanUnpoisonMemoryRegion(result, size);
}
// rjf: panic on failure
#if OS_FEATURE_GRAPHICAL
if(Unlikely(result == 0))
{
os_graphical_message(1, str8_lit("Fatal Allocation Failure"), str8_lit("Unexpected memory allocation failure."));
os_abort(1);
}
#endif
return result;
} }
internal U64 internal U64
@@ -179,85 +182,35 @@ arena_pos(Arena *arena)
} }
internal void internal void
arena_pop_to(Arena *arena, U64 big_pos_unclamped) arena_pop_to(Arena *arena, U64 pos)
{ {
U64 big_pos = ClampBot(ARENA_HEADER_SIZE, big_pos_unclamped); U64 big_pos = ClampBot(ARENA_HEADER_SIZE, pos);
// unroll the chain
Arena *current = arena->current; Arena *current = arena->current;
for (Arena *prev = 0; current->base_pos >= big_pos; current = prev) {
#if ARENA_FREE_LIST
for(Arena *prev = 0; current->base_pos >= big_pos; current = prev)
{
prev = current->prev;
current->pos = ARENA_HEADER_SIZE;
arena->free_size += current->res_size;
SLLStackPush_N(arena->free_last, current, prev);
AsanPoisonMemoryRegion((U8*)current + ARENA_HEADER_SIZE, current->res_size - ARENA_HEADER_SIZE);
}
#else
for(Arena *prev = 0; current->base_pos >= big_pos; current = prev)
{
prev = current->prev; prev = current->prev;
os_release(current, current->res); os_release(current, current->res);
} }
AssertAlways(current); #endif
arena->current = current; arena->current = current;
// compute arena-relative position
U64 new_pos = big_pos - current->base_pos; U64 new_pos = big_pos - current->base_pos;
AssertAlways(new_pos <= current->pos); AssertAlways(new_pos <= current->pos);
// poison popped memory block
AsanPoisonMemoryRegion((U8*)current + new_pos, (current->pos - new_pos)); AsanPoisonMemoryRegion((U8*)current + new_pos, (current->pos - new_pos));
// update position
current->pos = new_pos; current->pos = new_pos;
} }
internal void //- rjf: arena push/pop helpers
arena_absorb(Arena *arena, Arena *sub)
{
// base adjustment
Arena *current = arena->current;
U64 base_adjust = current->base_pos + current->res;
for (Arena *node = sub->current; node != 0; node = node->prev) {
node->base_pos += base_adjust;
}
// attach sub to arena
sub->prev = arena->current;
arena->current = sub->current;
sub->current = sub;
}
////////////////////////////////
// Wrappers
internal void *
arena_push(Arena *arena, U64 size)
{
void *memory = arena_push__impl(arena, size);
return memory;
}
internal void *
arena_push_contiguous(Arena *arena, U64 size)
{
B32 restore = arena->grow;
arena->grow = 0;
void *memory = arena_push(arena, size);
arena->grow = restore;
return memory;
}
internal void
arena_push_align(Arena *arena, U64 align)
{
Assert(IsPow2(align));
U64 amt = AlignPadPow2(arena->pos, align);
void *ptr = arena_push(arena, amt);
MemoryZero(ptr, amt);
}
internal void
arena_put_back(Arena *arena, U64 amt)
{
U64 pos_old = arena_pos(arena);
U64 pos_new = pos_old;
if (amt < pos_old) {
pos_new = pos_old - amt;
}
arena_pop_to(arena, pos_new);
}
internal void internal void
arena_clear(Arena *arena) arena_clear(Arena *arena)
@@ -265,6 +218,20 @@ arena_clear(Arena *arena)
arena_pop_to(arena, 0); arena_pop_to(arena, 0);
} }
internal void
arena_pop(Arena *arena, U64 amt)
{
U64 pos_old = arena_pos(arena);
U64 pos_new = pos_old;
if(amt < pos_old)
{
pos_new = pos_old - amt;
}
arena_pop_to(arena, pos_new);
}
//- rjf: temporary arena scopes
internal Temp internal Temp
temp_begin(Arena *arena) temp_begin(Arena *arena)
{ {
@@ -278,25 +245,3 @@ temp_end(Temp temp)
{ {
arena_pop_to(temp.arena, temp.pos); arena_pop_to(temp.arena, temp.pos);
} }
////////////////////////////////
//~ NOTE(allen): "Mini-Arena" Helper
internal B32
ensure_commit(void **cmtptr, void *pos, U64 cmt_block_size){
B32 result = 0;
U8 *cmt = (U8*)*cmtptr;
if (cmt < (U8*)pos){
U64 cmt_size_raw = (U8*)pos - cmt;
U64 cmt_size = AlignPow2(cmt_size_raw, cmt_block_size);
if (os_commit(cmt, cmt_size)){
*cmtptr = cmt + cmt_size;
result = 1;
}
}
else{
result = 1;
}
return(result);
}
+51 -43
View File
@@ -7,38 +7,49 @@
//////////////////////////////// ////////////////////////////////
//~ rjf: Constants //~ rjf: Constants
#define ARENA_HEADER_SIZE 128 #if ARENA_FREE_LIST
# define ARENA_HEADER_SIZE 128
#ifndef ARENA_RESERVE_SIZE #else
# define ARENA_RESERVE_SIZE MB(64) # define ARENA_HEADER_SIZE 64
#endif
#ifndef ARENA_COMMIT_SIZE
# define ARENA_COMMIT_SIZE KB(64)
#endif
#ifndef ARENA_RESERVE_SIZE_LARGE_PAGES
# define ARENA_RESERVE_SIZE_LARGE_PAGES MB(8)
#endif
#ifndef ARENA_COMMIT_SIZE_LARGE_PAGES
# define ARENA_COMMIT_SIZE_LARGE_PAGES MB(2)
#endif #endif
//////////////////////////////// ////////////////////////////////
//~ rjf: Arena Types //~ rjf: Types
typedef U32 ArenaFlags;
enum
{
ArenaFlag_NoChain = (1<<0),
ArenaFlag_LargePages = (1<<1),
};
typedef struct ArenaParams ArenaParams;
struct ArenaParams
{
ArenaFlags flags;
U64 reserve_size;
U64 commit_size;
void *optional_backing_buffer;
};
typedef struct Arena Arena; typedef struct Arena Arena;
struct Arena struct Arena
{ {
struct Arena *prev; Arena *prev; // previous arena in chain
struct Arena *current; Arena *current; // current arena in chain
ArenaFlags flags;
U32 cmt_size;
U64 res_size;
U64 base_pos; U64 base_pos;
U64 pos; U64 pos;
U64 cmt; U64 cmt;
U64 res; U64 res;
U64 align; #if ARENA_FREE_LIST
B8 grow; U64 free_size;
B8 large_pages; Arena *free_last;
#endif
}; };
StaticAssert(sizeof(Arena) <= ARENA_HEADER_SIZE, arena_header_size_check);
typedef struct Temp Temp; typedef struct Temp Temp;
struct Temp struct Temp
@@ -48,40 +59,37 @@ struct Temp
}; };
//////////////////////////////// ////////////////////////////////
// Implementation //~ rjf: Global Defaults
internal Arena* arena_alloc__sized(U64 init_res, U64 init_cmt); global U64 arena_default_reserve_size = MB(64);
global U64 arena_default_commit_size = KB(64);
global ArenaFlags arena_default_flags = 0;
internal Arena* arena_alloc(void); ////////////////////////////////
//~ rjf: Arena Functions
//- rjf: arena creation/destruction
internal Arena *arena_alloc_(ArenaParams *params);
#define arena_alloc(...) arena_alloc_(&(ArenaParams){.reserve_size = arena_default_reserve_size, .commit_size = arena_default_commit_size, .flags = arena_default_flags, __VA_ARGS__})
internal void arena_release(Arena *arena); internal void arena_release(Arena *arena);
internal void* arena_push__impl(Arena *arena, U64 size); //- rjf: arena push/pop/pos core functions
internal void *arena_push(Arena *arena, U64 size, U64 align);
internal U64 arena_pos(Arena *arena); internal U64 arena_pos(Arena *arena);
internal void arena_pop_to(Arena *arena, U64 pos); internal void arena_pop_to(Arena *arena, U64 pos);
internal void arena_absorb(Arena *arena, Arena *sub); //- rjf: arena push/pop helpers
////////////////////////////////
// Wrappers
internal void* arena_push(Arena *arena, U64 size);
internal void* arena_push_contiguous(Arena *arena, U64 size);
internal void arena_clear(Arena *arena); internal void arena_clear(Arena *arena);
internal void arena_push_align(Arena *arena, U64 align); internal void arena_pop(Arena *arena, U64 amt);
internal void arena_put_back(Arena *arena, U64 amt);
//- rjf: temporary arena scopes
internal Temp temp_begin(Arena *arena); internal Temp temp_begin(Arena *arena);
internal void temp_end(Temp temp); internal void temp_end(Temp temp);
//////////////////////////////// //- rjf: push helper macros
//~ NOTE(allen): "Mini-Arena" Helper #define push_array_no_zero_aligned(a, T, c, align) (T *)arena_push((a), sizeof(T)*(c), (align))
#define push_array_aligned(a, T, c, align) (T *)MemoryZero(push_array_no_zero_aligned(a, T, c, align), sizeof(T)*(c))
internal B32 ensure_commit(void **cmt, void *pos, U64 cmt_block_size); #define push_array_no_zero(a, T, c) push_array_no_zero_aligned(a, T, c, Max(8, AlignOf(T)))
#define push_array(a, T, c) push_array_aligned(a, T, c, Max(8, AlignOf(T)))
////////////////////////////////
//~ NOTE(allen): Main API Macros
#define push_array_no_zero(a,T,c) (T*)arena_push((a), sizeof(T)*(c))
#define push_array(a,T,c) (T*)MemoryZero(push_array_no_zero(a,T,c), sizeof(T)*(c))
#endif // BASE_ARENA_H #endif // BASE_ARENA_H
+3 -1
View File
@@ -92,6 +92,7 @@ cmd_line_from_string_list(Arena *arena, String8List command_line)
// NOTE(rjf): Parse command line. // NOTE(rjf): Parse command line.
B32 after_passthrough_option = 0; B32 after_passthrough_option = 0;
B32 first_passthrough = 1;
for(String8Node *node = command_line.first->next, *next = 0; node != 0; node = next) for(String8Node *node = command_line.first->next, *next = 0; node != 0; node = next)
{ {
next = node->next; next = node->next;
@@ -175,10 +176,11 @@ cmd_line_from_string_list(Arena *arena, String8List command_line)
// NOTE(rjf): Default path, treat as a passthrough config option to be // NOTE(rjf): Default path, treat as a passthrough config option to be
// handled by tool-specific code. // handled by tool-specific code.
else if(!str8_match(node->string, str8_lit("--"), 0)) else if(!str8_match(node->string, str8_lit("--"), 0) || !first_passthrough)
{ {
str8_list_push(arena, &parsed.inputs, node->string); str8_list_push(arena, &parsed.inputs, node->string);
after_passthrough_option = 1; after_passthrough_option = 1;
first_passthrough = 0;
} }
} }
+11 -1
View File
@@ -183,7 +183,7 @@
#endif #endif
#if !defined(BUILD_ISSUES_LINK_STRING_LITERAL) #if !defined(BUILD_ISSUES_LINK_STRING_LITERAL)
# define BUILD_ISSUES_LINK_STRING_LITERAL "https://github.com/EpicGames/raddebugger/issues" # define BUILD_ISSUES_LINK_STRING_LITERAL "https://github.com/EpicGamesExt/raddebugger/issues"
#endif #endif
#define BUILD_TITLE_STRING_LITERAL BUILD_TITLE " (" BUILD_VERSION_STRING_LITERAL " " BUILD_RELEASE_PHASE_STRING_LITERAL ") - " __DATE__ "" BUILD_GIT_HASH_STRING_LITERAL_APPEND BUILD_MODE_STRING_LITERAL_APPEND #define BUILD_TITLE_STRING_LITERAL BUILD_TITLE " (" BUILD_VERSION_STRING_LITERAL " " BUILD_RELEASE_PHASE_STRING_LITERAL ") - " __DATE__ "" BUILD_GIT_HASH_STRING_LITERAL_APPEND BUILD_MODE_STRING_LITERAL_APPEND
@@ -234,4 +234,14 @@
# define LANG_C 0 # define LANG_C 0
#endif #endif
////////////////////////////////
//~ rjf: Unsupported Errors
#if ARCH_X86
# error You tried to build in x86 (32 bit) mode, but currently, only building in x64 (64 bit) mode is supported.
#endif
#if !ARCH_X64
# error You tried to build with an unsupported architecture. Currently, only building in x64 mode is supported.
#endif
#endif // BASE_CONTEXT_CRACKING_H #endif // BASE_CONTEXT_CRACKING_H
+13 -13
View File
@@ -399,23 +399,23 @@ txt_rng_contains(TxtRng r, TxtPt pt)
//~ rjf: Toolchain/Environment Enum Functions //~ rjf: Toolchain/Environment Enum Functions
internal U64 internal U64
bit_size_from_arch(Architecture arch) bit_size_from_arch(Arch arch)
{ {
// TODO(rjf): metacode // TODO(rjf): metacode
U64 arch_bitsize = 0; U64 arch_bitsize = 0;
switch(arch) switch(arch)
{ {
case Architecture_x64: arch_bitsize = 64; break; case Arch_x64: arch_bitsize = 64; break;
case Architecture_x86: arch_bitsize = 32; break; case Arch_x86: arch_bitsize = 32; break;
case Architecture_arm64: arch_bitsize = 64; break; case Arch_arm64: arch_bitsize = 64; break;
case Architecture_arm32: arch_bitsize = 32; break; case Arch_arm32: arch_bitsize = 32; break;
default: break; default: break;
} }
return arch_bitsize; return arch_bitsize;
} }
internal U64 internal U64
max_instruction_size_from_arch(Architecture arch) max_instruction_size_from_arch(Arch arch)
{ {
// TODO(rjf): make this real // TODO(rjf): make this real
return 64; return 64;
@@ -434,17 +434,17 @@ operating_system_from_context(void){
return os; return os;
} }
internal Architecture internal Arch
architecture_from_context(void){ arch_from_context(void){
Architecture arch = Architecture_Null; Arch arch = Arch_Null;
#if ARCH_X64 #if ARCH_X64
arch = Architecture_x64; arch = Arch_x64;
#elif ARCH_X86 #elif ARCH_X86
arch = Architecture_x86; arch = Arch_x86;
#elif ARCH_ARM64 #elif ARCH_ARM64
arch = Architecture_arm64; arch = Arch_arm64;
#elif ARCH_ARM32 #elif ARCH_ARM32
arch = Architecture_arm32; arch = Arch_arm32;
#endif #endif
return arch; return arch;
} }
+59 -16
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/)
#ifndef BASE_TYPES_H #ifndef BASE_CORE_H
#define BASE_TYPES_H #define BASE_CORE_H
//////////////////////////////// ////////////////////////////////
//~ rjf: Foreign Includes //~ rjf: Foreign Includes
@@ -91,6 +91,19 @@
#define ClampBot(X,B) Max(X,B) #define ClampBot(X,B) Max(X,B)
#define Clamp(A,X,B) (((X)<(A))?(A):((X)>(B))?(B):(X)) #define Clamp(A,X,B) (((X)<(A))?(A):((X)>(B))?(B):(X))
////////////////////////////////
//~ rjf: Type -> Alignment
#if COMPILER_MSVC
# define AlignOf(T) __alignof(T)
#elif COMPILER_CLANG
# define AlignOf(T) __alignof(T)
#elif COMPILER_GCC
# define AlignOf(T) __alignof__(T)
#else
# error AlignOf not defined for this compiler.
#endif
//////////////////////////////// ////////////////////////////////
//~ rjf: Member Offsets //~ rjf: Member Offsets
@@ -105,8 +118,10 @@
#define DeferLoop(begin, end) for(int _i_ = ((begin), 0); !_i_; _i_ += 1, (end)) #define DeferLoop(begin, end) for(int _i_ = ((begin), 0); !_i_; _i_ += 1, (end))
#define DeferLoopChecked(begin, end) for(int _i_ = 2 * !(begin); (_i_ == 2 ? ((end), 0) : !_i_); _i_ += 1, (end)) #define DeferLoopChecked(begin, end) for(int _i_ = 2 * !(begin); (_i_ == 2 ? ((end), 0) : !_i_); _i_ += 1, (end))
#define EachEnumVal(type, it) type it = (type)0; it < type##_COUNT; it = (type)(it+1) #define EachIndex(it, count) (U64 it = 0; it < (count); it += 1)
#define EachNonZeroEnumVal(type, it) type it = (type)1; it < type##_COUNT; it = (type)(it+1) #define EachElement(it, array) (U64 it = 0; it < ArrayCount(array); it += 1)
#define EachEnumVal(type, it) (type it = (type)0; it < type##_COUNT; it = (type)(it+1))
#define EachNonZeroEnumVal(type, it) (type it = (type)1; it < type##_COUNT; it = (type)(it+1))
//////////////////////////////// ////////////////////////////////
//~ rjf: Memory Operation Macros //~ rjf: Memory Operation Macros
@@ -168,6 +183,7 @@
# define ins_atomic_u64_dec_eval(x) InterlockedDecrement64((volatile __int64 *)(x)) # define ins_atomic_u64_dec_eval(x) InterlockedDecrement64((volatile __int64 *)(x))
# define ins_atomic_u64_eval_assign(x,c) InterlockedExchange64((volatile __int64 *)(x),(c)) # define ins_atomic_u64_eval_assign(x,c) InterlockedExchange64((volatile __int64 *)(x),(c))
# define ins_atomic_u64_add_eval(x,c) InterlockedAdd64((volatile __int64 *)(x), c) # define ins_atomic_u64_add_eval(x,c) InterlockedAdd64((volatile __int64 *)(x), c)
# define ins_atomic_u64_eval_cond_assign(x,k,c) InterlockedCompareExchange64((volatile __int64 *)(x),(k),(c))
# define ins_atomic_u32_eval(x,c) InterlockedAdd((volatile LONG *)(x), 0) # define ins_atomic_u32_eval(x,c) InterlockedAdd((volatile LONG *)(x), 0)
# define ins_atomic_u32_eval_assign(x,c) InterlockedExchange((volatile LONG *)(x),(c)) # define ins_atomic_u32_eval_assign(x,c) InterlockedExchange((volatile LONG *)(x),(c))
# define ins_atomic_u32_eval_cond_assign(x,k,c) InterlockedCompareExchange((volatile LONG *)(x),(k),(c)) # define ins_atomic_u32_eval_cond_assign(x,k,c) InterlockedCompareExchange((volatile LONG *)(x),(k),(c))
@@ -177,7 +193,16 @@
# endif # endif
#elif OS_LINUX #elif OS_LINUX
# if ARCH_X64 # if ARCH_X64
# define ins_atomic_u64_eval(x) __sync_fetch_and_add((volatile U64 *)(x), 0)
# define ins_atomic_u64_inc_eval(x) __sync_fetch_and_add((volatile U64 *)(x), 1) # define ins_atomic_u64_inc_eval(x) __sync_fetch_and_add((volatile U64 *)(x), 1)
# define ins_atomic_u64_dec_eval(x) __sync_fetch_and_sub((volatile U64 *)(x), 1)
# define ins_atomic_u64_eval_assign(x,c) __sync_lock_test_and_set((volatile U64 *)(x),(c))
# define ins_atomic_u64_add_eval(x,c) __sync_fetch_and_add((volatile U64 *)(x), c)
# define ins_atomic_u64_eval_cond_assign(x,k,c) __sync_val_compare_and_swap((volatile U64 *)(x),(c),(k))
# define ins_atomic_u32_eval(x,c) __sync_fetch_and_add((volatile U32 *)(x), 0)
# define ins_atomic_u32_eval_assign(x,c) __sync_lock_test_and_set((volatile U32 *)(x),(c))
# define ins_atomic_u32_eval_cond_assign(x,k,c) __sync_val_compare_and_swap((volatile U32 *)(x),(c),(k))
# define ins_atomic_ptr_eval_assign(x,c) (void*)ins_atomic_u64_eval_assign((volatile U64 *)(x), (U64)(c))
# else # else
# error Atomic intrinsics not defined for this operating system / architecture combination. # error Atomic intrinsics not defined for this operating system / architecture combination.
# endif # endif
@@ -264,7 +289,7 @@ CheckNil(nil,p) ? \
# endif # endif
# define NO_ASAN __attribute__((no_sanitize("address"))) # define NO_ASAN __attribute__((no_sanitize("address")))
#else #else
# error "NO_ASAN is not defined for this compiler." # define NO_ASAN
#endif #endif
#if ASAN_ENABLED #if ASAN_ENABLED
@@ -390,6 +415,19 @@ typedef enum Corner
} }
Corner; Corner;
typedef enum Dir2
{
Dir2_Invalid = -1,
Dir2_Left,
Dir2_Up,
Dir2_Right,
Dir2_Down,
Dir2_COUNT
}
Dir2;
#define axis2_from_dir2(d) (((d) & 1) ? Axis2_Y : Axis2_X)
#define side_from_dir2(d) (((d) < Dir2_Right) ? Side_Min : Side_Max)
//////////////////////////////// ////////////////////////////////
//~ rjf: Toolchain/Environment Enums //~ rjf: Toolchain/Environment Enums
@@ -403,16 +441,16 @@ typedef enum OperatingSystem
} }
OperatingSystem; OperatingSystem;
typedef enum Architecture typedef enum Arch
{ {
Architecture_Null, Arch_Null,
Architecture_x64, Arch_x64,
Architecture_x86, Arch_x86,
Architecture_arm64, Arch_arm64,
Architecture_arm32, Arch_arm32,
Architecture_COUNT, Arch_COUNT,
} }
Architecture; Arch;
typedef enum Compiler typedef enum Compiler
{ {
@@ -743,11 +781,11 @@ internal B32 txt_rng_contains(TxtRng r, TxtPt pt);
//////////////////////////////// ////////////////////////////////
//~ rjf: Toolchain/Environment Enum Functions //~ rjf: Toolchain/Environment Enum Functions
internal U64 bit_size_from_arch(Architecture arch); internal U64 bit_size_from_arch(Arch arch);
internal U64 max_instruction_size_from_arch(Architecture arch); internal U64 max_instruction_size_from_arch(Arch arch);
internal OperatingSystem operating_system_from_context(void); internal OperatingSystem operating_system_from_context(void);
internal Architecture architecture_from_context(void); internal Arch arch_from_context(void);
internal Compiler compiler_from_context(void); internal Compiler compiler_from_context(void);
//////////////////////////////// ////////////////////////////////
@@ -765,4 +803,9 @@ internal U64 ring_read(U8 *ring_base, U64 ring_size, U64 ring_pos, void *dst_dat
#define ring_write_struct(ring_base, ring_size, ring_pos, ptr) ring_write((ring_base), (ring_size), (ring_pos), (ptr), sizeof(*(ptr))) #define ring_write_struct(ring_base, ring_size, ring_pos, ptr) ring_write((ring_base), (ring_size), (ring_pos), (ptr), sizeof(*(ptr)))
#define ring_read_struct(ring_base, ring_size, ring_pos, ptr) ring_read((ring_base), (ring_size), (ring_pos), (ptr), sizeof(*(ptr))) #define ring_read_struct(ring_base, ring_size, ring_pos, ptr) ring_read((ring_base), (ring_size), (ring_pos), (ptr), sizeof(*(ptr)))
////////////////////////////////
//~ rjf: Sorts
#define quick_sort(ptr, count, element_size, cmp_function) qsort((ptr), (count), (element_size), (int (*)(const void *, const void *))(cmp_function))
#endif // BASE_CORE_H #endif // BASE_CORE_H
+67 -35
View File
@@ -1,88 +1,96 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal void internal void
main_thread_base_entry_point(void (*entry_point)(CmdLine *cmdline), char **arguments, U64 arguments_count) main_thread_base_entry_point(void (*entry_point)(CmdLine *cmdline), char **arguments, U64 arguments_count)
{ {
Temp scratch = scratch_begin(0, 0);
ThreadNameF("[main thread]");
//- rjf: set up telemetry
#if PROFILE_TELEMETRY #if PROFILE_TELEMETRY
local_persist U8 tm_data[MB(64)]; local_persist U8 tm_data[MB(64)];
tmLoadLibrary(TM_RELEASE); tmLoadLibrary(TM_RELEASE);
tmSetMaxThreadCount(256); tmSetMaxThreadCount(256);
tmInitialize(sizeof(tm_data), (char *)tm_data); tmInitialize(sizeof(tm_data), (char *)tm_data);
#endif #endif
TCTX tctx;
tctx_init_and_equip(&tctx); //- rjf: parse command line
ThreadNameF("[main thread]");
Temp scratch = scratch_begin(0, 0);
String8List command_line_argument_strings = os_string_list_from_argcv(scratch.arena, (int)arguments_count, arguments); String8List command_line_argument_strings = os_string_list_from_argcv(scratch.arena, (int)arguments_count, arguments);
CmdLine cmdline = cmd_line_from_string_list(scratch.arena, command_line_argument_strings); CmdLine cmdline = cmd_line_from_string_list(scratch.arena, command_line_argument_strings);
//- rjf: begin captures
B32 capture = cmd_line_has_flag(&cmdline, str8_lit("capture")); B32 capture = cmd_line_has_flag(&cmdline, str8_lit("capture"));
if(capture) if(capture)
{ {
ProfBeginCapture(arguments[0]); ProfBeginCapture(arguments[0]);
} }
#if defined(OS_CORE_H)
os_init(); //- rjf: initialize all included layers
#endif #if defined(TASK_SYSTEM_H) && !defined(TS_INIT_MANUAL)
#if defined(TASK_SYSTEM_H)
ts_init(); ts_init();
#endif #endif
#if defined(HASH_STORE_H) #if defined(HASH_STORE_H) && !defined(HS_INIT_MANUAL)
hs_init(); hs_init();
#endif #endif
#if defined(FILE_STREAM_H) #if defined(FILE_STREAM_H) && !defined(FS_INIT_MANUAL)
fs_init(); fs_init();
#endif #endif
#if defined(TEXT_CACHE_H) #if defined(TEXT_CACHE_H) && !defined(TXT_INIT_MANUAL)
txt_init(); txt_init();
#endif #endif
#if defined(DASM_CACHE_H) #if defined(MUTABLE_TEXT_H) && !defined(MTX_INIT_MANUAL)
mtx_init();
#endif
#if defined(DASM_CACHE_H) && !defined(DASM_INIT_MANUAL)
dasm_init(); dasm_init();
#endif #endif
#if defined(DBGI_H) #if defined(DBGI_H) && !defined(DBGI_INIT_MANUAL)
dbgi_init(); di_init();
#endif #endif
#if defined(TXTI_H) #if defined(FUZZY_SEARCH_H) && !defined(FZY_INIT_MANUAL)
txti_init(); fzy_init();
#endif #endif
#if defined(DEMON_CORE_H) #if defined(DEMON_CORE_H) && !defined(DMN_INIT_MANUAL)
dmn_init(); dmn_init();
#endif #endif
#if defined(CTRL_CORE_H) #if defined(CTRL_CORE_H) && !defined(CTRL_INIT_MANUAL)
ctrl_init(); ctrl_init();
#endif #endif
#if defined(DASM_H) #if defined(OS_GFX_H) && !defined(OS_GFX_INIT_MANUAL)
dasmi_init(); os_gfx_init();
#endif #endif
#if defined(OS_GRAPHICAL_H) #if defined(FONT_PROVIDER_H) && !defined(FP_INIT_MANUAL)
os_graphical_init();
#endif
#if defined(FONT_PROVIDER_H)
fp_init(); fp_init();
#endif #endif
#if defined(RENDER_CORE_H) #if defined(RENDER_CORE_H) && !defined(R_INIT_MANUAL)
r_init(&cmdline); r_init(&cmdline);
#endif #endif
#if defined(TEXTURE_CACHE_H) #if defined(TEXTURE_CACHE_H) && !defined(TEX_INIT_MANUAL)
tex_init(); tex_init();
#endif #endif
#if defined(GEO_CACHE_H) #if defined(GEO_CACHE_H) && !defined(GEO_INIT_MANUAL)
geo_init(); geo_init();
#endif #endif
#if defined(FONT_CACHE_H) #if defined(FONT_CACHE_H) && !defined(FNT_INIT_MANUAL)
f_init(); fnt_init();
#endif #endif
#if defined(DF_CORE_H) #if defined(DBG_ENGINE_CORE_H) && !defined(D_INIT_MANUAL)
DF_StateDeltaHistory *hist = df_state_delta_history_alloc(); d_init();
df_core_init(&cmdline, hist);
#endif #endif
#if defined(DF_GFX_H) #if defined(RADDBG_CORE_H) && !defined(RD_INIT_MANUAL)
df_gfx_init(update_and_render, df_state_delta_history()); rd_init(&cmdline);
#endif #endif
//- rjf: call into entry point
entry_point(&cmdline); entry_point(&cmdline);
//- rjf: end captures
if(capture) if(capture)
{ {
ProfEndCapture(); ProfEndCapture();
} }
scratch_end(scratch); scratch_end(scratch);
tctx_release();
} }
internal void internal void
@@ -93,3 +101,27 @@ supplement_thread_base_entry_point(void (*entry_point)(void *params), void *para
entry_point(params); entry_point(params);
tctx_release(); tctx_release();
} }
internal B32
update(void)
{
ProfTick(0);
#if defined(TEXT_CACHE_H)
txt_user_clock_tick();
#endif
#if defined(DASM_CACHE_H)
dasm_user_clock_tick();
#endif
#if defined(GEO_CACHE_H)
geo_user_clock_tick();
#endif
#if defined(TEXTURE_CACHE_H)
tex_user_clock_tick();
#endif
#if OS_FEATURE_GRAPHICAL
B32 result = frame();
#else
B32 result = 0;
#endif
return result;
}
+1
View File
@@ -6,5 +6,6 @@
internal void main_thread_base_entry_point(void (*entry_point)(CmdLine *cmdline), char **arguments, U64 arguments_count); internal void main_thread_base_entry_point(void (*entry_point)(CmdLine *cmdline), char **arguments, U64 arguments_count);
internal void supplement_thread_base_entry_point(void (*entry_point)(void *params), void *params); internal void supplement_thread_base_entry_point(void (*entry_point)(void *params), void *params);
internal B32 update(void);
#endif // BASE_ENTRY_POINT_H #endif // BASE_ENTRY_POINT_H
+4 -2
View File
@@ -4,8 +4,8 @@
//////////////////////////////// ////////////////////////////////
//~ rjf: Base Includes //~ rjf: Base Includes
#undef RADDBG_LAYER_COLOR #undef MARKUP_LAYER_COLOR
#define RADDBG_LAYER_COLOR 0.20f, 0.60f, 0.80f #define MARKUP_LAYER_COLOR 0.20f, 0.60f, 0.80f
#include "base_core.c" #include "base_core.c"
#include "base_profile.c" #include "base_profile.c"
@@ -15,4 +15,6 @@
#include "base_thread_context.c" #include "base_thread_context.c"
#include "base_command_line.c" #include "base_command_line.c"
#include "base_markup.c" #include "base_markup.c"
#include "base_meta.c"
#include "base_log.c"
#include "base_entry_point.c" #include "base_entry_point.c"
+2
View File
@@ -17,6 +17,8 @@
#include "base_thread_context.h" #include "base_thread_context.h"
#include "base_command_line.h" #include "base_command_line.h"
#include "base_markup.h" #include "base_markup.h"
#include "base_meta.h"
#include "base_log.h"
#include "base_entry_point.h" #include "base_entry_point.h"
#endif // BASE_INC_H #endif // BASE_INC_H
+103
View File
@@ -0,0 +1,103 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Globals/Thread-Locals
C_LINKAGE thread_static Log *log_active;
#if !BUILD_SUPPLEMENTARY_UNIT
C_LINKAGE thread_static Log *log_active = 0;
#endif
////////////////////////////////
//~ rjf: Log Creation/Selection
internal Log *
log_alloc(void)
{
Arena *arena = arena_alloc();
Log *log = push_array(arena, Log, 1);
log->arena = arena;
return log;
}
internal void
log_release(Log *log)
{
arena_release(log->arena);
}
internal void
log_select(Log *log)
{
log_active = log;
}
////////////////////////////////
//~ rjf: Log Building/Clearing
internal void
log_msg(LogMsgKind kind, String8 string)
{
if(log_active != 0 && log_active->top_scope != 0)
{
String8 string_copy = push_str8_copy(log_active->arena, string);
str8_list_push(log_active->arena, &log_active->top_scope->strings[kind], string_copy);
}
}
internal void
log_msgf(LogMsgKind kind, char *fmt, ...)
{
if(log_active != 0)
{
Temp scratch = scratch_begin(0, 0);
va_list args;
va_start(args, fmt);
String8 string = push_str8fv(scratch.arena, fmt, args);
log_msg(kind, string);
va_end(args);
scratch_end(scratch);
}
}
////////////////////////////////
//~ rjf: Log Scopes
internal void
log_scope_begin(void)
{
if(log_active != 0)
{
U64 pos = arena_pos(log_active->arena);
LogScope *scope = push_array(log_active->arena, LogScope, 1);
scope->pos = pos;
SLLStackPush(log_active->top_scope, scope);
}
}
internal LogScopeResult
log_scope_end(Arena *arena)
{
LogScopeResult result = {0};
if(log_active != 0)
{
LogScope *scope = log_active->top_scope;
if(scope != 0)
{
SLLStackPop(log_active->top_scope);
if(arena != 0)
{
for EachEnumVal(LogMsgKind, kind)
{
Temp scratch = scratch_begin(&arena, 1);
String8 result_unindented = str8_list_join(scratch.arena, &scope->strings[kind], 0);
result.strings[kind] = indented_from_string(arena, result_unindented);
scratch_end(scratch);
}
}
arena_pop_to(log_active->arena, scope->pos);
}
}
return result;
}
+65
View File
@@ -0,0 +1,65 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_LOG_H
#define BASE_LOG_H
////////////////////////////////
//~ rjf: Log Types
typedef enum LogMsgKind
{
LogMsgKind_Info,
LogMsgKind_UserError,
LogMsgKind_COUNT
}
LogMsgKind;
typedef struct LogScope LogScope;
struct LogScope
{
LogScope *next;
U64 pos;
String8List strings[LogMsgKind_COUNT];
};
typedef struct LogScopeResult LogScopeResult;
struct LogScopeResult
{
String8 strings[LogMsgKind_COUNT];
};
typedef struct Log Log;
struct Log
{
Arena *arena;
LogScope *top_scope;
};
////////////////////////////////
//~ rjf: Log Creation/Selection
internal Log *log_alloc(void);
internal void log_release(Log *log);
internal void log_select(Log *log);
////////////////////////////////
//~ rjf: Log Building
internal void log_msg(LogMsgKind kind, String8 string);
internal void log_msgf(LogMsgKind kind, char *fmt, ...);
#define log_info(s) log_msg(LogMsgKind_Info, (s))
#define log_infof(fmt, ...) log_msgf(LogMsgKind_Info, (fmt), __VA_ARGS__)
#define log_user_error(s) log_msg(LogMsgKind_UserError, (s))
#define log_user_errorf(fmt, ...) log_msgf(LogMsgKind_UserError, (fmt), __VA_ARGS__)
#define LogInfoNamedBlock(s) DeferLoop(log_infof("%S:\n{\n", (s)), log_infof("}\n"))
#define LogInfoNamedBlockF(fmt, ...) DeferLoop((log_infof(fmt, __VA_ARGS__), log_infof(":\n{\n")), log_infof("}\n"))
////////////////////////////////
//~ rjf: Log Scopes
internal void log_scope_begin(void);
internal LogScopeResult log_scope_end(Arena *arena);
#endif // BASE_LOG_H
+3 -3
View File
@@ -2,20 +2,20 @@
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
internal void internal void
thread_name(String8 string) set_thread_name(String8 string)
{ {
ProfThreadName("%.*s", str8_varg(string)); ProfThreadName("%.*s", str8_varg(string));
os_set_thread_name(string); os_set_thread_name(string);
} }
internal void internal void
thread_namef(char *fmt, ...) set_thread_namef(char *fmt, ...)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
String8 string = push_str8fv(scratch.arena, fmt, args); String8 string = push_str8fv(scratch.arena, fmt, args);
thread_name(string); set_thread_name(string);
va_end(args); va_end(args);
scratch_end(scratch); scratch_end(scratch);
} }
+4 -4
View File
@@ -4,9 +4,9 @@
#ifndef BASE_MARKUP_H #ifndef BASE_MARKUP_H
#define BASE_MARKUP_H #define BASE_MARKUP_H
internal void thread_namef(char *fmt, ...); internal void set_thread_name(String8 string);
internal void thread_name(String8 string); internal void set_thread_namef(char *fmt, ...);
#define ThreadNameF(...) (ProfThreadName(__VA_ARGS__), thread_namef(__VA_ARGS__)) #define ThreadNameF(...) (set_thread_namef(__VA_ARGS__))
#define ThreadName(str) (ProfThreadName("%s", str8_varg(str)), thread_name(str)) #define ThreadName(str) (set_thread_name(str))
#endif // BASE_MARKUP_H #endif // BASE_MARKUP_H
+422
View File
@@ -0,0 +1,422 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Type Info Lookups
internal Member *
member_from_name(Type *type, String8 name)
{
Member *member = &member_nil;
if(type->members != 0 && name.size != 0)
{
for(U64 idx = 0; idx < type->count; idx += 1)
{
if(str8_match(type->members[idx].name, name, 0))
{
member = &type->members[idx];
break;
}
}
}
return member;
}
////////////////////////////////
//~ rjf: Type Info * Instance Operations
internal void
typed_data_rebase_ptrs(Type *type, String8 data, void *base_ptr)
{
Temp scratch = scratch_begin(0, 0);
typedef struct RebaseTypeTask RebaseTypeTask;
struct RebaseTypeTask
{
RebaseTypeTask *next;
Type *type;
U8 *ptr;
};
RebaseTypeTask start_task = {0, type, data.str};
RebaseTypeTask *first_task = &start_task;
RebaseTypeTask *last_task = first_task;
for(RebaseTypeTask *t = first_task; t != 0; t = t->next)
{
switch(t->type->kind)
{
default:{}break;
case TypeKind_Ptr:
if(!(t->type->flags & TypeFlag_IsExternal))
{
*(U64 *)t->ptr = ((U64)(*(U8 **)t->ptr - (U8 *)base_ptr));
}break;
case TypeKind_Array:
{
for(U64 idx = 0; idx < t->type->count; idx += 1)
{
RebaseTypeTask *task = push_array(scratch.arena, RebaseTypeTask, 1);
task->type = t->type->direct;
task->ptr = t->ptr + t->type->direct->size * idx;
SLLQueuePush(first_task, last_task, task);
}
}break;
case TypeKind_Struct:
{
for(U64 idx = 0; idx < t->type->count; idx += 1)
{
Member *member = &t->type->members[idx];
RebaseTypeTask *task = push_array(scratch.arena, RebaseTypeTask, 1);
task->type = member->type;
task->ptr = t->ptr + member->value;
SLLQueuePush(first_task, last_task, task);
}
}break;
}
}
scratch_end(scratch);
}
internal String8
serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params)
{
Temp scratch = scratch_begin(&arena, 1);
String8List strings = {0};
str8_serial_begin(scratch.arena, &strings);
{
typedef struct SerializeTypeTask SerializeTypeTask;
struct SerializeTypeTask
{
SerializeTypeTask *next;
Type *type;
U64 count;
U8 *src;
Type *containing_type;
U8 *containing_ptr;
B32 is_post_header;
};
SerializeTypeTask start_task = {0, type, 1, data.str};
SerializeTypeTask *first_task = &start_task;
SerializeTypeTask *last_task = first_task;
for(SerializeTypeTask *t = first_task; t != 0; t = t->next)
{
switch(t->type->kind)
{
//- rjf: leaf -> just copy the data directly
default:
if(TypeKind_FirstLeaf <= t->type->kind && t->type->kind <= TypeKind_LastLeaf)
{
str8_serial_push_string(scratch.arena, &strings, str8(t->src, t->type->size*t->count));
}break;
//- rjf: pointers -> try to interpret/understand pointer & read/write, otherwise just write as plain data
case TypeKind_Ptr:
{
// rjf: unpack info about this pointer
TypeSerializePtrRefInfo *ptr_ref_info = 0;
for(U64 idx = 0; idx < params->ptr_ref_infos_count; idx += 1)
{
if(params->ptr_ref_infos[idx].type == t->type->direct)
{
ptr_ref_info = &params->ptr_ref_infos[idx];
break;
}
}
// rjf: indexification -> subtract base, divide direct size, write index
if(ptr_ref_info != 0 && ptr_ref_info->indexify_base != 0)
{
U64 ptr_value = 0;
MemoryCopy(&ptr_value, t->src, sizeof(ptr_value));
U64 ptr_write_value = ((U64)((U8 *)ptr_value - (U8 *)ptr_ref_info->indexify_base)/t->type->direct->size);
str8_serial_push_struct(scratch.arena, &strings, &ptr_write_value);
}
// rjf: offsetification -> subtract base, write offsets
else if(ptr_ref_info != 0 && ptr_ref_info->offsetify_base != 0)
{
U64 ptr_value = 0;
MemoryCopy(&ptr_value, t->src, sizeof(ptr_value));
U64 ptr_write_value = (U64)((U8 *)ptr_value - (U8 *)ptr_ref_info->offsetify_base);
str8_serial_push_struct(scratch.arena, &strings, &ptr_write_value);
}
// rjf: size-by-member (pre-header): still potentially dependent on other members which
// delimit our size, so push a new post-header task for pointer.
else if(t->type->count_delimiter_name.size != 0 && !t->is_post_header)
{
SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1);
task->type = t->type;
task->count = t->count;
task->src = t->src;
task->containing_type = t->containing_type;
task->containing_ptr = t->containing_ptr;
task->is_post_header = 1;
SLLQueuePush(first_task, last_task, task);
}
// rjf: size-by-member (post-header): all flat parts of containing struct have been
// iterated, so now we can read the size, & descend to new task to read pointer
// destination contents
else if(t->type->count_delimiter_name.size != 0 && t->is_post_header)
{
// rjf: determine count of this pointer
U64 count = 0;
{
Member *count_member = member_from_name(t->containing_type, t->type->count_delimiter_name);
MemoryCopy(&count, t->containing_ptr + count_member->value, count_member->type->size);
}
// rjf: push task
SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1);
task->type = t->type->direct;
task->count = count;
task->src = *(void **)t->src;
task->containing_type = t->containing_type;
task->containing_ptr = t->containing_ptr;
SLLQueuePush(first_task, last_task, task);
}
// rjf: catch-all: write pointer value
else
{
str8_serial_push_string(scratch.arena, &strings, str8(t->src, t->type->size*t->count));
}
}break;
//- rjf: arrays -> descend to underlying type, + count
case TypeKind_Array:
{
SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1);
task->type = t->type->direct;
task->count = t->type->count;
task->src = t->src;
task->containing_type = t->containing_type;
task->containing_ptr = t->containing_ptr;
SLLQueuePush(first_task, last_task, task);
}break;
//- rjf: struct -> descend to members
case TypeKind_Struct:
{
U64 off = 0;
for(U64 idx = 0; idx < t->count; idx += 1)
{
for(U64 member_idx = 0; member_idx < t->type->count; member_idx += 1)
{
if(t->type->members[member_idx].flags & MemberFlag_DoNotSerialize)
{
continue;
}
SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1);
task->type = t->type->members[member_idx].type;
task->count = 1;
task->src = t->src + idx*t->type->size + t->type->members[member_idx].value;
task->containing_type = t->type;
task->containing_ptr = t->src;
SLLQueuePush(first_task, last_task, task);
}
}
}break;
//- rjf: enum -> descend to basic type interpretation
case TypeKind_Enum:
{
SerializeTypeTask *task = push_array(scratch.arena, SerializeTypeTask, 1);
task->type = t->type->direct;
task->count = t->count;
task->src = t->src;
task->containing_type = t->containing_type;
task->containing_ptr = t->containing_ptr;
SLLQueuePush(first_task, last_task, task);
}break;
}
}
}
String8 result = str8_serial_end(arena, &strings);
scratch_end(scratch);
return result;
}
internal String8
deserialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params)
{
String8 result = {0};
result.size = type->size;
result.str = push_array(arena, U8, result.size);
{
Temp scratch = scratch_begin(&arena, 1);
typedef struct DeserializeTypeTask DeserializeTypeTask;
struct DeserializeTypeTask
{
DeserializeTypeTask *next;
Type *type;
U64 count;
U8 *dst;
Type *containing_type;
U8 *containing_ptr;
B32 is_post_header;
};
U64 read_off = 0;
DeserializeTypeTask start_task = {0, type, 1, result.str};
DeserializeTypeTask *first_task = &start_task;
DeserializeTypeTask *last_task = first_task;
for(DeserializeTypeTask *t = first_task; t != 0; t = t->next)
{
U8 *t_src = data.str + read_off;
switch(t->type->kind)
{
//- rjf: leaf -> copy the data directly
default:
if(TypeKind_FirstLeaf <= t->type->kind && t->type->kind <= TypeKind_LastLeaf)
{
MemoryCopy(t->dst, t_src, t->type->size*t->count);
read_off += t->type->size*t->count;
}break;
//- rjf: pointers -> try to interpret/understand pointer & read/write, otherwise skip
case TypeKind_Ptr:
{
// rjf: unpack info about this pointer
TypeSerializePtrRefInfo *ptr_ref_info = 0;
for(U64 idx = 0; idx < params->ptr_ref_infos_count; idx += 1)
{
if(params->ptr_ref_infos[idx].type == t->type->direct)
{
ptr_ref_info = &params->ptr_ref_infos[idx];
break;
}
}
// rjf: indexification -> add base, multiply direct size
if(ptr_ref_info != 0 && ptr_ref_info->indexify_base != 0)
{
U64 ptr_value = 0;
MemoryCopy(&ptr_value, t_src, sizeof(ptr_value));
U64 ptr_write_value = (ptr_value + (U64)ptr_ref_info->indexify_base) * t->type->direct->size;
MemoryCopy(t->dst, &ptr_write_value, sizeof(ptr_write_value));
read_off += sizeof(ptr_value);
}
// rjf: offsetification -> subtract base, write offsets
else if(ptr_ref_info != 0 && ptr_ref_info->offsetify_base != 0)
{
U64 ptr_value = 0;
MemoryCopy(&ptr_value, t_src, sizeof(ptr_value));
U64 ptr_write_value = ptr_value + (U64)ptr_ref_info->offsetify_base;
MemoryCopy(t->dst, &ptr_write_value, sizeof(ptr_write_value));
read_off += sizeof(ptr_value);
}
// rjf: size-by-member (pre-header): still potentially dependent on other members which
// delimit our size, so push a new post-header task for pointer.
else if(t->type->count_delimiter_name.size != 0 && !t->is_post_header)
{
DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1);
task->type = t->type;
task->count = t->count;
task->dst = t->dst;
task->containing_type = t->containing_type;
task->containing_ptr = t->containing_ptr;
task->is_post_header = 1;
SLLQueuePush(first_task, last_task, task);
}
// rjf: size-by-member (post-header): all flat parts of containing struct have been
// iterated, so now we can read the size, & descend to new task to read pointer
// destination contents
else if(t->type->count_delimiter_name.size != 0 && t->is_post_header)
{
// rjf: determine count of this pointer
U64 count = 0;
{
Member *count_member = member_from_name(t->containing_type, t->type->count_delimiter_name);
MemoryCopy(&count, t->containing_ptr + count_member->value, count_member->type->size);
}
// rjf: allocate buffer for pointer destination; write address into pointer value slot
U64 ptr_dest_buffer_size = (count+1)*t->type->direct->size;
U8 *ptr_dest_buffer = push_array(arena, U8, ptr_dest_buffer_size);
MemoryCopy(t->dst, &ptr_dest_buffer, sizeof(ptr_dest_buffer));
// rjf: push task
DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1);
task->type = t->type->direct;
task->count = count;
task->dst = ptr_dest_buffer;
task->containing_type = t->containing_type;
task->containing_ptr = t->containing_ptr;
SLLQueuePush(first_task, last_task, task);
}
// rjf: catch-all: read pointer value
else
{
MemoryCopy(t->dst, t_src, t->type->size*t->count);
read_off += t->type->size*t->count;
}
}break;
//- rjf: arrays -> descend to underlying type, + count
case TypeKind_Array:
{
DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1);
task->type = t->type->direct;
task->count = t->type->count;
task->dst = t->dst;
task->containing_type = t->containing_type;
task->containing_ptr = t->containing_ptr;
SLLQueuePush(first_task, last_task, task);
}break;
//- rjf: struct -> descend to members
case TypeKind_Struct:
{
for(U64 idx = 0; idx < t->count; idx += 1)
{
for(U64 member_idx = 0; member_idx < t->type->count; member_idx += 1)
{
if(t->type->members[member_idx].flags & MemberFlag_DoNotSerialize)
{
continue;
}
DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1);
task->type = t->type->members[member_idx].type;
task->count = 1;
task->dst = t->dst + idx*t->type->size + t->type->members[member_idx].value;
task->containing_type = t->type;
task->containing_ptr = t->dst;
SLLQueuePush(first_task, last_task, task);
}
}
}break;
//- rjf: enum -> descend to basic type interpretation
case TypeKind_Enum:
{
DeserializeTypeTask *task = push_array(scratch.arena, DeserializeTypeTask, 1);
task->type = t->type->direct;
task->count = t->count;
task->dst = t->dst;
task->containing_type = t->containing_type;
task->containing_ptr = t->containing_ptr;
SLLQueuePush(first_task, last_task, task);
}break;
}
}
if(params->advance_out != 0)
{
params->advance_out[0] = read_off;
}
scratch_end(scratch);
}
return result;
}
internal String8
deep_copy_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params)
{
Temp scratch = scratch_begin(&arena, 1);
String8 data_srlz = serialized_from_typed_data(scratch.arena, type, data, params);
String8 data_copy = deserialized_from_typed_data(arena, type, data_srlz, params);
scratch_end(scratch);
return data_copy;
}
+274
View File
@@ -0,0 +1,274 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef BASE_META_H
#define BASE_META_H
////////////////////////////////
//~ rjf: Meta Markup Features
#define EmbedFile(name, path)
#define TweakB32(name, default) (TWEAK_##name)
#define TweakF32(name, default, min, max) (TWEAK_##name)
////////////////////////////////
//~ rjf: Tweak Info Tables
typedef struct TweakB32Info TweakB32Info;
struct TweakB32Info
{
String8 name;
B32 default_value;
B32 *value_ptr;
};
typedef struct TweakF32Info TweakF32Info;
struct TweakF32Info
{
String8 name;
F32 default_value;
Rng1F32 value_range;
F32 *value_ptr;
};
typedef struct TweakB32InfoTable TweakB32InfoTable;
struct TweakB32InfoTable
{
TweakB32Info *v;
U64 count;
};
typedef struct TweakF32InfoTable TweakF32InfoTable;
struct TweakF32InfoTable
{
TweakF32Info *v;
U64 count;
};
typedef struct EmbedInfo EmbedInfo;
struct EmbedInfo
{
String8 name;
String8 *data;
U128 *hash;
};
typedef struct EmbedInfoTable EmbedInfoTable;
struct EmbedInfoTable
{
EmbedInfo *v;
U64 count;
};
////////////////////////////////
//~ rjf: Type Info Types
typedef enum TypeKind
{
TypeKind_Null,
// rjf: leaves
TypeKind_Void, TypeKind_FirstLeaf = TypeKind_Void,
TypeKind_U8,
TypeKind_U16,
TypeKind_U32,
TypeKind_U64,
TypeKind_S8,
TypeKind_S16,
TypeKind_S32,
TypeKind_S64,
TypeKind_B8,
TypeKind_B16,
TypeKind_B32,
TypeKind_B64,
TypeKind_F32,
TypeKind_F64, TypeKind_LastLeaf = TypeKind_F64,
// rjf: operators
TypeKind_Ptr,
TypeKind_Array,
// rjf: user-defined-types
TypeKind_Struct,
TypeKind_Union,
TypeKind_Enum,
TypeKind_COUNT
}
TypeKind;
typedef U32 TypeFlags;
enum
{
TypeFlag_IsExternal = (1<<0),
TypeFlag_IsPlainText = (1<<1),
TypeFlag_IsCodeText = (1<<2),
TypeFlag_IsPathText = (1<<3),
};
typedef U32 MemberFlags;
enum
{
MemberFlag_DoNotSerialize = (1<<0),
};
typedef struct Type Type;
typedef struct Member Member;
struct Member
{
String8 name;
String8 pretty_name;
Type *type;
U64 value;
MemberFlags flags;
};
typedef struct Type Type;
struct Type
{
TypeKind kind;
TypeFlags flags;
U64 size;
Type *direct;
String8 name;
String8 count_delimiter_name; // gathered from surrounding members, turns *->[1] into *->[N]
U64 count;
Member *members;
};
////////////////////////////////
//~ rjf: Type Serialization Parameters
typedef struct TypeSerializePtrRefInfo TypeSerializePtrRefInfo;
struct TypeSerializePtrRefInfo
{
Type *type; // pointers to this
void *indexify_base; // can be indexified using this
void *offsetify_base; // can be offsetified using this
void *nil_ptr; // is terminal if matching 0 or this
};
typedef struct TypeSerializeParams TypeSerializeParams;
struct TypeSerializeParams
{
U64 *advance_out;
TypeSerializePtrRefInfo *ptr_ref_infos;
U64 ptr_ref_infos_count;
};
////////////////////////////////
//~ rjf: Type Name -> Type Info
#define type(T) (&T##__type)
////////////////////////////////
//~ rjf: Type Info Table Initializer Helpers
#define member_lit_comp(S, ti, m, ...) {str8_lit_comp(#m), {0}, (ti), OffsetOf(S, m), __VA_ARGS__}
#define struct_members(S) read_only global Member S##__members[] =
#define struct_type(S, ...) read_only global Type S##__type = {TypeKind_Struct, 0, sizeof(S), &type_nil, str8_lit_comp(#S), {0}, ArrayCount(S##__members), S##__members, __VA_ARGS__}
#define named_struct_type(name, S, ...) read_only global Type name##__type = {TypeKind_Struct, 0, sizeof(S), &type_nil, str8_lit_comp(#name), {0}, ArrayCount(name##__members), name##__members, __VA_ARGS__}
#define ptr_type(name, ti, ...) read_only global Type name = {TypeKind_Ptr, 0, sizeof(void *), (ti), __VA_ARGS__}
////////////////////////////////
//~ rjf: Globals
read_only global Type type_nil = {TypeKind_Null, 0, 0, &type_nil};
read_only global Member member_nil = {{0}, {0}, &type_nil};
////////////////////////////////
//~ rjf: Built-In Types
//- rjf: leaves
read_only global Type void__type = {TypeKind_Void, 0, 0, &type_nil, str8_lit_comp("void")};
read_only global Type U8__type = {TypeKind_U8, 0, sizeof(U8), &type_nil, str8_lit_comp("U8")};
read_only global Type U16__type = {TypeKind_U16, 0, sizeof(U16), &type_nil, str8_lit_comp("U16")};
read_only global Type U32__type = {TypeKind_U32, 0, sizeof(U32), &type_nil, str8_lit_comp("U32")};
read_only global Type U64__type = {TypeKind_U64, 0, sizeof(U64), &type_nil, str8_lit_comp("U64")};
read_only global Type S8__type = {TypeKind_S8, 0, sizeof(S8), &type_nil, str8_lit_comp("S8")};
read_only global Type S16__type = {TypeKind_S16, 0, sizeof(S16), &type_nil, str8_lit_comp("S16")};
read_only global Type S32__type = {TypeKind_S32, 0, sizeof(S32), &type_nil, str8_lit_comp("S32")};
read_only global Type S64__type = {TypeKind_S64, 0, sizeof(S64), &type_nil, str8_lit_comp("S64")};
read_only global Type B8__type = {TypeKind_B8, 0, sizeof(B8), &type_nil, str8_lit_comp("B8")};
read_only global Type B16__type = {TypeKind_B16, 0, sizeof(B16), &type_nil, str8_lit_comp("B16")};
read_only global Type B32__type = {TypeKind_B32, 0, sizeof(B32), &type_nil, str8_lit_comp("B32")};
read_only global Type B64__type = {TypeKind_B64, 0, sizeof(B64), &type_nil, str8_lit_comp("B64")};
read_only global Type F32__type = {TypeKind_F32, 0, sizeof(F32), &type_nil, str8_lit_comp("F32")};
read_only global Type F64__type = {TypeKind_F64, 0, sizeof(F64), &type_nil, str8_lit_comp("F64")};
//- rjf: Rng1U64
struct_members(Rng1U64)
{
member_lit_comp(Rng1U64, type(U64), min),
member_lit_comp(Rng1U64, type(U64), max),
};
struct_type(Rng1U64);
//- rjf: String8
ptr_type(String8__str_ptr_type, type(U8), str8_lit_comp("size"));
struct_members(String8)
{
member_lit_comp(String8, &String8__str_ptr_type, str),
member_lit_comp(String8, type(U64), size),
};
struct_type(String8);
//- rjf: String8Node
extern Type String8Node__type;
Type String8Node__ptr_type = {TypeKind_Ptr, 0, sizeof(void *), &String8Node__type};
Member String8Node__members[] =
{
{str8_lit_comp("next"), {0}, &String8Node__ptr_type, OffsetOf(String8Node, next)},
{str8_lit_comp("string"), {0}, type(String8), OffsetOf(String8Node, string)},
};
Type String8Node__type =
{
TypeKind_Struct,
0,
sizeof(String8Node),
&type_nil,
str8_lit_comp("String8Node"),
{0},
ArrayCount(String8Node__members),
String8Node__members,
};
//- rjf: String8List
Member String8List__members[] =
{
{str8_lit_comp("first"), {0}, &String8Node__ptr_type, OffsetOf(String8List, first)},
{str8_lit_comp("last"), {0}, &String8Node__ptr_type, OffsetOf(String8List, last), MemberFlag_DoNotSerialize},
{str8_lit_comp("node_count"), {0}, type(U64), OffsetOf(String8List, node_count)},
{str8_lit_comp("total_size"), {0}, type(U64), OffsetOf(String8List, total_size)},
};
Type String8List__type =
{
TypeKind_Struct,
0,
sizeof(String8List),
&type_nil,
str8_lit_comp("String8List"),
{0},
ArrayCount(String8List__members),
String8List__members,
};
////////////////////////////////
//~ rjf: Type Info Lookups
internal Member *member_from_name(Type *type, String8 name);
#define EachMember(T, it) (Member *it = (type(T))->members; it != 0 && it < (type(T))->members + (type(T))->count; it += 1)
////////////////////////////////
//~ rjf: Type Info * Instance Operations
internal void typed_data_rebase_ptrs(Type *type, String8 data, void *base_ptr);
internal String8 serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params);
internal String8 deserialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params);
internal String8 deep_copy_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params);
#define struct_rebase_ptrs(T, ptr, base) typed_data_rebase_ptrs(type(T), str8_struct(ptr), (base))
#define serialized_from_struct(arena, T, ptr, ...) serialized_from_typed_data((arena), type(T), str8_struct(ptr), &(TypeSerializeParams){.ptr_ref_infos = 0, __VA_ARGS__})
#define struct_from_serialized(arena, T, string, ...) (T *)deserialized_from_typed_data((arena), type(T), (string), &(TypeSerializeParams){.ptr_ref_infos = 0, __VA_ARGS__}).str
#define deep_copy_from_struct(arena, T, ptr, ...) (T *)deep_copy_from_typed_data((arena), type(T), str8_struct(ptr), &(TypeSerializeParams){.ptr_ref_infos = 0, __VA_ARGS__}).str
#endif // BASE_META_H
+147 -11
View File
@@ -946,11 +946,11 @@ str8_array_from_list(Arena *arena, String8List *list)
{ {
String8Array array; String8Array array;
array.count = list->node_count; array.count = list->node_count;
array.strings = push_array_no_zero(arena, String8, array.count); array.v = push_array_no_zero(arena, String8, array.count);
U64 idx = 0; U64 idx = 0;
for(String8Node *n = list->first; n != 0; n = n->next, idx += 1) for(String8Node *n = list->first; n != 0; n = n->next, idx += 1)
{ {
array.strings[idx] = n->string; array.v[idx] = n->string;
} }
return array; return array;
} }
@@ -960,7 +960,7 @@ str8_array_reserve(Arena *arena, U64 count)
{ {
String8Array arr; String8Array arr;
arr.count = 0; arr.count = 0;
arr.strings = push_array(arena, String8, count); arr.v = push_array(arena, String8, count);
return arr; return arr;
} }
@@ -1281,7 +1281,7 @@ utf16_decode(U16 *str, U64 max){
result.codepoint = str[0]; result.codepoint = str[0];
result.inc = 1; result.inc = 1;
if (max > 1 && 0xD800 <= str[0] && str[0] < 0xDC00 && 0xDC00 <= str[1] && str[1] < 0xE000){ if (max > 1 && 0xD800 <= str[0] && str[0] < 0xDC00 && 0xDC00 <= str[1] && str[1] < 0xE000){
result.codepoint = ((str[0] - 0xD800) << 10) | (str[1] - 0xDC00) + 0x10000; result.codepoint = ((str[0] - 0xD800) << 10) | ((str[1] - 0xDC00) + 0x10000);
result.inc = 2; result.inc = 2;
} }
return(result); return(result);
@@ -1358,7 +1358,7 @@ str8_from_16(Arena *arena, String16 in){
size += utf8_encode(str + size, consume.codepoint); size += utf8_encode(str + size, consume.codepoint);
} }
str[size] = 0; str[size] = 0;
arena_put_back(arena, (cap - size)); arena_pop(arena, (cap - size));
return(str8(str, size)); return(str8(str, size));
} }
@@ -1375,7 +1375,7 @@ str16_from_8(Arena *arena, String8 in){
size += utf16_encode(str + size, consume.codepoint); size += utf16_encode(str + size, consume.codepoint);
} }
str[size] = 0; str[size] = 0;
arena_put_back(arena, (cap - size)*2); arena_pop(arena, (cap - size)*2);
return(str16(str, size)); return(str16(str, size));
} }
@@ -1390,7 +1390,7 @@ str8_from_32(Arena *arena, String32 in){
size += utf8_encode(str + size, *ptr); size += utf8_encode(str + size, *ptr);
} }
str[size] = 0; str[size] = 0;
arena_put_back(arena, (cap - size)); arena_pop(arena, (cap - size));
return(str8(str, size)); return(str8(str, size));
} }
@@ -1408,7 +1408,7 @@ str32_from_8(Arena *arena, String8 in){
size += 1; size += 1;
} }
str[size] = 0; str[size] = 0;
arena_put_back(arena, (cap - size)*4); arena_pop(arena, (cap - size)*4);
return(str32(str, size)); return(str32(str, size));
} }
@@ -1459,7 +1459,7 @@ string_from_operating_system(OperatingSystem os){
} }
internal String8 internal String8
string_from_architecture(Architecture arch){ string_from_arch(Arch arch){
local_persist String8 strings[] = { local_persist String8 strings[] = {
str8_lit_comp("Null"), str8_lit_comp("Null"),
str8_lit_comp("x64"), str8_lit_comp("x64"),
@@ -1468,7 +1468,7 @@ string_from_architecture(Architecture arch){
str8_lit_comp("arm32"), str8_lit_comp("arm32"),
}; };
String8 result = str8_lit("error"); String8 result = str8_lit("error");
if (arch < Architecture_COUNT){ if (arch < Arch_COUNT){
result = strings[arch]; result = strings[arch];
} }
return(result); return(result);
@@ -1566,7 +1566,143 @@ string_from_elapsed_time(Arena *arena, DateTime dt){
} }
//////////////////////////////// ////////////////////////////////
//~ rjf: Textual String Wrapping //~ rjf: Basic Text Indentation
internal String8
indented_from_string(Arena *arena, String8 string)
{
Temp scratch = scratch_begin(&arena, 1);
read_only local_persist U8 indentation_bytes[] = " ";
String8List indented_strings = {0};
S64 depth = 0;
S64 next_depth = 0;
U64 line_begin_off = 0;
for(U64 off = 0; off <= string.size; off += 1)
{
U8 byte = off<string.size ? string.str[off] : 0;
switch(byte)
{
default:{}break;
case '{':case '[':case '(':{next_depth += 1; next_depth = Max(0, next_depth);}break;
case '}':case ']':case ')':{next_depth -= 1; next_depth = Max(0, next_depth); depth = next_depth;}break;
case '\n':
case 0:
{
String8 line = str8_skip_chop_whitespace(str8_substr(string, r1u64(line_begin_off, off)));
if(line.size != 0)
{
str8_list_pushf(scratch.arena, &indented_strings, "%.*s%S\n", (int)depth*2, indentation_bytes, line);
}
if(line.size == 0 && indented_strings.node_count != 0 && off < string.size)
{
str8_list_pushf(scratch.arena, &indented_strings, "\n");
}
line_begin_off = off+1;
depth = next_depth;
}break;
}
}
String8 result = str8_list_join(arena, &indented_strings, 0);
scratch_end(scratch);
return result;
}
////////////////////////////////
//~ rjf: Text Escaping
internal String8
escaped_from_raw_str8(Arena *arena, String8 string)
{
Temp scratch = scratch_begin(&arena, 1);
String8List parts = {0};
U64 start_split_idx = 0;
for(U64 idx = 0; idx <= string.size; idx += 1)
{
U8 byte = (idx < string.size) ? string.str[idx] : 0;
B32 split = 1;
String8 separator_replace = {0};
switch(byte)
{
default:{split = 0;}break;
case 0: {}break;
case '\a': {separator_replace = str8_lit("\\a");}break;
case '\b': {separator_replace = str8_lit("\\b");}break;
case '\f': {separator_replace = str8_lit("\\f");}break;
case '\n': {separator_replace = str8_lit("\\n");}break;
case '\r': {separator_replace = str8_lit("\\r");}break;
case '\t': {separator_replace = str8_lit("\\t");}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;
}
if(split)
{
String8 substr = str8_substr(string, r1u64(start_split_idx, idx));
start_split_idx = idx+1;
str8_list_push(scratch.arena, &parts, substr);
if(separator_replace.size != 0)
{
str8_list_push(scratch.arena, &parts, separator_replace);
}
}
}
StringJoin join = {0};
String8 result = str8_list_join(arena, &parts, &join);
scratch_end(scratch);
return result;
}
internal String8
raw_from_escaped_str8(Arena *arena, String8 string)
{
Temp scratch = scratch_begin(&arena, 1);
String8List strs = {0};
U64 start = 0;
for(U64 idx = 0; idx <= string.size; idx += 1)
{
if(idx == string.size || string.str[idx] == '\\' || string.str[idx] == '\r')
{
String8 str = str8_substr(string, r1u64(start, idx));
if(str.size != 0)
{
str8_list_push(scratch.arena, &strs, str);
}
start = idx+1;
}
if(idx < string.size && string.str[idx] == '\\')
{
U8 next_char = string.str[idx+1];
U8 replace_byte = 0;
switch(next_char)
{
default:{}break;
case 'a': replace_byte = 0x07; break;
case 'b': replace_byte = 0x08; break;
case 'e': replace_byte = 0x1b; break;
case 'f': replace_byte = 0x0c; break;
case 'n': replace_byte = 0x0a; break;
case 'r': replace_byte = 0x0d; break;
case 't': replace_byte = 0x09; break;
case 'v': replace_byte = 0x0b; break;
case '\\':replace_byte = '\\'; break;
case '\'':replace_byte = '\''; break;
case '"': replace_byte = '"'; break;
case '?': replace_byte = '?'; break;
}
String8 replace_string = push_str8_copy(scratch.arena, str8(&replace_byte, 1));
str8_list_push(scratch.arena, &strs, replace_string);
idx += 1;
start += 1;
}
}
String8 result = str8_list_join(arena, &strs, 0);
scratch_end(scratch);
return result;
}
////////////////////////////////
//~ rjf: Text Wrapping
internal String8List internal String8List
wrapped_lines_from_string(Arena *arena, String8 string, U64 first_line_max_width, U64 max_width, U64 wrap_indent) wrapped_lines_from_string(Arena *arena, String8 string, U64 first_line_max_width, U64 max_width, U64 wrap_indent)
+15 -3
View File
@@ -63,7 +63,7 @@ struct String8List
typedef struct String8Array String8Array; typedef struct String8Array String8Array;
struct String8Array struct String8Array
{ {
String8 *strings; String8 *v;
U64 count; U64 count;
}; };
@@ -86,6 +86,7 @@ enum
typedef enum PathStyle typedef enum PathStyle
{ {
PathStyle_Null,
PathStyle_Relative, PathStyle_Relative,
PathStyle_WindowsAbsolute, PathStyle_WindowsAbsolute,
PathStyle_UnixAbsolute, PathStyle_UnixAbsolute,
@@ -315,7 +316,7 @@ internal String32 str32_from_8(Arena *arena, String8 in);
internal String8 string_from_dimension(Dimension dimension); internal String8 string_from_dimension(Dimension dimension);
internal String8 string_from_side(Side side); internal String8 string_from_side(Side side);
internal String8 string_from_operating_system(OperatingSystem os); internal String8 string_from_operating_system(OperatingSystem os);
internal String8 string_from_architecture(Architecture arch); internal String8 string_from_arch(Arch arch);
//////////////////////////////// ////////////////////////////////
//~ rjf: Time Types -> String //~ rjf: Time Types -> String
@@ -327,7 +328,18 @@ internal String8 push_file_name_date_time_string(Arena *arena, DateTime *date_ti
internal String8 string_from_elapsed_time(Arena *arena, DateTime dt); internal String8 string_from_elapsed_time(Arena *arena, DateTime dt);
//////////////////////////////// ////////////////////////////////
//~ rjf: Textual String Wrapping //~ rjf: Basic Text Indentation
internal String8 indented_from_string(Arena *arena, String8 string);
////////////////////////////////
//~ rjf: Text Escaping
internal String8 escaped_from_raw_str8(Arena *arena, String8 string);
internal String8 raw_from_escaped_str8(Arena *arena, String8 string);
////////////////////////////////
//~ rjf: Text Wrapping
internal String8List wrapped_lines_from_string(Arena *arena, String8 string, U64 first_line_max_width, U64 max_width, U64 wrap_indent); internal String8List wrapped_lines_from_string(Arena *arena, String8 string, U64 first_line_max_width, U64 max_width, U64 wrap_indent);
+2 -2
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 count); internal Arena* tctx_get_scratch(Arena **conflicts, U64 countt);
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);
@@ -38,4 +38,4 @@ internal void tctx_read_srcloc(char **file_name, U64 *line_number);
#define scratch_begin(conflicts, count) temp_begin(tctx_get_scratch((conflicts), (count))) #define scratch_begin(conflicts, count) temp_begin(tctx_get_scratch((conflicts), (count)))
#define scratch_end(scratch) temp_end(scratch) #define scratch_end(scratch) temp_end(scratch)
#endif //BASE_THREAD_CONTEXT_H #endif // BASE_THREAD_CONTEXT_H
+337 -197
View File
@@ -7,21 +7,44 @@
#include "generated/codeview.meta.c" #include "generated/codeview.meta.c"
//////////////////////////////// ////////////////////////////////
//~ CodeView Common Functions //~ CodeView Common Decoding Helper Functions
internal U64
cv_hash_from_string(String8 string)
{
U64 result = 5381;
for(U64 i = 0; i < string.size; i += 1)
{
result = ((result << 5) + result) + string.str[i];
}
return result;
}
internal U64
cv_hash_from_item_id(CV_ItemId item_id)
{
U64 result = cv_hash_from_string(str8_struct(&item_id));
return result;
}
internal CV_NumericParsed internal CV_NumericParsed
cv_numeric_from_data_range(U8 *first, U8 *opl){ cv_numeric_from_data_range(U8 *first, U8 *opl)
{
CV_NumericParsed result = {0}; CV_NumericParsed result = {0};
if (first + 2 <= opl){ if(first + 2 <= opl)
{
U16 x = *(U16*)first; U16 x = *(U16*)first;
if (x < 0x8000){ if(x < 0x8000)
{
result.kind = CV_NumericKind_USHORT; result.kind = CV_NumericKind_USHORT;
result.val = first; result.val = first;
result.encoded_size = 2; result.encoded_size = 2;
} }
else{ else
{
U64 val_size = 0; U64 val_size = 0;
switch (x){ switch(x)
{
case CV_NumericKind_CHAR: val_size = 1; break; case CV_NumericKind_CHAR: val_size = 1; break;
case CV_NumericKind_SHORT: case CV_NumericKind_SHORT:
case CV_NumericKind_USHORT: val_size = 2; break; case CV_NumericKind_USHORT: val_size = 2; break;
@@ -46,21 +69,30 @@ cv_numeric_from_data_range(U8 *first, U8 *opl){
case CV_NumericKind_UTF8STRING:val_size = 0; break; // TODO: ??? case CV_NumericKind_UTF8STRING:val_size = 0; break; // TODO: ???
case CV_NumericKind_FLOAT16: val_size = 2; break; case CV_NumericKind_FLOAT16: val_size = 2; break;
} }
if(first + 2 + val_size <= opl)
if (first + 2 + val_size <= opl){ {
result.kind = x; result.kind = x;
result.val = (first + 2); result.val = (first + 2);
result.encoded_size = 2 + val_size; result.encoded_size = 2 + val_size;
} }
} }
} }
return(result); return result;
}
internal U64
cv_read_numeric(String8 data, U64 offset, CV_NumericParsed *out)
{
*out = cv_numeric_from_data_range(data.str + offset, data.str + data.size);
return out->encoded_size;
} }
internal B32 internal B32
cv_numeric_fits_in_u64(CV_NumericParsed *num){ cv_numeric_fits_in_u64(CV_NumericParsed *num)
{
B32 result = 0; B32 result = 0;
switch (num->kind){ switch(num->kind)
{
case CV_NumericKind_USHORT: case CV_NumericKind_USHORT:
case CV_NumericKind_ULONG: case CV_NumericKind_ULONG:
case CV_NumericKind_UQUADWORD: case CV_NumericKind_UQUADWORD:
@@ -68,13 +100,15 @@ cv_numeric_fits_in_u64(CV_NumericParsed *num){
result = 1; result = 1;
}break; }break;
} }
return(result); return result;
} }
internal B32 internal B32
cv_numeric_fits_in_s64(CV_NumericParsed *num){ cv_numeric_fits_in_s64(CV_NumericParsed *num)
{
B32 result = 0; B32 result = 0;
switch (num->kind){ switch(num->kind)
{
case CV_NumericKind_CHAR: case CV_NumericKind_CHAR:
case CV_NumericKind_SHORT: case CV_NumericKind_SHORT:
case CV_NumericKind_LONG: case CV_NumericKind_LONG:
@@ -83,111 +117,169 @@ cv_numeric_fits_in_s64(CV_NumericParsed *num){
result = 1; result = 1;
}break; }break;
} }
return(result); return result;
} }
internal B32 internal B32
cv_numeric_fits_in_f64(CV_NumericParsed *num){ cv_numeric_fits_in_f64(CV_NumericParsed *num)
{
B32 result = 0; B32 result = 0;
switch (num->kind){ switch(num->kind)
{
case CV_NumericKind_FLOAT32: case CV_NumericKind_FLOAT32:
case CV_NumericKind_FLOAT64: case CV_NumericKind_FLOAT64:
{ {
result = 1; result = 1;
}break; }break;
} }
return(result); return result;
} }
internal U64 internal U64
cv_u64_from_numeric(CV_NumericParsed *num){ cv_u64_from_numeric(CV_NumericParsed *num)
{
U64 result = 0; U64 result = 0;
switch (num->kind){ switch(num->kind)
case CV_NumericKind_USHORT:
{ {
result = *(U16*)num->val; case CV_NumericKind_USHORT: {result = *(U16*)num->val;}break;
}break; case CV_NumericKind_ULONG: {result = *(U32*)num->val;}break;
case CV_NumericKind_UQUADWORD:{result = *(U64*)num->val;}break;
case CV_NumericKind_ULONG:
{
result = *(U32*)num->val;
}break;
case CV_NumericKind_UQUADWORD:
{
result = *(U64*)num->val;
}break;
} }
return(result); return result;
} }
internal S64 internal S64
cv_s64_from_numeric(CV_NumericParsed *num){ cv_s64_from_numeric(CV_NumericParsed *num)
{
S64 result = 0; S64 result = 0;
switch (num->kind){ switch(num->kind)
case CV_NumericKind_CHAR:
{ {
result = *(S8*)num->val; case CV_NumericKind_CHAR: {result = *(S8*)num->val;}break;
}break; case CV_NumericKind_SHORT: {result = *(S16*)num->val;}break;
case CV_NumericKind_LONG: {result = *(S32*)num->val;}break;
case CV_NumericKind_SHORT: case CV_NumericKind_QUADWORD: {result = *(S64*)num->val;}break;
{
result = *(S16*)num->val;
}break;
case CV_NumericKind_LONG:
{
result = *(S32*)num->val;
}break;
case CV_NumericKind_QUADWORD:
{
result = *(S64*)num->val;
}break;
} }
return(result); return(result);
} }
internal F64 internal F64
cv_f64_from_numeric(CV_NumericParsed *num){ cv_f64_from_numeric(CV_NumericParsed *num)
{
F64 result = 0; F64 result = 0;
switch (num->kind){ switch(num->kind)
case CV_NumericKind_FLOAT32:
{ {
result = *(F32*)num->val; case CV_NumericKind_FLOAT32:{result = *(F32*)num->val;}break;
}break; case CV_NumericKind_FLOAT64:{result = *(F64*)num->val;}break;
case CV_NumericKind_FLOAT64:
{
result = *(F64*)num->val;
}break;
} }
return(result); return(result);
} }
internal U64
cv_decode_inline_annot_u32(String8 data, U64 offset, U32 *out_value)
{
U64 cursor = offset;
// rjf: read header
U8 header = 0;
cursor += str8_deserial_read_struct(data, cursor, &header);
// rjf: decode value
U32 value = 0;
{
// 1 byte
if((header & 0x80) == 0)
{
value = header;
}
// 2 bytes
else if((header & 0xC0) == 0x80 && cursor+1 <= data.size)
{
U8 second_byte;
cursor += str8_deserial_read_struct(data, cursor, &second_byte);
value = ((header & 0x3F) << 8) | second_byte;
}
// 4 bytes
else if((header & 0xE0) == 0xC0 && cursor+3 <= data.size)
{
U8 second_byte, third_byte, fourth_byte;
cursor += str8_deserial_read_struct(data, cursor, &second_byte);
cursor += str8_deserial_read_struct(data, cursor, &third_byte);
cursor += str8_deserial_read_struct(data, cursor, &fourth_byte);
value = (((U32)header & 0x1F) << 24) | ((U32)second_byte << 16) | ((U32)third_byte << 8) | (U32)fourth_byte;
}
// bad encode
else if((header & 0xE0) == 0xE0)
{
value = max_U32;
}
}
// rjf: output results
if(out_value)
{
*out_value = value;
}
U64 read_size = cursor - offset;
return read_size;
}
internal U64
cv_decode_inline_annot_s32(String8 data, U64 offset, S32 *out_value)
{
U32 value;
U64 read_size = cv_decode_inline_annot_u32(data, offset, &value);
if(value & 1)
{
value = -(value >> 1);
}
else
{
value = value >> 1;
}
*out_value = (S32)value;
return read_size;
}
internal S32
cv_inline_annot_signed_from_unsigned_operand(U32 value)
{
if(value & 1)
{
value = -(value >> 1);
}
else
{
value = value >> 1;
}
S32 result = (S32)value;
return result;
}
//////////////////////////////// ////////////////////////////////
//~ CodeView Sym Parser Functions //~ CodeView Parsing Functions
//- the first pass parser //- rjf: record range stream parsing
internal CV_RecRangeStream* internal CV_RecRangeStream*
cv_rec_range_stream_from_data(Arena *arena, String8 sym_data, U64 sym_align){ cv_rec_range_stream_from_data(Arena *arena, String8 sym_data, U64 sym_align)
{
Assert(1 <= sym_align && IsPow2OrZero(sym_align)); Assert(1 <= sym_align && IsPow2OrZero(sym_align));
CV_RecRangeStream *result = push_array(arena, CV_RecRangeStream, 1); CV_RecRangeStream *result = push_array(arena, CV_RecRangeStream, 1);
U8 *data = sym_data.str; U8 *data = sym_data.str;
U64 cursor = 0; U64 cursor = 0;
U64 cap = sym_data.size; U64 cap = sym_data.size;
for (;cursor + sizeof(CV_RecHeader) <= cap;){ for(;cursor + sizeof(CV_RecHeader) <= cap;)
{
// setup a new chunk // setup a new chunk
arena_push_align(arena, 64); CV_RecRangeChunk *cur_chunk = push_array_aligned(arena, CV_RecRangeChunk, 1, 64);
CV_RecRangeChunk *cur_chunk = cv_rec_range_stream_push_chunk(arena, result); SLLQueuePush(result->first_chunk, result->last_chunk, cur_chunk);
U64 partial_count = 0; U64 partial_count = 0;
for (;partial_count < CV_REC_RANGE_CHUNK_SIZE && cursor + sizeof(CV_RecHeader) <= cap; for(;partial_count < CV_REC_RANGE_CHUNK_SIZE && cursor + sizeof(CV_RecHeader) <= cap; partial_count += 1)
partial_count += 1){ {
// compute cap // compute cap
CV_RecHeader *hdr = (CV_RecHeader*)(data + cursor); CV_RecHeader *hdr = (CV_RecHeader*)(data + cursor);
U64 symbol_cap_unclamped = cursor + 2 + hdr->size; U64 symbol_cap_unclamped = cursor + 2 + hdr->size;
@@ -201,110 +293,110 @@ cv_rec_range_stream_from_data(Arena *arena, String8 sym_data, U64 sym_align){
U32 next_pos = AlignPow2(symbol_cap, sym_align); U32 next_pos = AlignPow2(symbol_cap, sym_align);
cursor = next_pos; cursor = next_pos;
} }
result->total_count += partial_count; result->total_count += partial_count;
} }
return result;
return(result);
} }
//- sym internal CV_RecRangeArray
cv_rec_range_array_from_stream(Arena *arena, CV_RecRangeStream *stream)
{
U64 total_count = stream->total_count;
CV_RecRange *ranges = push_array_no_zero_aligned(arena, CV_RecRange, total_count, 8);
U64 idx = 0;
for(CV_RecRangeChunk *chunk = stream->first_chunk; chunk != 0; chunk = chunk->next)
{
U64 copy_count_raw = total_count - idx;
U64 copy_count = ClampTop(copy_count_raw, CV_REC_RANGE_CHUNK_SIZE);
MemoryCopy(ranges + idx, chunk->ranges, copy_count*sizeof(CV_RecRange));
idx += copy_count;
}
CV_RecRangeArray result = {0};
result.ranges = ranges;
result.count = total_count;
return result;
}
internal CV_SymParsed* //- rjf: sym stream parsing
cv_sym_from_data(Arena *arena, String8 sym_data, U64 sym_align){
internal CV_SymParsed *
cv_sym_from_data(Arena *arena, String8 sym_data, U64 sym_align)
{
Assert(1 <= sym_align && IsPow2OrZero(sym_align)); Assert(1 <= sym_align && IsPow2OrZero(sym_align));
ProfBegin("cv_sym_from_data"); ProfBeginFunction();
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
// gather up symbols //- rjf: gather symbols
CV_RecRangeStream *stream = cv_rec_range_stream_from_data(scratch.arena, sym_data, sym_align); CV_RecRangeStream *stream = cv_rec_range_stream_from_data(scratch.arena, sym_data, sym_align);
// convert to result //- rjf: convert to result, fill basics
CV_SymParsed *result = push_array(arena, CV_SymParsed, 1); CV_SymParsed *result = push_array(arena, CV_SymParsed, 1);
result->data = sym_data; result->data = sym_data;
result->sym_align = sym_align; result->sym_align = sym_align;
result->sym_ranges = cv_rec_range_array_from_stream(arena, stream); result->sym_ranges = cv_rec_range_array_from_stream(arena, stream);
cv_sym_top_level_info_from_syms(arena, sym_data, &result->sym_ranges, &result->info);
scratch_end(scratch); //- rjf: extract top-level-info
{
ProfEnd(); CV_RecRange *range = result->sym_ranges.ranges;
CV_RecRange *opl = range + result->sym_ranges.count;
return(result); for(;range < opl; range += 1)
} {
internal void
cv_sym_top_level_info_from_syms(Arena *arena, String8 sym_data,
CV_RecRangeArray *ranges,
CV_SymTopLevelInfo *info_out){
MemoryZeroStruct(info_out);
CV_RecRange *range = ranges->ranges;
CV_RecRange *opl = range + ranges->count;
for (; range < opl; range += 1){
U8 *first = sym_data.str + range->off + 2; U8 *first = sym_data.str + range->off + 2;
U64 cap = range->hdr.size - 2; U64 cap = range->hdr.size - 2;
switch(range->hdr.kind)
switch (range->hdr.kind){ {
case CV_SymKind_COMPILE: case CV_SymKind_COMPILE:
if(sizeof(CV_SymCompile) <= cap)
{ {
if (sizeof(CV_SymCompile) <= cap){
CV_SymCompile *compile = (CV_SymCompile*)first; CV_SymCompile *compile = (CV_SymCompile*)first;
String8 ver_str = str8_cstring_capped((char*)(compile + 1), (char *)(first + cap)); String8 ver_str = str8_cstring_capped((char*)(compile + 1), (char *)(first + cap));
result->info.arch = compile->machine;
info_out->arch = compile->machine; result->info.language = CV_CompileFlags_ExtractLanguage(compile->flags);;
info_out->language = CV_CompileFlags_ExtractLanguage(compile->flags);; result->info.compiler_name = ver_str;
info_out->compiler_name = ver_str;
}
}break; }break;
case CV_SymKind_COMPILE2: case CV_SymKind_COMPILE2:
if(sizeof(CV_SymCompile2) <= cap)
{ {
if (sizeof(CV_SymCompile2) <= cap){
CV_SymCompile2 *compile2 = (CV_SymCompile2*)first; CV_SymCompile2 *compile2 = (CV_SymCompile2*)first;
String8 ver_str = str8_cstring_capped((char*)(compile2 + 1), (char*)(first + cap)); String8 ver_str = str8_cstring_capped((char*)(compile2 + 1), (char*)(first + cap));
String8 compiler_name = push_str8f(arena, "%.*s %u.%u.%u", String8 compiler_name = push_str8f(arena, "%.*s %u.%u.%u",
str8_varg(ver_str), str8_varg(ver_str),
compile2->ver_major, compile2->ver_major,
compile2->ver_minor, compile2->ver_minor,
compile2->ver_build); compile2->ver_build);
result->info.arch = compile2->machine;
info_out->arch = compile2->machine; result->info.language = CV_Compile2Flags_ExtractLanguage(compile2->flags);;
info_out->language = CV_Compile2Flags_ExtractLanguage(compile2->flags);; result->info.compiler_name = compiler_name;
info_out->compiler_name = compiler_name;
}
}break; }break;
case CV_SymKind_COMPILE3: case CV_SymKind_COMPILE3:
if(sizeof(CV_SymCompile3) <= cap)
{ {
if (sizeof(CV_SymCompile3) <= cap){
CV_SymCompile3 *compile3 = (CV_SymCompile3*)first; CV_SymCompile3 *compile3 = (CV_SymCompile3*)first;
String8 ver_str = str8_cstring_capped((char*)(compile3 + 1), (char *)(first + cap)); String8 ver_str = str8_cstring_capped((char*)(compile3 + 1), (char *)(first + cap));
String8 compiler_name = push_str8f(arena, "%.*s %u.%u.%u", String8 compiler_name = push_str8f(arena, "%.*s %u.%u.%u",
str8_varg(ver_str), str8_varg(ver_str),
compile3->ver_major, compile3->ver_major,
compile3->ver_minor, compile3->ver_minor,
compile3->ver_build); compile3->ver_build);
result->info.arch = compile3->machine;
info_out->arch = compile3->machine; result->info.language = CV_Compile3Flags_ExtractLanguage(compile3->flags);;
info_out->language = CV_Compile3Flags_ExtractLanguage(compile3->flags);; result->info.compiler_name = compiler_name;
info_out->compiler_name = compiler_name;
}
}break; }break;
} }
} }
}
scratch_end(scratch);
ProfEnd();
return result;
} }
//- leaf //- rjf: leaf stream parsing
internal CV_LeafParsed*
cv_leaf_from_data(Arena *arena, String8 leaf_data, CV_TypeId itype_first){
ProfBegin("cv_leaf_from_data");
internal CV_LeafParsed *
cv_leaf_from_data(Arena *arena, String8 leaf_data, CV_TypeId itype_first)
{
ProfBeginFunction();
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
// gather up symbols // gather up symbols
@@ -318,57 +410,31 @@ cv_leaf_from_data(Arena *arena, String8 leaf_data, CV_TypeId itype_first){
result->leaf_ranges = cv_rec_range_array_from_stream(arena, stream); result->leaf_ranges = cv_rec_range_array_from_stream(arena, stream);
scratch_end(scratch); scratch_end(scratch);
ProfEnd(); ProfEnd();
return result;
return(result);
}
//- range streams
internal CV_RecRangeChunk*
cv_rec_range_stream_push_chunk(Arena *arena, CV_RecRangeStream *stream){
CV_RecRangeChunk *result = push_array_no_zero(arena, CV_RecRangeChunk, 1);
SLLQueuePush(stream->first_chunk, stream->last_chunk, result);
return(result);
}
internal CV_RecRangeArray
cv_rec_range_array_from_stream(Arena *arena, CV_RecRangeStream *stream){
U64 total_count = stream->total_count;
CV_RecRange *ranges = push_array_no_zero(arena, CV_RecRange, total_count);
U64 idx = 0;
for (CV_RecRangeChunk *chunk = stream->first_chunk;
chunk != 0;
chunk = chunk->next){
U64 copy_count_raw = total_count - idx;
U64 copy_count = ClampTop(copy_count_raw, CV_REC_RANGE_CHUNK_SIZE);
MemoryCopy(ranges + idx, chunk->ranges, copy_count*sizeof(CV_RecRange));
idx += copy_count;
}
CV_RecRangeArray result = {0};
result.ranges = ranges;
result.count = total_count;
return(result);
} }
//////////////////////////////// ////////////////////////////////
//~ CodeView C13 Parser Functions //~ CodeView C13 Parser Functions
internal CV_C13Parsed* internal CV_C13Parsed *
cv_c13_from_data(Arena *arena, String8 c13_data, PDB_Strtbl *strtbl, PDB_CoffSectionArray *sections){ cv_c13_parsed_from_data(Arena *arena, String8 c13_data, String8 strtbl, COFF_SectionHeaderArray sections)
ProfBegin("cv_c13_from_data"); {
ProfBeginFunction();
// gather c13 data //////////////////////////////
//- rjf: gather c13 sub-sections
//
CV_C13SubSectionNode *file_chksms = 0; CV_C13SubSectionNode *file_chksms = 0;
CV_C13SubSectionNode *first = 0; CV_C13SubSectionNode *first = 0;
CV_C13SubSectionNode *last = 0; CV_C13SubSectionNode *last = 0;
U64 count = 0; U64 count = 0;
{ {
U32 cursor = 0; U32 cursor = 0;
for (; cursor + sizeof(CV_C13_SubSectionHeader) <= c13_data.size;){ for(; cursor + sizeof(CV_C13SubSectionHeader) <= c13_data.size;)
{
// read header // read header
CV_C13_SubSectionHeader *hdr = (CV_C13_SubSectionHeader*)(c13_data.str + cursor); CV_C13SubSectionHeader *hdr = (CV_C13SubSectionHeader*)(c13_data.str + cursor);
// get sub section info // get sub section info
U32 sub_section_off = cursor + sizeof(*hdr); U32 sub_section_off = cursor + sizeof(*hdr);
@@ -378,15 +444,16 @@ cv_c13_from_data(Arena *arena, String8 c13_data, PDB_Strtbl *strtbl, PDB_CoffSec
U32 sub_section_size = after_sub_section_off - sub_section_off; U32 sub_section_size = after_sub_section_off - sub_section_off;
// emit sub section // emit sub section
if (!(hdr->kind & CV_C13_SubSectionKind_IgnoreFlag)){ if(!(hdr->kind & CV_C13SubSectionKind_IgnoreFlag))
{
CV_C13SubSectionNode *node = push_array(arena, CV_C13SubSectionNode, 1); CV_C13SubSectionNode *node = push_array(arena, CV_C13SubSectionNode, 1);
SLLQueuePush(first, last, node); SLLQueuePush(first, last, node);
count += 1; count += 1;
node->kind = hdr->kind; node->kind = hdr->kind;
node->off = sub_section_off; node->off = sub_section_off;
node->size = sub_section_size; node->size = sub_section_size;
if(hdr->kind == CV_C13SubSectionKind_FileChksms)
if (hdr->kind == CV_C13_SubSectionKind_FileChksms){ {
file_chksms = node; file_chksms = node;
} }
} }
@@ -396,79 +463,91 @@ cv_c13_from_data(Arena *arena, String8 c13_data, PDB_Strtbl *strtbl, PDB_CoffSec
} }
} }
// parse each section //////////////////////////////
for (CV_C13SubSectionNode *node = first; //- rjf: parse each sub-section
//
U64 inlinee_lines_parsed_slots_count = 4096;
CV_C13InlineeLinesParsedNode **inlinee_lines_parsed_slots = push_array(arena, CV_C13InlineeLinesParsedNode *, inlinee_lines_parsed_slots_count);
for(CV_C13SubSectionNode *node = first;
node != 0; node != 0;
node = node->next){ node = node->next)
{
U8 *first = c13_data.str + node->off; U8 *first = c13_data.str + node->off;
U32 cap = node->size; U32 cap = node->size;
switch(node->kind)
{
default:{}break;
switch (node->kind){ //////////////////////////
case CV_C13_SubSectionKind_Lines: //- rjf: line info sub-section
//
case CV_C13SubSectionKind_Lines:
if(sizeof(CV_C13SubSecLinesHeader) <= cap)
{ {
// read header // read header
if (sizeof(CV_C13_SubSecLinesHeader) <= cap){
U32 read_off = 0; U32 read_off = 0;
U64 read_off_opl = node->size; U64 read_off_opl = node->size;
CV_C13_SubSecLinesHeader *hdr = (CV_C13_SubSecLinesHeader*)(first + read_off); CV_C13SubSecLinesHeader *hdr = (CV_C13SubSecLinesHeader*)(first + read_off);
read_off += sizeof(*hdr); read_off += sizeof(*hdr);
// extract top level info // extract top level info
U32 sec_idx = hdr->sec; U32 sec_idx = hdr->sec;
B32 has_cols = !!(hdr->flags & CV_C13_SubSecLinesFlag_HasColumns); B32 has_cols = !!(hdr->flags & CV_C13SubSecLinesFlag_HasColumns);
U64 secrel_off = hdr->sec_off; U64 secrel_off = hdr->sec_off;
U64 secrel_opl = secrel_off + hdr->len; U64 secrel_opl = secrel_off + hdr->len;
U64 sec_base_off = sections->sections[sec_idx - 1].voff; U64 sec_base_off = sections.v[sec_idx - 1].voff;
// rjf: bad section index -> skip // rjf: bad section index -> skip
if(sec_idx < 1 || sections->count < sec_idx) if(sec_idx < 1 || sections.count < sec_idx)
{ {
continue; continue;
} }
// read files // read files
for(;read_off+sizeof(CV_C13_File) <= read_off_opl;) for(;read_off+sizeof(CV_C13File) <= read_off_opl;)
{ {
// rjf: grab next file header // rjf: grab next file header
CV_C13_File *file = (CV_C13_File*)(first + read_off); CV_C13File *file = (CV_C13File*)(first + read_off);
U32 file_off = file->file_off; U32 file_off = file->file_off;
U32 line_count_unclamped = file->num_lines; U32 line_count_unclamped = file->num_lines;
U32 block_size = file->block_size; U32 block_size = file->block_size;
// file_name from file_off // file_name from file_off
String8 file_name = {0}; String8 file_name = {0};
if (file_off + sizeof(CV_C13_Checksum) <= file_chksms->size){ if(file_off + sizeof(CV_C13Checksum) <= file_chksms->size)
CV_C13_Checksum *checksum = (CV_C13_Checksum*)(c13_data.str + file_chksms->off + file_off); {
CV_C13Checksum *checksum = (CV_C13Checksum*)(c13_data.str + file_chksms->off + file_off);
U32 name_off = checksum->name_off; U32 name_off = checksum->name_off;
file_name = pdb_strtbl_string_from_off(strtbl, name_off); file_name = str8_cstring_capped((char*)(strtbl.str + name_off),
(char*)(strtbl.str + strtbl.size));
} }
// array layouts // array layouts
U32 line_item_size = sizeof(CV_C13_Line); U32 line_item_size = sizeof(CV_C13Line);
if (has_cols){ if (has_cols){
line_item_size += sizeof(CV_C13_Column); line_item_size += sizeof(CV_C13Column);
} }
U32 line_array_off = read_off + sizeof(*file); U32 line_array_off = read_off + sizeof(*file);
U32 line_count_max = (read_off_opl - line_array_off) / line_item_size; U32 line_count_max = (read_off_opl - line_array_off) / line_item_size;
U32 line_count = ClampTop(line_count_unclamped, line_count_max); U32 line_count = ClampTop(line_count_unclamped, line_count_max);
U32 col_array_off = line_array_off + line_count*sizeof(CV_C13_Line); U32 col_array_off = line_array_off + line_count*sizeof(CV_C13Line);
// parse lines // parse lines
U64 *voffs = push_array_no_zero(arena, U64, line_count + 1); U64 *voffs = push_array_no_zero(arena, U64, line_count + 1);
U32 *line_nums = push_array_no_zero(arena, U32, line_count); U32 *line_nums = push_array_no_zero(arena, U32, line_count);
{ {
CV_C13_Line *line_ptr = (CV_C13_Line*)(first + line_array_off); CV_C13Line *line_ptr = (CV_C13Line*)(first + line_array_off);
CV_C13_Line *line_opl = line_ptr + line_count; CV_C13Line *line_opl = line_ptr + line_count;
// TODO(allen): check order correctness here // TODO(allen): check order correctness here
U32 i = 0; U32 i = 0;
for (; line_ptr < line_opl; line_ptr += 1, i += 1){ for (; line_ptr < line_opl; line_ptr += 1, i += 1){
voffs[i] = line_ptr->off + secrel_off + sec_base_off; voffs[i] = line_ptr->off + secrel_off + sec_base_off;
line_nums[i] = CV_C13_LineFlags_ExtractLineNumber(line_ptr->flags); line_nums[i] = CV_C13LineFlags_ExtractLineNumber(line_ptr->flags);
} }
voffs[i] = secrel_opl + sec_base_off; voffs[i] = secrel_opl + sec_base_off;
} }
@@ -489,19 +568,80 @@ cv_c13_from_data(Arena *arena, String8 c13_data, PDB_Strtbl *strtbl, PDB_CoffSec
read_off += sizeof(*file); read_off += sizeof(*file);
read_off += line_item_size*line_count; read_off += line_item_size*line_count;
} }
}break;
//////////////////////////
//- rjf: inlinee line info sub-section
//
case CV_C13SubSectionKind_InlineeLines:
if(sizeof(CV_C13InlineeLinesSig) <= cap)
{
// rjf: read sig
U32 read_off = 0;
U64 read_off_opl = node->size;
CV_C13InlineeLinesSig *sig = (CV_C13InlineeLinesSig *)(first + read_off);
read_off += sizeof(*sig);
// rjf: read source lines
for(;read_off + sizeof(CV_C13InlineeSourceLineHeader) <= read_off_opl;)
{
// rjf: read next header
CV_C13InlineeSourceLineHeader *hdr = (CV_C13InlineeSourceLineHeader *)(first + read_off);
read_off += sizeof(*hdr);
// rjf: file_off -> file_name
String8 file_name = {0};
if(hdr->file_off + sizeof(CV_C13Checksum) <= file_chksms->size)
{
CV_C13Checksum *checksum = (CV_C13Checksum*)(c13_data.str + file_chksms->off + hdr->file_off);
U32 name_off = checksum->name_off;
file_name = str8_cstring_capped((char*)(strtbl.str + name_off),
(char*)(strtbl.str + strtbl.size));
}
// rjf: parse extra files
U32 extra_file_count = 0;
U32 *extra_files = 0;
if(*sig == CV_C13InlineeLinesSig_EXTRA_FILES && read_off+sizeof(U32) <= read_off_opl)
{
U32 *extra_file_count_ptr = (U32 *)(first + read_off);
read_off += sizeof(*extra_file_count_ptr);
U32 max_extra_file_count = (read_off_opl-read_off)/sizeof(U32);
extra_file_count = Min(*extra_file_count_ptr, max_extra_file_count);
extra_files = (U32 *)(first + read_off);
read_off += sizeof(*extra_files)*extra_file_count;
}
// rjf: push node for this inlinee lines parsed into this subsection's list
CV_C13InlineeLinesParsedNode *n = push_array(arena, CV_C13InlineeLinesParsedNode, 1);
SLLQueuePush(node->inlinee_lines_first, node->inlinee_lines_last, n);
n->v.inlinee = hdr->inlinee;
n->v.file_name = file_name;
n->v.file_off = hdr->file_off;
n->v.first_source_ln = hdr->first_source_ln;
n->v.extra_file_count = extra_file_count;
n->v.extra_files = extra_files;
// rjf: push node into inlinee parse hash table
U64 hash = cv_hash_from_item_id(hdr->inlinee);
U64 slot_idx = hash%inlinee_lines_parsed_slots_count;
SLLStackPush_N(inlinee_lines_parsed_slots[slot_idx], n, hash_next);
} }
}break; }break;
} }
} }
// convert to result //////////////////////////////
//- rjf: fill output
//
CV_C13Parsed *result = push_array(arena, CV_C13Parsed, 1); CV_C13Parsed *result = push_array(arena, CV_C13Parsed, 1);
result->data = c13_data;
result->first_sub_section = first; result->first_sub_section = first;
result->last_sub_section = last; result->last_sub_section = last;
result->sub_section_count = count; result->sub_section_count = count;
result->file_chksms_sub_section = file_chksms; result->file_chksms_sub_section = file_chksms;
result->inlinee_lines_parsed_slots = inlinee_lines_parsed_slots;
result->inlinee_lines_parsed_slots_count = inlinee_lines_parsed_slots_count;
ProfEnd(); ProfEnd();
return result;
return(result);
} }
+768 -585
View File
File diff suppressed because it is too large Load Diff
+9 -1
View File
@@ -246,7 +246,7 @@ cv_string_from_arch:
{MANTYPREF - 0x1028} {MANTYPREF - 0x1028}
{UNAMESPACE_ST - 0x1029} {UNAMESPACE_ST - 0x1029}
{ST_MAX - 0x1100} {ST_MAX - 0x1100}
{OBJNAME Objname 0x1101} {OBJNAME ObjName 0x1101}
{THUNK32 Thunk32 0x1102} {THUNK32 Thunk32 0x1102}
{BLOCK32 Block32 0x1103} {BLOCK32 Block32 0x1103}
{WITH32 - 0x1104} {WITH32 - 0x1104}
@@ -462,6 +462,7 @@ CV_BasicTypeTable:
@table(name header_type_name val) @table(name header_type_name val)
CV_LeafKindTable: CV_LeafKindTable:
{ {
{NOTYPE - 0x0000}
{MODIFIER_16t - 0x0001} {MODIFIER_16t - 0x0001}
{POINTER_16t - 0x0002} {POINTER_16t - 0x0002}
{ARRAY_16t - 0x0003} {ARRAY_16t - 0x0003}
@@ -586,6 +587,13 @@ CV_LeafKindTable:
{VECTOR - 0x151b} {VECTOR - 0x151b}
{MATRIX - 0x151c} {MATRIX - 0x151c}
{VFTABLE - 0x151d} {VFTABLE - 0x151d}
{FUNC_ID FuncId 0x1601}
{MFUNC_ID MFuncId 0x1602}
{BUILDINFO BuildInfo 0x1603}
{SUBSTR_LIST SubstrList 0x1604}
{STRING_ID StringId 0x1605}
{UDT_SRC_LINE UDTSrcLine 0x1606}
{UDT_MOD_SRC_LINE UDTModSrcLine 0x1607}
{CLASS2 Struct2 0x1608} {CLASS2 Struct2 0x1608}
{STRUCT2 Struct2 0x1609} {STRUCT2 Struct2 0x1609}
} }
+32 -20
View File
@@ -49,12 +49,12 @@ cv_stringize_lvar_addr_gap_list(Arena *arena, String8List *out, void *first, voi
} }
internal String8 internal String8
cv_string_from_c13_sub_section_kind(CV_C13_SubSectionKind kind){ cv_string_from_c13_sub_section_kind(CV_C13SubSectionKind kind){
String8 result = str8_lit("UNRECOGNIZED_C13_SUB_SECTION_KIND"); String8 result = str8_lit("UNRECOGNIZED_C13_SUB_SECTION_KIND");
switch (kind){ switch (kind){
case 0: str8_lit("PARSE_ERROR"); break; case 0: str8_lit("PARSE_ERROR"); break;
#define X(N,c) case CV_C13_SubSectionKind_##N: result = str8_lit(#N); break; #define X(N,c) case CV_C13SubSectionKind_##N: result = str8_lit(#N); break;
CV_C13_SubSectionKindXList(X) CV_C13SubSectionKindXList(X)
#undef X #undef X
} }
return(result); return(result);
@@ -408,11 +408,11 @@ cv_stringize_sym_range(Arena *arena, String8List *out,
case CV_SymKind_OBJNAME: case CV_SymKind_OBJNAME:
{ {
if (sizeof(CV_SymObjname) > cap){ if (sizeof(CV_SymObjName) > cap){
str8_list_push(arena, out, str8_lit(" bad symbol range\n")); str8_list_push(arena, out, str8_lit(" bad symbol range\n"));
} }
else{ else{
CV_SymObjname *objname = (CV_SymObjname*)first; CV_SymObjName *objname = (CV_SymObjName*)first;
// sig // sig
str8_list_pushf(arena, out, " sig=%u\n", objname->sig); str8_list_pushf(arena, out, " sig=%u\n", objname->sig);
@@ -568,22 +568,22 @@ cv_stringize_sym_range(Arena *arena, String8List *out,
CV_SymPub32 *pub32 = (CV_SymPub32*)first; CV_SymPub32 *pub32 = (CV_SymPub32*)first;
// flags // flags
CV_PubFlags flags = pub32->flags; CV_Pub32Flags flags = pub32->flags;
str8_list_push(arena, out, str8_lit(" flags=")); str8_list_push(arena, out, str8_lit(" flags="));
if (flags == 0){ if (flags == 0){
str8_list_push(arena, out, str8_lit("0|")); str8_list_push(arena, out, str8_lit("0|"));
} }
else{ else{
if (flags&CV_PubFlag_Code){ if (flags&CV_Pub32Flag_Code){
str8_list_push(arena, out, str8_lit("Code|")); str8_list_push(arena, out, str8_lit("Code|"));
} }
if (flags&CV_PubFlag_Function){ if (flags&CV_Pub32Flag_Function){
str8_list_push(arena, out, str8_lit("Function|")); str8_list_push(arena, out, str8_lit("Function|"));
} }
if (flags&CV_PubFlag_ManagedCode){ if (flags&CV_Pub32Flag_ManagedCode){
str8_list_push(arena, out, str8_lit("ManagedCode|")); str8_list_push(arena, out, str8_lit("ManagedCode|"));
} }
if (flags&CV_PubFlag_MSIL){ if (flags&CV_Pub32Flag_MSIL){
str8_list_push(arena, out, str8_lit("MSIL|")); str8_list_push(arena, out, str8_lit("MSIL|"));
} }
} }
@@ -2004,7 +2004,7 @@ cv_stringize_leaf_range(Arena *arena, String8List *out,
} }
}break; }break;
case CV_LeafIDKind_FUNC_ID: case CV_LeafKind_FUNC_ID:
{ {
if (sizeof(CV_LeafFuncId) > cap){ if (sizeof(CV_LeafFuncId) > cap){
str8_list_push(arena, out, str8_lit(" bad leaf range\n")); str8_list_push(arena, out, str8_lit(" bad leaf range\n"));
@@ -2020,7 +2020,7 @@ cv_stringize_leaf_range(Arena *arena, String8List *out,
} }
}break; }break;
case CV_LeafIDKind_MFUNC_ID: case CV_LeafKind_MFUNC_ID:
{ {
if (sizeof(CV_LeafMFuncId) > cap){ if (sizeof(CV_LeafMFuncId) > cap){
str8_list_push(arena, out, str8_lit(" bad leaf range\n")); str8_list_push(arena, out, str8_lit(" bad leaf range\n"));
@@ -2036,7 +2036,7 @@ cv_stringize_leaf_range(Arena *arena, String8List *out,
} }
}break; }break;
case CV_LeafIDKind_BUILDINFO: case CV_LeafKind_BUILDINFO:
{ {
if (sizeof(CV_LeafBuildInfo) > cap){ if (sizeof(CV_LeafBuildInfo) > cap){
str8_list_push(arena, out, str8_lit(" bad leaf range\n")); str8_list_push(arena, out, str8_lit(" bad leaf range\n"));
@@ -2057,7 +2057,7 @@ cv_stringize_leaf_range(Arena *arena, String8List *out,
} }
}break; }break;
case CV_LeafIDKind_SUBSTR_LIST: case CV_LeafKind_SUBSTR_LIST:
{ {
if (sizeof(CV_LeafSubstrList) > cap){ if (sizeof(CV_LeafSubstrList) > cap){
str8_list_push(arena, out, str8_lit(" bad leaf range\n")); str8_list_push(arena, out, str8_lit(" bad leaf range\n"));
@@ -2078,7 +2078,7 @@ cv_stringize_leaf_range(Arena *arena, String8List *out,
} }
}break; }break;
case CV_LeafIDKind_STRING_ID: case CV_LeafKind_STRING_ID:
{ {
if (sizeof(CV_LeafStringId) > cap){ if (sizeof(CV_LeafStringId) > cap){
str8_list_push(arena, out, str8_lit(" bad leaf range\n")); str8_list_push(arena, out, str8_lit(" bad leaf range\n"));
@@ -2093,7 +2093,7 @@ cv_stringize_leaf_range(Arena *arena, String8List *out,
} }
}break; }break;
case CV_LeafIDKind_UDT_SRC_LINE: case CV_LeafKind_UDT_SRC_LINE:
{ {
if (sizeof(CV_LeafUDTSrcLine) > cap){ if (sizeof(CV_LeafUDTSrcLine) > cap){
str8_list_push(arena, out, str8_lit(" bad leaf range\n")); str8_list_push(arena, out, str8_lit(" bad leaf range\n"));
@@ -2243,7 +2243,7 @@ cv_stringize_leaf_range(Arena *arena, String8List *out,
//case CV_LeafIDKind_SUBSTR_LIST: //case CV_LeafIDKind_SUBSTR_LIST:
//case CV_LeafIDKind_STRING_ID: //case CV_LeafIDKind_STRING_ID:
//case CV_LeafIDKind_UDT_SRC_LINE: //case CV_LeafIDKind_UDT_SRC_LINE:
case CV_LeafIDKind_UDT_MOD_SRC_LINE: case CV_LeafKind_UDT_MOD_SRC_LINE:
{ {
str8_list_push(arena, out, str8_lit(" no stringizer path\n")); str8_list_push(arena, out, str8_lit(" no stringizer path\n"));
@@ -2280,7 +2280,7 @@ cv_stringize_c13_parsed(Arena *arena, String8List *out, CV_C13Parsed *c13){
switch(node->kind) switch(node->kind)
{ {
case CV_C13_SubSectionKind_Lines: case CV_C13SubSectionKind_Lines:
{ {
if (node->lines_first == 0) if (node->lines_first == 0)
{ {
@@ -2309,12 +2309,12 @@ cv_stringize_c13_parsed(Arena *arena, String8List *out, CV_C13Parsed *c13){
} }
}break; }break;
case CV_C13_SubSectionKind_FileChksms: case CV_C13SubSectionKind_FileChksms:
{ {
str8_list_push(arena, out, str8_lit(" no stringizer path\n")); str8_list_push(arena, out, str8_lit(" no stringizer path\n"));
}break; }break;
case CV_C13_SubSectionKind_InlineeLines: case CV_C13SubSectionKind_InlineeLines:
{ {
str8_list_push(arena, out, str8_lit(" no stringizer path\n")); str8_list_push(arena, out, str8_lit(" no stringizer path\n"));
}break; }break;
@@ -2328,3 +2328,15 @@ cv_stringize_c13_parsed(Arena *arena, String8List *out, CV_C13Parsed *c13){
str8_list_push(arena, out, str8_lit("\n")); str8_list_push(arena, out, str8_lit("\n"));
} }
} }
internal String8
cv_string_from_inline_range_kind(CV_InlineRangeKind kind)
{
String8 result = str8_zero();
switch (kind) {
case CV_InlineRangeKind_Expr: result = str8_lit("Expr"); break;
case CV_InlineRangeKind_Stmt: result = str8_lit("Stmt"); break;
}
return result;
}
+3 -1
View File
@@ -27,7 +27,7 @@ internal void cv_stringize_lvar_addr_gap_list(Arena *arena, String8List *out,
void *first, void *opl); void *first, void *opl);
internal String8 cv_string_from_basic_type(CV_BasicType basic_type); internal String8 cv_string_from_basic_type(CV_BasicType basic_type);
internal String8 cv_string_from_c13_sub_section_kind(CV_C13_SubSectionKind kind); internal String8 cv_string_from_c13_sub_section_kind(CV_C13SubSectionKind kind);
internal String8 cv_string_from_reg(CV_Arch arch, CV_Reg reg); internal String8 cv_string_from_reg(CV_Arch arch, CV_Reg reg);
internal String8 cv_string_from_pointer_kind(CV_PointerKind ptr_kind); internal String8 cv_string_from_pointer_kind(CV_PointerKind ptr_kind);
internal String8 cv_string_from_pointer_mode(CV_PointerMode ptr_mode); internal String8 cv_string_from_pointer_mode(CV_PointerMode ptr_mode);
@@ -79,4 +79,6 @@ internal void cv_stringize_leaf_array(Arena *arena, String8List *out,
internal void cv_stringize_c13_parsed(Arena *arena, String8List *out, CV_C13Parsed *c13); internal void cv_stringize_c13_parsed(Arena *arena, String8List *out, CV_C13Parsed *c13);
internal String8 cv_string_from_inline_range_kind(CV_InlineRangeKind kind);
#endif // CODEVIEW_STRINGIZE_H #endif // CODEVIEW_STRINGIZE_H
+16 -4
View File
@@ -447,6 +447,7 @@ String8 result = str8_lit("<Unknown CV_LeafKind>");
switch(v) switch(v)
{ {
default:{}break; default:{}break;
case CV_LeafKind_NOTYPE:{result = str8_lit("NOTYPE");}break;
case CV_LeafKind_MODIFIER_16t:{result = str8_lit("MODIFIER_16t");}break; case CV_LeafKind_MODIFIER_16t:{result = str8_lit("MODIFIER_16t");}break;
case CV_LeafKind_POINTER_16t:{result = str8_lit("POINTER_16t");}break; case CV_LeafKind_POINTER_16t:{result = str8_lit("POINTER_16t");}break;
case CV_LeafKind_ARRAY_16t:{result = str8_lit("ARRAY_16t");}break; case CV_LeafKind_ARRAY_16t:{result = str8_lit("ARRAY_16t");}break;
@@ -571,6 +572,13 @@ case CV_LeafKind_BINTERFACE:{result = str8_lit("BINTERFACE");}break;
case CV_LeafKind_VECTOR:{result = str8_lit("VECTOR");}break; case CV_LeafKind_VECTOR:{result = str8_lit("VECTOR");}break;
case CV_LeafKind_MATRIX:{result = str8_lit("MATRIX");}break; case CV_LeafKind_MATRIX:{result = str8_lit("MATRIX");}break;
case CV_LeafKind_VFTABLE:{result = str8_lit("VFTABLE");}break; case CV_LeafKind_VFTABLE:{result = str8_lit("VFTABLE");}break;
case CV_LeafKind_FUNC_ID:{result = str8_lit("FUNC_ID");}break;
case CV_LeafKind_MFUNC_ID:{result = str8_lit("MFUNC_ID");}break;
case CV_LeafKind_BUILDINFO:{result = str8_lit("BUILDINFO");}break;
case CV_LeafKind_SUBSTR_LIST:{result = str8_lit("SUBSTR_LIST");}break;
case CV_LeafKind_STRING_ID:{result = str8_lit("STRING_ID");}break;
case CV_LeafKind_UDT_SRC_LINE:{result = str8_lit("UDT_SRC_LINE");}break;
case CV_LeafKind_UDT_MOD_SRC_LINE:{result = str8_lit("UDT_MOD_SRC_LINE");}break;
case CV_LeafKind_CLASS2:{result = str8_lit("CLASS2");}break; case CV_LeafKind_CLASS2:{result = str8_lit("CLASS2");}break;
case CV_LeafKind_STRUCT2:{result = str8_lit("STRUCT2");}break; case CV_LeafKind_STRUCT2:{result = str8_lit("STRUCT2");}break;
} }
@@ -592,7 +600,7 @@ case CV_SymKind_OEM:{result = sizeof(CV_SymOEM);}break;
case CV_SymKind_VFTABLE32:{result = sizeof(CV_SymVPath32);}break; case CV_SymKind_VFTABLE32:{result = sizeof(CV_SymVPath32);}break;
case CV_SymKind_FRAMEPROC:{result = sizeof(CV_SymFrameproc);}break; case CV_SymKind_FRAMEPROC:{result = sizeof(CV_SymFrameproc);}break;
case CV_SymKind_ANNOTATION:{result = sizeof(CV_SymAnnotation);}break; case CV_SymKind_ANNOTATION:{result = sizeof(CV_SymAnnotation);}break;
case CV_SymKind_OBJNAME:{result = sizeof(CV_SymObjname);}break; case CV_SymKind_OBJNAME:{result = sizeof(CV_SymObjName);}break;
case CV_SymKind_THUNK32:{result = sizeof(CV_SymThunk32);}break; case CV_SymKind_THUNK32:{result = sizeof(CV_SymThunk32);}break;
case CV_SymKind_BLOCK32:{result = sizeof(CV_SymBlock32);}break; case CV_SymKind_BLOCK32:{result = sizeof(CV_SymBlock32);}break;
case CV_SymKind_LABEL32:{result = sizeof(CV_SymLabel32);}break; case CV_SymKind_LABEL32:{result = sizeof(CV_SymLabel32);}break;
@@ -696,11 +704,15 @@ case CV_LeafKind_ONEMETHOD:{result = sizeof(CV_LeafOneMethod);}break;
case CV_LeafKind_NESTTYPEEX:{result = sizeof(CV_LeafNestTypeEx);}break; case CV_LeafKind_NESTTYPEEX:{result = sizeof(CV_LeafNestTypeEx);}break;
case CV_LeafKind_TYPESERVER2:{result = sizeof(CV_LeafTypeServer2);}break; case CV_LeafKind_TYPESERVER2:{result = sizeof(CV_LeafTypeServer2);}break;
case CV_LeafKind_INTERFACE:{result = sizeof(CV_LeafStruct);}break; case CV_LeafKind_INTERFACE:{result = sizeof(CV_LeafStruct);}break;
case CV_LeafKind_FUNC_ID:{result = sizeof(CV_LeafFuncId);}break;
case CV_LeafKind_MFUNC_ID:{result = sizeof(CV_LeafMFuncId);}break;
case CV_LeafKind_BUILDINFO:{result = sizeof(CV_LeafBuildInfo);}break;
case CV_LeafKind_SUBSTR_LIST:{result = sizeof(CV_LeafSubstrList);}break;
case CV_LeafKind_STRING_ID:{result = sizeof(CV_LeafStringId);}break;
case CV_LeafKind_UDT_SRC_LINE:{result = sizeof(CV_LeafUDTSrcLine);}break;
case CV_LeafKind_UDT_MOD_SRC_LINE:{result = sizeof(CV_LeafUDTModSrcLine);}break;
case CV_LeafKind_CLASS2:{result = sizeof(CV_LeafStruct2);}break; case CV_LeafKind_CLASS2:{result = sizeof(CV_LeafStruct2);}break;
case CV_LeafKind_STRUCT2:{result = sizeof(CV_LeafStruct2);}break; case CV_LeafKind_STRUCT2:{result = sizeof(CV_LeafStruct2);}break;
} }
return result; return result;
} }
C_LINKAGE_BEGIN
C_LINKAGE_END
+8 -3
View File
@@ -381,6 +381,7 @@ CV_BasicType_PTR = 0xf0,
typedef U16 CV_LeafKind; typedef U16 CV_LeafKind;
typedef enum CV_LeafKindEnum typedef enum CV_LeafKindEnum
{ {
CV_LeafKind_NOTYPE = 0x0000,
CV_LeafKind_MODIFIER_16t = 0x0001, CV_LeafKind_MODIFIER_16t = 0x0001,
CV_LeafKind_POINTER_16t = 0x0002, CV_LeafKind_POINTER_16t = 0x0002,
CV_LeafKind_ARRAY_16t = 0x0003, CV_LeafKind_ARRAY_16t = 0x0003,
@@ -505,6 +506,13 @@ CV_LeafKind_BINTERFACE = 0x151a,
CV_LeafKind_VECTOR = 0x151b, CV_LeafKind_VECTOR = 0x151b,
CV_LeafKind_MATRIX = 0x151c, CV_LeafKind_MATRIX = 0x151c,
CV_LeafKind_VFTABLE = 0x151d, CV_LeafKind_VFTABLE = 0x151d,
CV_LeafKind_FUNC_ID = 0x1601,
CV_LeafKind_MFUNC_ID = 0x1602,
CV_LeafKind_BUILDINFO = 0x1603,
CV_LeafKind_SUBSTR_LIST = 0x1604,
CV_LeafKind_STRING_ID = 0x1605,
CV_LeafKind_UDT_SRC_LINE = 0x1606,
CV_LeafKind_UDT_MOD_SRC_LINE = 0x1607,
CV_LeafKind_CLASS2 = 0x1608, CV_LeafKind_CLASS2 = 0x1608,
CV_LeafKind_STRUCT2 = 0x1609, CV_LeafKind_STRUCT2 = 0x1609,
} CV_LeafKindEnum; } CV_LeafKindEnum;
@@ -517,7 +525,4 @@ internal String8 cv_type_name_from_basic_type(CV_BasicType v);
internal String8 cv_string_from_leaf_kind(CV_LeafKind v); internal String8 cv_string_from_leaf_kind(CV_LeafKind v);
internal U64 cv_header_struct_size_from_sym_kind(CV_SymKind v); internal U64 cv_header_struct_size_from_sym_kind(CV_SymKind v);
internal U64 cv_header_struct_size_from_leaf_kind(CV_LeafKind v); internal U64 cv_header_struct_size_from_leaf_kind(CV_LeafKind v);
C_LINKAGE_BEGIN
C_LINKAGE_END
#endif // CODEVIEW_META_H #endif // CODEVIEW_META_H
+305 -47
View File
@@ -28,7 +28,7 @@ coff_is_obj(String8 data)
switch (header->machine) { switch (header->machine) {
case COFF_MachineType_UNKNOWN: case COFF_MachineType_UNKNOWN:
case COFF_MachineType_X86: case COFF_MachineType_X64: case COFF_MachineType_X86: case COFF_MachineType_X64:
case COFF_MachineType_ARM33: case COFF_MachineType_ARM: case COFF_MachineType_AM33: case COFF_MachineType_ARM:
case COFF_MachineType_ARM64: case COFF_MachineType_ARMNT: case COFF_MachineType_ARM64: case COFF_MachineType_ARMNT:
case COFF_MachineType_EBC: case COFF_MachineType_IA64: case COFF_MachineType_EBC: case COFF_MachineType_IA64:
case COFF_MachineType_M32R: case COFF_MachineType_MIPS16: case COFF_MachineType_M32R: case COFF_MachineType_MIPS16:
@@ -304,7 +304,7 @@ coff_symbol_array_from_data_16(Arena *arena, String8 data, U64 symbol_array_off,
{ {
COFF_Symbol32Array result; COFF_Symbol32Array result;
result.count = symbol_count; result.count = symbol_count;
result.v = push_array_no_zero(arena, COFF_Symbol32, result.count); result.v = push_array_no_zero_aligned(arena, COFF_Symbol32, result.count, 8);
COFF_Symbol16 *sym16_arr = (COFF_Symbol16 *)(data.str + symbol_array_off); COFF_Symbol16 *sym16_arr = (COFF_Symbol16 *)(data.str + symbol_array_off);
for (U64 isymbol = 0; isymbol < symbol_count; isymbol += 1) { for (U64 isymbol = 0; isymbol < symbol_count; isymbol += 1) {
@@ -393,6 +393,28 @@ coff_word_size_from_machine(COFF_MachineType machine)
return result; return result;
} }
internal U64
coff_default_exe_base_from_machine(COFF_MachineType machine)
{
U64 exe_base = 0;
switch (coff_word_size_from_machine(machine)) {
case 4: exe_base = 0x400000; break;
case 8: exe_base = 0x140000000; break;
}
return exe_base;
}
internal U64
coff_default_dll_base_from_machine(COFF_MachineType machine)
{
U64 dll_base = 0;
switch (coff_word_size_from_machine(machine)) {
case 4: dll_base = 0x10000000; break;
case 8: dll_base = 0x180000000; break;
}
return dll_base;
}
internal String8 internal String8
coff_make_import_lookup(Arena *arena, U16 hint, String8 name) coff_make_import_lookup(Arena *arena, U16 hint, String8 name)
{ {
@@ -421,6 +443,114 @@ coff_make_ordinal_64(U16 hint)
//////////////////////////////// ////////////////////////////////
internal String8
coff_make_import_header_by_name(Arena *arena,
String8 dll_name,
COFF_MachineType machine,
COFF_TimeStamp time_stamp,
String8 name,
U16 hint,
COFF_ImportHeaderType type)
{
struct {
U16 sig1;
U16 sig2;
U16 version;
COFF_MachineType machine;
COFF_TimeStamp time_stamp;
U32 sizeof_data;
U16 hint_ordinal;
U16 flags;
} import_header = {
COFF_MachineType_UNKNOWN, // sig1
max_U16, // sig2
0, // version
machine,
time_stamp,
safe_cast_u32(name.size + dll_name.size + 2), // sizeof_data
0, // hint_ordinal
0, // flags
};
import_header.flags |= (U16)(type & COFF_IMPORT_HEADER_TYPE_MASK) << COFF_IMPORT_HEADER_TYPE_SHIFT;
import_header.flags |= COFF_ImportHeaderNameType_NAME << COFF_IMPORT_HEADER_NAME_TYPE_SHIFT;
import_header.hint_ordinal = hint;
// alloc memory
U64 buffer_size = sizeof(import_header) + import_header.sizeof_data;
U8 *buffer = push_array_no_zero(arena, U8, buffer_size);
// copy header
MemoryCopy(buffer, &import_header, sizeof(import_header));
// copy function name
U8 *func_name = buffer + sizeof(import_header);
MemoryCopy(func_name, name.str, name.size);
func_name[name.size] = 0;
// copy dll name
U8 *dll_name_buffer = buffer + sizeof(import_header) + name.size + 1;
MemoryCopy(dll_name_buffer, dll_name.str, dll_name.size);
dll_name_buffer[dll_name.size] = 0;
String8 import_data = str8(buffer, buffer_size);
return import_data;
}
internal String8
coff_make_import_header_by_ordinal(Arena *arena,
String8 dll_name,
COFF_MachineType machine,
COFF_TimeStamp time_stamp,
U16 ordinal,
COFF_ImportHeaderType type)
{
struct {
U16 sig1;
U16 sig2;
U16 version;
COFF_MachineType machine;
COFF_TimeStamp time_stamp;
U32 sizeof_data;
U16 hint_ordinal;
U16 flags;
} import_header = {
COFF_MachineType_UNKNOWN, // sig1
max_U16, // sig2
0, // version
machine,
time_stamp,
safe_cast_u32(/* name.size + */ dll_name.size + 2), // sizeof_data
0, // hint_ordinal
0, // flags
};
import_header.flags |= (U16)(type & COFF_IMPORT_HEADER_TYPE_MASK) << COFF_IMPORT_HEADER_TYPE_SHIFT;
import_header.flags |= COFF_ImportHeaderNameType_ORDINAL << COFF_IMPORT_HEADER_NAME_TYPE_SHIFT;
import_header.hint_ordinal = ordinal;
// alloc memory
U64 buffer_size = sizeof(import_header) + import_header.sizeof_data;
U8 *buffer = push_array_no_zero(arena, U8, buffer_size);
// copy header
MemoryCopyStruct(buffer, &import_header);
// no function name write zero
U8 *func_name = buffer + sizeof(import_header);
func_name[0] = 0;
// copy dll name
U8 *dll_name_buffer = buffer + sizeof(import_header) + /* name.size */ + 1;
MemoryCopy(dll_name_buffer, dll_name.str, dll_name.size);
dll_name_buffer[dll_name.size] = 0;
String8 import_data = str8(buffer, buffer_size);
return import_data;
}
////////////////////////////////
internal B32 internal B32
coff_resource_id_is_equal(COFF_ResourceID a, COFF_ResourceID b) coff_resource_id_is_equal(COFF_ResourceID a, COFF_ResourceID b)
{ {
@@ -455,6 +585,25 @@ coff_resource_id_copy(Arena *arena, COFF_ResourceID id)
return result; return result;
} }
internal U64
coff_sizeof_resource_id(COFF_ResourceID id)
{
U64 size = 0;
switch (id.type) {
case COFF_ResourceIDType_NULL: break;
case COFF_ResourceIDType_NUMBER: {
size += sizeof(U16);
size += sizeof(U16);
} break;
case COFF_ResourceIDType_STRING: {
size += sizeof(U16);
size += (id.u.string.size + /* null: */1) * sizeof(U16);
} break;
default: InvalidPath;
}
return AlignPow2(size, COFF_RES_ALIGN);
}
internal COFF_ResourceID internal COFF_ResourceID
coff_convert_resource_id(Arena *arena, COFF_ResourceID_16 *id_16) coff_convert_resource_id(Arena *arena, COFF_ResourceID_16 *id_16)
{ {
@@ -558,6 +707,67 @@ coff_resource_list_from_data(Arena *arena, String8 data)
return list; return list;
} }
internal void
coff_write_resource_id(Arena *arena, String8List *srl, COFF_ResourceID id)
{
switch (id.type) {
case COFF_ResourceIDType_NULL: break;
case COFF_ResourceIDType_NUMBER: {
str8_serial_push_u16(arena, srl, max_U16);
str8_serial_push_u16(arena, srl, id.u.number);
} break;
case COFF_ResourceIDType_STRING: {
String16 str16 = str16_from_8(arena, id.u.string);
Assert(str16.size <= max_U16);
str8_serial_push_u16(arena, srl, str16.size);
str8_serial_push_data(arena, srl, str16.str, str16.size);
} break;
default: InvalidPath;
}
str8_serial_push_align(arena, srl, COFF_RES_ALIGN);
}
internal String8List
coff_write_resource(Arena *arena,
COFF_ResourceID type,
COFF_ResourceID name,
U32 data_version,
COFF_ResourceMemoryFlags memory_flags,
U16 language_id,
U32 version,
U32 characteristics,
String8 data)
{
U64 header_size = sizeof(COFF_ResourceHeaderPrefix) +
coff_sizeof_resource_id(type) +
coff_sizeof_resource_id(name) +
sizeof(data_version) +
sizeof(memory_flags) +
sizeof(language_id) +
sizeof(version) +
sizeof(characteristics);
COFF_ResourceHeaderPrefix *header = push_array(arena, COFF_ResourceHeaderPrefix, 1);
header->data_size = safe_cast_u32(data.size);
header->header_size = safe_cast_u32(header_size);
String8List srl = {0};
str8_serial_begin(arena, &srl);
str8_serial_push_data(arena, &srl, &g_coff_res_magic[0], sizeof(g_coff_res_magic));
str8_serial_push_data(arena, &srl, header, sizeof(*header));
coff_write_resource_id(arena, &srl, type);
coff_write_resource_id(arena, &srl, name);
str8_serial_push_u32(arena, &srl, data_version);
str8_serial_push_u16(arena, &srl, memory_flags);
str8_serial_push_u16(arena, &srl, language_id);
str8_serial_push_u32(arena, &srl, version);
str8_serial_push_u32(arena, &srl, characteristics);
str8_serial_push_string(arena, &srl, data);
str8_serial_push_align(arena, &srl, COFF_RES_ALIGN);
return srl;
}
//////////////////////////////// ////////////////////////////////
internal COFF_DataType internal COFF_DataType
@@ -591,18 +801,22 @@ coff_is_import(String8 data)
internal B32 internal B32
coff_is_archive(String8 data) coff_is_archive(String8 data)
{ {
U64 sig = 0; B32 is_archive = 0;
str8_deserial_read_struct(data, 0, &sig); U8 sig[sizeof(g_coff_archive_sig)];
B32 is_archive = sig == COFF_ARCHIVE_SIG; if (str8_deserial_read_struct(data, 0, &sig) == sizeof(sig)) {
is_archive = MemoryCompare(&sig[0], &g_coff_archive_sig[0], sizeof(g_coff_archive_sig)) == 0;
}
return is_archive; return is_archive;
} }
internal B32 internal B32
coff_is_thin_archive(String8 data) coff_is_thin_archive(String8 data)
{ {
U64 sig = 0; B32 is_archive = 0;
str8_deserial_read_struct(data, 0, &sig); U8 sig[sizeof(g_coff_thin_archive_sig)];
B32 is_archive = sig == COFF_THIN_ARCHIVE_SIG; if (str8_deserial_read_struct(data, 0, &sig) == sizeof(sig)) {
is_archive = MemoryCompare(&sig[0], &g_coff_thin_archive_sig[0], sizeof(g_coff_thin_archive_sig)) == 0;
}
return is_archive; return is_archive;
} }
@@ -751,11 +965,9 @@ coff_read_archive_long_name(String8 long_names, String8 name)
internal U64 internal U64
coff_archive_member_iter_init(String8 data) coff_archive_member_iter_init(String8 data)
{ {
U64 cursor = 0; U64 cursor = data.size;
U64 sig = 0; if (coff_is_archive(data)) {
cursor += str8_deserial_read_struct(data, cursor, &sig); cursor = sizeof(g_coff_archive_sig);
if (sig != COFF_ARCHIVE_SIG) {
cursor = data.size;
} }
return cursor; return cursor;
} }
@@ -915,11 +1127,9 @@ coff_archive_from_data(Arena *arena, String8 data)
internal U64 internal U64
coff_thin_archive_member_iter_init(String8 data) coff_thin_archive_member_iter_init(String8 data)
{ {
U64 cursor = 0; U64 cursor = data.size;
U64 sig = 0; if (coff_is_thin_archive(data)) {
cursor += str8_deserial_read_struct(data, cursor, &sig); cursor = sizeof(g_coff_thin_archive_sig);
if (sig != COFF_THIN_ARCHIVE_SIG) {
cursor = data.size;
} }
return cursor; return cursor;
} }
@@ -990,6 +1200,46 @@ coff_archive_parse_from_data(Arena *arena, String8 data)
//////////////////////////////// ////////////////////////////////
read_only struct
{
String8 string;
COFF_MachineType machine;
} g_coff_machine_map[] = {
{ str8_lit_comp(""), COFF_MachineType_UNKNOWN },
{ str8_lit_comp("X86"), COFF_MachineType_X86 },
{ str8_lit_comp("X64"), COFF_MachineType_X64 },
{ str8_lit_comp("AM33"), COFF_MachineType_AM33 },
{ str8_lit_comp("ARM"), COFF_MachineType_ARM },
{ str8_lit_comp("ARM64"), COFF_MachineType_ARM64 },
{ str8_lit_comp("ARMNT"), COFF_MachineType_ARMNT },
{ str8_lit_comp("EBC"), COFF_MachineType_EBC },
{ str8_lit_comp("IA64"), COFF_MachineType_IA64 },
{ str8_lit_comp("M32R"), COFF_MachineType_M32R },
{ str8_lit_comp("MIPS16"), COFF_MachineType_MIPS16 },
{ str8_lit_comp("MIPSFPU"), COFF_MachineType_MIPSFPU },
{ str8_lit_comp("MIPSFPU16"), COFF_MachineType_MIPSFPU16 },
{ str8_lit_comp("POWERPC"), COFF_MachineType_POWERPC },
{ str8_lit_comp("POWERPCFP"), COFF_MachineType_POWERPCFP },
{ str8_lit_comp("R4000"), COFF_MachineType_R4000 },
{ str8_lit_comp("RISCV32"), COFF_MachineType_RISCV32 },
{ str8_lit_comp("RISCV64"), COFF_MachineType_RISCV64 },
{ str8_lit_comp("SH3"), COFF_MachineType_SH3 },
{ str8_lit_comp("SH3DSP"), COFF_MachineType_SH3DSP },
{ str8_lit_comp("SH4"), COFF_MachineType_SH4 },
{ str8_lit_comp("SH5"), COFF_MachineType_SH5 },
{ str8_lit_comp("THUMB"), COFF_MachineType_THUMB },
{ str8_lit_comp("WCEMIPSV2"), COFF_MachineType_WCEMIPSV2 },
};
read_only static struct {
char * name;
COFF_ImportHeaderType type;
} g_coff_import_header_type_map[] = {
{ "CODE", COFF_ImportHeaderType_CODE },
{ "DATA", COFF_ImportHeaderType_DATA },
{ "CONST", COFF_ImportHeaderType_CONST },
};
internal String8 internal String8
coff_string_from_comdat_select_type(COFF_ComdatSelectType select) coff_string_from_comdat_select_type(COFF_ComdatSelectType select)
{ {
@@ -1009,35 +1259,10 @@ coff_string_from_comdat_select_type(COFF_ComdatSelectType select)
internal String8 internal String8
coff_string_from_machine_type(COFF_MachineType machine) coff_string_from_machine_type(COFF_MachineType machine)
{ {
String8 result = str8(0,0); Assert(machine < ArrayCount(g_coff_machine_map));
switch (machine) { Assert(machine == g_coff_machine_map[machine].machine);
case COFF_MachineType_UNKNOWN: result = str8_lit("UNKNOWN"); break; String8 string = g_coff_machine_map[machine].string;
case COFF_MachineType_X86: result = str8_lit("X86"); break; return string;
case COFF_MachineType_X64: result = str8_lit("X64"); break;
case COFF_MachineType_ARM33: result = str8_lit("ARM33"); break;
case COFF_MachineType_ARM: result = str8_lit("ARM"); break;
case COFF_MachineType_ARM64: result = str8_lit("ARM64"); break;
case COFF_MachineType_ARMNT: result = str8_lit("ARMNT"); break;
case COFF_MachineType_EBC: result = str8_lit("EBC"); break;
case COFF_MachineType_IA64: result = str8_lit("IA64"); break;
case COFF_MachineType_M32R: result = str8_lit("M32R"); break;
case COFF_MachineType_MIPS16: result = str8_lit("MIPS16"); break;
case COFF_MachineType_MIPSFPU: result = str8_lit("MIPSFPU"); break;
case COFF_MachineType_MIPSFPU16: result = str8_lit("MIPSFPU16"); break;
case COFF_MachineType_POWERPC: result = str8_lit("POWERPC"); break;
case COFF_MachineType_POWERPCFP: result = str8_lit("POWERPCFP"); break;
case COFF_MachineType_R4000: result = str8_lit("R4000"); break;
case COFF_MachineType_RISCV32: result = str8_lit("RISCV32"); break;
case COFF_MachineType_RISCV64: result = str8_lit("RISCV64"); break;
case COFF_MachineType_RISCV128: result = str8_lit("RISCV128"); break;
case COFF_MachineType_SH3: result = str8_lit("SH3"); break;
case COFF_MachineType_SH3DSP: result = str8_lit("SH3DSP"); break;
case COFF_MachineType_SH4: result = str8_lit("SH4"); break;
case COFF_MachineType_SH5: result = str8_lit("SH5"); break;
case COFF_MachineType_THUMB: result = str8_lit("THUMB"); break;
case COFF_MachineType_WCEMIPSV2: result = str8_lit("WCEMIPSV2"); break;
}
return result;
} }
internal String8 internal String8
@@ -1117,3 +1342,36 @@ coff_string_from_section_flags(Arena *arena, COFF_SectionFlags flags)
return result; return result;
} }
internal String8
coff_string_from_import_header_type(COFF_ImportHeaderType type)
{
for (U64 i = 0; i < ArrayCount(g_coff_import_header_type_map); ++i) {
if (g_coff_import_header_type_map[i].type == type) {
return str8_cstring(g_coff_import_header_type_map[i].name);
}
}
return str8(0,0);
}
internal COFF_MachineType
coff_machine_from_string(String8 string)
{
for (U64 i = 0; i < ArrayCount(g_coff_machine_map); ++i) {
if (str8_match(g_coff_machine_map[i].string, string, StringMatchFlag_CaseInsensitive)) {
return g_coff_machine_map[i].machine;
}
}
return COFF_MachineType_UNKNOWN;
}
internal COFF_ImportHeaderType
coff_import_header_type_from_string(String8 name)
{
for (U64 i = 0; i < ArrayCount(g_coff_import_header_type_map); ++i) {
if (str8_match(str8_cstring(g_coff_import_header_type_map[i].name), name, StringMatchFlag_CaseInsensitive)) {
return g_coff_import_header_type_map[i].type;
}
}
return COFF_ImportHeaderType_COUNT;
}
+55 -7
View File
@@ -48,7 +48,7 @@ enum
COFF_MachineType_UNKNOWN = 0x0, COFF_MachineType_UNKNOWN = 0x0,
COFF_MachineType_X86 = 0x14c, COFF_MachineType_X86 = 0x14c,
COFF_MachineType_X64 = 0x8664, COFF_MachineType_X64 = 0x8664,
COFF_MachineType_ARM33 = 0x1d3, COFF_MachineType_AM33 = 0x1d3,
COFF_MachineType_ARM = 0x1c0, COFF_MachineType_ARM = 0x1c0,
COFF_MachineType_ARM64 = 0xaa64, COFF_MachineType_ARM64 = 0xaa64,
COFF_MachineType_ARMNT = 0x1c4, COFF_MachineType_ARMNT = 0x1c4,
@@ -556,6 +556,11 @@ typedef U32 COFF_FeatFlags;
#define COFF_RES_ALIGN 4u #define COFF_RES_ALIGN 4u
read_only U8 g_coff_res_magic[] = {
0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
typedef struct COFF_ResourceHeaderPrefix typedef struct COFF_ResourceHeaderPrefix
{ {
U32 data_size; U32 data_size;
@@ -643,14 +648,12 @@ typedef struct COFF_ResourceDirEntry
//////////////////////////////// ////////////////////////////////
// !<arch>\n read_only global U8 g_coff_archive_sig[8] = "!<arch>\n";
#define COFF_ARCHIVE_SIG 0x0A3E686372613C21ULL read_only global U8 g_coff_thin_archive_sig[8] = "!<thin>\n";
// !<thin>\n
#define COFF_THIN_ARCHIVE_SIG 0xA3E6E6968743C21ULL
#define COFF_ARCHIVE_MAX_SHORT_NAME_SIZE 15
#define COFF_ARCHIVE_ALIGN 2 #define COFF_ARCHIVE_ALIGN 2
#define COFF_ARCHIVE_MAX_SHORT_NAME_SIZE 15
#define COFF_ARCHIVE_MEMBER_HEADER_SIZE 60
typedef struct COFF_ArchiveMemberHeader typedef struct COFF_ArchiveMemberHeader
{ {
@@ -817,6 +820,14 @@ typedef struct COFF_ArchiveParse
String8 long_names; String8 long_names;
} COFF_ArchiveParse; } COFF_ArchiveParse;
////////////////////////////////
typedef struct COFF_SectionHeaderArray
{
U64 count;
COFF_SectionHeader *v;
} COFF_SectionHeaderArray;
//////////////////////////////// ////////////////////////////////
//~ rjf: Globals //~ rjf: Globals
@@ -845,17 +856,47 @@ internal COFF_Symbol16Node * coff_symbol16_list_push(Arena *arena, COFF_Symbol16
internal COFF_RelocInfo coff_reloc_info_from_section_header(String8 data, COFF_SectionHeader *header); internal COFF_RelocInfo coff_reloc_info_from_section_header(String8 data, COFF_SectionHeader *header);
internal U64 coff_word_size_from_machine(COFF_MachineType machine); internal U64 coff_word_size_from_machine(COFF_MachineType machine);
internal U64 coff_default_exe_base_from_machine(COFF_MachineType machine);
internal U64 coff_default_dll_base_from_machine(COFF_MachineType machine);
internal String8 coff_make_import_lookup(Arena *arena, U16 hint, String8 name); internal String8 coff_make_import_lookup(Arena *arena, U16 hint, String8 name);
internal U32 coff_make_ordinal_32(U16 hint); internal U32 coff_make_ordinal_32(U16 hint);
internal U64 coff_make_ordinal_64(U16 hint); internal U64 coff_make_ordinal_64(U16 hint);
internal String8 coff_make_import_header_by_name(Arena *arena,
String8 dll_name,
COFF_MachineType machine,
COFF_TimeStamp time_stamp,
String8 name,
U16 hint,
COFF_ImportHeaderType type);
internal String8 coff_make_import_header_by_ordinal(Arena *arena,
String8 dll_name,
COFF_MachineType machine,
COFF_TimeStamp time_stamp,
U16 ordinal,
COFF_ImportHeaderType type);
internal B32 coff_resource_id_is_equal(COFF_ResourceID a, COFF_ResourceID b); internal B32 coff_resource_id_is_equal(COFF_ResourceID a, COFF_ResourceID b);
internal COFF_ResourceID coff_resource_id_copy(Arena *arena, COFF_ResourceID id); internal COFF_ResourceID coff_resource_id_copy(Arena *arena, COFF_ResourceID id);
internal U64 coff_sizeof_resource_id(COFF_ResourceID id);
internal COFF_ResourceID coff_convert_resource_id(Arena *arena, COFF_ResourceID_16 *id_16); internal COFF_ResourceID coff_convert_resource_id(Arena *arena, COFF_ResourceID_16 *id_16);
internal U64 coff_read_resource_id(String8 res, U64 off, COFF_ResourceID_16 *id_out); internal U64 coff_read_resource_id(String8 res, U64 off, COFF_ResourceID_16 *id_out);
internal U64 coff_read_resource(String8 data, U64 off, Arena *arena, COFF_Resource *res_out); internal U64 coff_read_resource(String8 data, U64 off, Arena *arena, COFF_Resource *res_out);
internal COFF_ResourceList coff_resource_list_from_data(Arena *arena, String8 data); internal COFF_ResourceList coff_resource_list_from_data(Arena *arena, String8 data);
internal void coff_write_resource_id(Arena *arena, String8List *srl, COFF_ResourceID id);
internal String8List coff_write_resource(Arena *arena,
COFF_ResourceID type,
COFF_ResourceID name,
U32 data_version,
COFF_ResourceMemoryFlags memory_flags,
U16 language_id,
U32 version,
U32 characteristics,
String8 data);
internal COFF_DataType coff_data_type_from_data(String8 data); internal COFF_DataType coff_data_type_from_data(String8 data);
internal B32 coff_is_import(String8 data); internal B32 coff_is_import(String8 data);
internal B32 coff_is_archive(String8 data); internal B32 coff_is_archive(String8 data);
@@ -875,8 +916,15 @@ internal COFF_ArchiveParse coff_thin_archive_from_data(Arena *arena, String8 da
internal COFF_ArchiveType coff_archive_type_from_data(String8 data); internal COFF_ArchiveType coff_archive_type_from_data(String8 data);
internal COFF_ArchiveParse coff_archive_parse_from_data(Arena *arena, String8 data); internal COFF_ArchiveParse coff_archive_parse_from_data(Arena *arena, String8 data);
////////////////////////////////
// String <-> Enum
internal String8 coff_string_from_comdat_select_type(COFF_ComdatSelectType select); internal String8 coff_string_from_comdat_select_type(COFF_ComdatSelectType select);
internal String8 coff_string_from_machine_type(COFF_MachineType machine); internal String8 coff_string_from_machine_type(COFF_MachineType machine);
internal String8 coff_string_from_section_flags(Arena *arena, COFF_SectionFlags flags); internal String8 coff_string_from_section_flags(Arena *arena, COFF_SectionFlags flags);
internal String8 coff_string_from_import_header_type(COFF_ImportHeaderType type);
internal COFF_MachineType coff_machine_from_string(String8 string);
internal COFF_ImportHeaderType coff_import_header_type_from_string(String8 name);
#endif //COFF_H #endif //COFF_H
+29 -4
View File
@@ -2,7 +2,35 @@
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
//////////////////////////////// ////////////////////////////////
//~ rjf: Tables //~ rjf: Entity Kinds
@table(name display_string)
CTRL_EntityKindTable:
{
{Root "Root" }
{Machine "Machine" }
{Process "Process" }
{Thread "Thread" }
{Module "Module" }
{EntryPoint "Entry Point" }
{DebugInfoPath "Debug Info Path" }
}
@enum CTRL_EntityKind:
{
Null,
@expand(CTRL_EntityKindTable a) `$(a.name)`,
COUNT,
}
@data(String8) ctrl_entity_kind_display_string_table:
{
`{0}`,
@expand(CTRL_EntityKindTable a) `str8_lit_comp("$(a.display_name)")`
}
////////////////////////////////
//~ rjf: Exception Codes
@table(name lower_name code default display_string) @table(name lower_name code default display_string)
CTRL_ExceptionCodeKindTable: CTRL_ExceptionCodeKindTable:
@@ -46,9 +74,6 @@ CTRL_ExceptionCodeKindTable:
{Win32DirectXDebugLayer win32_directx_debug_layer 0x0000087a 1 "(Win32) DirectX Debug Layer" } {Win32DirectXDebugLayer win32_directx_debug_layer 0x0000087a 1 "(Win32) DirectX Debug Layer" }
} }
////////////////////////////////
//~ rjf: Generators
@enum CTRL_ExceptionCodeKind: @enum CTRL_ExceptionCodeKind:
{ {
Null, Null,
+2718 -499
View File
File diff suppressed because it is too large Load Diff
+507 -78
View File
@@ -13,45 +13,244 @@ typedef U64 CTRL_MachineID;
#define CTRL_MachineID_Local (1) #define CTRL_MachineID_Local (1)
//////////////////////////////// ////////////////////////////////
//~ rjf: Machine/Handle Pair Types //~ rjf: Meta Evaluation Types
typedef struct CTRL_MachineIDHandlePair CTRL_MachineIDHandlePair; //- rjf: styled string types
struct CTRL_MachineIDHandlePair
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")),
member_lit_comp(String8, type(U64), size, .pretty_name = str8_lit_comp("Size")),
};
Member CTRL_CodeString8__members[] =
{
member_lit_comp(String8, &CTRL_CodeString8__str_ptr_type, str, .pretty_name = str8_lit_comp("Contents")),
member_lit_comp(String8, type(U64), size, .pretty_name = str8_lit_comp("Size")),
};
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")\
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)
{
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Label")),
member_lit_comp(CTRL_MetaEval, type(CTRL_PathString8), exe, .pretty_name = str8_lit_comp("Executable")),
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")),
};
struct_members(CTRL_PinMetaEval)
{
member_lit_comp(CTRL_MetaEval, type(CTRL_CodeString8), label, .pretty_name = str8_lit_comp("Expression")),
member_lit_comp(CTRL_MetaEval, type(U32), color, .pretty_name = str8_lit_comp("Color")),
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;
};
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
typedef struct CTRL_Handle CTRL_Handle;
struct CTRL_Handle
{ {
CTRL_MachineID machine_id; CTRL_MachineID machine_id;
DMN_Handle handle; DMN_Handle dmn_handle;
}; };
typedef struct CTRL_MachineIDHandlePairNode CTRL_MachineIDHandlePairNode; typedef struct CTRL_HandleNode CTRL_HandleNode;
struct CTRL_MachineIDHandlePairNode struct CTRL_HandleNode
{ {
CTRL_MachineIDHandlePairNode *next; CTRL_HandleNode *next;
CTRL_MachineIDHandlePair v; CTRL_Handle v;
}; };
typedef struct CTRL_MachineIDHandlePairList CTRL_MachineIDHandlePairList; typedef struct CTRL_HandleList CTRL_HandleList;
struct CTRL_MachineIDHandlePairList struct CTRL_HandleList
{ {
CTRL_MachineIDHandlePairNode *first; CTRL_HandleNode *first;
CTRL_MachineIDHandlePairNode *last; CTRL_HandleNode *last;
U64 count; U64 count;
}; };
//////////////////////////////// ////////////////////////////////
//~ rjf: Entity Types //~ rjf: Generated Code
typedef enum CTRL_EntityKind #include "generated/ctrl.meta.h"
{
CTRL_EntityKind_Null, ////////////////////////////////
CTRL_EntityKind_Root, //~ rjf: Entity Types
CTRL_EntityKind_Machine,
CTRL_EntityKind_Process,
CTRL_EntityKind_Thread,
CTRL_EntityKind_Module,
CTRL_EntityKind_EntryPoint,
CTRL_EntityKind_COUNT
}
CTRL_EntityKind;
typedef struct CTRL_Entity CTRL_Entity; typedef struct CTRL_Entity CTRL_Entity;
struct CTRL_Entity struct CTRL_Entity
@@ -62,14 +261,47 @@ struct CTRL_Entity
CTRL_Entity *prev; CTRL_Entity *prev;
CTRL_Entity *parent; CTRL_Entity *parent;
CTRL_EntityKind kind; CTRL_EntityKind kind;
Architecture arch; Arch arch;
CTRL_MachineID machine_id; B32 is_frozen;
DMN_Handle handle; U32 rgba;
CTRL_Handle handle;
U64 id; U64 id;
Rng1U64 vaddr_range; Rng1U64 vaddr_range;
U64 stack_base;
U64 timestamp;
String8 string; String8 string;
}; };
typedef struct CTRL_EntityNode CTRL_EntityNode;
struct CTRL_EntityNode
{
CTRL_EntityNode *next;
CTRL_Entity *v;
};
typedef struct CTRL_EntityList CTRL_EntityList;
struct CTRL_EntityList
{
CTRL_EntityNode *first;
CTRL_EntityNode *last;
U64 count;
};
typedef struct CTRL_EntityArray CTRL_EntityArray;
struct CTRL_EntityArray
{
CTRL_Entity **v;
U64 count;
};
typedef struct CTRL_EntityRec CTRL_EntityRec;
struct CTRL_EntityRec
{
CTRL_Entity *next;
S32 push_count;
S64 pop_count;
};
typedef struct CTRL_EntityHashNode CTRL_EntityHashNode; typedef struct CTRL_EntityHashNode CTRL_EntityHashNode;
struct CTRL_EntityHashNode struct CTRL_EntityHashNode
{ {
@@ -102,27 +334,86 @@ struct CTRL_EntityStore
CTRL_EntityHashNode *hash_node_free; CTRL_EntityHashNode *hash_node_free;
U64 hash_slots_count; U64 hash_slots_count;
CTRL_EntityStringChunkNode *free_string_chunks[8]; CTRL_EntityStringChunkNode *free_string_chunks[8];
U64 entity_kind_counts[CTRL_EntityKind_COUNT];
Arena *entity_kind_lists_arenas[CTRL_EntityKind_COUNT];
U64 entity_kind_lists_gens[CTRL_EntityKind_COUNT];
U64 entity_kind_alloc_gens[CTRL_EntityKind_COUNT];
CTRL_EntityList entity_kind_lists[CTRL_EntityKind_COUNT];
}; };
//////////////////////////////// ////////////////////////////////
//~ rjf: Unwind Types //~ rjf: Unwind Types
typedef U32 CTRL_UnwindFlags;
enum
{
CTRL_UnwindFlag_Error = (1<<0),
CTRL_UnwindFlag_Stale = (1<<1),
};
typedef struct CTRL_UnwindStepResult CTRL_UnwindStepResult;
struct CTRL_UnwindStepResult
{
CTRL_UnwindFlags flags;
};
typedef struct CTRL_UnwindFrame CTRL_UnwindFrame; typedef struct CTRL_UnwindFrame CTRL_UnwindFrame;
struct CTRL_UnwindFrame struct CTRL_UnwindFrame
{ {
CTRL_UnwindFrame *next;
CTRL_UnwindFrame *prev;
U64 rip;
void *regs; void *regs;
}; };
typedef struct CTRL_UnwindFrameNode CTRL_UnwindFrameNode;
struct CTRL_UnwindFrameNode
{
CTRL_UnwindFrameNode *next;
CTRL_UnwindFrameNode *prev;
CTRL_UnwindFrame v;
};
typedef struct CTRL_UnwindFrameArray CTRL_UnwindFrameArray;
struct CTRL_UnwindFrameArray
{
CTRL_UnwindFrame *v;
U64 count;
};
typedef struct CTRL_Unwind CTRL_Unwind; typedef struct CTRL_Unwind CTRL_Unwind;
struct CTRL_Unwind struct CTRL_Unwind
{ {
CTRL_UnwindFrame *first; CTRL_UnwindFrameArray frames;
CTRL_UnwindFrame *last; CTRL_UnwindFlags flags;
U64 count; };
B32 error;
////////////////////////////////
//~ 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;
struct CTRL_CallStackFrame
{
CTRL_CallStackInlineFrame *first_inline_frame;
CTRL_CallStackInlineFrame *last_inline_frame;
U64 inline_frame_count;
void *regs;
RDI_Parsed *rdi;
RDI_Procedure *procedure;
};
typedef struct CTRL_CallStack CTRL_CallStack;
struct CTRL_CallStack
{
CTRL_CallStackFrame *frames;
U64 concrete_frame_count;
U64 inline_frame_count;
U64 total_frame_count;
}; };
//////////////////////////////// ////////////////////////////////
@@ -174,6 +465,7 @@ struct CTRL_Spoof
typedef enum CTRL_UserBreakpointKind typedef enum CTRL_UserBreakpointKind
{ {
CTRL_UserBreakpointKind_Null,
CTRL_UserBreakpointKind_FileNameAndLineColNumber, CTRL_UserBreakpointKind_FileNameAndLineColNumber,
CTRL_UserBreakpointKind_SymbolNameAndOffset, CTRL_UserBreakpointKind_SymbolNameAndOffset,
CTRL_UserBreakpointKind_VirtualAddress, CTRL_UserBreakpointKind_VirtualAddress,
@@ -207,9 +499,14 @@ struct CTRL_UserBreakpointList
}; };
//////////////////////////////// ////////////////////////////////
//~ rjf: Generated Code //~ rjf: Evaluation Spaces
#include "generated/ctrl.meta.h" typedef U64 CTRL_EvalSpaceKind;
enum
{
CTRL_EvalSpaceKind_Entity = E_SpaceKind_FirstUserDefined,
CTRL_EvalSpaceKind_Meta,
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Message Types //~ rjf: Message Types
@@ -224,6 +521,9 @@ typedef enum CTRL_MsgKind
CTRL_MsgKind_Run, CTRL_MsgKind_Run,
CTRL_MsgKind_SingleStep, CTRL_MsgKind_SingleStep,
CTRL_MsgKind_SetUserEntryPoints, CTRL_MsgKind_SetUserEntryPoints,
CTRL_MsgKind_SetModuleDebugInfoPath,
CTRL_MsgKind_FreezeThread,
CTRL_MsgKind_ThawThread,
CTRL_MsgKind_COUNT, CTRL_MsgKind_COUNT,
} }
CTRL_MsgKind; CTRL_MsgKind;
@@ -240,9 +540,8 @@ struct CTRL_Msg
CTRL_MsgKind kind; CTRL_MsgKind kind;
CTRL_RunFlags run_flags; CTRL_RunFlags run_flags;
CTRL_MsgID msg_id; CTRL_MsgID msg_id;
CTRL_MachineID machine_id; CTRL_Handle entity;
DMN_Handle entity; CTRL_Handle parent;
DMN_Handle parent;
U32 entity_id; U32 entity_id;
U32 exit_code; U32 exit_code;
B32 env_inherit; B32 env_inherit;
@@ -251,10 +550,12 @@ struct CTRL_Msg
String8List entry_points; String8List entry_points;
String8List cmd_line_string_list; String8List cmd_line_string_list;
String8List env_string_list; String8List env_string_list;
String8 stdout_path;
String8 stderr_path;
String8 stdin_path;
CTRL_TrapList traps; CTRL_TrapList traps;
CTRL_UserBreakpointList user_bps; CTRL_UserBreakpointList user_bps;
CTRL_MachineIDHandlePairList freeze_state_threads; // NOTE(rjf): can be frozen or unfrozen, depending on `freeze_state_is_frozen` CTRL_MetaEvalArray meta_evals;
B32 freeze_state_is_frozen;
}; };
typedef struct CTRL_MsgNode CTRL_MsgNode; typedef struct CTRL_MsgNode CTRL_MsgNode;
@@ -292,9 +593,17 @@ typedef enum CTRL_EventKind
CTRL_EventKind_EndThread, CTRL_EventKind_EndThread,
CTRL_EventKind_EndModule, CTRL_EventKind_EndModule,
//- rjf: debug strings //- rjf: thread freeze state changes
CTRL_EventKind_ThreadFrozen,
CTRL_EventKind_ThreadThawed,
//- rjf: debug info changes
CTRL_EventKind_ModuleDebugInfoPathChange,
//- rjf: debug strings / decorations
CTRL_EventKind_DebugString, CTRL_EventKind_DebugString,
CTRL_EventKind_ThreadName, CTRL_EventKind_ThreadName,
CTRL_EventKind_ThreadColor,
//- rjf: memory //- rjf: memory
CTRL_EventKind_MemReserve, CTRL_EventKind_MemReserve,
@@ -338,17 +647,18 @@ struct CTRL_Event
CTRL_EventCause cause; CTRL_EventCause cause;
CTRL_ExceptionKind exception_kind; CTRL_ExceptionKind exception_kind;
CTRL_MsgID msg_id; CTRL_MsgID msg_id;
CTRL_MachineID machine_id; CTRL_Handle entity;
DMN_Handle entity; CTRL_Handle parent;
DMN_Handle parent; Arch arch;
Architecture arch;
U64 u64_code; U64 u64_code;
U32 entity_id; U32 entity_id;
Rng1U64 vaddr_rng; Rng1U64 vaddr_rng;
U64 rip_vaddr; U64 rip_vaddr;
U64 stack_base; U64 stack_base;
U64 tls_root; U64 tls_root;
U64 timestamp;
U32 exception_code; U32 exception_code;
U32 rgba;
String8 string; String8 string;
}; };
@@ -396,8 +706,7 @@ struct CTRL_ProcessMemoryCacheNode
CTRL_ProcessMemoryCacheNode *next; CTRL_ProcessMemoryCacheNode *next;
CTRL_ProcessMemoryCacheNode *prev; CTRL_ProcessMemoryCacheNode *prev;
Arena *arena; Arena *arena;
CTRL_MachineID machine_id; CTRL_Handle handle;
DMN_Handle process;
U64 range_hash_slots_count; U64 range_hash_slots_count;
CTRL_ProcessMemoryRangeHashSlot *range_hash_slots; CTRL_ProcessMemoryRangeHashSlot *range_hash_slots;
}; };
@@ -444,8 +753,7 @@ struct CTRL_ThreadRegCacheNode
{ {
CTRL_ThreadRegCacheNode *next; CTRL_ThreadRegCacheNode *next;
CTRL_ThreadRegCacheNode *prev; CTRL_ThreadRegCacheNode *prev;
CTRL_MachineID machine_id; CTRL_Handle handle;
DMN_Handle thread;
U64 block_size; U64 block_size;
void *block; void *block;
U64 reg_gen; U64 reg_gen;
@@ -474,6 +782,46 @@ struct CTRL_ThreadRegCache
CTRL_ThreadRegCacheStripe *stripes; CTRL_ThreadRegCacheStripe *stripes;
}; };
////////////////////////////////
//~ rjf: Module Image Info Cache Types
typedef struct CTRL_ModuleImageInfoCacheNode CTRL_ModuleImageInfoCacheNode;
struct CTRL_ModuleImageInfoCacheNode
{
CTRL_ModuleImageInfoCacheNode *next;
CTRL_ModuleImageInfoCacheNode *prev;
CTRL_Handle module;
Arena *arena;
PE_IntelPdata *pdatas;
U64 pdatas_count;
U64 entry_point_voff;
Rng1U64 tls_vaddr_range;
String8 initial_debug_info_path;
};
typedef struct CTRL_ModuleImageInfoCacheSlot CTRL_ModuleImageInfoCacheSlot;
struct CTRL_ModuleImageInfoCacheSlot
{
CTRL_ModuleImageInfoCacheNode *first;
CTRL_ModuleImageInfoCacheNode *last;
};
typedef struct CTRL_ModuleImageInfoCacheStripe CTRL_ModuleImageInfoCacheStripe;
struct CTRL_ModuleImageInfoCacheStripe
{
Arena *arena;
OS_Handle rw_mutex;
};
typedef struct CTRL_ModuleImageInfoCache CTRL_ModuleImageInfoCache;
struct CTRL_ModuleImageInfoCache
{
U64 slots_count;
CTRL_ModuleImageInfoCacheSlot *slots;
U64 stripes_count;
CTRL_ModuleImageInfoCacheStripe *stripes;
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Wakeup Hook Function Types //~ rjf: Wakeup Hook Function Types
@@ -490,12 +838,13 @@ struct CTRL_State
CTRL_WakeupFunctionType *wakeup_hook; CTRL_WakeupFunctionType *wakeup_hook;
// rjf: name -> register/alias hash tables for eval // rjf: name -> register/alias hash tables for eval
EVAL_String2NumMap arch_string2reg_tables[Architecture_COUNT]; E_String2NumMap arch_string2reg_tables[Arch_COUNT];
EVAL_String2NumMap arch_string2alias_tables[Architecture_COUNT]; E_String2NumMap arch_string2alias_tables[Arch_COUNT];
// 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_ModuleImageInfoCache module_image_info_cache;
// rjf: user -> ctrl msg ring buffer // rjf: user -> ctrl msg ring buffer
U64 u2c_ring_size; U64 u2c_ring_size;
@@ -507,6 +856,7 @@ struct CTRL_State
// rjf: ctrl -> user event ring buffer // rjf: ctrl -> user event ring buffer
U64 c2u_ring_size; U64 c2u_ring_size;
U64 c2u_ring_max_string_size;
U8 *c2u_ring_base; U8 *c2u_ring_base;
U64 c2u_ring_write_pos; U64 c2u_ring_write_pos;
U64 c2u_ring_read_pos; U64 c2u_ring_read_pos;
@@ -514,7 +864,9 @@ struct CTRL_State
OS_Handle c2u_ring_cv; OS_Handle c2u_ring_cv;
// rjf: ctrl thread state // rjf: ctrl thread state
String8 ctrl_thread_log_path;
OS_Handle ctrl_thread; OS_Handle ctrl_thread;
Log *ctrl_thread_log;
CTRL_EntityStore *ctrl_thread_entity_store; CTRL_EntityStore *ctrl_thread_entity_store;
Arena *dmn_event_arena; Arena *dmn_event_arena;
DMN_EventNode *first_dmn_event_node; DMN_EventNode *first_dmn_event_node;
@@ -522,6 +874,8 @@ struct CTRL_State
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;
@@ -551,18 +905,28 @@ read_only global CTRL_Entity ctrl_entity_nil =
&ctrl_entity_nil, &ctrl_entity_nil,
}; };
////////////////////////////////
//~ rjf: Logging Markup
#define CTRL_CtrlThreadLogScope DeferLoop(log_scope_begin(), ctrl_thread__end_and_flush_info_log())
//////////////////////////////// ////////////////////////////////
//~ rjf: Basic Type Functions //~ rjf: Basic Type Functions
internal U64 ctrl_hash_from_string(String8 string); internal U64 ctrl_hash_from_string(String8 string);
internal U64 ctrl_hash_from_machine_id_handle(CTRL_MachineID machine_id, DMN_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 String8 ctrl_string_from_event_kind(CTRL_EventKind kind);
internal String8 ctrl_string_from_msg_kind(CTRL_MsgKind kind);
//////////////////////////////// ////////////////////////////////
//~ rjf: Machine/Handle Pair Type Functions //~ rjf: Handle Type Functions
internal void ctrl_machine_id_handle_pair_list_push(Arena *arena, CTRL_MachineIDHandlePairList *list, CTRL_MachineIDHandlePair *pair); internal CTRL_Handle ctrl_handle_zero(void);
internal CTRL_MachineIDHandlePairList ctrl_machine_id_handle_pair_list_copy(Arena *arena, CTRL_MachineIDHandlePairList *src); internal CTRL_Handle ctrl_handle_make(CTRL_MachineID machine_id, DMN_Handle dmn_handle);
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 CTRL_HandleList ctrl_handle_list_copy(Arena *arena, CTRL_HandleList *src);
//////////////////////////////// ////////////////////////////////
//~ rjf: Trap Type Functions //~ rjf: Trap Type Functions
@@ -584,6 +948,8 @@ internal void ctrl_msg_deep_copy(Arena *arena, CTRL_Msg *dst, CTRL_Msg *src);
//- rjf: list building //- rjf: list building
internal CTRL_Msg *ctrl_msg_list_push(Arena *arena, CTRL_MsgList *list); internal CTRL_Msg *ctrl_msg_list_push(Arena *arena, CTRL_MsgList *list);
internal CTRL_MsgList ctrl_msg_list_deep_copy(Arena *arena, CTRL_MsgList *src);
internal void ctrl_msg_list_concat_in_place(CTRL_MsgList *dst, CTRL_MsgList *src);
//- rjf: serialization //- rjf: serialization
internal String8 ctrl_serialized_string_from_msg_list(Arena *arena, CTRL_MsgList *msgs); internal String8 ctrl_serialized_string_from_msg_list(Arena *arena, CTRL_MsgList *msgs);
@@ -597,29 +963,56 @@ internal CTRL_Event *ctrl_event_list_push(Arena *arena, CTRL_EventList *list);
internal void ctrl_event_list_concat_in_place(CTRL_EventList *dst, CTRL_EventList *to_push); internal void ctrl_event_list_concat_in_place(CTRL_EventList *dst, CTRL_EventList *to_push);
//- rjf: serialization //- rjf: serialization
internal String8 ctrl_serialized_string_from_event(Arena *arena, CTRL_Event *event); internal String8 ctrl_serialized_string_from_event(Arena *arena, CTRL_Event *event, U64 max);
internal CTRL_Event ctrl_event_from_serialized_string(Arena *arena, String8 string); internal CTRL_Event ctrl_event_from_serialized_string(Arena *arena, String8 string);
//////////////////////////////// ////////////////////////////////
//~ rjf: Entity Type Functions //~ rjf: Entity Type Functions
//- rjf: entity list data structures
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);
#define ctrl_entity_list_first(list) ((list)->first ? (list)->first->v : &ctrl_entity_nil)
//- rjf: entity array data structure
internal CTRL_EntityArray ctrl_entity_array_from_list(Arena *arena, CTRL_EntityList *list);
//- rjf: cache creation/destruction //- rjf: cache creation/destruction
internal CTRL_EntityStore *ctrl_entity_store_alloc(void); internal CTRL_EntityStore *ctrl_entity_store_alloc(void);
internal void ctrl_entity_store_release(CTRL_EntityStore *store); internal void ctrl_entity_store_release(CTRL_EntityStore *store);
//- rjf: string allocation/deletion //- 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 String8 ctrl_entity_string_alloc(CTRL_EntityStore *store, String8 string);
internal void ctrl_entity_string_release(CTRL_EntityStore *store, String8 string); internal void ctrl_entity_string_release(CTRL_EntityStore *store, String8 string);
//- rjf: entity construction/deletion //- rjf: entity construction/deletion
internal CTRL_Entity *ctrl_entity_alloc(CTRL_EntityStore *store, CTRL_Entity *parent, CTRL_EntityKind kind, Architecture arch, CTRL_MachineID machine_id, DMN_Handle handle, U64 id); internal 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); internal void ctrl_entity_release(CTRL_EntityStore *store, CTRL_Entity *entity);
//- rjf: entity equipment //- rjf: entity equipment
internal void ctrl_entity_equip_string(CTRL_EntityStore *store, CTRL_Entity *entity, String8 string); internal void ctrl_entity_equip_string(CTRL_EntityStore *store, CTRL_Entity *entity, String8 string);
//- rjf: entity store lookups //- rjf: entity store lookups
internal CTRL_Entity *ctrl_entity_from_machine_id_handle(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle handle); internal CTRL_Entity *ctrl_entity_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_ancestor_from_kind(CTRL_Entity *entity, CTRL_EntityKind kind);
internal CTRL_Entity *ctrl_process_from_entity(CTRL_Entity *entity);
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 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_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_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_voff_range_from_vaddr_range(CTRL_Entity *module, Rng1U64 vaddr_range);
internal B32 ctrl_entity_tree_is_frozen(CTRL_Entity *root);
//- rjf: entity tree iteration
internal CTRL_EntityRec ctrl_entity_rec_depth_first(CTRL_Entity *entity, CTRL_Entity *subtree_root, U64 sib_off, U64 child_off);
#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))
//- 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_EntityStore *store, CTRL_EventList *list);
@@ -638,34 +1031,62 @@ 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 interaction
internal U128 ctrl_calc_hash_store_key_from_process_vaddr_range(CTRL_MachineID machine_id, DMN_Handle process, Rng1U64 range, B32 zero_terminated); internal U128 ctrl_calc_hash_store_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 range, B32 zero_terminated);
internal U128 ctrl_stored_hash_from_process_vaddr_range(CTRL_MachineID machine_id, DMN_Handle process, Rng1U64 range, B32 zero_terminated, B32 *out_is_stale, U64 endt_us); 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 //- rjf: bundled key/stream helper
internal U128 ctrl_hash_store_key_from_process_vaddr_range(CTRL_MachineID machine_id, DMN_Handle process, Rng1U64 range, B32 zero_terminated); 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_MachineID machine_id, DMN_Handle process, Rng1U64 range, U64 endt_us); 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_query_cached_zero_terminated_data_from_process_vaddr_limit(Arena *arena, CTRL_MachineID machine_id, DMN_Handle process, U64 vaddr, U64 limit, U64 element_size, U64 endt_us); internal 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_read_cached_process_memory(CTRL_Handle process, Rng1U64 range, B32 *is_stale_out, void *out, U64 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_MachineID machine_id, DMN_Handle process, Rng1U64 range, void *src); 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_MachineID machine_id, DMN_Handle thread); internal void *ctrl_query_cached_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle handle);
internal U64 ctrl_query_cached_tls_root_vaddr_from_thread(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle thread); internal U64 ctrl_query_cached_tls_root_vaddr_from_thread(CTRL_EntityStore *store, CTRL_Handle handle);
internal U64 ctrl_query_cached_rip_from_thread(CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle thread); internal U64 ctrl_query_cached_rip_from_thread(CTRL_EntityStore *store, CTRL_Handle handle);
internal U64 ctrl_query_cached_rsp_from_thread(CTRL_EntityStore *store, CTRL_Handle handle);
//- rjf: thread register writing //- rjf: thread register writing
internal B32 ctrl_thread_write_reg_block(CTRL_MachineID machine_id, DMN_Handle thread, void *block); internal B32 ctrl_thread_write_reg_block(CTRL_Handle thread, void *block);
////////////////////////////////
//~ rjf: Module Image Info Functions
//- rjf: cache lookups
internal PE_IntelPdata *ctrl_intel_pdata_from_module_voff(Arena *arena, CTRL_Handle module_handle, U64 voff);
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 String8 ctrl_initial_debug_info_path_from_module(Arena *arena, CTRL_Handle module_handle);
//////////////////////////////// ////////////////////////////////
//~ rjf: Unwinding Functions //~ rjf: Unwinding Functions
internal CTRL_Unwind ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_MachineID machine_id, DMN_Handle thread, U64 endt_us); //- rjf: unwind deep copier
internal CTRL_Unwind ctrl_unwind_deep_copy(Arena *arena, Arch arch, CTRL_Unwind *src);
//- rjf: [x64]
internal REGS_Reg64 *ctrl_unwind_reg_from_pe_gpr_reg__pe_x64(REGS_RegBlockX64 *regs, PE_UnwindGprRegX64 gpr_reg);
internal CTRL_UnwindStepResult ctrl_unwind_step__pe_x64(CTRL_EntityStore *store, CTRL_Handle process_handle, CTRL_Handle module_handle, REGS_RegBlockX64 *regs, U64 endt_us);
//- 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);
//- rjf: abstracted full unwind
internal CTRL_Unwind ctrl_unwind_from_thread(Arena *arena, CTRL_EntityStore *store, CTRL_Handle thread, U64 endt_us);
////////////////////////////////
//~ 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);
//////////////////////////////// ////////////////////////////////
//~ rjf: Halting All Attached Processes //~ rjf: Halting All Attached Processes
@@ -681,8 +1102,8 @@ internal U64 ctrl_mem_gen(void);
internal U64 ctrl_reg_gen(void); internal U64 ctrl_reg_gen(void);
//- rjf: name -> register/alias hash tables, for eval //- rjf: name -> register/alias hash tables, for eval
internal EVAL_String2NumMap *ctrl_string2reg_from_arch(Architecture arch); internal E_String2NumMap *ctrl_string2reg_from_arch(Arch arch);
internal EVAL_String2NumMap *ctrl_string2alias_from_arch(Architecture arch); internal E_String2NumMap *ctrl_string2alias_from_arch(Arch arch);
//////////////////////////////// ////////////////////////////////
//~ rjf: Control-Thread Functions //~ rjf: Control-Thread Functions
@@ -699,14 +1120,22 @@ 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_MachineID machine_id, DMN_Handle process, DMN_Handle module, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); 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_process_user_bp_traps(Arena *arena, CTRL_MachineID machine_id, DMN_Handle process, 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);
//- 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_close(CTRL_Handle module);
//- 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);
//- rjf: eval helpers //- rjf: eval helpers
internal B32 ctrl_eval_memory_read(void *u, void *out, U64 addr, U64 size); internal B32 ctrl_eval_space_read(void *u, E_Space space, void *out, Rng1U64 vaddr_range);
//- rjf: log flusher
internal void ctrl_thread__flush_info_log(String8 string);
internal void ctrl_thread__end_and_flush_info_log(void);
//- rjf: msg kind implementations //- rjf: msg kind implementations
internal void ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg); internal void ctrl_thread__launch(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
@@ -720,8 +1149,8 @@ internal void ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
//~ rjf: Memory-Stream Thread Functions //~ rjf: Memory-Stream Thread Functions
//- rjf: user -> memory stream communication //- rjf: user -> memory stream communication
internal B32 ctrl_u2ms_enqueue_req(CTRL_MachineID machine_id, DMN_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us); internal B32 ctrl_u2ms_enqueue_req(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us);
internal void ctrl_u2ms_dequeue_req(CTRL_MachineID *out_machine_id, DMN_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated); internal void ctrl_u2ms_dequeue_req(CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated);
//- rjf: entry point //- rjf: entry point
internal void ctrl_mem_stream_thread__entry_point(void *p); internal void ctrl_mem_stream_thread__entry_point(void *p);
+12
View File
@@ -4,6 +4,18 @@
//- GENERATED CODE //- GENERATED CODE
C_LINKAGE_BEGIN C_LINKAGE_BEGIN
String8 ctrl_entity_kind_display_string_table[8] =
{
{0},
str8_lit_comp("Root"),
str8_lit_comp("Machine"),
str8_lit_comp("Process"),
str8_lit_comp("Thread"),
str8_lit_comp("Module"),
str8_lit_comp("EntryPoint"),
str8_lit_comp("DebugInfoPath"),
};
U32 ctrl_exception_code_kind_code_table[38] = U32 ctrl_exception_code_kind_code_table[38] =
{ {
0, 0,
+15
View File
@@ -6,6 +6,19 @@
#ifndef CTRL_META_H #ifndef CTRL_META_H
#define CTRL_META_H #define CTRL_META_H
typedef enum CTRL_EntityKind
{
CTRL_EntityKind_Null,
CTRL_EntityKind_Root,
CTRL_EntityKind_Machine,
CTRL_EntityKind_Process,
CTRL_EntityKind_Thread,
CTRL_EntityKind_Module,
CTRL_EntityKind_EntryPoint,
CTRL_EntityKind_DebugInfoPath,
CTRL_EntityKind_COUNT,
} CTRL_EntityKind;
typedef enum CTRL_ExceptionCodeKind typedef enum CTRL_ExceptionCodeKind
{ {
CTRL_ExceptionCodeKind_Null, CTRL_ExceptionCodeKind_Null,
@@ -50,10 +63,12 @@ CTRL_ExceptionCodeKind_COUNT,
} CTRL_ExceptionCodeKind; } CTRL_ExceptionCodeKind;
C_LINKAGE_BEGIN C_LINKAGE_BEGIN
extern String8 ctrl_entity_kind_display_string_table[8];
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];
extern B8 ctrl_exception_code_kind_default_enable_table[38]; extern B8 ctrl_exception_code_kind_default_enable_table[38];
C_LINKAGE_END C_LINKAGE_END
#endif // CTRL_META_H #endif // CTRL_META_H
+427 -151
View File
@@ -2,69 +2,239 @@
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
//////////////////////////////// ////////////////////////////////
//~ rjf: Third Party Includes //~ rjf: Instruction Decoding/Disassembling Type Functions
#include "third_party/udis86/config.h" #if !defined(ZYDIS_H)
#include "third_party/udis86/udis86.h" #include "third_party/zydis/zydis.h"
#include "third_party/udis86/libudis86/decode.c" #include "third_party/zydis/zydis.c"
#include "third_party/udis86/libudis86/itab.c" #endif
#include "third_party/udis86/libudis86/syn-att.c"
#include "third_party/udis86/libudis86/syn-intel.c" internal DASM_Inst
#include "third_party/udis86/libudis86/syn.c" dasm_inst_from_code(Arena *arena, Arch arch, U64 vaddr, String8 code, DASM_Syntax syntax)
#include "third_party/udis86/libudis86/udis86.c" {
DASM_Inst inst = {0};
switch(arch)
{
default:{}break;
//- rjf: x86/x64 disassembly
case Arch_x86:
case Arch_x64:
{
// rjf: determine zydis formatter style
ZydisFormatterStyle style = ZYDIS_FORMATTER_STYLE_INTEL;
switch(syntax)
{
default:{}break;
case DASM_Syntax_Intel:{style = ZYDIS_FORMATTER_STYLE_INTEL;}break;
case DASM_Syntax_ATT: {style = ZYDIS_FORMATTER_STYLE_ATT;}break;
}
// rjf: disassemble one instruction
ZydisDisassembledInstruction zinst = {0};
ZyanStatus status = ZydisDisassemble(ZYDIS_MACHINE_MODE_LONG_64, vaddr, code.str, code.size, &zinst, style);
// rjf: analyze
DASM_InstFlags flags = 0;
U64 jump_dest_vaddr = 0;
{
ZydisDecodedOperand *first_visible_op = (zinst.info.operand_count_visible > 0 ? &zinst.operands[0] : 0);
ZydisDecodedOperand *first_op = (zinst.info.operand_count > 0 ? &zinst.operands[0] : 0);
ZydisDecodedOperand *second_op = (zinst.info.operand_count > 1 ? &zinst.operands[1] : 0);
if(first_visible_op != 0)
{
ZydisCalcAbsoluteAddress(&zinst.info, first_visible_op, vaddr, &jump_dest_vaddr);
}
if(first_op != 0 && second_op != 0 && first_op->type == ZYDIS_OPERAND_TYPE_REGISTER &&
(first_op->reg.value == ZYDIS_REGISTER_RSP ||
first_op->reg.value == ZYDIS_REGISTER_ESP ||
first_op->reg.value == ZYDIS_REGISTER_SP))
{
flags |= DASM_InstFlag_ChangesStackPointer;
if(second_op->type != ZYDIS_OPERAND_TYPE_IMMEDIATE)
{
flags |= DASM_InstFlag_ChangesStackPointerVariably;
}
}
if(zinst.info.attributes & (ZYDIS_ATTRIB_HAS_REP|
ZYDIS_ATTRIB_HAS_REPE|
ZYDIS_ATTRIB_HAS_REPZ|
ZYDIS_ATTRIB_HAS_REPNZ|
ZYDIS_ATTRIB_HAS_REPNE))
{
flags |= DASM_InstFlag_Repeats;
}
switch(zinst.info.mnemonic)
{
case ZYDIS_MNEMONIC_CALL:
{
flags |= DASM_InstFlag_Call;
}break;
case ZYDIS_MNEMONIC_JB:
case ZYDIS_MNEMONIC_JBE:
case ZYDIS_MNEMONIC_JCXZ:
case ZYDIS_MNEMONIC_JECXZ:
case ZYDIS_MNEMONIC_JKNZD:
case ZYDIS_MNEMONIC_JKZD:
case ZYDIS_MNEMONIC_JL:
case ZYDIS_MNEMONIC_JLE:
case ZYDIS_MNEMONIC_JNB:
case ZYDIS_MNEMONIC_JNBE:
case ZYDIS_MNEMONIC_JNL:
case ZYDIS_MNEMONIC_JNLE:
case ZYDIS_MNEMONIC_JNO:
case ZYDIS_MNEMONIC_JNP:
case ZYDIS_MNEMONIC_JNS:
case ZYDIS_MNEMONIC_JNZ:
case ZYDIS_MNEMONIC_JO:
case ZYDIS_MNEMONIC_JP:
case ZYDIS_MNEMONIC_JRCXZ:
case ZYDIS_MNEMONIC_JS:
case ZYDIS_MNEMONIC_JZ:
case ZYDIS_MNEMONIC_LOOP:
case ZYDIS_MNEMONIC_LOOPE:
case ZYDIS_MNEMONIC_LOOPNE:
{
flags |= DASM_InstFlag_Branch;
}break;
case ZYDIS_MNEMONIC_JMP:
{
flags |= DASM_InstFlag_UnconditionalJump;
}break;
case ZYDIS_MNEMONIC_RET:
{
flags |= DASM_InstFlag_Return;
}break;
case ZYDIS_MNEMONIC_PUSH:
case ZYDIS_MNEMONIC_POP:
{
flags |= DASM_InstFlag_ChangesStackPointer;
}break;
default:
{
flags |= DASM_InstFlag_NonFlow;
}break;
}
}
// rjf: convert
{
inst.flags = flags;
inst.size = zinst.info.length;
inst.string = push_str8_copy(arena, str8_cstring(zinst.text));
inst.jump_dest_vaddr = jump_dest_vaddr;
}
}break;
}
return inst;
}
//////////////////////////////// ////////////////////////////////
//~ rjf: Instruction Type Functions //~ rjf: Control Flow Analysis
internal DASM_CtrlFlowInfo
dasm_ctrl_flow_info_from_arch_vaddr_code(Arena *arena, DASM_InstFlags exit_points_mask, Arch arch, U64 vaddr, String8 code)
{
Temp scratch = scratch_begin(&arena, 1);
DASM_CtrlFlowInfo info = {0};
for(U64 offset = 0; offset < code.size;)
{
DASM_Inst inst = dasm_inst_from_code(scratch.arena, arch, vaddr+offset, str8_skip(code, offset), DASM_Syntax_Intel);
U64 inst_vaddr = vaddr+offset;
offset += inst.size;
info.total_size += inst.size;
if(inst.flags & exit_points_mask)
{
DASM_CtrlFlowPoint point = {0};
point.inst_flags = inst.flags;
point.vaddr = inst_vaddr;
point.jump_dest_vaddr = inst.jump_dest_vaddr;
DASM_CtrlFlowPointNode *node = push_array(arena, DASM_CtrlFlowPointNode, 1);
node->v = point;
SLLQueuePush(info.exit_points.first, info.exit_points.last, node);
info.exit_points.count += 1;
}
}
scratch_end(scratch);
return info;
}
////////////////////////////////
//~ rjf: Parameter Type Functions
internal B32
dasm_params_match(DASM_Params *a, DASM_Params *b)
{
B32 result = (a->vaddr == b->vaddr &&
a->arch == b->arch &&
a->style_flags == b->style_flags &&
a->syntax == b->syntax &&
a->base_vaddr == b->base_vaddr &&
di_key_match(&a->dbgi_key, &b->dbgi_key));
return result;
}
////////////////////////////////
//~ rjf: Line Type Functions
internal void internal void
dasm_inst_chunk_list_push(Arena *arena, DASM_InstChunkList *list, U64 cap, DASM_Inst *inst) dasm_line_chunk_list_push(Arena *arena, DASM_LineChunkList *list, U64 cap, DASM_Line *inst)
{ {
DASM_InstChunkNode *node = list->last; DASM_LineChunkNode *node = list->last;
if(node == 0 || node->count >= node->cap) if(node == 0 || node->count >= node->cap)
{ {
node = push_array(arena, DASM_InstChunkNode, 1); node = push_array(arena, DASM_LineChunkNode, 1);
node->v = push_array_no_zero(arena, DASM_Inst, cap); node->v = push_array_no_zero(arena, DASM_Line, cap);
node->cap = cap; node->cap = cap;
SLLQueuePush(list->first, list->last, node); SLLQueuePush(list->first, list->last, node);
list->node_count += 1; list->node_count += 1;
} }
MemoryCopyStruct(&node->v[node->count], inst); MemoryCopyStruct(&node->v[node->count], inst);
node->count += 1; node->count += 1;
list->inst_count += 1; list->line_count += 1;
} }
internal DASM_InstArray internal DASM_LineArray
dasm_inst_array_from_chunk_list(Arena *arena, DASM_InstChunkList *list) dasm_line_array_from_chunk_list(Arena *arena, DASM_LineChunkList *list)
{ {
DASM_InstArray array = {0}; DASM_LineArray array = {0};
array.count = list->inst_count; array.count = list->line_count;
array.v = push_array_no_zero(arena, DASM_Inst, array.count); array.v = push_array_no_zero(arena, DASM_Line, array.count);
U64 idx = 0; U64 idx = 0;
for(DASM_InstChunkNode *n = list->first; n != 0; n = n->next) for(DASM_LineChunkNode *n = list->first; n != 0; n = n->next)
{ {
MemoryCopy(array.v+idx, n->v, sizeof(DASM_Inst)*n->count); MemoryCopy(array.v+idx, n->v, sizeof(DASM_Line)*n->count);
idx += n->count; idx += n->count;
} }
return array; return array;
} }
internal U64 internal U64
dasm_inst_array_idx_from_code_off__linear_scan(DASM_InstArray *array, U64 off) dasm_line_array_idx_from_code_off__linear_scan(DASM_LineArray *array, U64 off)
{ {
U64 result = 0; U64 result = 0;
for(U64 idx = 0; idx < array->count; idx += 1) for(U64 idx = 0; idx < array->count; idx += 1)
{ {
if(array->v[idx].code_off == off) U64 next_off = (idx+1 < array->count ? array->v[idx+1].code_off : max_U64);
if(array->v[idx].code_off <= off && off < next_off)
{ {
result = idx; result = idx;
if(!(array->v[idx].flags & DASM_LineFlag_Decorative))
{
break; break;
} }
} }
}
return result; return result;
} }
internal U64 internal U64
dasm_inst_array_code_off_from_idx(DASM_InstArray *array, U64 idx) dasm_line_array_code_off_from_idx(DASM_LineArray *array, U64 idx)
{ {
U64 off = 0; U64 off = 0;
if(idx < array->count) if(idx < array->count)
@@ -84,7 +254,7 @@ dasm_init(void)
dasm_shared = push_array(arena, DASM_Shared, 1); dasm_shared = push_array(arena, DASM_Shared, 1);
dasm_shared->arena = arena; dasm_shared->arena = arena;
dasm_shared->slots_count = 1024; dasm_shared->slots_count = 1024;
dasm_shared->stripes_count = Min(dasm_shared->slots_count, os_logical_core_count()); dasm_shared->stripes_count = Min(dasm_shared->slots_count, os_get_system_info()->logical_processor_count);
dasm_shared->slots = push_array(arena, DASM_Slot, dasm_shared->slots_count); dasm_shared->slots = push_array(arena, DASM_Slot, dasm_shared->slots_count);
dasm_shared->stripes = push_array(arena, DASM_Stripe, dasm_shared->stripes_count); dasm_shared->stripes = push_array(arena, DASM_Stripe, dasm_shared->stripes_count);
for(U64 idx = 0; idx < dasm_shared->stripes_count; idx += 1) for(U64 idx = 0; idx < dasm_shared->stripes_count; idx += 1)
@@ -101,9 +271,9 @@ dasm_init(void)
dasm_shared->parse_threads = push_array(arena, OS_Handle, dasm_shared->parse_thread_count); dasm_shared->parse_threads = push_array(arena, OS_Handle, dasm_shared->parse_thread_count);
for(U64 idx = 0; idx < dasm_shared->parse_thread_count; idx += 1) for(U64 idx = 0; idx < dasm_shared->parse_thread_count; idx += 1)
{ {
dasm_shared->parse_threads[idx] = os_launch_thread(dasm_parse_thread__entry_point, (void *)idx, 0); dasm_shared->parse_threads[idx] = os_thread_launch(dasm_parse_thread__entry_point, (void *)idx, 0);
} }
dasm_shared->evictor_thread = os_launch_thread(dasm_evictor_thread__entry_point, 0, 0); dasm_shared->evictor_detector_thread = os_thread_launch(dasm_evictor_detector_thread__entry_point, 0, 0);
} }
//////////////////////////////// ////////////////////////////////
@@ -134,16 +304,9 @@ dasm_scope_open(void)
dasm_tctx = push_array(arena, DASM_TCTX, 1); dasm_tctx = push_array(arena, DASM_TCTX, 1);
dasm_tctx->arena = arena; dasm_tctx->arena = arena;
} }
DASM_Scope *scope = dasm_tctx->free_scope; U64 base_pos = arena_pos(dasm_tctx->arena);
if(scope != 0) DASM_Scope *scope = push_array(dasm_tctx->arena, DASM_Scope, 1);
{ scope->base_pos = base_pos;
SLLStackPop(dasm_tctx->free_scope);
}
else
{
scope = push_array_no_zero(dasm_tctx->arena, DASM_Scope, 1);
}
MemoryZeroStruct(scope);
return scope; return scope;
} }
@@ -161,43 +324,27 @@ dasm_scope_close(DASM_Scope *scope)
{ {
for(DASM_Node *n = slot->first; n != 0; n = n->next) for(DASM_Node *n = slot->first; n != 0; n = n->next)
{ {
if(u128_match(t->hash, n->hash) && if(u128_match(t->hash, n->hash) && dasm_params_match(&t->params, &n->params))
t->addr == n->addr &&
t->arch == n->arch &&
t->style_flags == n->style_flags &&
t->syntax == n->syntax)
{ {
ins_atomic_u64_dec_eval(&n->scope_ref_count); ins_atomic_u64_dec_eval(&n->scope_ref_count);
break; break;
} }
} }
} }
SLLStackPush(dasm_tctx->free_touch, t);
} }
SLLStackPush(dasm_tctx->free_scope, scope); arena_pop_to(dasm_tctx->arena, scope->base_pos);
} }
internal void internal void
dasm_scope_touch_node__stripe_r_guarded(DASM_Scope *scope, DASM_Node *node) dasm_scope_touch_node__stripe_r_guarded(DASM_Scope *scope, DASM_Node *node)
{ {
DASM_Touch *touch = dasm_tctx->free_touch; DASM_Touch *touch = push_array(dasm_tctx->arena, DASM_Touch, 1);
ins_atomic_u64_inc_eval(&node->scope_ref_count); ins_atomic_u64_inc_eval(&node->scope_ref_count);
ins_atomic_u64_eval_assign(&node->last_time_touched_us, os_now_microseconds()); ins_atomic_u64_eval_assign(&node->last_time_touched_us, os_now_microseconds());
ins_atomic_u64_eval_assign(&node->last_user_clock_idx_touched, dasm_user_clock_idx()); ins_atomic_u64_eval_assign(&node->last_user_clock_idx_touched, dasm_user_clock_idx());
if(touch != 0)
{
SLLStackPop(dasm_tctx->free_touch);
}
else
{
touch = push_array_no_zero(dasm_tctx->arena, DASM_Touch, 1);
}
MemoryZeroStruct(touch);
touch->hash = node->hash; touch->hash = node->hash;
touch->addr = node->addr; MemoryCopyStruct(&touch->params, &node->params);
touch->arch = node->arch; touch->params.dbgi_key = di_key_copy(dasm_tctx->arena, &touch->params.dbgi_key);
touch->style_flags = node->style_flags;
touch->syntax = node->syntax;
SLLStackPush(scope->top_touch, touch); SLLStackPush(scope->top_touch, touch);
} }
@@ -205,7 +352,7 @@ dasm_scope_touch_node__stripe_r_guarded(DASM_Scope *scope, DASM_Node *node)
//~ rjf: Cache Lookups //~ rjf: Cache Lookups
internal DASM_Info internal DASM_Info
dasm_info_from_hash_addr_arch_style(DASM_Scope *scope, U128 hash, U64 addr, Architecture arch, DASM_StyleFlags style_flags, DASM_Syntax syntax) dasm_info_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()))
@@ -219,11 +366,7 @@ dasm_info_from_hash_addr_arch_style(DASM_Scope *scope, U128 hash, U64 addr, Arch
{ {
for(DASM_Node *n = slot->first; n != 0; n = n->next) for(DASM_Node *n = slot->first; n != 0; n = n->next)
{ {
if(u128_match(hash, n->hash) && if(u128_match(hash, n->hash) && dasm_params_match(params, &n->params))
addr == n->addr &&
arch == n->arch &&
style_flags == n->style_flags &&
syntax == n->syntax)
{ {
MemoryCopyStruct(&info, &n->info); MemoryCopyStruct(&info, &n->info);
found = 1; found = 1;
@@ -240,11 +383,7 @@ dasm_info_from_hash_addr_arch_style(DASM_Scope *scope, U128 hash, U64 addr, Arch
DASM_Node *node = 0; DASM_Node *node = 0;
for(DASM_Node *n = slot->first; n != 0; n = n->next) for(DASM_Node *n = slot->first; n != 0; n = n->next)
{ {
if(u128_match(hash, n->hash) && if(u128_match(hash, n->hash) && dasm_params_match(params, &n->params))
addr == n->addr &&
arch == n->arch &&
style_flags == n->style_flags &&
syntax == n->syntax)
{ {
node = n; node = n;
break; break;
@@ -252,6 +391,16 @@ dasm_info_from_hash_addr_arch_style(DASM_Scope *scope, U128 hash, U64 addr, Arch
} }
if(node == 0) if(node == 0)
{ {
LogInfoNamedBlockF("dasm_new_node")
{
log_infof("hash: [0x%I64x 0x%I64x]\n", hash.u64[0], hash.u64[1]);
log_infof("vaddr: 0x%I64x\n", params->vaddr);
log_infof("arch: %S\n", string_from_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)
{ {
@@ -264,31 +413,30 @@ dasm_info_from_hash_addr_arch_style(DASM_Scope *scope, U128 hash, U64 addr, Arch
MemoryZeroStruct(node); MemoryZeroStruct(node);
DLLPushBack(slot->first, slot->last, node); DLLPushBack(slot->first, slot->last, node);
node->hash = hash; node->hash = hash;
node->addr = addr; MemoryCopyStruct(&node->params, params);
node->arch = arch; // TODO(rjf): need to make this releasable - currently all exe_paths just leak
node->style_flags = style_flags; node->params.dbgi_key = di_key_copy(stripe->arena, &node->params.dbgi_key);
node->syntax = syntax;
node_is_new = 1; node_is_new = 1;
} }
} }
} }
if(node_is_new) if(node_is_new)
{ {
dasm_u2p_enqueue_req(hash, addr, arch, style_flags, syntax, max_U64); dasm_u2p_enqueue_req(hash, params, max_U64);
} }
} }
return info; return info;
} }
internal DASM_Info internal DASM_Info
dasm_info_from_key_addr_arch_style(DASM_Scope *scope, U128 key, U64 addr, Architecture arch, DASM_StyleFlags style_flags, DASM_Syntax syntax, U128 *hash_out) dasm_info_from_key_params(DASM_Scope *scope, U128 key, DASM_Params *params, U128 *hash_out)
{ {
DASM_Info result = {0}; DASM_Info result = {0};
for(U64 rewind_idx = 0; rewind_idx < 2; rewind_idx += 1) for(U64 rewind_idx = 0; rewind_idx < HS_KEY_HASH_HISTORY_COUNT; rewind_idx += 1)
{ {
U128 hash = hs_hash_from_key(key, rewind_idx); U128 hash = hs_hash_from_key(key, rewind_idx);
result = dasm_info_from_hash_addr_arch_style(scope, hash, addr, arch, style_flags, syntax); result = dasm_info_from_hash_params(scope, hash, params);
if(result.insts.count != 0) if(result.lines.count != 0)
{ {
if(hash_out) if(hash_out)
{ {
@@ -304,21 +452,27 @@ dasm_info_from_key_addr_arch_style(DASM_Scope *scope, U128 key, U64 addr, Archit
//~ rjf: Parse Threads //~ rjf: Parse Threads
internal B32 internal B32
dasm_u2p_enqueue_req(U128 hash, U64 addr, Architecture arch, DASM_StyleFlags style_flags, DASM_Syntax syntax, U64 endt_us) dasm_u2p_enqueue_req(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(addr)+sizeof(arch)) 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))
{ {
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, &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, &addr); dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, &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, &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);
dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, &style_flags); dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, &params->style_flags);
dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, &syntax); 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->syntax);
dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, &params->base_vaddr);
dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, &params->dbgi_key.path.size);
dasm_shared->u2p_ring_write_pos += ring_write(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, params->dbgi_key.path.str, params->dbgi_key.path.size);
dasm_shared->u2p_ring_write_pos += ring_write_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_write_pos, &params->dbgi_key.min_timestamp);
dasm_shared->u2p_ring_write_pos += 7;
dasm_shared->u2p_ring_write_pos -= dasm_shared->u2p_ring_write_pos%8;
break; break;
} }
if(os_now_microseconds() >= endt_us) if(os_now_microseconds() >= endt_us)
@@ -335,23 +489,30 @@ dasm_u2p_enqueue_req(U128 hash, U64 addr, Architecture arch, DASM_StyleFlags sty
} }
internal void internal void
dasm_u2p_dequeue_req(U128 *hash_out, U64 *addr_out, Architecture *arch_out, DASM_StyleFlags *style_flags_out, DASM_Syntax *syntax_out) dasm_u2p_dequeue_req(Arena *arena, 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(*addr_out)+sizeof(*arch_out)) 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, 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, addr_out); dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, &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, arch_out); dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, &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, style_flags_out); dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, &params_out->style_flags);
dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, syntax_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->syntax);
dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, &params_out->base_vaddr);
dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, &params_out->dbgi_key.path.size);
params_out->dbgi_key.path.str = push_array(arena, U8, params_out->dbgi_key.path.size);
dasm_shared->u2p_ring_read_pos += ring_read(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, params_out->dbgi_key.path.str, params_out->dbgi_key.path.size);
dasm_shared->u2p_ring_read_pos += ring_read_struct(dasm_shared->u2p_ring_base, dasm_shared->u2p_ring_size, dasm_shared->u2p_ring_read_pos, &params_out->dbgi_key.min_timestamp);
dasm_shared->u2p_ring_read_pos += 7;
dasm_shared->u2p_ring_read_pos -= dasm_shared->u2p_ring_read_pos%8;
break; break;
} }
os_condition_variable_wait(dasm_shared->u2p_ring_cv, dasm_shared->u2p_ring_mutex, max_U64); os_condition_variable_wait(dasm_shared->u2p_ring_cv, dasm_shared->u2p_ring_mutex, max_U64);
} }
os_condition_variable_broadcast(dasm_shared->u2p_ring_mutex); os_condition_variable_broadcast(dasm_shared->u2p_ring_cv);
} }
internal void internal void
@@ -361,15 +522,15 @@ dasm_parse_thread__entry_point(void *p)
for(;;) for(;;)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
HS_Scope *hs_scope = hs_scope_open();
DI_Scope *di_scope = di_scope_open();
TXT_Scope *txt_scope = txt_scope_open();
//- rjf: get next request //- rjf: get next request
U128 hash = {0}; U128 hash = {0};
U64 addr = 0; DASM_Params params = {0};
Architecture arch = Architecture_Null; dasm_u2p_dequeue_req(scratch.arena, &hash, &params);
DASM_StyleFlags style_flags = 0; U64 change_gen = fs_change_gen();
DASM_Syntax syntax = DASM_Syntax_Intel;
dasm_u2p_dequeue_req(&hash, &addr, &arch, &style_flags, &syntax);
HS_Scope *hs_scope = hs_scope_open();
//- rjf: unpack hash //- rjf: unpack hash
U64 slot_idx = hash.u64[1]%dasm_shared->slots_count; U64 slot_idx = hash.u64[1]%dasm_shared->slots_count;
@@ -383,11 +544,7 @@ dasm_parse_thread__entry_point(void *p)
{ {
for(DASM_Node *n = slot->first; n != 0; n = n->next) for(DASM_Node *n = slot->first; n != 0; n = n->next)
{ {
if(u128_match(n->hash, hash) && if(u128_match(n->hash, hash) && dasm_params_match(&n->params, &params))
n->addr == addr &&
n->arch == arch &&
n->style_flags == style_flags &&
n->syntax == syntax)
{ {
got_task = !ins_atomic_u32_eval_cond_assign(&n->is_working, 1, 0); got_task = !ins_atomic_u32_eval_cond_assign(&n->is_working, 1, 0);
break; break;
@@ -395,6 +552,13 @@ dasm_parse_thread__entry_point(void *p)
} }
} }
//- rjf: get dbg info
RDI_Parsed *rdi = &di_rdi_parsed_nil;
if(got_task && params.dbgi_key.path.size != 0)
{
rdi = di_rdi_from_key(di_scope, &params.dbgi_key, max_U64);
}
//- rjf: hash -> data //- rjf: hash -> data
String8 data = {0}; String8 data = {0};
if(got_task) if(got_task)
@@ -402,59 +566,128 @@ dasm_parse_thread__entry_point(void *p)
data = hs_data_from_hash(hs_scope, hash); data = hs_data_from_hash(hs_scope, hash);
} }
//- rjf: data * arch * addr -> decode artifacts //- rjf: data * arch * addr * dbg -> decode artifacts
DASM_InstChunkList inst_list = {0}; DASM_LineChunkList line_list = {0};
String8List inst_strings = {0}; String8List inst_strings = {0};
if(got_task) if(got_task)
{ {
switch(arch) switch(params.arch)
{ {
default:{}break; default:{}break;
//- rjf: x86/x64 decoding //- rjf: x86/x64 decoding
case Architecture_x64: case Arch_x64:
case Architecture_x86: case Arch_x86:
{ {
// rjf: grab context
struct ud udc;
ud_init(&udc);
ud_set_mode(&udc, bit_size_from_arch(arch));
ud_set_pc(&udc, addr);
ud_set_input_buffer(&udc, data.str, data.size);
ud_set_vendor(&udc, UD_VENDOR_ANY);
ud_set_syntax(&udc, syntax == DASM_Syntax_Intel ? UD_SYN_INTEL : UD_SYN_ATT);
// rjf: disassemble // rjf: disassemble
U64 byte_process_start_off = 0; RDI_SourceFile *last_file = &rdi_nil_element_union.source_file;
RDI_Line *last_line = 0;
for(U64 off = 0; off < data.size;) for(U64 off = 0; off < data.size;)
{ {
// rjf: disassemble one instruction // rjf: disassemble one instruction
U64 size = ud_disassemble(&udc); DASM_Inst inst = dasm_inst_from_code(scratch.arena, params.arch, params.vaddr+off, str8_skip(data, off), params.syntax);
if(size == 0) if(inst.size == 0)
{ {
break; break;
} }
// rjf: analyze // rjf: push strings derived from voff -> line info
struct ud_operand *first_op = (struct ud_operand *)ud_insn_opr(&udc, 0); if(params.style_flags & (DASM_StyleFlag_SourceFilesNames|DASM_StyleFlag_SourceLines))
U64 rel_voff = (first_op != 0 && first_op->type == UD_OP_JIMM) ? ud_syn_rel_target(&udc, first_op) : 0;
// rjf: push
String8 addr_part = {0};
if(style_flags & DASM_StyleFlag_Addresses)
{ {
addr_part = push_str8f(scratch.arena, "%016I64X ", addr+off); if(rdi != &di_rdi_parsed_nil)
{
U64 voff = (params.vaddr+off) - params.base_vaddr;
U32 unit_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_UnitVMap, voff);
RDI_Unit *unit = rdi_element_from_name_idx(rdi, Units, unit_idx);
RDI_LineTable *line_table = rdi_element_from_name_idx(rdi, LineTables, unit->line_table_idx);
RDI_ParsedLineTable unit_line_info = {0};
rdi_parsed_from_line_table(rdi, line_table, &unit_line_info);
U64 line_info_idx = rdi_line_info_idx_from_voff(&unit_line_info, voff);
if(line_info_idx < unit_line_info.count)
{
RDI_Line *line = &unit_line_info.lines[line_info_idx];
RDI_SourceFile *file = rdi_element_from_name_idx(rdi, SourceFiles, line->file_idx);
String8 file_normalized_full_path = {0};
file_normalized_full_path.str = rdi_string_from_idx(rdi, file->normal_full_path_string_idx, &file_normalized_full_path.size);
if(file != last_file)
{
if(params.style_flags & DASM_StyleFlag_SourceFilesNames &&
file->normal_full_path_string_idx != 0 && file_normalized_full_path.size != 0)
{
String8 inst_string = push_str8f(scratch.arena, "> %S", file_normalized_full_path);
DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst);
str8_list_push(scratch.arena, &inst_strings, inst_string);
}
if(params.style_flags & DASM_StyleFlag_SourceFilesNames && file->normal_full_path_string_idx == 0)
{
String8 inst_string = str8_lit(">");
DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst);
str8_list_push(scratch.arena, &inst_strings, inst_string);
}
last_file = file;
}
if(line && line != last_line && file->normal_full_path_string_idx != 0 &&
params.style_flags & DASM_StyleFlag_SourceLines &&
file_normalized_full_path.size != 0)
{
FileProperties props = os_properties_from_file_path(file_normalized_full_path);
if(props.modified != 0)
{
// 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
U128 key = fs_key_from_path_range(file_normalized_full_path, r1u64(0, max_U64));
TXT_LangKind lang_kind = txt_lang_kind_from_extension(file_normalized_full_path);
U64 endt_us = max_U64;
U128 hash = {0};
TXT_TextInfo text_info = {0};
for(;os_now_microseconds() <= endt_us;)
{
text_info = txt_text_info_from_key_lang(txt_scope, key, lang_kind, &hash);
if(!u128_match(hash, u128_zero()))
{
break;
}
}
if(0 < line->line_num && line->line_num < text_info.lines_count)
{
String8 data = hs_data_from_hash(hs_scope, hash);
String8 line_text = str8_skip_chop_whitespace(str8_substr(data, text_info.lines_ranges[line->line_num-1]));
if(line_text.size != 0)
{
String8 inst_string = push_str8f(scratch.arena, "> %S", line_text);
DASM_Line inst = {u32_from_u64_saturate(off), DASM_LineFlag_Decorative, 0, r1u64(inst_strings.total_size + inst_strings.node_count,
inst_strings.total_size + inst_strings.node_count + inst_string.size)};
dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &inst);
str8_list_push(scratch.arena, &inst_strings, inst_string);
}
}
}
last_line = line;
}
}
}
}
// rjf: push line
String8 addr_part = {0};
if(params.style_flags & DASM_StyleFlag_Addresses)
{
addr_part = push_str8f(scratch.arena, "%s0x%016I64x ", rdi != &di_rdi_parsed_nil ? " " : "", params.vaddr+off);
} }
String8 code_bytes_part = {0}; String8 code_bytes_part = {0};
if(style_flags & DASM_StyleFlag_CodeBytes) if(params.style_flags & DASM_StyleFlag_CodeBytes)
{ {
String8List code_bytes_strings = {0}; String8List code_bytes_strings = {0};
str8_list_push(scratch.arena, &code_bytes_strings, str8_lit("{")); str8_list_push(scratch.arena, &code_bytes_strings, str8_lit("{"));
for(U64 byte_idx = 0; byte_idx < size || byte_idx < 16; byte_idx += 1) for(U64 byte_idx = 0; byte_idx < inst.size || byte_idx < 16; byte_idx += 1)
{ {
if(byte_idx < size) if(byte_idx < inst.size)
{ {
str8_list_pushf(scratch.arena, &code_bytes_strings, "%02x%s ", (U32)data.str[off+byte_idx], byte_idx == size-1 ? "}" : ""); str8_list_pushf(scratch.arena, &code_bytes_strings, "%02x%s ", (U32)data.str[off+byte_idx], byte_idx == inst.size-1 ? "}" : "");
} }
else if(byte_idx < 8) else if(byte_idx < 8)
{ {
@@ -464,14 +697,31 @@ dasm_parse_thread__entry_point(void *p)
str8_list_push(scratch.arena, &code_bytes_strings, str8_lit(" ")); str8_list_push(scratch.arena, &code_bytes_strings, str8_lit(" "));
code_bytes_part = str8_list_join(scratch.arena, &code_bytes_strings, 0); code_bytes_part = str8_list_join(scratch.arena, &code_bytes_strings, 0);
} }
String8 inst_string = push_str8f(scratch.arena, "%S%S%s", addr_part, code_bytes_part, udc.asm_buf); String8 symbol_part = {0};
DASM_Inst inst = {off, rel_voff, r1u64(inst_strings.total_size + inst_strings.node_count, if(inst.jump_dest_vaddr != 0 && rdi != &di_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);
if(scope_idx != 0)
{
RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx);
RDI_U32 procedure_idx = scope->proc_idx;
RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, procedure_idx);
String8 procedure_name = {0};
procedure_name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &procedure_name.size);
if(procedure_name.size != 0)
{
symbol_part = push_str8f(scratch.arena, " (%S)", procedure_name);
}
}
}
String8 inst_string = push_str8f(scratch.arena, "%S%S%S%S", addr_part, code_bytes_part, inst.string, symbol_part);
DASM_Line line = {u32_from_u64_saturate(off), 0, inst.jump_dest_vaddr, r1u64(inst_strings.total_size + inst_strings.node_count,
inst_strings.total_size + inst_strings.node_count + inst_string.size)}; inst_strings.total_size + inst_strings.node_count + inst_string.size)};
dasm_inst_chunk_list_push(scratch.arena, &inst_list, 1024, &inst); dasm_line_chunk_list_push(scratch.arena, &line_list, 1024, &line);
str8_list_push(scratch.arena, &inst_strings, inst_string); str8_list_push(scratch.arena, &inst_strings, inst_string);
// rjf: increment // rjf: increment
off += size; off += inst.size;
} }
}break; }break;
} }
@@ -495,10 +745,11 @@ dasm_parse_thread__entry_point(void *p)
{ {
hash.u64[0], hash.u64[0],
hash.u64[1], hash.u64[1],
addr, params.vaddr,
(U64)arch, (U64)params.arch,
(U64)style_flags, (U64)params.style_flags,
(U64)syntax, (U64)params.syntax,
(U64)rdi,
0x4d534144, 0x4d534144,
}; };
text_key = hs_hash_from_data(str8((U8 *)hash_data, sizeof(hash_data))); text_key = hs_hash_from_data(str8((U8 *)hash_data, sizeof(hash_data)));
@@ -510,7 +761,7 @@ dasm_parse_thread__entry_point(void *p)
//- rjf: produce value bundle //- rjf: produce value bundle
info_arena = arena_alloc(); info_arena = arena_alloc();
info.text_key = text_key; info.text_key = text_key;
info.insts = dasm_inst_array_from_chunk_list(info_arena, &inst_list); info.lines = dasm_line_array_from_chunk_list(info_arena, &line_list);
} }
//- rjf: commit results to cache //- rjf: commit results to cache
@@ -518,14 +769,18 @@ dasm_parse_thread__entry_point(void *p)
{ {
for(DASM_Node *n = slot->first; n != 0; n = n->next) for(DASM_Node *n = slot->first; n != 0; n = n->next)
{ {
if(u128_match(n->hash, hash) && if(u128_match(n->hash, hash) && dasm_params_match(&n->params, &params))
addr == n->addr &&
arch == n->arch &&
style_flags == n->style_flags &&
syntax == n->syntax)
{ {
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))
{
n->change_gen = change_gen;
}
else
{
n->change_gen = 0;
}
ins_atomic_u32_eval_assign(&n->is_working, 0); ins_atomic_u32_eval_assign(&n->is_working, 0);
ins_atomic_u64_inc_eval(&n->load_count); ins_atomic_u64_inc_eval(&n->load_count);
break; break;
@@ -533,24 +788,29 @@ dasm_parse_thread__entry_point(void *p)
} }
} }
txt_scope_close(txt_scope);
di_scope_close(di_scope);
hs_scope_close(hs_scope); hs_scope_close(hs_scope);
scratch_end(scratch); scratch_end(scratch);
} }
} }
//////////////////////////////// ////////////////////////////////
//~ rjf: Evictor Threads //~ rjf: Evictor/Detector Thread
internal void internal void
dasm_evictor_thread__entry_point(void *p) dasm_evictor_detector_thread__entry_point(void *p)
{ {
ThreadNameF("[dasm] evictor thread"); ThreadNameF("[dasm] evictor/detector thread");
for(;;) for(;;)
{ {
U64 change_gen = fs_change_gen();
U64 check_time_us = os_now_microseconds(); U64 check_time_us = os_now_microseconds();
U64 check_time_user_clocks = dasm_user_clock_idx(); U64 check_time_user_clocks = dasm_user_clock_idx();
U64 evict_threshold_us = 10*1000000; U64 evict_threshold_us = 10*1000000;
U64 retry_threshold_us = 1*1000000;
U64 evict_threshold_user_clocks = 10; U64 evict_threshold_user_clocks = 10;
U64 retry_threshold_user_clocks = 10;
for(U64 slot_idx = 0; slot_idx < dasm_shared->slots_count; slot_idx += 1) for(U64 slot_idx = 0; slot_idx < dasm_shared->slots_count; slot_idx += 1)
{ {
U64 stripe_idx = slot_idx%dasm_shared->stripes_count; U64 stripe_idx = slot_idx%dasm_shared->stripes_count;
@@ -570,6 +830,13 @@ dasm_evictor_thread__entry_point(void *p)
slot_has_work = 1; slot_has_work = 1;
break; break;
} }
if(n->change_gen != 0 && n->change_gen != change_gen &&
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)
{
slot_has_work = 1;
break;
}
} }
} }
if(slot_has_work) OS_MutexScopeW(stripe->rw_mutex) if(slot_has_work) OS_MutexScopeW(stripe->rw_mutex)
@@ -590,10 +857,19 @@ dasm_evictor_thread__entry_point(void *p)
} }
SLLStackPush(stripe->free_node, n); SLLStackPush(stripe->free_node, n);
} }
if(n->change_gen != 0 && n->change_gen != change_gen &&
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)
{
if(dasm_u2p_enqueue_req(n->hash, &n->params, max_U64))
{
n->last_time_requested_us = os_now_microseconds();
n->last_user_clock_idx_requested = check_time_user_clocks;
} }
} }
os_sleep_milliseconds(5);
} }
os_sleep_milliseconds(1000); }
}
os_sleep_milliseconds(100);
} }
} }
+154 -46
View File
@@ -5,14 +5,7 @@
#define DASM_CACHE_H #define DASM_CACHE_H
//////////////////////////////// ////////////////////////////////
//~ rjf: Stringification Types //~ rjf: Disassembly Syntax Types
typedef U32 DASM_StyleFlags;
enum
{
DASM_StyleFlag_Addresses = (1<<0),
DASM_StyleFlag_CodeBytes = (1<<1),
};
typedef enum DASM_Syntax typedef enum DASM_Syntax
{ {
@@ -23,41 +16,143 @@ typedef enum DASM_Syntax
DASM_Syntax; DASM_Syntax;
//////////////////////////////// ////////////////////////////////
//~ rjf: Instruction Types //~ rjf: Disassembly Instruction Info Types
typedef U32 DASM_InstFlags;
enum
{
DASM_InstFlag_Call = (1<<0),
DASM_InstFlag_Branch = (1<<1),
DASM_InstFlag_UnconditionalJump = (1<<2),
DASM_InstFlag_Return = (1<<3),
DASM_InstFlag_NonFlow = (1<<4),
DASM_InstFlag_Repeats = (1<<5),
DASM_InstFlag_ChangesStackPointer = (1<<6),
DASM_InstFlag_ChangesStackPointerVariably = (1<<7),
};
typedef struct DASM_Inst DASM_Inst; typedef struct DASM_Inst DASM_Inst;
struct DASM_Inst struct DASM_Inst
{ {
U64 code_off; DASM_InstFlags flags;
U32 size;
String8 string;
U64 jump_dest_vaddr;
};
////////////////////////////////
//~ rjf: Control Flow Analysis Types
typedef struct DASM_CtrlFlowPoint DASM_CtrlFlowPoint;
struct DASM_CtrlFlowPoint
{
U64 vaddr;
U64 jump_dest_vaddr;
DASM_InstFlags inst_flags;
};
typedef struct DASM_CtrlFlowPointNode DASM_CtrlFlowPointNode;
struct DASM_CtrlFlowPointNode
{
DASM_CtrlFlowPointNode *next;
DASM_CtrlFlowPoint v;
};
typedef struct DASM_CtrlFlowPointList DASM_CtrlFlowPointList;
struct DASM_CtrlFlowPointList
{
DASM_CtrlFlowPointNode *first;
DASM_CtrlFlowPointNode *last;
U64 count;
};
typedef struct DASM_CtrlFlowInfo DASM_CtrlFlowInfo;
struct DASM_CtrlFlowInfo
{
DASM_CtrlFlowPointList exit_points;
U64 total_size;
};
////////////////////////////////
//~ rjf: Disassembly Text Decoration Types
typedef U32 DASM_StyleFlags;
enum
{
DASM_StyleFlag_Addresses = (1<<0),
DASM_StyleFlag_CodeBytes = (1<<1),
DASM_StyleFlag_SourceFilesNames = (1<<2),
DASM_StyleFlag_SourceLines = (1<<3),
DASM_StyleFlag_SymbolNames = (1<<4),
};
////////////////////////////////
//~ rjf: Disassembling Parameters Bundle
typedef struct DASM_Params DASM_Params;
struct DASM_Params
{
U64 vaddr;
Arch arch;
DASM_StyleFlags style_flags;
DASM_Syntax syntax;
U64 base_vaddr;
DI_Key dbgi_key;
};
////////////////////////////////
//~ rjf: Disassembly Text Line Types
typedef U32 DASM_LineFlags;
enum
{
DASM_LineFlag_Decorative = (1<<0),
};
typedef struct DASM_Line DASM_Line;
struct DASM_Line
{
U32 code_off;
DASM_LineFlags flags;
U64 addr; U64 addr;
Rng1U64 text_range; Rng1U64 text_range;
}; };
typedef struct DASM_InstChunkNode DASM_InstChunkNode; typedef struct DASM_LineChunkNode DASM_LineChunkNode;
struct DASM_InstChunkNode struct DASM_LineChunkNode
{ {
DASM_InstChunkNode *next; DASM_LineChunkNode *next;
DASM_Inst *v; DASM_Line *v;
U64 cap; U64 cap;
U64 count; U64 count;
}; };
typedef struct DASM_InstChunkList DASM_InstChunkList; typedef struct DASM_LineChunkList DASM_LineChunkList;
struct DASM_InstChunkList struct DASM_LineChunkList
{ {
DASM_InstChunkNode *first; DASM_LineChunkNode *first;
DASM_InstChunkNode *last; DASM_LineChunkNode *last;
U64 node_count; U64 node_count;
U64 inst_count; U64 line_count;
}; };
typedef struct DASM_InstArray DASM_InstArray; typedef struct DASM_LineArray DASM_LineArray;
struct DASM_InstArray struct DASM_LineArray
{ {
DASM_Inst *v; DASM_Line *v;
U64 count; U64 count;
}; };
////////////////////////////////
//~ rjf: Disassembly Result Bundle
typedef struct DASM_Result DASM_Result;
struct DASM_Result
{
String8 text;
DASM_LineArray lines;
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Value Bundle Type //~ rjf: Value Bundle Type
@@ -65,7 +160,7 @@ typedef struct DASM_Info DASM_Info;
struct DASM_Info struct DASM_Info
{ {
U128 text_key; U128 text_key;
DASM_InstArray insts; DASM_LineArray lines;
}; };
//////////////////////////////// ////////////////////////////////
@@ -80,10 +175,10 @@ struct DASM_Node
// rjf: key // rjf: key
U128 hash; U128 hash;
U64 addr; DASM_Params params;
Architecture arch;
DASM_StyleFlags style_flags; // rjf: generations
DASM_Syntax syntax; U64 change_gen;
// rjf: value // rjf: value
Arena *info_arena; Arena *info_arena;
@@ -95,6 +190,8 @@ struct DASM_Node
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 load_count;
U64 last_time_requested_us;
U64 last_user_clock_idx_requested;
}; };
typedef struct DASM_Slot DASM_Slot; typedef struct DASM_Slot DASM_Slot;
@@ -121,10 +218,7 @@ struct DASM_Touch
{ {
DASM_Touch *next; DASM_Touch *next;
U128 hash; U128 hash;
U64 addr; DASM_Params params;
Architecture arch;
DASM_StyleFlags style_flags;
DASM_Syntax syntax;
}; };
typedef struct DASM_Scope DASM_Scope; typedef struct DASM_Scope DASM_Scope;
@@ -132,6 +226,7 @@ struct DASM_Scope
{ {
DASM_Scope *next; DASM_Scope *next;
DASM_Touch *top_touch; DASM_Touch *top_touch;
U64 base_pos;
}; };
//////////////////////////////// ////////////////////////////////
@@ -141,8 +236,6 @@ typedef struct DASM_TCTX DASM_TCTX;
struct DASM_TCTX struct DASM_TCTX
{ {
Arena *arena; Arena *arena;
DASM_Scope *free_scope;
DASM_Touch *free_touch;
}; };
//////////////////////////////// ////////////////////////////////
@@ -174,8 +267,8 @@ struct DASM_Shared
U64 parse_thread_count; U64 parse_thread_count;
OS_Handle *parse_threads; OS_Handle *parse_threads;
// rjf: evictor thread // rjf: evictor/detector thread
OS_Handle evictor_thread; OS_Handle evictor_detector_thread;
}; };
//////////////////////////////// ////////////////////////////////
@@ -185,12 +278,27 @@ thread_static DASM_TCTX *dasm_tctx = 0;
global DASM_Shared *dasm_shared = 0; global DASM_Shared *dasm_shared = 0;
//////////////////////////////// ////////////////////////////////
//~ rjf: Instruction Type Functions //~ rjf: Instruction Decoding/Disassembling Type Functions
internal void dasm_inst_chunk_list_push(Arena *arena, DASM_InstChunkList *list, U64 cap, DASM_Inst *inst); internal DASM_Inst dasm_inst_from_code(Arena *arena, Arch arch, U64 vaddr, String8 code, DASM_Syntax syntax);
internal DASM_InstArray dasm_inst_array_from_chunk_list(Arena *arena, DASM_InstChunkList *list);
internal U64 dasm_inst_array_idx_from_code_off__linear_scan(DASM_InstArray *array, U64 off); ////////////////////////////////
internal U64 dasm_inst_array_code_off_from_idx(DASM_InstArray *array, U64 idx); //~ rjf: Control Flow Analysis
internal DASM_CtrlFlowInfo dasm_ctrl_flow_info_from_arch_vaddr_code(Arena *arena, DASM_InstFlags exit_points_mask, Arch arch, U64 vaddr, String8 code);
////////////////////////////////
//~ rjf: Parameter Type Functions
internal B32 dasm_params_match(DASM_Params *a, DASM_Params *b);
////////////////////////////////
//~ rjf: Line Type Functions
internal void dasm_line_chunk_list_push(Arena *arena, DASM_LineChunkList *list, U64 cap, DASM_Line *line);
internal DASM_LineArray dasm_line_array_from_chunk_list(Arena *arena, DASM_LineChunkList *list);
internal U64 dasm_line_array_idx_from_code_off__linear_scan(DASM_LineArray *array, U64 off);
internal U64 dasm_line_array_code_off_from_idx(DASM_LineArray *array, U64 idx);
//////////////////////////////// ////////////////////////////////
//~ rjf: Main Layer Initialization //~ rjf: Main Layer Initialization
@@ -213,19 +321,19 @@ 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_addr_arch_style(DASM_Scope *scope, U128 hash, U64 addr, Architecture arch, DASM_StyleFlags style_flags, DASM_Syntax syntax); internal DASM_Info dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params);
internal DASM_Info dasm_info_from_key_addr_arch_style(DASM_Scope *scope, U128 key, U64 addr, Architecture arch, DASM_StyleFlags style_flags, DASM_Syntax syntax, U128 *hash_out); internal DASM_Info dasm_info_from_key_params(DASM_Scope *scope, U128 key, DASM_Params *params, U128 *hash_out);
//////////////////////////////// ////////////////////////////////
//~ rjf: Parse Threads //~ rjf: Parse Threads
internal B32 dasm_u2p_enqueue_req(U128 hash, U64 addr, Architecture arch, DASM_StyleFlags style_flags, DASM_Syntax syntax, U64 endt_us); internal B32 dasm_u2p_enqueue_req(U128 hash, DASM_Params *params, U64 endt_us);
internal void dasm_u2p_dequeue_req(U128 *hash_out, U64 *addr_out, Architecture *arch_out, DASM_StyleFlags *style_flags_out, DASM_Syntax *syntax_out); internal void dasm_u2p_dequeue_req(Arena *arena, U128 *hash_out, DASM_Params *params_out);
internal void dasm_parse_thread__entry_point(void *p); internal void dasm_parse_thread__entry_point(void *p);
//////////////////////////////// ////////////////////////////////
//~ rjf: Evictor Threads //~ rjf: Evictor/Detector Thread
internal void dasm_evictor_thread__entry_point(void *p); internal void dasm_evictor_detector_thread__entry_point(void *p);
#endif // DASM_CACHE_H #endif // DASM_CACHE_H
+133
View File
@@ -0,0 +1,133 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ 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 )
// / | | | \___ _________________________________/ | | | | |
// / | | | \ / | | | | |
D_CmdTable: // | | | | | | | | | |
{
//- 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" }
{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" }
{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" }
{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" }
{Detach 1 1 Process null Nil Process 0 0 0 0 0 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." "" }
{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" }
{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" }
{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" }
{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" }
{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." "" }
{Halt 1 1 Null null Nil Null 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." "" }
{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." "" }
//- 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." "" }
{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 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 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 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 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
{FreezeThread 1 1 Thread null Nil Thread 0 0 0 0 0 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." "" }
{FreezeProcess 1 1 Process null Nil Process 0 0 0 0 0 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." "" }
{FreezeMachine 0 1 Machine null Nil Machine 0 0 0 0 0 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." "" }
{FreezeLocalMachine 1 1 Null null Nil Null 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." "" }
{FreezeEntity 0 0 Null null Nil Null 0 0 0 0 0 0 Null "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." "" }
//- 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." "" }
{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." "" }
//- 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." "" }
}
@enum D_CmdKind:
{
Null,
@expand(D_CmdTable, a) `$(a.name)`,
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
@table(name)
D_DevToggleTable:
{
{telemetry_capture}
{simulate_lag}
{draw_ui_text_pos}
{draw_ui_focus_debug}
{draw_ui_box_heatmap}
{eval_compiler_tooltips}
{eval_watch_key_tooltips}
{cmd_context_tooltips}
{scratch_mouse_draw}
{updating_indicator}
}
@gen
{
@expand(D_DevToggleTable a) `global B32 DEV_$(a.name) = 0;`
}
@gen
{
`struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] =`;
`{`;
@expand(D_DevToggleTable a) `{&DEV_$(a.name), str8_lit_comp("$(a.name)")},`
`};`;
}
File diff suppressed because it is too large Load Diff
+495
View File
@@ -0,0 +1,495 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DBG_ENGINE_CORE_H
#define DBG_ENGINE_CORE_H
////////////////////////////////
//~ rjf: Tick Input Types
typedef struct D_Target D_Target;
struct D_Target
{
String8 exe;
String8 args;
String8 working_directory;
String8 custom_entry_point_name;
String8 stdout_path;
String8 stderr_path;
String8 stdin_path;
String8List env;
};
typedef struct D_TargetArray D_TargetArray;
struct D_TargetArray
{
D_Target *v;
U64 count;
};
typedef struct D_Breakpoint D_Breakpoint;
struct D_Breakpoint
{
String8 file_path;
TxtPt pt;
String8 symbol_name;
U64 vaddr;
String8 condition;
};
typedef struct D_BreakpointArray D_BreakpointArray;
struct D_BreakpointArray
{
D_Breakpoint *v;
U64 count;
};
typedef struct D_PathMap D_PathMap;
struct D_PathMap
{
String8 src;
String8 dst;
};
typedef struct D_PathMapArray D_PathMapArray;
struct D_PathMapArray
{
D_PathMap *v;
U64 count;
};
////////////////////////////////
//~ rjf: Tick Output Types
typedef enum D_EventKind
{
D_EventKind_Null,
D_EventKind_ProcessEnd,
D_EventKind_Stop,
D_EventKind_COUNT
}
D_EventKind;
typedef enum D_EventCause
{
D_EventCause_Null,
D_EventCause_UserBreakpoint,
D_EventCause_Halt,
D_EventCause_COUNT
}
D_EventCause;
typedef struct D_Event D_Event;
struct D_Event
{
D_EventKind kind;
D_EventCause cause;
CTRL_Handle thread;
U64 vaddr;
U64 code;
};
typedef struct D_EventNode D_EventNode;
struct D_EventNode
{
D_EventNode *next;
D_Event v;
};
typedef struct D_EventList D_EventList;
struct D_EventList
{
D_EventNode *first;
D_EventNode *last;
U64 count;
};
////////////////////////////////
//~ rjf: Line Info Types
typedef struct D_Line D_Line;
struct D_Line
{
String8 file_path;
TxtPt pt;
Rng1U64 voff_range;
DI_Key dbgi_key;
};
typedef struct D_LineNode D_LineNode;
struct D_LineNode
{
D_LineNode *next;
D_Line v;
};
typedef struct D_LineList D_LineList;
struct D_LineList
{
D_LineNode *first;
D_LineNode *last;
U64 count;
};
typedef struct D_LineListArray D_LineListArray;
struct D_LineListArray
{
D_LineList *v;
U64 count;
DI_KeyList dbgi_keys;
};
////////////////////////////////
//~ rjf: Debug Engine Control Communication Types
typedef enum D_RunKind
{
D_RunKind_Run,
D_RunKind_SingleStep,
D_RunKind_Step,
D_RunKind_COUNT
}
D_RunKind;
////////////////////////////////
//~ rjf: Generated Code
#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
typedef struct D_CmdParams D_CmdParams;
struct D_CmdParams
{
CTRL_Handle machine;
CTRL_Handle process;
CTRL_Handle thread;
CTRL_Handle entity;
String8 string;
String8 file_path;
TxtPt cursor;
U64 vaddr;
B32 prefer_disasm;
U32 pid;
U32 rgba;
D_TargetArray targets;
};
typedef struct D_Cmd D_Cmd;
struct D_Cmd
{
D_CmdKind kind;
D_CmdParams params;
};
typedef struct D_CmdNode D_CmdNode;
struct D_CmdNode
{
D_CmdNode *next;
D_CmdNode *prev;
D_Cmd cmd;
};
typedef struct D_CmdList D_CmdList;
struct D_CmdList
{
D_CmdNode *first;
D_CmdNode *last;
U64 count;
};
////////////////////////////////
//~ 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
typedef struct D_RunTLSBaseCacheNode D_RunTLSBaseCacheNode;
struct D_RunTLSBaseCacheNode
{
D_RunTLSBaseCacheNode *hash_next;
CTRL_Handle process;
U64 root_vaddr;
U64 rip_vaddr;
U64 tls_base_vaddr;
};
typedef struct D_RunTLSBaseCacheSlot D_RunTLSBaseCacheSlot;
struct D_RunTLSBaseCacheSlot
{
D_RunTLSBaseCacheNode *first;
D_RunTLSBaseCacheNode *last;
};
typedef struct D_RunTLSBaseCache D_RunTLSBaseCache;
struct D_RunTLSBaseCache
{
Arena *arena;
U64 slots_count;
D_RunTLSBaseCacheSlot *slots;
};
//- rjf: per-run locals cache
typedef struct D_RunLocalsCacheNode D_RunLocalsCacheNode;
struct D_RunLocalsCacheNode
{
D_RunLocalsCacheNode *hash_next;
DI_Key dbgi_key;
U64 voff;
E_String2NumMap *locals_map;
};
typedef struct D_RunLocalsCacheSlot D_RunLocalsCacheSlot;
struct D_RunLocalsCacheSlot
{
D_RunLocalsCacheNode *first;
D_RunLocalsCacheNode *last;
};
typedef struct D_RunLocalsCache D_RunLocalsCache;
struct D_RunLocalsCache
{
Arena *arena;
U64 table_size;
D_RunLocalsCacheSlot *table;
};
////////////////////////////////
//~ rjf: Main State Types
typedef struct D_State D_State;
struct D_State
{
// rjf: top-level state
Arena *arena;
U64 frame_index;
U64 frame_eval_memread_endt_us;
// rjf: commands
Arena *cmds_arena;
D_CmdList cmds;
// rjf: output log key
U128 output_log_key;
// rjf: per-run caches
D_UnwindCache unwind_cache;
U64 tls_base_cache_reggen_idx;
U64 tls_base_cache_memgen_idx;
D_RunTLSBaseCache tls_base_caches[2];
U64 tls_base_cache_gen;
U64 locals_cache_reggen_idx;
D_RunLocalsCache locals_caches[2];
U64 locals_cache_gen;
U64 member_cache_reggen_idx;
D_RunLocalsCache member_caches[2];
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
Arena *ctrl_last_run_arena;
D_RunKind ctrl_last_run_kind;
U64 ctrl_last_run_frame_idx;
CTRL_Handle ctrl_last_run_thread_handle;
CTRL_RunFlags ctrl_last_run_flags;
CTRL_TrapList ctrl_last_run_traps;
D_BreakpointArray ctrl_last_run_extra_bps;
U128 ctrl_last_run_param_state_hash;
B32 ctrl_is_running;
B32 ctrl_thread_run_state;
B32 ctrl_soft_halt_issued;
Arena *ctrl_msg_arena;
CTRL_MsgList ctrl_msgs;
// rjf: ctrl -> user reading state
CTRL_EntityStore *ctrl_entity_store;
Arena *ctrl_stop_arena;
CTRL_Event ctrl_last_stop_event;
};
////////////////////////////////
//~ rjf: Globals
read_only global D_ViewRuleSpec d_nil_core_view_rule_spec = {0};
global D_State *d_state = 0;
////////////////////////////////
//~ rjf: Basic Helpers
internal U64 d_hash_from_seed_string(U64 seed, String8 string);
internal U64 d_hash_from_string(String8 string);
internal U64 d_hash_from_seed_string__case_insensitive(U64 seed, String8 string);
internal U64 d_hash_from_string__case_insensitive(String8 string);
////////////////////////////////
//~ rjf: Breakpoints
internal D_BreakpointArray d_breakpoint_array_copy(Arena *arena, D_BreakpointArray *src);
////////////////////////////////
//~ rjf: Path Map Application
internal String8List d_possible_path_overrides_from_maps_path(Arena *arena, D_PathMapArray *path_maps, String8 file_path);
////////////////////////////////
//~ rjf: Debug Info Extraction Type Pure Functions
internal D_LineList d_line_list_copy(Arena *arena, D_LineList *list);
////////////////////////////////
//~ rjf: Command Type Functions
//- rjf: command parameters
internal D_CmdParams d_cmd_params_copy(Arena *arena, D_CmdParams *src);
//- rjf: command lists
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
internal CTRL_TrapList d_trap_net_from_thread__step_over_inst(Arena *arena, CTRL_Entity *thread);
internal CTRL_TrapList d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread);
internal CTRL_TrapList d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread);
////////////////////////////////
//~ 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
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
internal D_LineList d_lines_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff);
//- rjf: file:line -> line info
// TODO(rjf): this depends on file path maps, needs to move
internal D_LineListArray d_lines_array_from_file_path_line_range(Arena *arena, String8 file_path, Rng1S64 line_num_range);
internal D_LineList d_lines_from_file_path_line_num(Arena *arena, String8 file_path, S64 line_num);
////////////////////////////////
//~ rjf: Process/Thread/Module Info Lookups
internal U64 d_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64 rip_vaddr);
////////////////////////////////
//~ rjf: Target Controls
//- rjf: stopped info from the control thread
internal CTRL_Event d_ctrl_last_stop_event(void);
////////////////////////////////
//~ rjf: Main State Accessors/Mutators
//- rjf: frame data
internal U64 d_frame_index(void);
//- rjf: control state
internal D_RunKind d_ctrl_last_run_kind(void);
internal U64 d_ctrl_last_run_frame_idx(void);
internal B32 d_ctrl_targets_running(void);
//- rjf: active entity based queries
internal DI_KeyList d_push_active_dbgi_key_list(Arena *arena);
//- 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_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 E_String2NumMap *d_query_cached_locals_map_from_dbgi_key_voff(DI_Key *dbgi_key, U64 voff);
internal E_String2NumMap *d_query_cached_member_map_from_dbgi_key_voff(DI_Key *dbgi_key, U64 voff);
//- rjf: top-level command dispatch
internal void d_push_cmd(D_CmdKind kind, D_CmdParams *params);
#define d_cmd(kind, ...) d_push_cmd((kind), &(D_CmdParams){.thread = {0}, __VA_ARGS__})
//- rjf: command iteration
internal B32 d_next_cmd(D_Cmd **cmd);
////////////////////////////////
//~ rjf: Main Layer Top-Level Calls
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);
#endif // DBG_ENGINE_CORE_H
@@ -1,4 +1,4 @@
// 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/)
#include "lib_raddbgi_make/raddbgi_make.c" #include "dbg_engine_core.c"
+9
View File
@@ -0,0 +1,9 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DBG_ENGINE_INC_H
#define DBG_ENGINE_INC_H
#include "dbg_engine_core.h"
#endif // DBG_ENGINE_INC_H
@@ -0,0 +1,33 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
//- 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
@@ -0,0 +1,97 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
//- GENERATED CODE
#ifndef DBG_ENGINE_META_H
#define DBG_ENGINE_META_H
typedef enum D_CmdKind
{
D_CmdKind_Null,
D_CmdKind_LaunchAndRun,
D_CmdKind_LaunchAndInit,
D_CmdKind_Kill,
D_CmdKind_KillAll,
D_CmdKind_Detach,
D_CmdKind_Continue,
D_CmdKind_StepIntoInst,
D_CmdKind_StepOverInst,
D_CmdKind_StepIntoLine,
D_CmdKind_StepOverLine,
D_CmdKind_StepOut,
D_CmdKind_Halt,
D_CmdKind_SoftHaltRefresh,
D_CmdKind_SetThreadIP,
D_CmdKind_RunToLine,
D_CmdKind_RunToAddress,
D_CmdKind_Run,
D_CmdKind_Restart,
D_CmdKind_StepInto,
D_CmdKind_StepOver,
D_CmdKind_FreezeThread,
D_CmdKind_ThawThread,
D_CmdKind_FreezeProcess,
D_CmdKind_ThawProcess,
D_CmdKind_FreezeMachine,
D_CmdKind_ThawMachine,
D_CmdKind_FreezeLocalMachine,
D_CmdKind_ThawLocalMachine,
D_CmdKind_FreezeEntity,
D_CmdKind_ThawEntity,
D_CmdKind_SetEntityColor,
D_CmdKind_SetEntityName,
D_CmdKind_Attach,
D_CmdKind_COUNT,
} 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_telemetry_capture = 0;
global B32 DEV_simulate_lag = 0;
global B32 DEV_draw_ui_text_pos = 0;
global B32 DEV_draw_ui_focus_debug = 0;
global B32 DEV_draw_ui_box_heatmap = 0;
global B32 DEV_eval_compiler_tooltips = 0;
global B32 DEV_eval_watch_key_tooltips = 0;
global B32 DEV_cmd_context_tooltips = 0;
global B32 DEV_scratch_mouse_draw = 0;
global B32 DEV_updating_indicator = 0;
struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] =
{
{&DEV_telemetry_capture, str8_lit_comp("telemetry_capture")},
{&DEV_simulate_lag, str8_lit_comp("simulate_lag")},
{&DEV_draw_ui_text_pos, str8_lit_comp("draw_ui_text_pos")},
{&DEV_draw_ui_focus_debug, str8_lit_comp("draw_ui_focus_debug")},
{&DEV_draw_ui_box_heatmap, str8_lit_comp("draw_ui_box_heatmap")},
{&DEV_eval_compiler_tooltips, str8_lit_comp("eval_compiler_tooltips")},
{&DEV_eval_watch_key_tooltips, str8_lit_comp("eval_watch_key_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")},
};
#endif // DBG_ENGINE_META_H
+610 -1062
View File
File diff suppressed because it is too large Load Diff
+166 -342
View File
@@ -5,290 +5,166 @@
#define DBGI_H #define DBGI_H
//////////////////////////////// ////////////////////////////////
//~ rjf: Info Bundle Types //~ rjf: Cache Key Type
typedef struct DBGI_Parse DBGI_Parse; typedef struct DI_Key DI_Key;
struct DBGI_Parse struct DI_Key
{ {
U64 gen; String8 path;
Arena *arena; U64 min_timestamp;
void *exe_base;
FileProperties exe_props;
String8 dbg_path;
void *dbg_base;
FileProperties dbg_props;
PE_BinInfo pe;
RDI_Parsed rdi;
}; };
//////////////////////////////// typedef struct DI_KeyNode DI_KeyNode;
//~ rjf: Exe -> Debug Forced Override Cache Types struct DI_KeyNode
typedef struct DBGI_ForceNode DBGI_ForceNode;
struct DBGI_ForceNode
{ {
DBGI_ForceNode *next; DI_KeyNode *next;
String8 exe_path; DI_Key v;
U64 dbg_path_cap;
U64 dbg_path_size;
U8 *dbg_path_base;
}; };
typedef struct DBGI_ForceSlot DBGI_ForceSlot; typedef struct DI_KeyList DI_KeyList;
struct DBGI_ForceSlot struct DI_KeyList
{ {
DBGI_ForceNode *first; DI_KeyNode *first;
DBGI_ForceNode *last; DI_KeyNode *last;
};
typedef struct DBGI_ForceStripe DBGI_ForceStripe;
struct DBGI_ForceStripe
{
Arena *arena;
OS_Handle rw_mutex;
OS_Handle cv;
};
////////////////////////////////
//~ rjf: Binary Cache State Types
typedef U32 DBGI_BinaryFlags;
enum
{
DBGI_BinaryFlag_ParseInFlight = (1<<0),
};
typedef struct DBGI_Binary DBGI_Binary;
struct DBGI_Binary
{
// rjf: links & metadata
DBGI_Binary *next;
String8 exe_path;
U64 refcount;
U64 scope_touch_count;
U64 last_time_enqueued_for_parse_us;
DBGI_BinaryFlags flags;
U64 gen;
// rjf: exe handles
OS_Handle exe_file;
OS_Handle exe_file_map;
// rjf: debug handles
OS_Handle dbg_file;
OS_Handle dbg_file_map;
// rjf: analysis results
DBGI_Parse parse;
};
typedef struct DBGI_BinarySlot DBGI_BinarySlot;
struct DBGI_BinarySlot
{
DBGI_Binary *first;
DBGI_Binary *last;
};
typedef struct DBGI_BinaryStripe DBGI_BinaryStripe;
struct DBGI_BinaryStripe
{
Arena *arena;
OS_Handle rw_mutex;
OS_Handle cv;
};
////////////////////////////////
//~ rjf: Fuzzy Search Cache Types
typedef enum DBGI_FuzzySearchTarget
{
DBGI_FuzzySearchTarget_Procedures,
DBGI_FuzzySearchTarget_GlobalVariables,
DBGI_FuzzySearchTarget_ThreadVariables,
DBGI_FuzzySearchTarget_UDTs,
DBGI_FuzzySearchTarget_COUNT
}
DBGI_FuzzySearchTarget;
typedef struct DBGI_FuzzySearchItem DBGI_FuzzySearchItem;
struct DBGI_FuzzySearchItem
{
U64 idx;
U64 missed_size;
FuzzyMatchRangeList match_ranges;
};
typedef struct DBGI_FuzzySearchItemChunk DBGI_FuzzySearchItemChunk;
struct DBGI_FuzzySearchItemChunk
{
DBGI_FuzzySearchItemChunk *next;
DBGI_FuzzySearchItem *v;
U64 count;
U64 cap;
};
typedef struct DBGI_FuzzySearchItemChunkList DBGI_FuzzySearchItemChunkList;
struct DBGI_FuzzySearchItemChunkList
{
DBGI_FuzzySearchItemChunk *first;
DBGI_FuzzySearchItemChunk *last;
U64 chunk_count;
U64 total_count;
};
typedef struct DBGI_FuzzySearchItemArray DBGI_FuzzySearchItemArray;
struct DBGI_FuzzySearchItemArray
{
DBGI_FuzzySearchItem *v;
U64 count; U64 count;
}; };
typedef struct DBGI_FuzzySearchBucket DBGI_FuzzySearchBucket; typedef struct DI_KeyArray DI_KeyArray;
struct DBGI_FuzzySearchBucket struct DI_KeyArray
{ {
Arena *arena; DI_Key *v;
String8 exe_path; U64 count;
String8 query;
DBGI_FuzzySearchTarget target;
};
typedef struct DBGI_FuzzySearchNode DBGI_FuzzySearchNode;
struct DBGI_FuzzySearchNode
{
DBGI_FuzzySearchNode *next;
U128 key;
U64 scope_touch_count;
U64 last_time_submitted_us;
DBGI_FuzzySearchBucket buckets[3];
U64 gen;
U64 submit_gen;
DBGI_FuzzySearchItemArray gen_items;
};
typedef struct DBGI_FuzzySearchSlot DBGI_FuzzySearchSlot;
struct DBGI_FuzzySearchSlot
{
DBGI_FuzzySearchNode *first;
DBGI_FuzzySearchNode *last;
};
typedef struct DBGI_FuzzySearchStripe DBGI_FuzzySearchStripe;
struct DBGI_FuzzySearchStripe
{
Arena *arena;
OS_Handle rw_mutex;
OS_Handle cv;
};
typedef struct DBGI_FuzzySearchThread DBGI_FuzzySearchThread;
struct DBGI_FuzzySearchThread
{
OS_Handle thread;
OS_Handle u2f_ring_mutex;
OS_Handle u2f_ring_cv;
U64 u2f_ring_size;
U8 *u2f_ring_base;
U64 u2f_ring_write_pos;
U64 u2f_ring_read_pos;
};
////////////////////////////////
//~ rjf: Weak Access Scope Types
typedef struct DBGI_TouchedBinary DBGI_TouchedBinary;
struct DBGI_TouchedBinary
{
DBGI_TouchedBinary *next;
DBGI_Binary *binary;
};
typedef struct DBGI_TouchedFuzzySearch DBGI_TouchedFuzzySearch;
struct DBGI_TouchedFuzzySearch
{
DBGI_TouchedFuzzySearch *next;
DBGI_FuzzySearchNode *node;
};
typedef struct DBGI_Scope DBGI_Scope;
struct DBGI_Scope
{
DBGI_Scope *next;
DBGI_TouchedBinary *first_tb;
DBGI_TouchedBinary *last_tb;
DBGI_TouchedFuzzySearch *first_tfs;
DBGI_TouchedFuzzySearch *last_tfs;
};
typedef struct DBGI_ThreadCtx DBGI_ThreadCtx;
struct DBGI_ThreadCtx
{
Arena *arena;
DBGI_Scope *free_scope;
DBGI_TouchedBinary *free_tb;
DBGI_TouchedFuzzySearch *free_tfs;
}; };
//////////////////////////////// ////////////////////////////////
//~ rjf: Event Types //~ rjf: Event Types
typedef enum DBGI_EventKind typedef enum DI_EventKind
{ {
DBGI_EventKind_Null, DI_EventKind_Null,
DBGI_EventKind_ConversionStarted, DI_EventKind_ConversionStarted,
DBGI_EventKind_ConversionEnded, DI_EventKind_ConversionEnded,
DBGI_EventKind_ConversionFailureUnsupportedFormat, DI_EventKind_ConversionFailureUnsupportedFormat,
DBGI_EventKind_COUNT DI_EventKind_COUNT
} }
DBGI_EventKind; DI_EventKind;
typedef struct DBGI_Event DBGI_Event; typedef struct DI_Event DI_Event;
struct DBGI_Event struct DI_Event
{ {
DBGI_EventKind kind; DI_EventKind kind;
String8 string; String8 string;
}; };
typedef struct DBGI_EventNode DBGI_EventNode; typedef struct DI_EventNode DI_EventNode;
struct DBGI_EventNode struct DI_EventNode
{ {
DBGI_EventNode *next; DI_EventNode *next;
DBGI_Event v; DI_Event v;
}; };
typedef struct DBGI_EventList DBGI_EventList; typedef struct DI_EventList DI_EventList;
struct DBGI_EventList struct DI_EventList
{ {
DBGI_EventNode *first; DI_EventNode *first;
DBGI_EventNode *last; DI_EventNode *last;
U64 count; U64 count;
}; };
//////////////////////////////// ////////////////////////////////
//~ rjf: Cross-Thread Shared State //~ rjf: Cache Types
typedef struct DBGI_Shared DBGI_Shared; typedef struct DI_StringChunkNode DI_StringChunkNode;
struct DBGI_Shared struct DI_StringChunkNode
{
DI_StringChunkNode *next;
U64 size;
};
typedef struct DI_Node DI_Node;
struct DI_Node
{
// rjf: links
DI_Node *next;
DI_Node *prev;
// rjf: metadata
U64 ref_count;
U64 touch_count;
U64 is_working;
U64 last_time_requested_us;
// rjf: key
DI_Key key;
// rjf: file handles
OS_Handle file;
OS_Handle file_map;
void *file_base;
FileProperties file_props;
// rjf: parse artifacts
Arena *arena;
RDI_Parsed rdi;
B32 parse_done;
};
typedef struct DI_Slot DI_Slot;
struct DI_Slot
{
DI_Node *first;
DI_Node *last;
};
typedef struct DI_Stripe DI_Stripe;
struct DI_Stripe
{
Arena *arena;
DI_Node *free_node;
DI_StringChunkNode *free_string_chunks[8];
OS_Handle rw_mutex;
OS_Handle cv;
};
////////////////////////////////
//~ rjf: Scoped Access Types
typedef struct DI_Touch DI_Touch;
struct DI_Touch
{
DI_Touch *next;
DI_Node *node;
};
typedef struct DI_Scope DI_Scope;
struct DI_Scope
{
DI_Scope *next;
DI_Touch *first_touch;
DI_Touch *last_touch;
};
typedef struct DI_TCTX DI_TCTX;
struct DI_TCTX
{
Arena *arena;
DI_Scope *free_scope;
DI_Touch *free_touch;
};
////////////////////////////////
//~ rjf: Shared State Types
typedef struct DI_Shared DI_Shared;
struct DI_Shared
{ {
// rjf: arena
Arena *arena; Arena *arena;
// rjf: forced override table // rjf: node cache
U64 force_slots_count; U64 slots_count;
U64 force_stripes_count; DI_Slot *slots;
DBGI_ForceSlot *force_slots; U64 stripes_count;
DBGI_ForceStripe *force_stripes; DI_Stripe *stripes;
// rjf: binary table
U64 binary_slots_count;
U64 binary_stripes_count;
DBGI_BinarySlot *binary_slots;
DBGI_BinaryStripe *binary_stripes;
// rjf: fuzzy search cache table
U64 fuzzy_search_slots_count;
U64 fuzzy_search_stripes_count;
DBGI_FuzzySearchSlot *fuzzy_search_slots;
DBGI_FuzzySearchStripe *fuzzy_search_stripes;
// rjf: user -> parse ring // rjf: user -> parse ring
OS_Handle u2p_ring_mutex; OS_Handle u2p_ring_mutex;
@@ -309,123 +185,71 @@ struct DBGI_Shared
// rjf: threads // rjf: threads
U64 parse_thread_count; U64 parse_thread_count;
OS_Handle *parse_threads; OS_Handle *parse_threads;
U64 fuzzy_thread_count;
DBGI_FuzzySearchThread *fuzzy_threads;
}; };
//////////////////////////////// ////////////////////////////////
//~ rjf: Globals //~ rjf: Globals
global DBGI_Shared *dbgi_shared = 0; global DI_Shared *di_shared = 0;
thread_static DBGI_ThreadCtx *dbgi_tctx = 0; thread_static DI_TCTX *di_tctx = 0;
global DBGI_Parse dbgi_parse_nil = global RDI_Parsed di_rdi_parsed_nil = {0};
{
0, ////////////////////////////////
0, //~ rjf: Basic Helpers
0,
{0}, internal U64 di_hash_from_string(String8 string, StringMatchFlags match_flags);
{0}, internal U64 di_hash_from_key(DI_Key *k);
0, internal DI_Key di_key_zero(void);
{0}, internal B32 di_key_match(DI_Key *a, DI_Key *b);
{0}, internal DI_Key di_key_copy(Arena *arena, DI_Key *src);
{ internal DI_Key di_normalized_key_from_key(Arena *arena, DI_Key *src);
0, internal void di_key_list_push(Arena *arena, DI_KeyList *list, DI_Key *key);
0, internal DI_KeyArray di_key_array_from_list(Arena *arena, DI_KeyList *list);
0,
0,
{0},
0,
0,
0,
0,
0,
0,
0,
&rdi_binary_section_nil, 1,
&rdi_file_path_node_nil, 1,
&rdi_source_file_nil, 1,
&rdi_unit_nil, 1,
&rdi_vmap_entry_nil, 1,
&rdi_type_node_nil, 1,
&rdi_udt_nil, 1,
&rdi_member_nil, 1,
&rdi_enum_member_nil, 1,
&rdi_global_variable_nil, 1,
&rdi_vmap_entry_nil, 1,
&rdi_thread_variable_nil, 1,
&rdi_procedure_nil, 1,
&rdi_scope_nil, 1,
&rdi_voff_nil, 1,
&rdi_vmap_entry_nil, 1,
&rdi_local_nil, 1,
&rdi_location_block_nil, 1,
0, 0,
0, 0,
},
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Main Layer Initialization //~ rjf: Main Layer Initialization
internal void dbgi_init(void); internal void di_init(void);
////////////////////////////////
//~ rjf: Thread-Context Idempotent Initialization
internal void dbgi_ensure_tctx_inited(void);
////////////////////////////////
//~ rjf: Helpers
internal U64 dbgi_hash_from_string(String8 string, StringMatchFlags match_flags);
internal U64 dbgi_fuzzy_item_num_from_array_element_idx__linear_search(DBGI_FuzzySearchItemArray *array, U64 element_idx);
internal String8 dbgi_fuzzy_item_string_from_rdi_target_element_idx(RDI_Parsed *rdi, DBGI_FuzzySearchTarget target, U64 element_idx);
////////////////////////////////
//~ rjf: Forced Override Cache Functions
internal void dbgi_force_exe_path_dbg_path(String8 exe_path, String8 dbg_path);
internal String8 dbgi_forced_dbg_path_from_exe_path(Arena *arena, String8 exe_path);
//////////////////////////////// ////////////////////////////////
//~ rjf: Scope Functions //~ rjf: Scope Functions
internal DBGI_Scope *dbgi_scope_open(void); internal DI_Scope *di_scope_open(void);
internal void dbgi_scope_close(DBGI_Scope *scope); internal void di_scope_close(DI_Scope *scope);
internal void dbgi_scope_touch_binary__stripe_mutex_r_guarded(DBGI_Scope *scope, DBGI_Binary *binary); internal void di_scope_touch_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_Node *node);
internal void dbgi_scope_touch_fuzzy_search__stripe_mutex_r_guarded(DBGI_Scope *scope, DBGI_FuzzySearchNode *node);
//////////////////////////////// ////////////////////////////////
//~ rjf: Binary Cache Functions //~ rjf: Per-Slot Functions
internal void dbgi_binary_open(String8 exe_path); internal DI_Node *di_node_from_key_slot__stripe_mutex_r_guarded(DI_Slot *slot, DI_Key *key);
internal void dbgi_binary_close(String8 exe_path);
internal DBGI_Parse *dbgi_parse_from_exe_path(DBGI_Scope *scope, String8 exe_path, U64 endt_us);
//////////////////////////////// ////////////////////////////////
//~ rjf: Fuzzy Search Cache Functions //~ rjf: Per-Stripe Functions
internal DBGI_FuzzySearchItemArray dbgi_fuzzy_search_items_from_key_exe_query(DBGI_Scope *scope, U128 key, String8 exe_path, String8 query, DBGI_FuzzySearchTarget target, U64 endt_us, B32 *stale_out); internal U64 di_string_bucket_idx_from_string_size(U64 size);
internal String8 di_string_alloc__stripe_mutex_w_guarded(DI_Stripe *stripe, String8 string);
internal void di_string_release__stripe_mutex_w_guarded(DI_Stripe *stripe, String8 string);
////////////////////////////////
//~ rjf: Key Opening/Closing
internal void di_open(DI_Key *key);
internal void di_close(DI_Key *key);
////////////////////////////////
//~ rjf: Cache Lookups
internal RDI_Parsed *di_rdi_from_key(DI_Scope *scope, DI_Key *key, U64 endt_us);
//////////////////////////////// ////////////////////////////////
//~ rjf: Parse Threads //~ rjf: Parse Threads
internal B32 dbgi_u2p_enqueue_exe_path(String8 exe_path, U64 endt_us); internal B32 di_u2p_enqueue_key(DI_Key *key, U64 endt_us);
internal String8 dbgi_u2p_dequeue_exe_path(Arena *arena); internal void di_u2p_dequeue_key(Arena *arena, DI_Key *out_key);
internal void dbgi_p2u_push_event(DBGI_Event *event); internal void di_p2u_push_event(DI_Event *event);
internal DBGI_EventList dbgi_p2u_pop_events(Arena *arena, U64 endt_us); internal DI_EventList di_p2u_pop_events(Arena *arena, U64 endt_us);
internal void dbgi_parse_thread_entry_point(void *p); internal void di_parse_thread__entry_point(void *p);
//////////////////////////////// #endif // DBGI_H
//~ rjf: Fuzzy Searching Threads
internal B32 dbgi_u2f_enqueue_req(U128 key, U64 endt_us);
internal void dbgi_u2f_dequeue_req(Arena *arena, DBGI_FuzzySearchThread *thread, U128 *key_out);
internal int dbgi_qsort_compare_fuzzy_search_items(DBGI_FuzzySearchItem *a, DBGI_FuzzySearchItem *b);
internal void dbgi_fuzzy_thread__entry_point(void *p);
#endif //DBGI_H
+39 -4
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/)
////////////////////////////////
//~ rjf: Generated Code
#include "generated/demon.meta.c"
//////////////////////////////// ////////////////////////////////
//~ rjf: Basic Type Functions (Helpers, Implemented Once) //~ rjf: Basic Type Functions (Helpers, Implemented Once)
@@ -126,8 +131,8 @@ dmn_rip_from_thread(DMN_Handle thread)
U64 result = 0; U64 result = 0;
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
{ {
Architecture arch = dmn_arch_from_thread(thread); Arch arch = dmn_arch_from_thread(thread);
U64 reg_block_size = regs_block_size_from_architecture(arch); U64 reg_block_size = regs_block_size_from_arch(arch);
void *reg_block = push_array(scratch.arena, U8, reg_block_size); void *reg_block = push_array(scratch.arena, U8, reg_block_size);
dmn_thread_read_reg_block(thread, reg_block); dmn_thread_read_reg_block(thread, reg_block);
result = regs_rip_from_arch_block(arch, reg_block); result = regs_rip_from_arch_block(arch, reg_block);
@@ -142,8 +147,8 @@ dmn_rsp_from_thread(DMN_Handle thread)
U64 result = 0; U64 result = 0;
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
{ {
Architecture arch = dmn_arch_from_thread(thread); Arch arch = dmn_arch_from_thread(thread);
U64 reg_block_size = regs_block_size_from_architecture(arch); U64 reg_block_size = regs_block_size_from_arch(arch);
void *reg_block = push_array(scratch.arena, U8, reg_block_size); void *reg_block = push_array(scratch.arena, U8, reg_block_size);
dmn_thread_read_reg_block(thread, reg_block); dmn_thread_read_reg_block(thread, reg_block);
result = regs_rsp_from_arch_block(arch, reg_block); result = regs_rsp_from_arch_block(arch, reg_block);
@@ -151,3 +156,33 @@ dmn_rsp_from_thread(DMN_Handle thread)
scratch_end(scratch); scratch_end(scratch);
return result; return result;
} }
////////////////////////////////
//~ Memory Helpers
internal String8
dmn_process_read_cstring(Arena *arena, DMN_Handle process, U64 addr)
{
Temp scratch = scratch_begin(&arena, 1);
String8List block_list = {0};
for(U64 cursor = addr, stride = 256; ; cursor += stride)
{
U8 *raw_block = push_array_no_zero(scratch.arena, U8, stride);
U64 read_size = dmn_process_read(process, r1u64(cursor, cursor + stride), raw_block);
String8 block = str8_cstring_capped(raw_block, raw_block + read_size);
str8_list_push(scratch.arena, &block_list, block);
if(read_size != stride || (block.size+1 <= read_size && block.str[block.size] == 0))
{
break;
}
}
String8 result = str8_list_join(arena, &block_list, 0);
scratch_end(scratch);
return result;
}
+10 -4
View File
@@ -15,7 +15,7 @@
typedef struct DMN_CtrlCtx DMN_CtrlCtx; typedef struct DMN_CtrlCtx DMN_CtrlCtx;
struct DMN_CtrlCtx struct DMN_CtrlCtx
{ {
U64 u64 [1]; U64 u64[1];
}; };
//////////////////////////////// ////////////////////////////////
@@ -68,7 +68,7 @@ struct DMN_Event
DMN_Handle process; DMN_Handle process;
DMN_Handle thread; DMN_Handle thread;
DMN_Handle module; DMN_Handle module;
Architecture arch; Arch arch;
U64 address; U64 address;
U64 size; U64 size;
String8 string; String8 string;
@@ -192,7 +192,7 @@ internal DMN_CtrlCtx *dmn_ctrl_begin(void);
internal void dmn_ctrl_exclusive_access_begin(void); internal void dmn_ctrl_exclusive_access_begin(void);
internal void dmn_ctrl_exclusive_access_end(void); internal void dmn_ctrl_exclusive_access_end(void);
#define DMN_CtrlExclusiveAccessScope DeferLoop(dmn_ctrl_exclusive_access_begin(), dmn_ctrl_exclusive_access_end()) #define DMN_CtrlExclusiveAccessScope DeferLoop(dmn_ctrl_exclusive_access_begin(), dmn_ctrl_exclusive_access_end())
internal U32 dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_LaunchOptions *options); internal U32 dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params);
internal B32 dmn_ctrl_attach(DMN_CtrlCtx *ctx, U32 pid); internal B32 dmn_ctrl_attach(DMN_CtrlCtx *ctx, U32 pid);
internal B32 dmn_ctrl_kill(DMN_CtrlCtx *ctx, DMN_Handle process, U32 exit_code); internal B32 dmn_ctrl_kill(DMN_CtrlCtx *ctx, DMN_Handle process, U32 exit_code);
internal B32 dmn_ctrl_detach(DMN_CtrlCtx *ctx, DMN_Handle process); internal B32 dmn_ctrl_detach(DMN_CtrlCtx *ctx, DMN_Handle process);
@@ -217,13 +217,19 @@ internal void dmn_access_close(void);
#define DMN_AccessScope DeferLoopChecked(dmn_access_open(), dmn_access_close()) #define DMN_AccessScope DeferLoopChecked(dmn_access_open(), dmn_access_close())
//- rjf: processes //- rjf: processes
internal U64 dmn_process_memory_reserve(DMN_Handle process, U64 vaddr, U64 size);
internal void dmn_process_memory_commit(DMN_Handle process, U64 vaddr, U64 size);
internal void dmn_process_memory_decommit(DMN_Handle process, U64 vaddr, U64 size);
internal void dmn_process_memory_release(DMN_Handle process, U64 vaddr, U64 size);
internal void dmn_process_memory_protect(DMN_Handle process, U64 vaddr, U64 size, OS_AccessFlags flags);
internal U64 dmn_process_read(DMN_Handle process, Rng1U64 range, void *dst); internal U64 dmn_process_read(DMN_Handle process, Rng1U64 range, void *dst);
internal B32 dmn_process_write(DMN_Handle process, Rng1U64 range, void *src); internal B32 dmn_process_write(DMN_Handle process, Rng1U64 range, void *src);
#define dmn_process_read_struct(process, vaddr, ptr) dmn_process_read((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr) #define dmn_process_read_struct(process, vaddr, ptr) dmn_process_read((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
#define dmn_process_write_struct(process, vaddr, ptr) dmn_process_write((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr) #define dmn_process_write_struct(process, vaddr, ptr) dmn_process_write((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
internal String8 dmn_process_read_cstring(Arena *arena, DMN_Handle process, U64 addr);
//- rjf: threads //- rjf: threads
internal Architecture dmn_arch_from_thread(DMN_Handle handle); internal Arch dmn_arch_from_thread(DMN_Handle handle);
internal U64 dmn_stack_base_vaddr_from_thread(DMN_Handle handle); internal U64 dmn_stack_base_vaddr_from_thread(DMN_Handle handle);
internal U64 dmn_tls_root_vaddr_from_thread(DMN_Handle handle); internal U64 dmn_tls_root_vaddr_from_thread(DMN_Handle handle);
internal B32 dmn_thread_read_reg_block(DMN_Handle handle, void *reg_block); internal B32 dmn_thread_read_reg_block(DMN_Handle handle, void *reg_block);
+10
View File
@@ -61,6 +61,11 @@ DMN_ExceptionKindTable:
COUNT COUNT
} }
@data(String8) dmn_event_kind_string_table:
{
@expand(DMN_EventKindTable a) `str8_lit_comp("$(a.name)")`
}
@enum DMN_ErrorKind: @enum DMN_ErrorKind:
{ {
@expand(DMN_ErrorKindTable a) `$(a.name)`, @expand(DMN_ErrorKindTable a) `$(a.name)`,
@@ -78,3 +83,8 @@ DMN_ExceptionKindTable:
@expand(DMN_ExceptionKindTable a) `$(a.name)`, @expand(DMN_ExceptionKindTable a) `$(a.name)`,
COUNT COUNT
} }
@data(String8) dmn_exception_kind_string_table:
{
@expand(DMN_ExceptionKindTable a) `str8_lit_comp("$(a.name)")`
}
+4 -2
View File
@@ -1,10 +1,12 @@
// 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/)
#include "demon_core.c" #include "demon/demon_core.c"
#if OS_WINDOWS #if OS_WINDOWS
# include "win32/demon_core_win32.c" # include "demon/win32/demon_core_win32.c"
#elif OS_LINUX
# include "demon/linux/demon_core_linux.c"
#else #else
# error Demon layer backend not defined for this operating system. # error Demon layer backend not defined for this operating system.
#endif #endif
+4 -2
View File
@@ -4,10 +4,12 @@
#ifndef DEMON_INC_H #ifndef DEMON_INC_H
#define DEMON_INC_H #define DEMON_INC_H
#include "demon_core.h" #include "demon/demon_core.h"
#if OS_WINDOWS #if OS_WINDOWS
# include "win32/demon_core_win32.h" # include "demon/win32/demon_core_win32.h"
#elif OS_LINUX
# include "demon/linux/demon_core_linux.h"
#else #else
# error Demon layer backend not defined for this operating system. # error Demon layer backend not defined for this operating system.
#endif #endif
+30
View File
@@ -4,5 +4,35 @@
//- GENERATED CODE //- GENERATED CODE
C_LINKAGE_BEGIN C_LINKAGE_BEGIN
String8 dmn_event_kind_string_table[17] =
{
str8_lit_comp("Null"),
str8_lit_comp("Error"),
str8_lit_comp("HandshakeComplete"),
str8_lit_comp("CreateProcess"),
str8_lit_comp("ExitProcess"),
str8_lit_comp("CreateThread"),
str8_lit_comp("ExitThread"),
str8_lit_comp("LoadModule"),
str8_lit_comp("UnloadModule"),
str8_lit_comp("Breakpoint"),
str8_lit_comp("Trap"),
str8_lit_comp("SingleStep"),
str8_lit_comp("Exception"),
str8_lit_comp("Halt"),
str8_lit_comp("Memory"),
str8_lit_comp("DebugString"),
str8_lit_comp("SetThreadName"),
};
String8 dmn_exception_kind_string_table[5] =
{
str8_lit_comp("Null"),
str8_lit_comp("MemoryRead"),
str8_lit_comp("MemoryWrite"),
str8_lit_comp("MemoryExecute"),
str8_lit_comp("CppThrow"),
};
C_LINKAGE_END C_LINKAGE_END
+3
View File
@@ -58,6 +58,9 @@ DMN_ExceptionKind_COUNT,
} DMN_ExceptionKind; } DMN_ExceptionKind;
C_LINKAGE_BEGIN C_LINKAGE_BEGIN
extern String8 dmn_event_kind_string_table[17];
extern String8 dmn_exception_kind_string_table[5];
C_LINKAGE_END C_LINKAGE_END
#endif // DEMON_META_H #endif // DEMON_META_H
+174
View File
@@ -0,0 +1,174 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: @dmn_os_hooks Main Layer Initialization (Implemented Per-OS)
internal void
dmn_init(void)
{
}
////////////////////////////////
//~ rjf: @dmn_os_hooks Blocking Control Thread Operations (Implemented Per-OS)
internal DMN_CtrlCtx *
dmn_ctrl_begin(void)
{
}
internal void
dmn_ctrl_exclusive_access_begin(void)
{
}
internal void
dmn_ctrl_exclusive_access_end(void)
{
}
internal U32
dmn_ctrl_launch(DMN_CtrlCtx *ctx, OS_ProcessLaunchParams *params)
{
}
internal B32
dmn_ctrl_attach(DMN_CtrlCtx *ctx, U32 pid)
{
}
internal B32
dmn_ctrl_kill(DMN_CtrlCtx *ctx, DMN_Handle process, U32 exit_code)
{
}
internal B32
dmn_ctrl_detach(DMN_CtrlCtx *ctx, DMN_Handle process)
{
}
internal DMN_EventList
dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
{
}
////////////////////////////////
//~ rjf: @dmn_os_hooks Halting (Implemented Per-OS)
internal void
dmn_halt(U64 code, U64 user_data)
{
}
////////////////////////////////
//~ rjf: @dmn_os_hooks Introspection Functions (Implemented Per-OS)
//- rjf: run/memory/register counters
internal U64
dmn_run_gen(void)
{
}
internal U64
dmn_mem_gen(void)
{
}
internal U64
dmn_reg_gen(void)
{
}
//- rjf: non-blocking-control-thread access barriers
internal B32
dmn_access_open(void)
{
}
internal void
dmn_access_close(void)
{
}
//- rjf: processes
internal U64
dmn_process_memory_reserve(DMN_Handle process, U64 vaddr, U64 size)
{
}
internal void
dmn_process_memory_commit(DMN_Handle process, U64 vaddr, U64 size)
{
}
internal void
dmn_process_memory_decommit(DMN_Handle process, U64 vaddr, U64 size)
{
}
internal void
dmn_process_memory_release(DMN_Handle process, U64 vaddr, U64 size)
{
}
internal void
dmn_process_memory_protect(DMN_Handle process, U64 vaddr, U64 size, OS_AccessFlags flags)
{
}
internal U64
dmn_process_read(DMN_Handle process, Rng1U64 range, void *dst)
{
}
internal B32
dmn_process_write(DMN_Handle process, Rng1U64 range, void *src)
{
}
//- rjf: threads
internal Arch
dmn_arch_from_thread(DMN_Handle handle)
{
}
internal U64
dmn_stack_base_vaddr_from_thread(DMN_Handle handle)
{
}
internal U64
dmn_tls_root_vaddr_from_thread(DMN_Handle handle)
{
}
internal B32
dmn_thread_read_reg_block(DMN_Handle handle, void *reg_block)
{
}
internal B32
dmn_thread_write_reg_block(DMN_Handle handle, void *reg_block)
{
}
//- rjf: system process listing
internal void
dmn_process_iter_begin(DMN_ProcessIter *iter)
{
}
internal B32
dmn_process_iter_next(Arena *arena, DMN_ProcessIter *iter, DMN_ProcessInfo *info_out)
{
}
internal void
dmn_process_iter_end(DMN_ProcessIter *iter)
{
}
+7
View File
@@ -0,0 +1,7 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DEMON_CORE_LINUX_H
#define DEMON_CORE_LINUX_H
#endif // DEMON_CORE_LINUX_H
+29 -29
View File
@@ -98,7 +98,7 @@ demon_lnx_executable_path_from_pid(Arena *arena, pid_t pid){
temp_end(restore_point); temp_end(restore_point);
} }
else{ else{
arena_put_back(arena, (cap - size - 1)); arena_pop(arena, (cap - size - 1));
result = str8(buffer, size + 1); result = str8(buffer, size + 1);
} }
@@ -115,10 +115,10 @@ demon_lnx_open_memory_fd_for_pid(pid_t pid){
return(result); return(result);
} }
internal Architecture internal Arch
demon_lnx_arch_from_pid(pid_t pid){ demon_lnx_arch_from_pid(pid_t pid){
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
Architecture result = Architecture_Null; Arch result = Arch_Null;
// exe path // exe path
String8 exe_path = demon_lnx_executable_path_from_pid(scratch.arena, pid); String8 exe_path = demon_lnx_executable_path_from_pid(scratch.arena, pid);
@@ -168,22 +168,22 @@ demon_lnx_arch_from_pid(pid_t pid){
switch (ehdr.e_machine){ switch (ehdr.e_machine){
case SYMS_ElfMachineKind_386: case SYMS_ElfMachineKind_386:
{ {
result = Architecture_x86; result = Arch_x86;
}break; }break;
case SYMS_ElfMachineKind_ARM: case SYMS_ElfMachineKind_ARM:
{ {
result = Architecture_arm32; result = Arch_arm32;
}break; }break;
case SYMS_ElfMachineKind_X86_64: case SYMS_ElfMachineKind_X86_64:
{ {
result = Architecture_x64; result = Arch_x64;
}break; }break;
case SYMS_ElfMachineKind_AARCH64: case SYMS_ElfMachineKind_AARCH64:
{ {
result = Architecture_arm64; result = Arch_arm64;
}break; }break;
} }
@@ -192,9 +192,9 @@ demon_lnx_arch_from_pid(pid_t pid){
} }
internal DEMON_LNX_ProcessAux internal DEMON_LNX_ProcessAux
demon_lnx_aux_from_pid(pid_t pid, Architecture arch){ demon_lnx_aux_from_pid(pid_t pid, Arch arch){
DEMON_LNX_ProcessAux result = {0}; DEMON_LNX_ProcessAux result = {0};
B32 addr_32bit = (arch == Architecture_x86 || arch == Architecture_arm32); B32 addr_32bit = (arch == Arch_x86 || arch == Arch_arm32);
// open aux data // open aux data
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
@@ -300,8 +300,8 @@ demon_lnx_phdr_info_from_memory(int memory_fd, B32 is_32bit, U64 phvaddr, U64 ph
internal DEMON_LNX_ModuleNode* internal DEMON_LNX_ModuleNode*
demon_lnx_module_list_from_process(Arena *arena, DEMON_Entity *process){ demon_lnx_module_list_from_process(Arena *arena, DEMON_Entity *process){
Architecture arch = (Architecture)process->arch; Arch arch = (Arch)process->arch;
B32 is_32bit = (arch == Architecture_x86 || arch == Architecture_arm32); B32 is_32bit = (arch == Arch_x86 || arch == Arch_arm32);
int memory_fd = (int)process->ext_u64; int memory_fd = (int)process->ext_u64;
// aux from pid // aux from pid
@@ -839,11 +839,11 @@ demon_os_run(Arena *arena, DEMON_OS_RunCtrls *controls){
U8 *trap_swap_bytes = 0; U8 *trap_swap_bytes = 0;
if (result.first == 0){ if (result.first == 0){
// TODO(allen): per-Architecture implementation of single steps // TODO(allen): per-Arch implementation of single steps
// set single step bit // set single step bit
if (single_step_thread != 0){ if (single_step_thread != 0){
switch (single_step_thread->arch){ switch (single_step_thread->arch){
case Architecture_x86: case Arch_x86:
{ {
// TODO(allen): possibly buggy // TODO(allen): possibly buggy
SYMS_RegX86 regs = {0}; SYMS_RegX86 regs = {0};
@@ -852,7 +852,7 @@ demon_os_run(Arena *arena, DEMON_OS_RunCtrls *controls){
demon_os_write_regs_x86(single_step_thread, &regs); demon_os_write_regs_x86(single_step_thread, &regs);
}break; }break;
case Architecture_x64: case Arch_x64:
{ {
// TODO(allen): possibly buggy // TODO(allen): possibly buggy
SYMS_RegX64 regs = {0}; SYMS_RegX64 regs = {0};
@@ -863,7 +863,7 @@ demon_os_run(Arena *arena, DEMON_OS_RunCtrls *controls){
} }
} }
// TODO(allen): per-Architecture implementation of traps // TODO(allen): per-Arch implementation of traps
trap_swap_bytes = push_array_no_zero(scratch.arena, U8, controls->trap_count); trap_swap_bytes = push_array_no_zero(scratch.arena, U8, controls->trap_count);
{ {
@@ -980,13 +980,13 @@ demon_os_run(Arena *arena, DEMON_OS_RunCtrls *controls){
union{ SYMS_RegX86 x86; SYMS_RegX64 x64; } regs = {0}; union{ SYMS_RegX86 x86; SYMS_RegX64 x64; } regs = {0};
switch (thread->arch){ switch (thread->arch){
case Architecture_x86: case Arch_x86:
{ {
demon_os_read_regs_x86(thread, &regs.x86); demon_os_read_regs_x86(thread, &regs.x86);
instruction_pointer = regs.x86.eip.u32; instruction_pointer = regs.x86.eip.u32;
}break; }break;
case Architecture_x64: case Arch_x64:
{ {
demon_os_read_regs_x64(thread, &regs.x64); demon_os_read_regs_x64(thread, &regs.x64);
instruction_pointer = regs.x64.rip.u64; instruction_pointer = regs.x64.rip.u64;
@@ -1052,7 +1052,7 @@ demon_os_run(Arena *arena, DEMON_OS_RunCtrls *controls){
// this stuff in the log to make sense of it still. // this stuff in the log to make sense of it still.
} }
else{ else{
Architecture arch = demon_lnx_arch_from_pid(new_pid); Arch arch = demon_lnx_arch_from_pid(new_pid);
// process entity // process entity
DEMON_Entity *new_process = demon_ent_new(demon_ent_root, DEMON_EntityKind_Process, new_pid); DEMON_Entity *new_process = demon_ent_new(demon_ent_root, DEMON_EntityKind_Process, new_pid);
@@ -1105,14 +1105,14 @@ demon_os_run(Arena *arena, DEMON_OS_RunCtrls *controls){
if (e_kind == DEMON_EventKind_Breakpoint){ if (e_kind == DEMON_EventKind_Breakpoint){
// TODO(allen): possibly buggy // TODO(allen): possibly buggy
switch (thread->arch){ switch (thread->arch){
case Architecture_x86: case Arch_x86:
{ {
instruction_pointer -= 1; instruction_pointer -= 1;
regs.x86.eip.u32 = instruction_pointer; regs.x86.eip.u32 = instruction_pointer;
demon_os_write_regs_x86(thread, &regs.x86); demon_os_write_regs_x86(thread, &regs.x86);
}break; }break;
case Architecture_x64: case Arch_x64:
{ {
instruction_pointer -= 1; instruction_pointer -= 1;
regs.x64.rip.u64 = instruction_pointer; regs.x64.rip.u64 = instruction_pointer;
@@ -1336,7 +1336,7 @@ demon_os_run(Arena *arena, DEMON_OS_RunCtrls *controls){
// cleanup // cleanup
if (did_run){ if (did_run){
// TODO(allen): per-Architecture // TODO(allen): per-Arch
// unset traps // unset traps
{ {
DEMON_OS_Trap *trap = controls->traps; DEMON_OS_Trap *trap = controls->traps;
@@ -1348,7 +1348,7 @@ demon_os_run(Arena *arena, DEMON_OS_RunCtrls *controls){
} }
} }
// TODO(allen): per-Architecture // TODO(allen): per-Arch
// unset single step bit // unset single step bit
// the single step bit is automatically unset whenever we single step // the single step bit is automatically unset whenever we single step
// but if *something else* happened, it will still be there ready to // but if *something else* happened, it will still be there ready to
@@ -1356,7 +1356,7 @@ demon_os_run(Arena *arena, DEMON_OS_RunCtrls *controls){
if (single_step_thread != 0){ if (single_step_thread != 0){
// TODO(allen): possibly buggy // TODO(allen): possibly buggy
switch (single_step_thread->arch){ switch (single_step_thread->arch){
case Architecture_x86: case Arch_x86:
{ {
SYMS_RegX86 regs = {0}; SYMS_RegX86 regs = {0};
demon_os_read_regs_x86(single_step_thread, &regs); demon_os_read_regs_x86(single_step_thread, &regs);
@@ -1364,7 +1364,7 @@ demon_os_run(Arena *arena, DEMON_OS_RunCtrls *controls){
demon_os_write_regs_x86(single_step_thread, &regs); demon_os_write_regs_x86(single_step_thread, &regs);
}break; }break;
case Architecture_x64: case Arch_x64:
{ {
SYMS_RegX64 regs = {0}; SYMS_RegX64 regs = {0};
demon_os_read_regs_x64(single_step_thread, &regs); demon_os_read_regs_x64(single_step_thread, &regs);
@@ -1555,7 +1555,7 @@ demon_os_launch_process(OS_LaunchOptions *options){
else{ else{
result = pid; result = pid;
Architecture arch = demon_lnx_arch_from_pid(pid); Arch arch = demon_lnx_arch_from_pid(pid);
// process entity // process entity
DEMON_Entity *process = demon_ent_new(demon_ent_root, DEMON_EntityKind_Process, pid); DEMON_Entity *process = demon_ent_new(demon_ent_root, DEMON_EntityKind_Process, pid);
@@ -1688,7 +1688,7 @@ demon_os_attach_process(U32 pid){
// initialize new entities on success // initialize new entities on success
if (result){ if (result){
Architecture arch = demon_lnx_arch_from_pid(the_process->pid); Arch arch = demon_lnx_arch_from_pid(the_process->pid);
// process entity // process entity
DEMON_Entity *process = demon_ent_new(demon_ent_root, DEMON_EntityKind_Process, the_process->pid); DEMON_Entity *process = demon_ent_new(demon_ent_root, DEMON_EntityKind_Process, the_process->pid);
@@ -1816,15 +1816,15 @@ internal U64
demon_os_tls_root_vaddr_from_thread(DEMON_Entity *thread){ demon_os_tls_root_vaddr_from_thread(DEMON_Entity *thread){
U64 result = 0; U64 result = 0;
switch (thread->arch){ switch (thread->arch){
case Architecture_x64: case Arch_x64:
case Architecture_x86: case Arch_x86:
{ {
U32 fsbase = 0; U32 fsbase = 0;
pid_t tid = (pid_t)thread->id; pid_t tid = (pid_t)thread->id;
if (ptrace(PT_GETFSBASE, tid, (void*)&fsbase, 0) != -1){ if (ptrace(PT_GETFSBASE, tid, (void*)&fsbase, 0) != -1){
result = (U64)fsbase; result = (U64)fsbase;
} }
if (thread->arch == Architecture_x64){ if (thread->arch == Arch_x64){
result += 8; result += 8;
} }
else{ else{
+2 -2
View File
@@ -198,8 +198,8 @@ internal B32 demon_lnx_attach_pid(Arena *arena, pid_t pid, DEM
internal String8 demon_lnx_executable_path_from_pid(Arena *arena, pid_t pid); internal String8 demon_lnx_executable_path_from_pid(Arena *arena, pid_t pid);
internal int demon_lnx_open_memory_fd_for_pid(pid_t pid); internal int demon_lnx_open_memory_fd_for_pid(pid_t pid);
internal Architecture demon_lnx_arch_from_pid(pid_t pid); internal Arch demon_lnx_arch_from_pid(pid_t pid);
internal DEMON_LNX_ProcessAux demon_lnx_aux_from_pid(pid_t pid, Architecture arch); internal DEMON_LNX_ProcessAux demon_lnx_aux_from_pid(pid_t pid, Arch arch);
internal DEMON_LNX_PhdrInfo demon_lnx_phdr_info_from_memory(int memory_fd, B32 is_32bit, internal DEMON_LNX_PhdrInfo demon_lnx_phdr_info_from_memory(int memory_fd, B32 is_32bit,
U64 phvaddr, U64 phstride, U64 phcount); U64 phvaddr, U64 phstride, U64 phcount);
internal DEMON_LNX_ModuleNode* demon_lnx_module_list_from_process(Arena *arena, DEMON_Entity *process); internal DEMON_LNX_ModuleNode* demon_lnx_module_list_from_process(Arena *arena, DEMON_Entity *process);
File diff suppressed because it is too large Load Diff
+11 -12
View File
@@ -54,6 +54,8 @@
#define DMN_W32_EXCEPTION_NO_MEMORY 0xC0000017u #define DMN_W32_EXCEPTION_NO_MEMORY 0xC0000017u
#define DMN_W32_EXCEPTION_THROW 0xE06D7363u #define DMN_W32_EXCEPTION_THROW 0xE06D7363u
#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_CLR 0xE0434352u
//////////////////////////////// ////////////////////////////////
//~ rjf: Win32 Register Codes //~ rjf: Win32 Register Codes
@@ -61,11 +63,11 @@
#define DMN_W32_CTX_X86 0x00010000 #define DMN_W32_CTX_X86 0x00010000
#define DMN_W32_CTX_X64 0x00100000 #define DMN_W32_CTX_X64 0x00100000
#define DMN_W32_CTX_INTEL_CONTROL 0x0001 #define DMN_W32_CTX_INTEL_CONTROL 0x0001 // segss, rsp, segcs, rip, and rflags
#define DMN_W32_CTX_INTEL_INTEGER 0x0002 #define DMN_W32_CTX_INTEL_INTEGER 0x0002 // rax, rcx, rdx, rbx, rbp, rsi, rdi, and r8-r15
#define DMN_W32_CTX_INTEL_SEGMENTS 0x0004 #define DMN_W32_CTX_INTEL_SEGMENTS 0x0004 // segds, seges, segfs, and seggs
#define DMN_W32_CTX_INTEL_FLOATS 0x0008 #define DMN_W32_CTX_INTEL_FLOATS 0x0008 // xmm0-xmm15
#define DMN_W32_CTX_INTEL_DEBUG 0x0010 #define DMN_W32_CTX_INTEL_DEBUG 0x0010 // dr0-dr3 and dr6-dr7
#define DMN_W32_CTX_INTEL_EXTENDED 0x0020 #define DMN_W32_CTX_INTEL_EXTENDED 0x0020
#define DMN_W32_CTX_INTEL_XSTATE 0x0040 #define DMN_W32_CTX_INTEL_XSTATE 0x0040
@@ -104,7 +106,7 @@ struct DMN_W32_Entity
U32 gen; U32 gen;
U64 id; U64 id;
HANDLE handle; HANDLE handle;
Architecture arch; Arch arch;
union union
{ {
struct struct
@@ -118,9 +120,6 @@ struct DMN_W32_Entity
U64 thread_local_base; U64 thread_local_base;
U64 last_name_hash; U64 last_name_hash;
U64 name_gather_time_us; U64 name_gather_time_us;
B32 last_run_reported_trap;
U64 last_run_reported_trap_pre_rip;
U64 last_run_reported_trap_post_rip;
} }
thread; thread;
struct struct
@@ -175,7 +174,7 @@ struct DMN_W32_InjectedBreak
typedef struct DMN_W32_ImageInfo DMN_W32_ImageInfo; typedef struct DMN_W32_ImageInfo DMN_W32_ImageInfo;
struct DMN_W32_ImageInfo struct DMN_W32_ImageInfo
{ {
Architecture arch; Arch arch;
U32 size; U32 size;
}; };
@@ -278,8 +277,8 @@ internal DMN_W32_ImageInfo dmn_w32_image_info_from_process_base_vaddr(HANDLE pro
//- rjf: threads //- rjf: threads
internal U16 dmn_w32_real_tag_word_from_xsave(XSAVE_FORMAT *fxsave); internal U16 dmn_w32_real_tag_word_from_xsave(XSAVE_FORMAT *fxsave);
internal U16 dmn_w32_xsave_tag_word_from_real_tag_word(U16 ftw); internal U16 dmn_w32_xsave_tag_word_from_real_tag_word(U16 ftw);
internal B32 dmn_w32_thread_read_reg_block(Architecture arch, HANDLE thread, void *reg_block); internal B32 dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block);
internal B32 dmn_w32_thread_write_reg_block(Architecture arch, HANDLE thread, void *reg_block); internal B32 dmn_w32_thread_write_reg_block(Arch arch, HANDLE thread, void *reg_block);
//- rjf: remote thread injection //- rjf: remote thread injection
internal DWORD dmn_w32_inject_thread(HANDLE process, U64 start_address); internal DWORD dmn_w32_inject_thread(HANDLE process, U64 start_address);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-516
View File
@@ -1,516 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
//- GENERATED CODE
C_LINKAGE_BEGIN
Rng1U64 df_g_cmd_param_slot_range_table[19] =
{
{0},
{OffsetOf(DF_CmdParams, window), OffsetOf(DF_CmdParams, window) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, panel), OffsetOf(DF_CmdParams, panel) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, dest_panel), OffsetOf(DF_CmdParams, dest_panel) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, prev_view), OffsetOf(DF_CmdParams, prev_view) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, view), OffsetOf(DF_CmdParams, view) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, entity), OffsetOf(DF_CmdParams, entity) + sizeof(DF_Handle)},
{OffsetOf(DF_CmdParams, entity_list), OffsetOf(DF_CmdParams, entity_list) + sizeof(DF_HandleList)},
{OffsetOf(DF_CmdParams, string), OffsetOf(DF_CmdParams, string) + sizeof(String8)},
{OffsetOf(DF_CmdParams, file_path), OffsetOf(DF_CmdParams, file_path) + sizeof(String8)},
{OffsetOf(DF_CmdParams, text_point), OffsetOf(DF_CmdParams, text_point) + sizeof(TxtPt)},
{OffsetOf(DF_CmdParams, cmd_spec), OffsetOf(DF_CmdParams, cmd_spec) + sizeof(struct DF_CmdSpec *)},
{OffsetOf(DF_CmdParams, view_spec), OffsetOf(DF_CmdParams, view_spec) + sizeof(struct DF_ViewSpec *)},
{OffsetOf(DF_CmdParams, vaddr), OffsetOf(DF_CmdParams, vaddr) + sizeof(U64)},
{OffsetOf(DF_CmdParams, voff), OffsetOf(DF_CmdParams, voff) + sizeof(U64)},
{OffsetOf(DF_CmdParams, index), OffsetOf(DF_CmdParams, index) + sizeof(U64)},
{OffsetOf(DF_CmdParams, id), OffsetOf(DF_CmdParams, id) + sizeof(U64)},
{OffsetOf(DF_CmdParams, prefer_dasm), OffsetOf(DF_CmdParams, prefer_dasm) + sizeof(B32)},
{OffsetOf(DF_CmdParams, force_confirm), OffsetOf(DF_CmdParams, force_confirm) + sizeof(B32)},
};
DF_IconKind df_g_entity_kind_icon_kind_table[26] =
{
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Machine,
DF_IconKind_FileOutline,
DF_IconKind_FileOutline,
DF_IconKind_FileOutline,
DF_IconKind_FileOutline,
DF_IconKind_Null,
DF_IconKind_Pin,
DF_IconKind_CircleFilled,
DF_IconKind_CircleFilled,
DF_IconKind_Target,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Threads,
DF_IconKind_Thread,
DF_IconKind_Module,
DF_IconKind_Null,
DF_IconKind_Threads,
DF_IconKind_Null,
DF_IconKind_Null,
DF_IconKind_Null,
};
String8 df_g_entity_kind_display_string_table[26] =
{
str8_lit_comp("Nil"),
str8_lit_comp("Root"),
str8_lit_comp("Machine"),
str8_lit_comp("File"),
str8_lit_comp("Override File Link"),
str8_lit_comp("Pending File Change"),
str8_lit_comp("Diagnostics Log"),
str8_lit_comp("Flash Marker"),
str8_lit_comp("Watch Pin"),
str8_lit_comp("Breakpoint"),
str8_lit_comp("Condition"),
str8_lit_comp("Target"),
str8_lit_comp("Executable"),
str8_lit_comp("Arguments"),
str8_lit_comp("Execution Path"),
str8_lit_comp("Entry Point Name"),
str8_lit_comp("Source"),
str8_lit_comp("Destination"),
str8_lit_comp("Process"),
str8_lit_comp("Thread"),
str8_lit_comp("Module"),
str8_lit_comp("Debug Info Override"),
str8_lit_comp("Pending Thread Name"),
str8_lit_comp("Conversion Task"),
str8_lit_comp("Conversion Failure"),
str8_lit_comp("EndedProcess"),
};
String8 df_g_entity_kind_name_label_table[26] =
{
str8_lit_comp("Label"),
str8_lit_comp("Label"),
str8_lit_comp("Label"),
str8_lit_comp("Label"),
str8_lit_comp("Label"),
str8_lit_comp("Label"),
str8_lit_comp("Label"),
str8_lit_comp("Label"),
str8_lit_comp("Expression"),
str8_lit_comp("Label"),
str8_lit_comp("Expression"),
str8_lit_comp("Label"),
str8_lit_comp("Executable"),
str8_lit_comp("Arguments"),
str8_lit_comp("Execution Path"),
str8_lit_comp("Symbol Name"),
str8_lit_comp("Path"),
str8_lit_comp("Path"),
str8_lit_comp("Label"),
str8_lit_comp("Label"),
str8_lit_comp("Label"),
str8_lit_comp("Label"),
str8_lit_comp("Label"),
str8_lit_comp("Label"),
str8_lit_comp("Label"),
str8_lit_comp("Label"),
};
DF_EntityKindFlags df_g_entity_kind_flags_table[26] =
{
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
(1*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 1*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProfileConfig | 1*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProfileConfig | 1*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 1*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 1*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProfileConfig | 1*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 1*DF_EntityKindFlag_LeafMutationSoftHalt | 1*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 1*DF_EntityKindFlag_TreeMutationSoftHalt | 1*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime),
};
DF_EntityOpFlags df_g_entity_kind_op_flags_table[26] =
{
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (1*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(1*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (1*DF_EntityOpFlag_Duplicate),
(1*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (1*DF_EntityOpFlag_Enable) | (1*DF_EntityOpFlag_Condition) | (1*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(1*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (1*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (1*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (1*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (1*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (1*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
(1*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate),
};
String8 df_g_cfg_src_string_table[4] =
{
str8_lit_comp("user"),
str8_lit_comp("profile"),
str8_lit_comp("command_line"),
str8_lit_comp("transient"),
};
DF_CoreCmdKind df_g_cfg_src_load_cmd_kind_table[4] =
{
DF_CoreCmdKind_OpenUser,
DF_CoreCmdKind_OpenProfile,
DF_CoreCmdKind_Null,
DF_CoreCmdKind_Null,
};
DF_CoreCmdKind df_g_cfg_src_write_cmd_kind_table[4] =
{
DF_CoreCmdKind_WriteUserData,
DF_CoreCmdKind_WriteProfileData,
DF_CoreCmdKind_Null,
DF_CoreCmdKind_Null,
};
DF_CoreCmdKind df_g_cfg_src_apply_cmd_kind_table[4] =
{
DF_CoreCmdKind_ApplyUserData,
DF_CoreCmdKind_ApplyProfileData,
DF_CoreCmdKind_Null,
DF_CoreCmdKind_Null,
};
DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[206] =
{
{ str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp("Exit"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_X},
{ str8_lit_comp("run_command"), str8_lit_comp("Runs a command from the command palette."), str8_lit_comp("help,cmd"), str8_lit_comp("Run Command"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_CmdSpec, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("error"), str8_lit_comp("Notifies of an error."), str8_lit_comp(""), str8_lit_comp("Error"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("launch_and_run"), str8_lit_comp("Starts debugging a new instance of a target, then runs."), str8_lit_comp("launch,start,run,target"), str8_lit_comp("Launch and Run"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_EntityList, DF_EntityKind_Target, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Play},
{ str8_lit_comp("launch_and_init"), str8_lit_comp("Starts debugging a new instance of a target, then stops at the program's entry point."), str8_lit_comp("launch,start,entry,point"), str8_lit_comp("Launch and Initialize"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_EntityList, DF_EntityKind_Target, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_PlayStepForward},
{ str8_lit_comp("kill"), str8_lit_comp("Kills the specified existing debugged process(es)."), str8_lit_comp("stop,kill"), str8_lit_comp("Kill"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_EntityList, DF_EntityKind_Process, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Stop},
{ str8_lit_comp("kill_all"), str8_lit_comp("Kills all debugged child processes."), str8_lit_comp("stop,kill,all"), str8_lit_comp("Kill All"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Stop},
{ str8_lit_comp("detach"), str8_lit_comp("Detaches the specified debugged process."), str8_lit_comp("detach"), str8_lit_comp("Detach"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_EntityList, DF_EntityKind_Process, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Null},
{ str8_lit_comp("continue"), str8_lit_comp("Continues all halted threads."), str8_lit_comp(""), str8_lit_comp("Continue"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Play},
{ str8_lit_comp("step_into_inst"), str8_lit_comp("Performs a step that goes into calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp("Step Into (Assembly)"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_StepInto},
{ str8_lit_comp("step_over_inst"), str8_lit_comp("Performs a step that skips calls, at the instruction level."), str8_lit_comp("single,step,thread"), str8_lit_comp("Step Over (Assembly)"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_StepOver},
{ str8_lit_comp("step_into_line"), str8_lit_comp("Performs a step that goes into calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp("Step Into (Line)"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_StepInto},
{ str8_lit_comp("step_over_line"), str8_lit_comp("Performs a step that skips calls, at the source code line level."), str8_lit_comp("step,thread"), str8_lit_comp("Step Over (Line)"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_StepOver},
{ str8_lit_comp("step_out"), str8_lit_comp("Runs to the end of the current function and exits it."), str8_lit_comp(""), str8_lit_comp("Step Out"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_StepOut},
{ str8_lit_comp("halt"), str8_lit_comp("Halts all running processes."), str8_lit_comp("pause"), str8_lit_comp("Halt"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Pause},
{ str8_lit_comp("soft_halt_refresh"), str8_lit_comp("Interrupts all running processes to collect data, and then resumes them."), str8_lit_comp(""), str8_lit_comp("Soft Halt Refresh"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Refresh},
{ str8_lit_comp("set_thread_ip"), str8_lit_comp("Sets the passed thread's instruction pointer at the passed address."), str8_lit_comp(""), str8_lit_comp("Set Thread IP"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_VirtualAddr, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Null},
{ str8_lit_comp("run_to_line"), str8_lit_comp("Runs until a particular source line is hit."), str8_lit_comp(""), str8_lit_comp("Run To Line"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Play},
{ str8_lit_comp("run_to_address"), str8_lit_comp("Runs until a particular address is hit."), str8_lit_comp(""), str8_lit_comp("Run To Address"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_VirtualAddr, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_PlayStepForward},
{ str8_lit_comp("run"), str8_lit_comp("Runs all targets after starting them if they have not been started yet."), str8_lit_comp("play"), str8_lit_comp("Run"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Play},
{ str8_lit_comp("restart"), str8_lit_comp("Kills all running processes, then restarts the targets which were used to launch all current processes (if any)."), str8_lit_comp("restart,retry"), str8_lit_comp("Restart"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Redo},
{ str8_lit_comp("step_into"), str8_lit_comp("Steps once, possibly into function calls, for either line or instructions."), str8_lit_comp(""), str8_lit_comp("Step Into"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_StepInto},
{ str8_lit_comp("step_over"), str8_lit_comp("Steps once, always over function calls, for either line or instructions."), str8_lit_comp(""), str8_lit_comp("Step Over"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_StepOver},
{ str8_lit_comp("run_to_cursor"), str8_lit_comp("Runs the selected thread to the current cursor."), str8_lit_comp(""), str8_lit_comp("Run To Cursor"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Play},
{ str8_lit_comp("set_next_statement"), str8_lit_comp("Sets the selected thread's instruction pointer to the cursor's position."), str8_lit_comp(""), str8_lit_comp("Set Next Statement"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_RightArrow},
{ str8_lit_comp("enable_solo_stepping_mode"), str8_lit_comp("Enables 'solo stepping mode', which suspends all non-selected threads before stepping."), str8_lit_comp("solo,stepping,mode,suspend"), str8_lit_comp("Enable Solo Stepping Mode"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Thread},
{ str8_lit_comp("disable_solo_stepping_mode"), str8_lit_comp("Disables 'solo stepping mode', which suspends all non-selected threads before stepping."), str8_lit_comp("solo,stepping,mode,suspend"), str8_lit_comp("Disable Solo Stepping Mode"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Thread},
{ str8_lit_comp("select_thread"), str8_lit_comp("Selects a thread."), str8_lit_comp(""), str8_lit_comp("Select Thread"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Thread, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Null},
{ str8_lit_comp("select_thread_window"), str8_lit_comp("Selects a thread for the active window, overriding the global selected thread."), str8_lit_comp(""), str8_lit_comp("Select Thread On Window"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Thread, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Null},
{ str8_lit_comp("select_thread_view"), str8_lit_comp("Selects a thread for the active view, overriding the global and per-window selected threads."), str8_lit_comp(""), str8_lit_comp("Select Thread On View"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Thread, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Null},
{ str8_lit_comp("select_unwind"), str8_lit_comp("Selects an unwind frame number for the selected thread."), str8_lit_comp(""), str8_lit_comp("Select Unwind"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("up_one_frame"), str8_lit_comp("Selects the callstack frame above the currently selected."), str8_lit_comp(""), str8_lit_comp("Up One Frame"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_UpArrow},
{ str8_lit_comp("down_one_frame"), str8_lit_comp("Selects the callstack frame below the currently selected."), str8_lit_comp(""), str8_lit_comp("Down One Frame"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_DownArrow},
{ str8_lit_comp("freeze_thread"), str8_lit_comp("Freezes the passed thread."), str8_lit_comp(""), str8_lit_comp("Freeze Thread"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Thread, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Locked},
{ str8_lit_comp("thaw_thread"), str8_lit_comp("Thaws the passed thread."), str8_lit_comp(""), str8_lit_comp("Thaw Thread"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Thread, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Unlocked},
{ str8_lit_comp("freeze_process"), str8_lit_comp("Freezes the passed process."), str8_lit_comp(""), str8_lit_comp("Freeze Process"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Process, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Locked},
{ str8_lit_comp("thaw_process"), str8_lit_comp("Thaws the passed process."), str8_lit_comp(""), str8_lit_comp("Thaw Process"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Process, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Unlocked},
{ str8_lit_comp("freeze_machine"), str8_lit_comp("Freezes the passed machine."), str8_lit_comp(""), str8_lit_comp("Freeze Machine"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Entity, DF_EntityKind_Machine, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Locked},
{ str8_lit_comp("thaw_machine"), str8_lit_comp("Thaws the passed machine."), str8_lit_comp(""), str8_lit_comp("Thaw Machine"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Entity, DF_EntityKind_Machine, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Unlocked},
{ str8_lit_comp("freeze_local_machine"), str8_lit_comp("Freezes the local machine."), str8_lit_comp(""), str8_lit_comp("Freeze Local Machine"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Machine},
{ str8_lit_comp("thaw_local_machine"), str8_lit_comp("Thaws the local machine."), str8_lit_comp(""), str8_lit_comp("Thaw Local Machine"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Machine},
{ str8_lit_comp("inc_ui_font_scale"), str8_lit_comp("Increases the font size used for UI."), str8_lit_comp(""), str8_lit_comp("Increase UI Font Scale"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("dec_ui_font_scale"), str8_lit_comp("Decreases the font size used for UI."), str8_lit_comp(""), str8_lit_comp("Decrease UI Font Scale"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("inc_code_font_scale"), str8_lit_comp("Increases the font size used for code."), str8_lit_comp(""), str8_lit_comp("Increase Code Font Scale"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("dec_code_font_scale"), str8_lit_comp("Decreases the font size used for code."), str8_lit_comp(""), str8_lit_comp("Decrease Code Font Scale"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("open_window"), str8_lit_comp("Opens a new window."), str8_lit_comp(""), str8_lit_comp("Open New Window"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Window},
{ str8_lit_comp("close_window"), str8_lit_comp("Closes an opened window."), str8_lit_comp(""), str8_lit_comp("Close Window"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Window},
{ str8_lit_comp("toggle_fullscreen"), str8_lit_comp("Toggles fullscreen view on the active window."), str8_lit_comp(""), str8_lit_comp("Toggle Fullscreen"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Window},
{ str8_lit_comp("confirm_accept"), str8_lit_comp("Accepts the active confirmation prompt."), str8_lit_comp(""), str8_lit_comp("Confirm Accept"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("confirm_cancel"), str8_lit_comp("Cancels the active confirmation prompt."), str8_lit_comp(""), str8_lit_comp("Confirm Cancel"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("reset_to_default_panels"), str8_lit_comp("Resets the window to the default panel layout."), str8_lit_comp("panel"), str8_lit_comp("Reset To Default Panel Layout"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Window},
{ str8_lit_comp("new_panel_right"), str8_lit_comp("Creates a new panel to the right of the active panel."), str8_lit_comp("panel"), str8_lit_comp("Split Panel Vertically"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_XSplit},
{ str8_lit_comp("new_panel_down"), str8_lit_comp("Creates a new panel at the bottom of the active panel."), str8_lit_comp("panel"), str8_lit_comp("Split Panel Horizontally"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_YSplit},
{ str8_lit_comp("rotate_panel_columns"), str8_lit_comp("Rotates all panels at the closest column level of the panel hierarchy."), str8_lit_comp(""), str8_lit_comp("Rotate Panel Columns"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("next_panel"), str8_lit_comp("Cycles the active panel forward."), str8_lit_comp(""), str8_lit_comp("Focus Next Panel"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_RightArrow},
{ str8_lit_comp("prev_panel"), str8_lit_comp("Cycles the active panel backwards."), str8_lit_comp(""), str8_lit_comp("Focus Previous Panel"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_LeftArrow},
{ str8_lit_comp("focus_panel"), str8_lit_comp("Focuses a new panel."), str8_lit_comp(""), str8_lit_comp("Focus Panel"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("focus_panel_right"), str8_lit_comp("Focuses a panel rightward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp("Focus Panel Right"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_RightArrow},
{ str8_lit_comp("focus_panel_left"), str8_lit_comp("Focuses a panel leftward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp("Focus Panel Left"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_LeftArrow},
{ str8_lit_comp("focus_panel_up"), str8_lit_comp("Focuses a panel upward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp("Focus Panel Up"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_UpArrow},
{ str8_lit_comp("focus_panel_down"), str8_lit_comp("Focuses a panel downward of the currently focused panel."), str8_lit_comp(""), str8_lit_comp("Focus Panel Down"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_DownArrow},
{ str8_lit_comp("undo"), str8_lit_comp("Undoes the previous action."), str8_lit_comp(""), str8_lit_comp("Undo"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Undo},
{ str8_lit_comp("redo"), str8_lit_comp("Redoes the first previously undone action."), str8_lit_comp(""), str8_lit_comp("Redo"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Redo},
{ str8_lit_comp("go_back"), str8_lit_comp("Returns to the previously selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp("Go Back"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_LeftArrow},
{ str8_lit_comp("go_forward"), str8_lit_comp("Returns to the next selected panel and tab in recorded history."), str8_lit_comp(""), str8_lit_comp("Go Forward"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_RightArrow},
{ str8_lit_comp("close_panel"), str8_lit_comp("Closes the currently active panel."), str8_lit_comp(""), str8_lit_comp("Close Panel"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_ClosePanel},
{ str8_lit_comp("next_tab"), str8_lit_comp("Focuses the next tab on the active panel."), str8_lit_comp(""), str8_lit_comp("Focus Next Tab"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_RightArrow},
{ str8_lit_comp("prev_tab"), str8_lit_comp("Focuses the previous tab on the active panel."), str8_lit_comp(""), str8_lit_comp("Focus Previous Tab"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_LeftArrow},
{ str8_lit_comp("move_tab_right"), str8_lit_comp("Moves the selected tab right one slot."), str8_lit_comp(""), str8_lit_comp("Move Tab Right"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_RightArrow},
{ str8_lit_comp("move_tab_left"), str8_lit_comp("Moves the selected tab left one slot."), str8_lit_comp(""), str8_lit_comp("Move Tab Left"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_LeftArrow},
{ str8_lit_comp("open_tab"), str8_lit_comp("Opens a new tab with the parameterized view specification."), str8_lit_comp(""), str8_lit_comp("Open Tab"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("close_tab"), str8_lit_comp("Closes the currently opened tab."), str8_lit_comp(""), str8_lit_comp("Close Tab"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_X},
{ str8_lit_comp("move_tab"), str8_lit_comp("Moves a tab to a new panel."), str8_lit_comp(""), str8_lit_comp("Move Tab"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("tab_bar_top"), str8_lit_comp("Anchors a panel's tab bar to the top of the panel."), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Top"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_UpArrow},
{ str8_lit_comp("tab_bar_bottom"), str8_lit_comp("Anchors a panel's tab bar to the bottom of the panel."), str8_lit_comp(""), str8_lit_comp("Anchor Tab Bar To Bottom"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_DownArrow},
{ str8_lit_comp("set_current_path"), str8_lit_comp("Sets the debugger's current path, which is used as a starting point when browsing for files."), str8_lit_comp(""), str8_lit_comp("Set Current Path"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_FileOutline},
{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp("Open"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_FilePath, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*1)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_FileOutline},
{ str8_lit_comp("reload"), str8_lit_comp("Reloads a loaded file."), str8_lit_comp("code,source,file,reload"), str8_lit_comp("Reload"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_File, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_FileOutline},
{ str8_lit_comp("reload_active"), str8_lit_comp("Reloads the active file."), str8_lit_comp("code,source,file,reload"), str8_lit_comp("Reload Active File"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_FileOutline},
{ str8_lit_comp("switch"), str8_lit_comp("Switches to a loaded file."), str8_lit_comp("code,source,file"), str8_lit_comp("Switch"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_File, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_FileOutline},
{ str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp("Switch To Partner File"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_FileOutline},
{ str8_lit_comp("set_file_override_link_src"), str8_lit_comp("Sets the source path for an override file link."), str8_lit_comp(""), str8_lit_comp("Set File Override Link Source"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("set_file_override_link_dst"), str8_lit_comp("Sets the destination path for an override file link."), str8_lit_comp(""), str8_lit_comp("Set File Override Link Destination"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp("Set File Replacement Path"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,profile,layout"), str8_lit_comp("Open User"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_FilePath, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*1)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Person},
{ str8_lit_comp("open_profile"), str8_lit_comp("Opens a profile file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("profile,project,session"), str8_lit_comp("Open Profile"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_FilePath, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*1)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Briefcase},
{ str8_lit_comp("apply_user_data"), str8_lit_comp("Applies user data from the active user file."), str8_lit_comp(""), str8_lit_comp("Apply User Data"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("apply_profile_data"), str8_lit_comp("Applies profile data from the active profile file."), str8_lit_comp(""), str8_lit_comp("Apply Profile Data"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp("Write User Data"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("write_profile_data"), str8_lit_comp("Writes profile data to the active profile file."), str8_lit_comp(""), str8_lit_comp("Write Profile Data"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_left"), str8_lit_comp("Moves the cursor or selection left."), str8_lit_comp(""), str8_lit_comp("Move Left"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_right"), str8_lit_comp("Moves the cursor or selection right."), str8_lit_comp(""), str8_lit_comp("Move Right"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_up"), str8_lit_comp("Moves the cursor or selection up."), str8_lit_comp(""), str8_lit_comp("Move Up"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_down"), str8_lit_comp("Moves the cursor or selection down."), str8_lit_comp(""), str8_lit_comp("Move Down"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_left_select"), str8_lit_comp("Moves the cursor or selection left, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Left Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_right_select"), str8_lit_comp("Moves the cursor or selection right, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Right Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_up_select"), str8_lit_comp("Moves the cursor or selection up, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Up Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_down_select"), str8_lit_comp("Moves the cursor or selection down, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Down Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_left_chunk"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp("Move Left Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_right_chunk"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp("Move Right Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_up_chunk"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp("Move Up Chunk"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_down_chunk"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp("Move Down Chunk"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_up_page"), str8_lit_comp("Moves the cursor or selection up one page."), str8_lit_comp(""), str8_lit_comp("Move Up Page"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_down_page"), str8_lit_comp("Moves the cursor or selection down one page."), str8_lit_comp(""), str8_lit_comp("Move Down Page"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_up_whole"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content."), str8_lit_comp(""), str8_lit_comp("Move Up Whole"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_down_whole"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content."), str8_lit_comp(""), str8_lit_comp("Move Down Whole"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_left_chunk_select"), str8_lit_comp("Moves the cursor or selection left one chunk."), str8_lit_comp(""), str8_lit_comp("Move Left Chunk Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_right_chunk_select"), str8_lit_comp("Moves the cursor or selection right one chunk."), str8_lit_comp(""), str8_lit_comp("Move Right Chunk Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_up_chunk_select"), str8_lit_comp("Moves the cursor or selection up one chunk."), str8_lit_comp(""), str8_lit_comp("Move Up Chunk Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_down_chunk_select"), str8_lit_comp("Moves the cursor or selection down one chunk."), str8_lit_comp(""), str8_lit_comp("Move Down Chunk Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_up_page_select"), str8_lit_comp("Moves the cursor or selection up one page, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Up Page Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_down_page_select"), str8_lit_comp("Moves the cursor or selection down one page, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Down Page Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_up_whole_select"), str8_lit_comp("Moves the cursor or selection to the beginning of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Up Whole Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_down_whole_select"), str8_lit_comp("Moves the cursor or selection to the end of the relevant content, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Down Whole Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_home"), str8_lit_comp("Moves the cursor to the beginning of the line."), str8_lit_comp(""), str8_lit_comp("Move Home"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_end"), str8_lit_comp("Moves the cursor to the end of the line."), str8_lit_comp(""), str8_lit_comp("Move End"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_home_select"), str8_lit_comp("Moves the cursor to the beginning of the line, while selecting."), str8_lit_comp(""), str8_lit_comp("Move Home Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("move_end_select"), str8_lit_comp("Moves the cursor to the end of the line, while selecting."), str8_lit_comp(""), str8_lit_comp("Move End Select"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("select_all"), str8_lit_comp("Selects everything possible."), str8_lit_comp(""), str8_lit_comp("Select All"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("delete_single"), str8_lit_comp("Deletes a single element to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp("Delete Single"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("delete_chunk"), str8_lit_comp("Deletes a chunk to the right of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp("Delete Chunk"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("backspace_single"), str8_lit_comp("Deletes a single element to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp("Backspace Single"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("backspace_chunk"), str8_lit_comp("Deletes a chunk to the left of the cursor, or the active selection."), str8_lit_comp(""), str8_lit_comp("Backspace Chunk"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("copy"), str8_lit_comp("Copies the active selection to the clipboard."), str8_lit_comp(""), str8_lit_comp("Copy"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Clipboard},
{ str8_lit_comp("cut"), str8_lit_comp("Copies the active selection to the clipboard, then deletes it."), str8_lit_comp(""), str8_lit_comp("Cut"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Clipboard},
{ str8_lit_comp("paste"), str8_lit_comp("Pastes the current contents of the clipboard."), str8_lit_comp(""), str8_lit_comp("Paste"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Clipboard},
{ str8_lit_comp("insert_text"), str8_lit_comp("Inserts the text that was used to cause this command."), str8_lit_comp(""), str8_lit_comp("Insert Text"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("goto_line"), str8_lit_comp("Jumps to a line number in the current code file."), str8_lit_comp(""), str8_lit_comp("Go To Line"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_TextPoint, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Null},
{ str8_lit_comp("goto_address"), str8_lit_comp("Jumps to an address in the current memory or disassembly view."), str8_lit_comp(""), str8_lit_comp("Go To Address"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_VirtualAddr, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Null},
{ str8_lit_comp("center_cursor"), str8_lit_comp("Snaps the current code view to center the cursor."), str8_lit_comp(""), str8_lit_comp("Center Cursor"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("contain_cursor"), str8_lit_comp("Snaps the current code view to contain the cursor."), str8_lit_comp(""), str8_lit_comp("Contain Cursor"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("find_text_forward"), str8_lit_comp("Searches the current code file forward (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp("Find Text (Forward)"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_String, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*1)|(DF_CmdQueryFlag_SelectOldInput*1)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Find},
{ str8_lit_comp("find_text_backward"), str8_lit_comp("Searches the current code file backwards (from the cursor) for a string."), str8_lit_comp(""), str8_lit_comp("Find Text (Backwards)"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_String, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*1)|(DF_CmdQueryFlag_SelectOldInput*1)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Find},
{ str8_lit_comp("find_next"), str8_lit_comp("Searches the current code file forward (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp("Find Next"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*1)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Find},
{ str8_lit_comp("find_prev"), str8_lit_comp("Searches the current code file backwards (from the cursor) for the last searched string."), str8_lit_comp(""), str8_lit_comp("Find Previous"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*1)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Find},
{ str8_lit_comp("find_thread"), str8_lit_comp("Jumps to the passed thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp("Find Thread"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Thread, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Find},
{ str8_lit_comp("find_selected_thread"), str8_lit_comp("Jumps to the selected thread in either source code, disassembly, or both if they're already open."), str8_lit_comp(""), str8_lit_comp("Find Selected Thread"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Find},
{ str8_lit_comp("goto_name"), str8_lit_comp("Searches for the passed string as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("Go To Name"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_String, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Null},
{ str8_lit_comp("goto_name_at_cursor"), str8_lit_comp("Searches for the text at the cursor as a file, a symbol in debug info, and more, then jumps to it if possible."), str8_lit_comp(""), str8_lit_comp("Go To Name At Cursor"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("toggle_watch_expr"), str8_lit_comp("Adds or removes an expression to an opened watch view."), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Binoculars},
{ str8_lit_comp("toggle_watch_expr_at_cursor"), str8_lit_comp("Adds or removes the expression that the cursor or selection is currently over to an opened watch view."), str8_lit_comp(""), str8_lit_comp("Toggle Watch Expression At Cursor"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Binoculars},
{ str8_lit_comp("set_columns"), str8_lit_comp("Sets the number of columns for a memory view."), str8_lit_comp(""), str8_lit_comp("Set Columns"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Index, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Thumbnails},
{ str8_lit_comp("toggle_address_visibility"), str8_lit_comp("Toggles the visibility of addresses in a disassembly view."), str8_lit_comp(""), str8_lit_comp("Toggle Address Visibility"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Thumbnails},
{ str8_lit_comp("toggle_code_bytes_visibility"), str8_lit_comp("Toggles the visibility of machine code bytes in a disassembly view."), str8_lit_comp(""), str8_lit_comp("Toggle Code Bytes Visibility"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Thumbnails},
{ str8_lit_comp("enable_entity"), str8_lit_comp("Enables an entity."), str8_lit_comp(""), str8_lit_comp("Enable Entity"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("disable_entity"), str8_lit_comp("Disables an entity."), str8_lit_comp(""), str8_lit_comp("Disable Entity"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("freeze_entity"), str8_lit_comp("Freezes an entity."), str8_lit_comp(""), str8_lit_comp("Freeze Entity"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("thaw_entity"), str8_lit_comp("Thaws an entity."), str8_lit_comp(""), str8_lit_comp("Thaw Entity"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("remove_entity"), str8_lit_comp("Removes an entity."), str8_lit_comp(""), str8_lit_comp("Remove Entity"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("name_entity"), str8_lit_comp("Equips an entity with a name."), str8_lit_comp(""), str8_lit_comp("Name Entity"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("edit_entity"), str8_lit_comp("Opens the editor for an entity."), str8_lit_comp(""), str8_lit_comp("Edit Entity"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("duplicate_entity"), str8_lit_comp("Duplicates an entity."), str8_lit_comp(""), str8_lit_comp("Duplicate Entity"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("text_breakpoint"), str8_lit_comp("Places or removes a breakpoint on the specified line of source code."), str8_lit_comp(""), str8_lit_comp("Text Breakpoint"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_CircleFilled},
{ str8_lit_comp("address_breakpoint"), str8_lit_comp("Places or removes a breakpoint on the specified address."), str8_lit_comp(""), str8_lit_comp("Address Breakpoint"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_VirtualAddr, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_CircleFilled},
{ str8_lit_comp("function_breakpoint"), str8_lit_comp("Places or removes a breakpoint on the first address(es) of the specified function."), str8_lit_comp(""), str8_lit_comp("Function Breakpoint"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_String, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_CircleFilled},
{ str8_lit_comp("toggle_breakpoint_cursor"), str8_lit_comp("Places or removes a breakpoint on the line on which the active cursor sits."), str8_lit_comp(""), str8_lit_comp("Toggle Breakpoint At Cursor"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_CircleFilled},
{ str8_lit_comp("remove_breakpoint"), str8_lit_comp("Removes an existing breakpoint."), str8_lit_comp(""), str8_lit_comp("Remove Breakpoint"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Breakpoint, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Trash},
{ str8_lit_comp("enable_breakpoint"), str8_lit_comp("Enables a breakpoint."), str8_lit_comp(""), str8_lit_comp("Enable Breakpoint"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Breakpoint, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_CheckFilled},
{ str8_lit_comp("disable_breakpoint"), str8_lit_comp("Disables a breakpoint."), str8_lit_comp(""), str8_lit_comp("Disable Breakpoint"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Breakpoint, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_CheckHollow},
{ str8_lit_comp("toggle_watch_pin"), str8_lit_comp("Places or removes a watch pin on a textual location on a particular entity."), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Binoculars},
{ str8_lit_comp("toggle_watch_pin_at_cursor"), str8_lit_comp("Places or removes a watch pin at the cursor on the currently active file."), str8_lit_comp(""), str8_lit_comp("Toggle Watch Pin At Cursor"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_String, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Binoculars},
{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("Add Target"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_FilePath, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*1)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Target},
{ str8_lit_comp("remove_target"), str8_lit_comp("Removes an existing target."), str8_lit_comp("delete,remove,target"), str8_lit_comp("Remove Target"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Target, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Trash},
{ str8_lit_comp("edit_target"), str8_lit_comp("Edits an existing target."), str8_lit_comp(""), str8_lit_comp("Edit Target"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Target, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Pencil},
{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp("Select Target"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Target, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Target},
{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp("Enable Target"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Target, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_CheckFilled},
{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp("Disable Target"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Target, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_CheckHollow},
{ str8_lit_comp("retry_ended_process"), str8_lit_comp("Launches a new process with the same options as the passed ended process."), str8_lit_comp(""), str8_lit_comp("Retry Ended Process"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Entity, DF_EntityKind_Process, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp("Attach"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_ID, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Null},
{ str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp("Register As Just-In-Time (JIT) Debugger"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("entity_ref_fast_path"), str8_lit_comp("Activates the default behavior when clicking an entity reference."), str8_lit_comp(""), str8_lit_comp("Entity Reference Fast Path"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("spawn_entity_view"), str8_lit_comp("Spawns a new view, given an entity and other parameterizations."), str8_lit_comp(""), str8_lit_comp("Spawn Entity View"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("find_code_location"), str8_lit_comp("Finds a specific source code location given file, line, and column coordinates. Opens the file if necessary."), str8_lit_comp(""), str8_lit_comp("Find Code Location"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_FilePath, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_FileOutline},
{ str8_lit_comp("filter"), str8_lit_comp("Begins filtering the active view."), str8_lit_comp("sort,search,filter,find"), str8_lit_comp("Filter"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Find},
{ str8_lit_comp("apply_filter"), str8_lit_comp("Applies the typed filter to the active view."), str8_lit_comp("sort,search,filter,find,apply"), str8_lit_comp("Apply Filter"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Find},
{ str8_lit_comp("clear_filter"), str8_lit_comp("Clears the filter applied to the active view."), str8_lit_comp("sort,search,filter,find,clear"), str8_lit_comp("Clear Filter"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Find},
{ str8_lit_comp("commands"), str8_lit_comp("Opens the list of all commands."), str8_lit_comp(""), str8_lit_comp("Commands"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_List},
{ str8_lit_comp("target"), str8_lit_comp("Opens the editor for a target."), str8_lit_comp(""), str8_lit_comp("Target"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Target},
{ str8_lit_comp("targets"), str8_lit_comp("Opens the list of all targets."), str8_lit_comp(""), str8_lit_comp("Targets"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Target},
{ str8_lit_comp("file_path_map"), str8_lit_comp("Opens the file path mapping editor."), str8_lit_comp(""), str8_lit_comp("File Path Map"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_FileOutline},
{ str8_lit_comp("scheduler"), str8_lit_comp("Opens the scheduler view, for process and thread controls."), str8_lit_comp("threads,processes,targets"), str8_lit_comp("Scheduler"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Scheduler},
{ str8_lit_comp("call_stack"), str8_lit_comp("Opens the call stack view."), str8_lit_comp("callstack,thread"), str8_lit_comp("Call Stack"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Thread},
{ str8_lit_comp("modules"), str8_lit_comp("Opens the modules view."), str8_lit_comp(""), str8_lit_comp("Modules"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Module},
{ str8_lit_comp("pending_entity"), str8_lit_comp("Opens a view which waits for the passed entity to be completely loaded, then replaces itself with a new view."), str8_lit_comp(""), str8_lit_comp("Pending Entity"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_FileOutline},
{ str8_lit_comp("code"), str8_lit_comp("Opens the code view for an already-loaded file."), str8_lit_comp(""), str8_lit_comp("Code"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_FileOutline},
{ str8_lit_comp("watch"), str8_lit_comp("Opens a watch view."), str8_lit_comp(""), str8_lit_comp("Watch"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Binoculars},
{ str8_lit_comp("locals"), str8_lit_comp("Opens a locals view."), str8_lit_comp(""), str8_lit_comp("Locals"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Binoculars},
{ str8_lit_comp("registers"), str8_lit_comp("Opens a registers view."), str8_lit_comp(""), str8_lit_comp("Registers"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Binoculars},
{ str8_lit_comp("globals"), str8_lit_comp("Opens a globals view."), str8_lit_comp(""), str8_lit_comp("Globals"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Binoculars},
{ str8_lit_comp("thread_locals"), str8_lit_comp("Opens a thread locals view."), str8_lit_comp(""), str8_lit_comp("Thread Locals"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Binoculars},
{ str8_lit_comp("types"), str8_lit_comp("Opens a types view."), str8_lit_comp(""), str8_lit_comp("Types"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Binoculars},
{ str8_lit_comp("procedures"), str8_lit_comp("Opens a procedures view."), str8_lit_comp(""), str8_lit_comp("Procedures"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Binoculars},
{ str8_lit_comp("output"), str8_lit_comp("Opens an output view."), str8_lit_comp(""), str8_lit_comp("Output"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_List},
{ str8_lit_comp("memory"), str8_lit_comp("Opens a memory view."), str8_lit_comp(""), str8_lit_comp("Memory"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Grid},
{ str8_lit_comp("disassembly"), str8_lit_comp("Opens the disassembly view."), str8_lit_comp("disasm"), str8_lit_comp("Disassembly"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Glasses},
{ str8_lit_comp("breakpoints"), str8_lit_comp("Opens the breakpoints view."), str8_lit_comp(""), str8_lit_comp("Breakpoints"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_CircleFilled},
{ str8_lit_comp("watch_pins"), str8_lit_comp("Opens the watch pins view."), str8_lit_comp(""), str8_lit_comp("Watch Pins"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Pin},
{ str8_lit_comp("exception_filters"), str8_lit_comp("Opens the exception filters view."), str8_lit_comp("exceptions,filters"), str8_lit_comp("Exception Filters"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Gear},
{ str8_lit_comp("theme"), str8_lit_comp("Opens the theme view."), str8_lit_comp("theme,color,scheme,palette"), str8_lit_comp("Theme"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Palette},
{ str8_lit_comp("pick_file"), str8_lit_comp("Opens the file browser to pick a file."), str8_lit_comp(""), str8_lit_comp("Pick File"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_FilePath, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*1)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_FileOutline},
{ str8_lit_comp("pick_folder"), str8_lit_comp("Opens the file browser to pick a folder."), str8_lit_comp(""), str8_lit_comp("Pick Folder"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_FilePath, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*1)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_FolderOpenFilled},
{ str8_lit_comp("pick_file_or_folder"), str8_lit_comp("Opens the file browser to pick a file or folder."), str8_lit_comp(""), str8_lit_comp("Pick File/Folder"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_FilePath, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*1)|(DF_CmdQueryFlag_AllowFolders*1)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_FileOutline},
{ str8_lit_comp("complete_query"), str8_lit_comp("Completes a query."), str8_lit_comp(""), str8_lit_comp("Complete Query"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("cancel_query"), str8_lit_comp("Cancels a query."), str8_lit_comp(""), str8_lit_comp("Cancel Query"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("toggle_dev_menu"), str8_lit_comp("Opens and closes the developer menu."), str8_lit_comp(""), str8_lit_comp("Toggle Developer Menu"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
};
DF_CoreViewRuleSpecInfo df_g_core_view_rule_spec_info_table[16] =
{
{str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, },
{str8_lit_comp("array"), str8_lit_comp("Array"), str8_lit_comp("Specifies that a pointer points to N elements, rather than only 1."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*1)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(array) , 0, },
{str8_lit_comp("list"), str8_lit_comp("List"), str8_lit_comp("Specifies that some struct, union, or class forms the top of a linked list, and the member which points at the following element in the list."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(list) , },
{str8_lit_comp("bswap"), str8_lit_comp("Byte Swap"), str8_lit_comp("Specifies that all integer primitives should be byte-swapped, such that their endianness is reversed."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*1)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(bswap) , 0, },
{str8_lit_comp("dec"), str8_lit_comp("Decimal Base (Base 10)"), str8_lit_comp("Specifies that all integral evaluations should appear in base-10 form."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, },
{str8_lit_comp("bin"), str8_lit_comp("Binary Base (Base 2)"), str8_lit_comp("Specifies that all integral evaluations should appear in base-2 form."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, },
{str8_lit_comp("oct"), str8_lit_comp("Octal Base (Base 8)"), str8_lit_comp("Specifies that all integral evaluations should appear in base-8 form."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, },
{str8_lit_comp("hex"), str8_lit_comp("Hexadecimal Base (Base 16)"), str8_lit_comp("Specifies that all integral evaluations should appear in base-16 form."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, },
{str8_lit_comp("only"), str8_lit_comp("Only Specified Members"), str8_lit_comp("Specifies that only the specified members should appear in struct, union, or class evaluations."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(only) , },
{str8_lit_comp("omit"), str8_lit_comp("Omit Specified Members"), str8_lit_comp("Omits a list of member names from appearing in struct, union, or class evaluations."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(omit) , },
{str8_lit_comp("no_addr"), str8_lit_comp("Disable Address Values"), str8_lit_comp("Displays only what pointers point to, if possible, without the pointer's address value."), (DF_CoreViewRuleSpecInfoFlag_Inherited*1)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, },
{str8_lit_comp("rgba"), str8_lit_comp("Color (RGBA)"), str8_lit_comp("Displays as a color, interpreting the data as encoding R, G, B, and A values."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(rgba) , },
{str8_lit_comp("text"), str8_lit_comp("Text"), str8_lit_comp("Displays as text."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(text) , },
{str8_lit_comp("disasm"), str8_lit_comp("Disassembly"), str8_lit_comp("Displays as disassembled instructions, interpreting the data as raw machine code."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(disasm) , },
{str8_lit_comp("bitmap"), str8_lit_comp("Bitmap"), str8_lit_comp("Displays as a bitmap, interpreting the data as raw pixel data."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(bitmap) , },
{str8_lit_comp("geo"), str8_lit_comp("Geometry"), str8_lit_comp("Displays as geometry, interpreting the data as vertex data."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*1)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(geo) , },
};
String8 df_g_icon_kind_text_table[69] =
{
str8_lit_comp(""),
str8_lit_comp("b"),
str8_lit_comp("c"),
str8_lit_comp("B"),
str8_lit_comp("C"),
str8_lit_comp("f"),
str8_lit_comp("F"),
str8_lit_comp("g"),
str8_lit_comp("h"),
str8_lit_comp("r"),
str8_lit_comp("s"),
str8_lit_comp("i"),
str8_lit_comp("w"),
str8_lit_comp("W"),
str8_lit_comp("k"),
str8_lit_comp("K"),
str8_lit_comp("L"),
str8_lit_comp("R"),
str8_lit_comp("U"),
str8_lit_comp("D"),
str8_lit_comp("G"),
str8_lit_comp("P"),
str8_lit_comp("3"),
str8_lit_comp("p"),
str8_lit_comp("O"),
str8_lit_comp("o"),
str8_lit_comp("!"),
str8_lit_comp("1"),
str8_lit_comp("<"),
str8_lit_comp(">"),
str8_lit_comp("^"),
str8_lit_comp("v"),
str8_lit_comp("9"),
str8_lit_comp("0"),
str8_lit_comp("7"),
str8_lit_comp("8"),
str8_lit_comp("+"),
str8_lit_comp("-"),
str8_lit_comp("'"),
str8_lit_comp("\""),
str8_lit_comp("M"),
str8_lit_comp("."),
str8_lit_comp("x"),
str8_lit_comp("q"),
str8_lit_comp("j"),
str8_lit_comp("u"),
str8_lit_comp("m"),
str8_lit_comp("n"),
str8_lit_comp("l"),
str8_lit_comp("a"),
str8_lit_comp("z"),
str8_lit_comp("y"),
str8_lit_comp("X"),
str8_lit_comp("Y"),
str8_lit_comp("S"),
str8_lit_comp("T"),
str8_lit_comp("Z"),
str8_lit_comp("d"),
str8_lit_comp("N"),
str8_lit_comp("E"),
str8_lit_comp("H"),
str8_lit_comp("e"),
str8_lit_comp("I"),
str8_lit_comp("J"),
str8_lit_comp("A"),
str8_lit_comp("?"),
str8_lit_comp("4"),
str8_lit_comp("5"),
str8_lit_comp("c"),
};
C_LINKAGE_END
File diff suppressed because it is too large Load Diff
-7
View File
@@ -1,7 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#include "df/core/df_core.c"
#include "df/gfx/df_gfx.c"
#include "df/gfx/df_views.c"
#include "df/gfx/df_view_rule_hooks.c"
-12
View File
@@ -1,12 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DEBUG_FRONTEND_INC_H
#define DEBUG_FRONTEND_INC_H
#include "df/core/df_core.h"
#include "df/gfx/df_gfx.h"
#include "df/gfx/df_views.h"
#include "df/gfx/df_view_rule_hooks.h"
#endif // DEBUG_FRONTEND_INC_H
-12207
View File
File diff suppressed because it is too large Load Diff
-1010
View File
File diff suppressed because it is too large Load Diff
-714
View File
@@ -1,714 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Embedded Data
@embed_file df_g_icon_font_bytes: "../data/icons.ttf"
@embed_file df_g_default_main_font_bytes: "../data/Roboto-Regular.ttf"
@embed_file df_g_default_code_font_bytes: "../data/liberation-mono.ttf"
//@embed_file df_g_default_code_font_bytes: "../data/Inconsolata-Regular.ttf"
////////////////////////////////
//~ rjf: Default Bindings
@table(name key ctrl shift alt)
DF_DefaultBindingTable:
{
//- rjf: low-level target control operations
{ "kill_all" F5 0 shift 0 }
{ "step_into_inst" F11 0 0 alt }
{ "step_over_inst" F10 0 0 alt }
{ "step_out" F11 0 shift 0 }
{ "halt" X ctrl shift 0 }
{ "halt" Pause 0 0 0 }
{ "soft_halt_refresh" R 0 0 alt }
//- rjf: high-level composite target control operations
{ "run" F5 0 0 0 }
{ "restart" F5 ctrl shift 0 }
{ "step_into" F11 0 0 0 }
{ "step_over" F10 0 0 0 }
{ "run_to_cursor" F10 ctrl 0 0 }
{ "set_next_statement" F10 ctrl shift 0 }
//- rjf: font sizes
{ "inc_ui_font_scale" Equal 0 0 alt }
{ "dec_ui_font_scale" Minus 0 0 alt }
{ "inc_code_font_scale" Equal 0 shift alt }
{ "dec_code_font_scale" Minus 0 shift alt }
//- rjf: windows
{ "window" N ctrl shift 0 }
{ "toggle_fullscreen" Return ctrl 0 0 }
//- rjf: panel splitting
{ "new_panel_right" P ctrl 0 0 }
{ "new_panel_down" Minus ctrl 0 0 }
//- rjf: panel rotation
{ "rotate_panel_columns" 2 ctrl 0 0 }
//- rjf: focused panel changing
{ "next_panel" Comma ctrl 0 0 }
{ "prev_panel" Comma ctrl shift 0 }
{ "focus_panel_right" Right ctrl 0 alt }
{ "focus_panel_left" Left ctrl 0 alt }
{ "focus_panel_up" Up ctrl 0 alt }
{ "focus_panel_down" Down ctrl 0 alt }
//- rjf: undo/redo
//{ "undo" Z ctrl 0 0 }
//{ "redo" Y ctrl 0 0 }
//- rjf: focus history
//{ "go_back" Left 0 0 alt }
//{ "go_forward" Right 0 0 alt }
//- rjf: panel removal
{ "close_panel" P ctrl shift 0 }
//- rjf: panel tab
{ "next_tab" PageDown ctrl 0 0 }
{ "prev_tab" PageUp ctrl 0 0 }
{ "next_tab" Tab ctrl 0 0 }
{ "prev_tab" Tab ctrl shift 0 }
{ "move_tab_right" PageDown ctrl shift 0 }
{ "move_tab_left" PageUp ctrl shift 0 }
{ "close_tab" W ctrl 0 0 }
{ "tab_bar_top" Up ctrl shift alt }
{ "tab_bar_bottom" Down ctrl shift alt }
//- rjf: files
{ "open" O ctrl 0 0 }
{ "reload_active" R ctrl shift 0 }
{ "switch" I ctrl 0 0 }
{ "switch_to_partner_file" O 0 0 alt }
//- rjf: setting config paths
{ "load_user" O ctrl shift alt }
{ "load_profile" O ctrl 0 alt }
//- rjf: directional movement & text controls
{ "move_left" Left 0 0 0 }
{ "move_right" Right 0 0 0 }
{ "move_up" Up 0 0 0 }
{ "move_down" Down 0 0 0 }
{ "move_left_select" Left 0 shift 0 }
{ "move_right_select" Right 0 shift 0 }
{ "move_up_select" Up 0 shift 0 }
{ "move_down_select" Down 0 shift 0 }
{ "move_left_chunk" Left ctrl 0 0 }
{ "move_right_chunk" Right ctrl 0 0 }
{ "move_up_chunk" Up ctrl 0 0 }
{ "move_down_chunk" Down ctrl 0 0 }
{ "move_up_page" PageUp 0 0 0 }
{ "move_down_page" PageDown 0 0 0 }
{ "move_up_whole" Home ctrl 0 0 }
{ "move_down_whole" End ctrl 0 0 }
{ "move_left_chunk_select" Left ctrl shift 0 }
{ "move_right_chunk_select" Right ctrl shift 0 }
{ "move_up_chunk_select" Up ctrl shift 0 }
{ "move_down_chunk_select" Down ctrl shift 0 }
{ "move_up_page_select" PageUp 0 shift 0 }
{ "move_down_page_select" PageDown 0 shift 0 }
{ "move_up_whole_select" Home ctrl shift 0 }
{ "move_down_whole_select" End ctrl shift 0 }
{ "move_home" Home 0 0 0 }
{ "move_end" End 0 0 0 }
{ "move_home_select" Home 0 shift 0 }
{ "move_end_select" End 0 shift 0 }
{ "select_all" A ctrl 0 0 }
{ "delete_single" Delete 0 0 0 }
{ "delete_chunk" Delete ctrl 0 0 }
{ "backspace_single" Backspace 0 0 0 }
{ "backspace_chunk" Backspace ctrl 0 0 }
{ "copy" C ctrl 0 0 }
{ "cut" X ctrl 0 0 }
{ "paste" V ctrl 0 0 }
{ "insert_text" Null 0 0 0 }
//- rjf: code navigation
{ "goto_line" G ctrl 0 0 }
{ "goto_address" G 0 0 alt }
{ "find_text_forward" F ctrl 0 0 }
{ "find_text_backward" R ctrl 0 0 }
{ "find_next" F3 0 0 0 }
{ "find_prev" F3 shift 0 0 }
//- rjf: thread finding
{ "find_selected_thread" F4 0 0 0 }
//- rjf: name finding
{ "goto_name" J ctrl 0 0 }
{ "goto_name_at_cursor" F12 0 0 0 }
//- rjf: watch expressions
{ "toggle_watch_expr_at_cursor" W 0 0 alt }
{ "toggle_watch_pin_at_cursor" F9 ctrl 0 0 }
//- rjf: breakpoints
{ "toggle_breakpoint_cursor" F9 0 0 0 }
//- rjf: targets
{ "add_target" T ctrl 0 0 }
//- rjf: attaching
{ "attach" F6 0 shift 0 }
//- rjf: filtering
{ "filter" Slash ctrl 0 0 }
//- rjf: command lister
{ "run_command" F1 0 0 0 }
}
////////////////////////////////
//~ rjf: Binding Version Remap Table
@table(old_name new_name)
DF_BindingVersionRemapTable:
{
{"commands" "run_command"}
{"load_user" "open_user"}
{"load_profile" "open_profile"}
}
////////////////////////////////
//~ rjf: Gfx Layer View Kinds
@table(name)
DF_NameKindTable:
{
{Null}
{EntityName}
{EntityKindName}
}
@table(name, name_lower, display_string, name_kind, icon, parameterized_by_entity, can_serialize, can_serialize_entity_path, can_filter, filter_is_code, typing_automatically_filters, inc_in_docs, docs_desc)
DF_GfxViewTable:
{
{ Null "null" "" Null Null 0 0 0 0 0 0 0 "" }
{ Empty "empty" "" Null Null 0 0 0 0 0 0 0 "" }
{ Commands "commands" "Commands" Null List 0 0 0 0 0 0 0 "" }
{ FileSystem "file_system" "File System" Null FileOutline 0 0 0 0 0 0 0 "" }
{ SystemProcesses "system_processes" "System Processes" Null Null 0 0 0 0 0 0 0 "" }
{ EntityLister "entity_lister" "Entity List" EntityKindName Null 0 0 0 0 0 0 0 "" }
{ SymbolLister "symbol_lister" "Symbols" Null Null 0 0 0 0 0 0 0 "" }
{ Target "target" "Target" EntityName Target 1 0 0 0 0 0 0 "" }
{ Targets "targets" "Targets" Null Target 0 1 0 1 0 1 1 "Displays a list of all targets, as well as controls for enabling, disabling, launching, editing, or deleting each target. For more information on targets, read the `Targets` section." }
{ FilePathMap "file_path_map" "File Path Map" Null FileOutline 0 1 0 0 0 0 1 "Displays a table of *path maps*. Each path map is a pair of file or folder paths, one being a 'source' path, and one being a 'destination' path. These pairs are used by the debugger when automatically searching for specific files - for instance, when attempting to snap to a source code location specified by debug info. If debug info refers to a path on the machine on which a target executable was originally built, but that path is not valid on the debugger machine, but some alternative path exists, then path maps may be used to redirect the debugger from the debug info's specified paths to the associated appropriate debugger machine file paths." }
{ Scheduler "scheduler" "Scheduler" Null Scheduler 0 1 0 1 1 1 1 "Displays all processes and threads to which the debugger is currently attached, and contains controls for selecting and freezing threads." }
{ CallStack "call_stack" "Call Stack" Null Thread 0 1 0 0 0 0 1 "Displays the call stack of the currently selected thread. Each frame in the call stack contains the associated module, function name, and return address. Allows selection of a particular call stack frame other than the top." }
{ Modules "modules" "Modules" Null Module 0 1 0 1 0 1 1 "Displays a table of all modules currently loaded by any process to which the debugger is attached. This table displays each module's name, virtual address range in the containing process' address space, and which debug info file is being used by the debugger for the associated module." }
{ PendingEntity "pending_entity" "Pending Entity" EntityName FileOutline 1 0 0 0 0 0 0 "" }
{ Code "code" "Code" EntityName FileOutline 1 1 1 0 0 0 0 "" }
{ Disassembly "disassembly" "Disassembly" Null Glasses 0 1 0 0 0 0 1 "Displays disassembled instructions in a textual form from the selected thread's containing process virtual address space." }
{ EvalViewer "eval_viewer" "Evaluation Viewer" Null Binoculars 0 1 0 0 0 0 0 "." }
{ Watch "watch" "Watch" Null Binoculars 0 1 0 1 1 1 1 "The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section." }
{ Locals "locals" "Locals" Null Binoculars 0 1 0 1 1 1 1 "Nearly identical to `Watch`, but automatically filled with local variables found within the selected call stack frame of the selected thread, according to the associated debug info. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." }
{ Registers "registers" "Registers" Null Binoculars 0 1 0 1 1 1 1 "Nearly identical to `Watch`, but automatically filled with all register names according to the selected thread's architecture. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." }
{ Globals "globals" "Globals" Null Binoculars 0 1 0 1 1 1 1 "Nearly identical to `Watch`, but automatically filled with all global variables within the selected thread's module. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." }
{ ThreadLocals "thread_locals" "Thread Locals" Null Binoculars 0 1 0 1 1 1 1 "Nearly identical to `Watch`, but automatically filled with all thread local variables within the selected thread's module. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." }
{ Types "types" "Types" Null Binoculars 0 1 0 1 1 1 1 "Nearly identical to `Watch`, but automatically filled with all types within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." }
{ Procedures "procedures" "Procedures" Null Binoculars 0 1 0 1 1 1 1 "Nearly identical to `Watch`, but automatically filled with all procedures within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." }
{ Output "output" "Output" Null List 0 1 0 0 0 0 1 "Displays textual output from the selected thread's containing process." }
{ Memory "memory" "Memory" Null Grid 0 1 1 0 0 0 1 "A familiar hex-editor-like interface for viewing memory of attached processes." }
{ Breakpoints "breakpoints" "Breakpoints" Null CircleFilled 0 1 0 1 0 1 1 "Displays a table of all breakpoints, containing information about each breakpoint's name, location, and hit count. Also contains per-breakpoint controls for enabling, deleting, or editing each breakpoint. For more information on breakpoints and their features, read the 'Breakpoints' section." }
{ WatchPins "watch_pins" "Watch Pins" Null Pin 0 1 0 1 1 1 1 "Displays a table of all watch pins (watched expressions, like those found in `Watch`, but instead of being within a table, being pinned to some source code location, like breakpoints). This table contains each pin's name, location, and controls for editing or deleting each pin." }
{ ExceptionFilters "exception_filters" "Exception Filters" Null Gear 0 1 0 1 0 1 1 "An interface which controls whether or not the debugger will halt attached processes upon encountering specific exception codes for the first time." }
{ Theme "theme" "Theme" Null Palette 0 1 0 0 0 0 1 "An interface for modifying the colors used in the debugger's UI. Allows selecting a theme preset, loading a theme from a file, and modifying individual colors within a theme." }
}
////////////////////////////////
//~ rjf: Command Parameter Slot -> View
@table(slot view_spec opt_cmd_spec)
DF_CmdParamSlot2ViewSpecMap:
{
{Entity "entity_lister" "" }
{EntityList "entity_lister" "" }
{FilePath "file_system" "" }
{CmdSpec "commands" "" }
{ID "system_processes" "" }
{String "symbol_lister" "goto_name" }
{String "symbol_lister" "function_breakpoint" }
}
////////////////////////////////
//~ rjf: Built-In Graphical View Rule Extensions
//
// NOTE(rjf): see @view_rule_info
@table(string vr ls ru bu wu)
DF_GfxViewRuleTable:
{
{"array" - - - - - }
{"list" x - - - - }
{"dec" - x - - - }
{"bin" - x - - - }
{"oct" - x - - - }
{"hex" - x - - - }
{"only" x x - - - }
{"omit" x x - - - }
{"no_addr" - x - - - }
{"rgba" - - x x - }
{"text" - - - x - }
{"disasm" - - - x - }
{"bitmap" - - x x x }
{"geo" - - x x - }
}
////////////////////////////////
//~ rjf: Theme Color Codes
@table(name display_name name_lower)
DF_ThemeTable:
{
{Null "Null" null }
{PlainText "Plain Text" plain_text }
{PlainBackground "Plain Background" plain_background }
{PlainBorder "Plain Border" plain_border }
{PlainOverlay "Plain Overlay" plain_overlay }
{CodeDefault "Code (Default)" code_default }
{CodeFunction "Code (Function)" code_function }
{CodeType "Code (Type)" code_type }
{CodeLocal "Code (Local)" code_local }
{CodeRegister "Code (Register)" code_register }
{CodeKeyword "Code (Keyword)" code_keyword }
{CodeSymbol "Code (Symbol)" code_symbol }
{CodeNumeric "Code (Numeric)" code_numeric }
{CodeString "Code (String)" code_string }
{CodeMeta "Code (Meta)" code_meta }
{CodeComment "Code (Comment)" code_comment }
{LineInfo0 "Line Info (0)" line_info_0 }
{LineInfo1 "Line Info (1)" line_info_1 }
{LineInfo2 "Line Info (2)" line_info_2 }
{LineInfo3 "Line Info (3)" line_info_3 }
{AltText "Alt Text" alt_text }
{AltBackground "Alt Background" alt_background }
{AltBorder "Alt Border" alt_border }
{AltOverlay "Alt Overlay" alt_overlay }
{TabInactive "Inactive Tab" tab_inactive }
{TabActive "Active Tab" tab_active }
{EntityBackground "Entity Background" entity_background }
{QueryBar "Query Bar" query_bar }
{WeakText "Weak Text" weak_text }
{TextSelection "Text Selection" text_selection }
{Cursor "Cursor" cursor }
{Highlight0 "Highlight (0)" highlight_0 }
{Highlight1 "Highlight (1)" highlight_1 }
{SuccessText "Success Text" success_text }
{SuccessBackground "Success Background" success_background }
{SuccessBorder "Success Border" success_border }
{FailureText "Failure Text" failure_text }
{FailureBackground "Failure Background" failure_background }
{FailureBorder "Failure Border" failure_border }
{ActionText "Action Text" action_text }
{ActionBackground "Action Background" action_background }
{ActionBorder "Action Border" action_border }
{DropSiteOverlay "Drop Site Overlay" drop_site_overlay }
{Thread0 "Thread (0)" thread_0 }
{Thread1 "Thread (1)" thread_1 }
{Thread2 "Thread (2)" thread_2 }
{Thread3 "Thread (3)" thread_3 }
{Thread4 "Thread (4)" thread_4 }
{Thread5 "Thread (5)" thread_5 }
{Thread6 "Thread (6)" thread_6 }
{Thread7 "Thread (7)" thread_7 }
{ThreadUnwound "Thread (Unwound)" thread_unwound }
{InactivePanelOverlay "Inactive Panel Overlay" inactive_panel_overlay }
{DropShadow "Drop Shadow" drop_shadow }
}
////////////////////////////////
//~ rjf: Theme Color Version Remap Table
@table(old_name new_name)
DF_ThemeColorVersionRemapTable:
{
}
////////////////////////////////
//~ rjf: Theme Presets
@table(name_upper name_lower display_string)
DF_ThemePresetTable:
{
{ DefaultDark default_dark "Default (Dark)" }
{ DefaultLight default_light "Default (Light)" }
{ VSDark vs_dark "VS (Dark)" }
{ VSLight vs_light "VS (Light)" }
{ SolarizedDark solarized_dark "Solarized (Dark)" }
{ SolarizedLight solarized_light "Solarized (Light)" }
{ HandmadeHero handmade_hero "Handmade Hero" }
{ FourCoder four_coder "4coder" }
{ FarManager far_manager "Far Manager" }
}
@table(name default_dark default_light vs_dark vs_light solarized_dark solarized_light handmade_hero four_coder far_manager)
DF_ThemePresetColorTable:
{
(null 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff 0xff00ffff )
(plain_text 0xe5e5e5ff 0x383838ff 0xe5e5e5ff 0x1e1e1eff 0xe5e5e5ff 0x1e1e1eff 0xa08563ff 0x90b080ff 0x00ffffff )
(plain_background 0x3333337f 0xedededfe 0x1e1e1eff 0xffffffff 0x002b36ff 0xfcf6e2ff 0x0c0c0cff 0x0c0c0cff 0x000082ff )
(plain_border 0xffffff19 0x0000001d 0xffffff19 0xcccedb1d 0xffffff19 0xcccedb1d 0xffffff19 0x181818a0 0xffffff19 )
(plain_overlay 0xffffff33 0x00000033 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 )
(code_default 0xe5e5e5ff 0x282828ff 0xd4d4d4ff 0x000000ff 0x839496ff 0x74878cff 0xa08563ff 0x90b080ff 0x00ffffff )
(code_function 0x7fcc99ff 0x2a7a45ff 0xdcdcaaff 0x74531fff 0x1c7dd1ff 0xc39d36ff 0xcc5735ff 0x7fcc99ff 0x49b2ffff )
(code_type 0x66b2e5ff 0x2c688fff 0x4ec9b0ff 0x2b91afff 0x1c7dd1ff 0x66b2e5ff 0xd8a51dff 0x66b2e5ff 0x49b2ffff )
(code_local 0xfe9548ff 0xfe9548ff 0xfe9548ff 0xfe9548ff 0xfe9548ff 0xfe9548ff 0xfe9548ff 0xfe9548ff 0xfe9548ff )
(code_register 0xd45d90ff 0xd45d90ff 0xd45d90ff 0xd45d90ff 0xd45d90ff 0xd45d90ff 0xd45d90ff 0xd45d90ff 0xd45d90ff )
(code_keyword 0xf7bf5eff 0xa47729ff 0x569cd6ff 0x0000ffff 0x63980fff 0xc39d36ff 0xac7b0bff 0xd08f20ff 0xff0000ff )
(code_symbol 0x994c32ff 0x6c2d18ff 0xb4b4b4ff 0x000000ff 0x839496ff 0x2e5256ff 0x994c32ff 0x994c32ff 0xffffffff )
(code_numeric 0x4ce54cff 0x2c7d2cff 0xb5cea8ff 0x000000ff 0xcb4b20ff 0x657b83ff 0x6b8e23ff 0x50ff30ff 0x2cff50ff )
(code_string 0xe5cc66ff 0xcc5a0fff 0xd69d85ff 0xc11515ff 0x2aa198ff 0x5ab4a9ff 0x6b8e23ff 0x50ff30ff 0xe5cc66ff )
(code_meta 0xe54c4cff 0x8a0c0cff 0x9b9b9bff 0x808080ff 0xe54c4cff 0xe54c4cff 0xdab98fff 0x50ff30ff 0xffff00ff )
(code_comment 0x7f7f7fff 0x7f7f7fff 0x6a9955ff 0x008000ff 0x7f7f7fff 0xadafb2ff 0x686868ff 0x2090f0ff 0x7f7f7fff )
(line_info_0 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f 0x99503d3f )
(line_info_1 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f 0xfe82493f )
(line_info_2 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f 0xffba173f )
(line_info_3 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f 0xcefd693f )
(alt_text 0xe5e5e5ff 0x535353ff 0xf1f1f1ff 0x535353ff 0xe5e5e5ff 0x535353ff 0xa08563ff 0x90b080ff 0x000000ff )
(alt_background 0x42474c7f 0xfefefebc 0x1b1b1cff 0xfefefebc 0x002b36ff 0xfcf6e2ff 0x0c0c0cff 0x0c0c0cff 0x008184ff )
(alt_border 0xffffff19 0xffffff19 0x333337ff 0xffffff19 0xffffff19 0xffffff19 0xffffff19 0xffffff19 0xffffff19 )
(alt_overlay 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 )
(tab_inactive 0x42474c7f 0x42474c7f 0x42474c7f 0x42474c7f 0x42474c7f 0x42474c7f 0x42474c7f 0x42474c7f 0x42474c7f )
(tab_active 0xa87a4c99 0xc7a27dff 0x007accff 0x007accff 0x28515eff 0xa87a4c99 0xa87a4c99 0xa87a4c99 0xa87a4c99 )
(entity_background 0x4293cc99 0x4293cc99 0x4293cc99 0x4293cc99 0x4293cc99 0x4293cc99 0x4293cc99 0x4293cc99 0x4293cc99 )
(query_bar 0x8e2d4ccc 0xd76489cc 0x8e2d4ccc 0x8e2d4ccc 0x8e2d4ccc 0x8e2d4ccc 0x8e2d4ccc 0x8e2d4ccc 0x8e2d4ccc )
(weak_text 0xffffff7f 0x0000007f 0xffffff7f 0x0000007f 0xffffff7f 0x0000007f 0xa08563af 0x90b080af 0xffffff7f )
(text_selection 0x99ccff4c 0x7d98b34c 0x99ccff4c 0x7d98b34c 0x99ccff4c 0x7d98b34c 0x99ccff4c 0x99ccff4c 0x99ccff4c )
(cursor 0x66e566e5 0x101010ff 0x66e566e5 0x101010ff 0x66e566e5 0x101010ff 0x66e566e5 0x66e566e5 0x66e566e5 )
(highlight_0 0xb27219ff 0xb272189b 0xb27219ff 0xb27219ff 0xb27219ff 0xb27219ff 0xb27219ff 0xb27219ff 0xb27219ff )
(highlight_1 0x327f19ff 0x327f19ff 0x327f19ff 0x327f19ff 0x327f19ff 0x327f19ff 0x327f19ff 0x327f19ff 0x327f19ff )
(success_text 0xe5e5e5ff 0xe5e5e5ff 0xe5e5e5ff 0xe5e5e5ff 0xe5e5e5ff 0xe5e5e5ff 0xe5e5e5ff 0xe5e5e5ff 0xe5e5e5ff )
(success_background 0x32b219ff 0x75db61ff 0x32b219ff 0x32b219ff 0x32b219ff 0x32b219ff 0x32b219ff 0x32b219ff 0x32b219ff )
(success_border 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 )
(failure_text 0xe5e5e5ff 0xe5e5e5ff 0xe5e5e5ff 0xe5e5e5ff 0xe5e5e5ff 0xe5e5e5ff 0xe5e5e5ff 0xe5e5e5ff 0xe5e5e5ff )
(failure_background 0xb23219ff 0xf27961ff 0xb23219ff 0xb23219ff 0xb23219ff 0xb23219ff 0xb23219ff 0xb23219ff 0xb23219ff )
(failure_border 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 )
(action_text 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff )
(action_background 0x327fb2ff 0x327fb2ff 0x327fb2ff 0x327fb2ff 0x327fb2ff 0x327fb2ff 0x327fb2ff 0x327fb2ff 0x327fb2ff )
(action_border 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 0xffffff33 )
(drop_site_overlay 0xffffff0c 0xffffff0c 0xffffff0c 0xffffff0c 0xffffff0c 0xffffff0c 0xffffff0c 0xffffff0c 0xffffff0c )
(thread_0 0xffcb7fff 0xad7c34ff 0xffcb7fff 0xad7c34ff 0xffcb7fff 0xad7c34ff 0xffcb7fff 0xffcb7fff 0xffcb7fff )
(thread_1 0xb2ff65ff 0x639b2aff 0xb2ff65ff 0x639b2aff 0xb2ff65ff 0x639b2aff 0xb2ff65ff 0xb2ff65ff 0xb2ff65ff )
(thread_2 0xff99e5ff 0xa94c91ff 0xff99e5ff 0xa94c91ff 0xff99e5ff 0xa94c91ff 0xff99e5ff 0xff99e5ff 0xff99e5ff )
(thread_3 0x6598ffff 0x305398ff 0x6598ffff 0x305398ff 0x6598ffff 0x305398ff 0x6598ffff 0x6598ffff 0x6598ffff )
(thread_4 0x65ffcbff 0x339574ff 0x65ffcbff 0x339574ff 0x65ffcbff 0x339574ff 0x65ffcbff 0x65ffcbff 0x65ffcbff )
(thread_5 0xff9819ff 0xbf7416ff 0xff9819ff 0xbf7416ff 0xff9819ff 0xbf7416ff 0xff9819ff 0xff9819ff 0xff9819ff )
(thread_6 0x9932ffff 0x57238bff 0x9932ffff 0x57238bff 0x9932ffff 0x57238bff 0x9932ffff 0x9932ffff 0x9932ffff )
(thread_7 0x65ff4cff 0x2a7e1cff 0x65ff4cff 0x2a7e1cff 0x65ff4cff 0x2a7e1cff 0x65ff4cff 0x65ff4cff 0x65ff4cff )
(thread_unwound 0xb2ccd8ff 0x236481ff 0xb2ccd8ff 0x236481ff 0xb2ccd8ff 0x236481ff 0xb2ccd8ff 0xb2ccd8ff 0xb2ccd8ff )
(inactive_panel_overlay 0x0000003f 0x0000000d 0x0000003f 0x0000000d 0x0000003f 0x0000000d 0x0000003f 0x0000003f 0x0000003f )
(drop_shadow 0x0000007f 0x0000003b 0x0000007f 0x0000003b 0x0000007f 0x0000003b 0x0000007f 0x0000007f 0x0000007f )
}
////////////////////////////////
//~ rjf: Generators
//- rjf: enums
@enum DF_NameKind:
{
@expand(DF_NameKindTable, a) `$(a.name)`,
COUNT,
}
@enum DF_GfxViewKind:
{
@expand(DF_GfxViewTable a) `$(a.name)`,
COUNT,
}
@enum DF_ThemeColor:
{
@expand(DF_ThemeTable a) `$(a.name)`,
COUNT,
}
@enum DF_ThemePreset:
{
@expand(DF_ThemePresetTable a) `$(a.name)`,
COUNT,
}
//- rjf: theme preset color tables
@data(String8) df_g_theme_preset_display_string_table:
{
@expand(DF_ThemePresetTable a) `str8_lit_comp("$(a.display_string)")`,
}
@data(String8) df_g_theme_preset_code_string_table:
{
@expand(DF_ThemePresetTable a) `str8_lit_comp("$(a.name_lower)")`,
}
@data(Vec4F32) df_g_theme_preset_colors__default_dark:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.default_dark))`,
}
@data(Vec4F32) df_g_theme_preset_colors__default_light:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.default_light))`,
}
@data(Vec4F32) df_g_theme_preset_colors__vs_dark:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.vs_dark))`,
}
@data(Vec4F32) df_g_theme_preset_colors__vs_light:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.vs_light))`,
}
@data(Vec4F32) df_g_theme_preset_colors__solarized_dark:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.solarized_dark))`,
}
@data(Vec4F32) df_g_theme_preset_colors__solarized_light:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.solarized_light))`,
}
@data(Vec4F32) df_g_theme_preset_colors__handmade_hero:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.handmade_hero))`,
}
@data(Vec4F32) df_g_theme_preset_colors__four_coder:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.four_coder))`,
}
@data(Vec4F32) df_g_theme_preset_colors__far_manager:
{
@expand(DF_ThemePresetColorTable a) `rgba_from_u32_lit_comp($(a.far_manager))`;
}
@data(`Vec4F32*`) df_g_theme_preset_colors_table:
{
@expand(DF_ThemePresetTable a) `df_g_theme_preset_colors__$(a.name_lower)`,
}
//- rjf: cmd param slot -> view spec tables
@data(DF_CmdParamSlot) df_g_cmd_param_slot_2_view_spec_src_map:
{
@expand(DF_CmdParamSlot2ViewSpecMap a) `DF_CmdParamSlot_$(a.slot)`
}
@data(String8) df_g_cmd_param_slot_2_view_spec_dst_map:
{
@expand(DF_CmdParamSlot2ViewSpecMap a) `str8_lit_comp("$(a.view_spec)")`
}
@data(String8) df_g_cmd_param_slot_2_view_spec_cmd_map:
{
@expand(DF_CmdParamSlot2ViewSpecMap a) `str8_lit_comp("$(a.opt_cmd_spec)")`
}
//- rjf: default bindings table
@data(DF_StringBindingPair) df_g_default_binding_table:
{
@expand(DF_DefaultBindingTable a) ```{str8_lit_comp("$(a.name)"), {OS_Key_$(a.key), 0 $(a.ctrl != 0 -> `|OS_EventFlag_Ctrl`) $(a.shift != 0 -> `|OS_EventFlag_Shift`) $(a.alt != 0 -> `|OS_EventFlag_Alt`)}}```;
}
//- rjf: binding version remap tables
@data(String8) df_g_binding_version_remap_old_name_table:
{
@expand(DF_BindingVersionRemapTable a) `str8_lit_comp("$(a.old_name)")`
}
@data(String8) df_g_binding_version_remap_new_name_table:
{
@expand(DF_BindingVersionRemapTable a) `str8_lit_comp("$(a.new_name)")`
}
//- rjf: view hook forward declares
@gen
{
@expand(DF_GfxViewTable a) `DF_VIEW_SETUP_FUNCTION_DEF($(a.name));`;
@expand(DF_GfxViewTable a) `DF_VIEW_STRING_FROM_STATE_FUNCTION_DEF($(a.name));`;
@expand(DF_GfxViewTable a) `DF_VIEW_CMD_FUNCTION_DEF($(a.name));`;
@expand(DF_GfxViewTable a) `DF_VIEW_UI_FUNCTION_DEF($(a.name));`;
}
//- rjf: gfx view rule function forward declares
@gen
{
``;
@expand(DF_GfxViewRuleTable a)
`$(a.vr == "x" -> "DF_GFX_VIEW_RULE_VIZ_ROW_PROD_FUNCTION_DEF(" .. a.name_lower .. ");")`;
@expand(DF_GfxViewRuleTable a)
`$(a.ls == "x" -> "DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_DEF(" .. a.name_lower .. ");")`;
@expand(DF_GfxViewRuleTable a)
`$(a.ru == "x" -> "DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_DEF(" .. a.name_lower .. ");")`;
@expand(DF_GfxViewRuleTable a)
`$(a.bu == "x" -> "DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(" .. a.name_lower .. ");")`;
@expand(DF_GfxViewRuleTable a)
`$(a.wu == "x" -> "DF_GFX_VIEW_RULE_WHOLE_UI_FUNCTION_DEF(" .. a.name_lower .. ");")`;
}
//- rjf: gfx view rule tables
@data(DF_GfxViewRuleSpecInfo) @c_file df_g_gfx_view_rule_spec_info_table:
{
@expand(DF_GfxViewRuleTable a)
```{ str8_lit_comp("$(a.string)"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*$(a.vr == "x"))|(DF_GfxViewRuleSpecInfoFlag_LineStringize*$(a.ls == "x"))|(DF_GfxViewRuleSpecInfoFlag_RowUI*$(a.ru == "x"))|(DF_GfxViewRuleSpecInfoFlag_BlockUI*$(a.bu == "x")), $(a.vr == "x" -> "DF_GFX_VIEW_RULE_VIZ_ROW_PROD_FUNCTION_NAME("..a.name_lower..")") $(a.vr != "x" -> 0), $(a.ls == "x" -> "DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME("..a.name_lower..")") $(a.ls != "x" -> 0), $(a.ru == "x" -> "DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_NAME("..a.name_lower..")") $(a.ru != "x" -> 0), $(a.bu == "x" -> "DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME("..a.name_lower..")") $(a.bu != "x" -> 0), $(a.wu == "x" -> "DF_GFX_VIEW_RULE_WHOLE_UI_FUNCTION_NAME("..a.name_lower..")") $(a.wu != "x" -> 0) }```;
}
//- rjf: default view spec info table
@data(DF_ViewSpecInfo) df_g_gfx_view_kind_spec_info_table:
{
@expand(DF_GfxViewTable a) ```{(0|$(a.parameterized_by_entity)*DF_ViewSpecFlag_ParameterizedByEntity|$(a.can_serialize)*DF_ViewSpecFlag_CanSerialize|$(a.can_serialize_entity_path)*DF_ViewSpecFlag_CanSerializeEntityPath|$(a.can_filter)*DF_ViewSpecFlag_CanFilter|$(a.filter_is_code)*DF_ViewSpecFlag_FilterIsCode|$(a.typing_automatically_filters)*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("$(a.name_lower)"), str8_lit_comp("$(a.display_string)"), DF_NameKind_$(a.name_kind), DF_IconKind_$(a.icon), DF_VIEW_SETUP_FUNCTION_NAME($(a.name)), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME($(a.name)), DF_VIEW_CMD_FUNCTION_NAME($(a.name)), DF_VIEW_UI_FUNCTION_NAME($(a.name))}```;
}
//- rjf: theme color tables
@data(String8) df_g_theme_color_display_string_table:
{
@expand(DF_ThemeTable a) `str8_lit_comp("$(a.display_name)")`
}
@data(String8) df_g_theme_color_cfg_string_table:
{
@expand(DF_ThemeTable a) `str8_lit_comp("$(a.name_lower)")`
}
////////////////////////////////
//~ rjf: Help/Docs/README
@markdown
raddbg_readme:
{
@title "The RAD Debugger (ALPHA)";
@p "The RAD Debugger is a native, user-mode, multi-process, graphical debugger. It currently only supports local-machine Windows x64 debugging with PDBs, with plans to expand and port in the future.";
@subtitle "Getting Started";
@p "To launch the RAD Debugger with your executable and command line arguments, run `raddbg` from the command line like so:";
@p "```raddbg my_program.exe --foo --bar --baz```";
@p "For more information, see the 'Command-Line Usage' section.";
@p "Default keyboard shortcuts for common debugger controls include:";
@unordered_list
{
@p "**Ctrl + O**: Open Source Code File";
@p "**F10**: Step Over";
@p "**F11**: Step Into";
@p "**Shift + F11**: Step Out";
@p "**F5**: Run";
@p "**Ctrl + Shift + X**, or **Pause**: Halt All Processes";
@p "**Shift + F5**: Kill All Processes";
@p "**Shift + F6**: Attach To Process";
@p "**Ctrl + F**: Search For Text (Forwards)";
@p "**F9**: Toggle Breakpoint At Cursor";
@p "**Ctrl + Comma**: Focus Next Panel";
@p "**Ctrl + Shift + Comma**: Focus Previous Panel";
@p "**Ctrl + Shift + Alt + Arrow Key**: Focus Panel In Direction";
@p "**Ctrl + Tab**: Focus Next Tab";
@p "**Ctrl + Shift + Tab**: Focus Previous Tab";
@p "**Ctrl + W**: Close Tab";
@p "**F1**: Open Command Palette";
}
@p "For more information, see the 'Commands' section.";
@p "View rules can be used to visualize expressions differently in the watch window. Here are some examples:";
@unordered_list
{
@p "`array:16`: Visualize a pointer as pointing to a 16-element array.";
@p "`array:(count*2)`: Visualize a pointer as pointing to a `count*2`-element array.";
@p "`list:next`: Visualize a linked list flatly, where each node has a `next` pointer, which points to the next node in the list.";
@p "`hex`: Visualize numeric literals as base-16 (hexadecimal).";
@p "`dec`: Visualize numeric literals as base-10 (decimal).";
@p "`oct`: Visualize numeric literals as base-8 (octal).";
@p "`bin`: Visualize numeric literals as base-2 (binary).";
@p "`omit:(foo bar baz)`: Prohibits members named `foo`, `bar`, and `baz` from being displayed.";
@p "`only:(foo bar baz)`: Only allows members named `foo`, `bar`, and `baz` to be displayed.";
}
@p "Multiple view rules can be specified on one line, so they can be combined like so:";
@p "```list:next, hex, omit:next```";
@p "For more information, see the 'View Rules' section.";
@subtitle "Command-Line Usage";
@p "When run normally, either by launching through a file explorer or running from a command line without arguments, `raddbg` will open a new instance of the debugger. But it also supports a number of command line options for a number of other purposes. These options are specified with a `-` or `--` prefix, followed by the name of the option, and if the option requires a parameter, followed by a `:` or `=`, followed by the parameter's content. A list of the possible options follows:";
@unordered_list
{
@p "`--help` Displays a help menu which documents the possible command line options.";
@p "`--user:<path>` Specifies a path to the user file which the debugger should use instead of the default. The default user file is stored at `%appdata%/raddbg/default.raddbg_user`. For more information on user files, read the 'User & Profile Files' section.";
@p "`--profile:<path>` Specifies a path to the profile file which the debugger should use instead of the default. The default profile file is stored at `%appdata%/raddbg/default.raddbg_profile`. For more information on profile files, read the 'User & Profile Files' section.";
@p "`--auto_run` Specifies that the debugger should immediately run its selected targets upon launching.";
@p "`--auto_step` Specifies that the debugger should immediately step into its selected targets upon launching.";
//@p "`--ipc` Specifies that the launched debugger instance is for communicating a command to another instance of the debugger. In this mode, any non-argument command line contents will be used to express a command. For more information on commands, read the 'Commands' section. For more information on driving another debugger instance with this argument, read the 'Driving Another Debugger Instance' section."
}
@p "On the command line, non-options (meaning any command line arguments *not* prefixed with a `-` or `--`) can also be specified. with normal usage, they are interpreted as the command line for a target (see the 'Targets' section)."
// add when --ipc support is ready: "When driving another debugger instance (using the `--ipc` argument), this additional command line text is used to encode a debugger command.";
@p "The debugger will stop parsing `-` and `--` prefixes as arguments after seeing a standalone `--`, *or* after seeing the first non-option argument, when reading the command line left-to-right. Some examples of command line usage and their interpretations are below:";
@unordered_list
{
@p "`raddbg --foo --bar --a:b --c=d test.exe` All options are used to configure `raddbg`. `test.exe` is interpreted as a target executable. `b` is interpreted as the parameter for the `a` option. `d` is interpreted as the parameter for the `c` option.";
@p "`raddbg test.exe --foo --bar` `test.exe` is interpreted as a target executable. `--foo --bar` is interpreted as arguments for `test.exe`, and thus are *not* used to configure `raddbg`.";
@p "`raddbg -- test.exe` `test.exe` is interpreted as a target executable.";
//@p "`raddbg --ipc find_code_location \"c:/foo/bar/baz.c:123:1\"` `--ipc` configures `raddbg` to drive another instance of `raddbg`. The remainder of the text is interpreted as a command.";
@p "`raddbg \"C:/path with spaces/test.exe\" --foo --bar` A target is formed from the `test.exe` path, and `--foo --bar` are interpreted as arguments to the `test.exe` target.";
}
@subtitle "Windows, Panels, & Tabs";
@p "Each opened *window* in the debugger frontend is subdivided into *panels*. Panels subdivide regions of their window without overlapping. Each panel can contain multiple *tabs*, and can have one tab selected at any time. Tabs can be dragged and dropped between panels. Each tab is used to view one of the many supported debugger interfaces, including source code, disassembly, memory, or watches. When a tab is selected, that interface will fill the tab's containing panel's region of the containing window.";
@p "There are no 'special' windows, panels, or tabs; the debugger is written such that the number of windows, each window's panel organization, and the placement and arrangement of tabs can all be organized in a large variety of ways.";
@p "A list of debugger interfaces, which can occupy tabs, are below:";
@unordered_list
{
@expand(DF_GfxViewTable a) @p "$(a.inc_in_docs -> '`'..a.display_string..'` '..a.docs_desc)";
}
@subtitle "Commands";
@p "The debugger is operated with *commands*. Commands may be manually executed in the debugger UI through the `Commands` menu (which you can open either in the `View` menu bar list, or by using the keybinding, which is F1 by default). Operations in the debugger UI are implemented with commands, so if it's ever unclear how to accomplish some operation through the UI, a useful fallback is searching for and running the command through the command menu.";
//@p "Commands are also how a debugger instance launched with `--ipc` may communicate with a primary debugger instance.";
//@p "A list of commands, how they're referred to textually (for the purposes of `--ipc` debugger instances), and their descriptions are below:";
@p "A list of commands and their descriptions are below:";
@unordered_list
{
@expand(DF_CoreCmdTable a) @p "$(a.lister_omit == 0 -> '`'..a.display_name..'` '..'(`'..a.string..'`) '..a.desc)";
}
@subtitle "Targets";
@p "A *target* is one executable and configuration for launching that executable, including command line arguments and working directory (the directory from which the executable is launched). Each target may also have a custom label (replaces the executable path when visualizing the target), and the name of a custom entry point function (when the default entry points - `main`, `WinMain`, etc. - are not desired when stepping into the program upon launch). The debugger can have several targets at once. Each target can also be enabled or disabled. Some operations work on all enabled targets - for instance, the `Run` or `Kill All` commands (standardly bound as F5 or Shift + F5). Enabling and disabling targets allows one to filter which targets are currently being worked with.";
@p "To add a target, you can run the `Add Target` command. A target is also created automatically from command line arguments - the rules for how this happens can be found in the `Command-Line Usage` section.";
@p "Targets created through command line usage are temporary, meaning they are not persistently saved across runs of the debugger. To change this, you can right click the command-line-created target in the `Targets` view, and click `Save To Profile`. After doing so, the target will be restored across runs, and will no longer need to be specified on the command-line.";
@subtitle "View Rules";
@p "*View Rules* are used to transform the way that evaluations in the debugger are visualized. An evaluation is produced by taking an expression string - for instance, the name of a variable - and using debug info and information from an attached process' live runtime (memory, registers, and so on) to interpret it.";
@p "Evaluations may be visualized in a variety of ways. A 64-bit unsigned integer may be visualized as a textual representation of the value with a radix of 10. A 32-bit floating-point value may be visualized as a textual representation of the value. An array of 32-bit floating-point values can be visualized as a list of textual representations of those values.";
@p "But all of these cases may be visualized in a number of other ways, as well. A 64-bit unsigned integer may be more usefully represented with a radix of 16, 8, or 2. An array of 32-bit floating-point values may encode the R, G, B, and A components of a color, or vertex positions for 3D geometry, or samples for a waveform. An array of bytes may encode raw pixel data for an image, or image data in a compressed format. A struct may have several members which are not useful to look at all the time. A struct may form the head of a linked list, and a flat linked list representation may be more preferable than the traditional watch view representation, which adds an additional layer of hierarchical nesting with the expansion of each 'next' pointer in a linked list. When designing the debugger, we felt that the traditional memory view and watch view representations of data in a debugged-process were not sufficient. View rules were added to the traditional watch view structure to allow per-row specification of extra visualization parameters.";
@p "View rules are specified with the name of a view rule, and depending on the view rule, a `:`, followed by parameters for the view rule. These parameters may be whitespace delimited, but importantly, multiple view rules may be specified per-row in a watch view. To explicitly separate the parameters of one view rule from the name of another - for instance, in a case like `array:16 bin`, where `bin` will not be interpreted as a view rule, but as a parameter of `array` - then commas and semicolons may be used to separate the two view rules (`array:16, bin`), or parentheses/braces/brackets may also be used to explicitly delimit the view rule parameters (`array:(16) bin`).";
@p "A list of currently-supported view rules are below:";
@unordered_list
{
@expand(DF_CoreViewRuleTable a) @p "$(a.docs == 'x' -> '`'..a.string..'` ('..a.display_name..') '..a.description)";
}
@subtitle "Breakpoints";
@p "Breakpoints interrupt execution of attached processes. They may be placed on specific code addresses, lines of source code, on specific symbol names. In the latter two cases, the higher level locations are resolved to code addresses. If there is no code associated with a line of source code, then the resolution path chooses to use the next closest line of source code in the same file. A symbol name breakpoint will only work if the symbol name is found within loaded debug info.";
@p "Breakpoints may have stop conditions attached to them. When a breakpoint is hit by a thread, before it stops execution, the stop condition is evaluated, and if it evaluates to a nonzero value, only then is execution stopped.";
@p "Each breakpoint has a hit count. Every time a breakpoint causes execution to stop, this counter is increased.";
@p "Processor breakpoints are not currently supported, but planned to be in the future.";
@subtitle "User & Profile Files";
@p "Applicable state controlling the debugger's appearance, behavior, targets, breakpoints, and other configurations is saved and reloaded across runs of the debugger through both *user files* and *profile files*. These files are auto-saved. These files are written in a textual format which can be hand-edited as necessary, but they're also continuously re-read and re-written by the debugger. By default, the debugger uses `%appdata%/raddbg/default.raddbg_user` for its user file path, and `%appdata%/raddbg/default.raddbg_profile` for its profile file path. These paths can be overridden on the command line (see the 'Command-Line Usage' section).";
@p "The *user file* defaultly stores file path maps, windows (including their preferred monitor, placement, and size), each window's panel layout and tabs, keybindings, theme colors, and fonts.";
@p "The *profile file* defaultly stores targets, breakpoints, watch pins, and exception code filters.";
@p "Because both can be hand-edited, however, if you want to store something normally stored in a user file in a profile file, or vice versa, this can be done by hand transferring the textual data from one file to another. There is no path in the debugger's UI to support this transfer, currently, although this is planned.";
//@subtitle "Driving Another Debugger Instance";
//@p "When the debugger is launched with the `--ipc` command-line argument, it does not launch another instance of the graphical debugger. Instead, it launches, sends a string encoding a command to a running instance of the graphical debugger, and then terminates. The set of commands which can be sent are identical to those which can be run from the debugger's UI itself, but these commands must be encoded textually (through the other command-line arguments). These commands are described in the 'Commands' section.";
}
File diff suppressed because it is too large Load Diff
-49
View File
@@ -1,49 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DF_VIEW_RULE_HOOKS_H
#define DF_VIEW_RULE_HOOKS_H
////////////////////////////////
//~ rjf: Helper Types
typedef struct DF_BitmapTopologyInfo DF_BitmapTopologyInfo;
struct DF_BitmapTopologyInfo
{
U64 width;
U64 height;
R_Tex2DFormat fmt;
};
typedef struct DF_GeoTopologyInfo DF_GeoTopologyInfo;
struct DF_GeoTopologyInfo
{
U64 index_count;
Rng1U64 vertices_vaddr_range;
};
typedef struct DF_TxtTopologyInfo DF_TxtTopologyInfo;
struct DF_TxtTopologyInfo
{
TXT_LangKind lang;
U64 size_cap;
};
typedef struct DF_DisasmTopologyInfo DF_DisasmTopologyInfo;
struct DF_DisasmTopologyInfo
{
Architecture arch;
U64 size_cap;
};
////////////////////////////////
//~ rjf: Helpers
internal Vec4F32 df_view_rule_hooks__rgba_from_eval(DF_Eval eval, TG_Graph *graph, RDI_Parsed *raddbg, DF_Entity *process);
internal void df_view_rule_hooks__eval_commit_rgba(DF_Eval eval, TG_Graph *graph, RDI_Parsed *raddbg, DF_CtrlCtx *ctrl_ctx, Vec4F32 rgba);
internal DF_BitmapTopologyInfo df_view_rule_hooks__bitmap_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg);
internal DF_GeoTopologyInfo df_view_rule_hooks__geo_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg);
internal DF_TxtTopologyInfo df_view_rule_hooks__txt_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg);
internal DF_DisasmTopologyInfo df_view_rule_hooks__disasm_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg);
#endif //DF_VIEW_RULE_HOOKS_H
File diff suppressed because it is too large Load Diff
-463
View File
@@ -1,463 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DEBUG_FRONTEND_VIEWS_H
#define DEBUG_FRONTEND_VIEWS_H
////////////////////////////////
//~ rjf: FileSystem @view_types
typedef enum DF_FileSortKind
{
DF_FileSortKind_Null,
DF_FileSortKind_Filename,
DF_FileSortKind_LastModified,
DF_FileSortKind_Size,
DF_FileSortKind_COUNT
}
DF_FileSortKind;
typedef struct DF_FileInfo DF_FileInfo;
struct DF_FileInfo
{
String8 filename;
FileProperties props;
FuzzyMatchRangeList match_ranges;
};
typedef struct DF_FileInfoNode DF_FileInfoNode;
struct DF_FileInfoNode
{
DF_FileInfoNode *next;
DF_FileInfo file_info;
};
typedef struct DF_FileSystemViewPathState DF_FileSystemViewPathState;
struct DF_FileSystemViewPathState
{
DF_FileSystemViewPathState *hash_next;
String8 normalized_path;
Vec2S64 cursor;
};
typedef struct DF_FileSystemViewState DF_FileSystemViewState;
struct DF_FileSystemViewState
{
B32 initialized;
U64 path_state_table_size;
DF_FileSystemViewPathState **path_state_table;
DF_FileSortKind sort_kind;
Side sort_side;
Arena *cached_files_arena;
String8 cached_files_path;
DF_FileSortKind cached_files_sort_kind;
Side cached_files_sort_side;
U64 cached_file_count;
DF_FileInfo *cached_files;
F32 col_pcts[3];
};
////////////////////////////////
//~ rjf: Commands @view_types
typedef struct DF_CmdListerItem DF_CmdListerItem;
struct DF_CmdListerItem
{
DF_CmdSpec *cmd_spec;
U64 registrar_idx;
U64 ordering_idx;
FuzzyMatchRangeList name_match_ranges;
FuzzyMatchRangeList desc_match_ranges;
FuzzyMatchRangeList tags_match_ranges;
};
typedef struct DF_CmdListerItemNode DF_CmdListerItemNode;
struct DF_CmdListerItemNode
{
DF_CmdListerItemNode *next;
DF_CmdListerItem item;
};
typedef struct DF_CmdListerItemList DF_CmdListerItemList;
struct DF_CmdListerItemList
{
DF_CmdListerItemNode *first;
DF_CmdListerItemNode *last;
U64 count;
};
typedef struct DF_CmdListerItemArray DF_CmdListerItemArray;
struct DF_CmdListerItemArray
{
DF_CmdListerItem *v;
U64 count;
};
////////////////////////////////
//~ rjf: PendingEntity @view_types
typedef struct DF_PendingEntityViewState DF_PendingEntityViewState;
struct DF_PendingEntityViewState
{
Arena *deferred_cmd_arena;
DF_CmdList deferred_cmds;
DF_Handle pick_file_override_target;
Arena *complete_cfg_arena;
DF_CfgNode *complete_cfg_root;
};
////////////////////////////////
//~ rjf: EntityLister @view_types
typedef struct DF_EntityListerItem DF_EntityListerItem;
struct DF_EntityListerItem
{
DF_Entity *entity;
FuzzyMatchRangeList name_match_ranges;
};
typedef struct DF_EntityListerItemNode DF_EntityListerItemNode;
struct DF_EntityListerItemNode
{
DF_EntityListerItemNode *next;
DF_EntityListerItem item;
};
typedef struct DF_EntityListerItemList DF_EntityListerItemList;
struct DF_EntityListerItemList
{
DF_EntityListerItemNode *first;
DF_EntityListerItemNode *last;
U64 count;
};
typedef struct DF_EntityListerItemArray DF_EntityListerItemArray;
struct DF_EntityListerItemArray
{
DF_EntityListerItem *v;
U64 count;
};
////////////////////////////////
//~ rjf: SystemProcesses @view_types
typedef struct DF_ProcessInfo DF_ProcessInfo;
struct DF_ProcessInfo
{
DMN_ProcessInfo info;
B32 is_attached;
FuzzyMatchRangeList attached_match_ranges;
FuzzyMatchRangeList name_match_ranges;
FuzzyMatchRangeList pid_match_ranges;
};
typedef struct DF_ProcessInfoNode DF_ProcessInfoNode;
struct DF_ProcessInfoNode
{
DF_ProcessInfoNode *next;
DF_ProcessInfo info;
};
typedef struct DF_ProcessInfoList DF_ProcessInfoList;
struct DF_ProcessInfoList
{
DF_ProcessInfoNode *first;
DF_ProcessInfoNode *last;
U64 count;
};
typedef struct DF_ProcessInfoArray DF_ProcessInfoArray;
struct DF_ProcessInfoArray
{
DF_ProcessInfo *v;
U64 count;
};
////////////////////////////////
//~ rjf: Breakpoint @view_types
typedef struct DF_BreakpointViewState DF_BreakpointViewState;
struct DF_BreakpointViewState
{
B32 initialized;
Vec2S32 selected_p;
F32 key_pct;
F32 val_pct;
};
////////////////////////////////
//~ rjf: Target @view_types
typedef struct DF_TargetViewState DF_TargetViewState;
struct DF_TargetViewState
{
B32 initialized;
// rjf: pick file kind
DF_EntityKind pick_dst_kind;
// rjf: selection cursor
Vec2S64 cursor;
// rjf: text input state
TxtPt input_cursor;
TxtPt input_mark;
U8 input_buffer[1024];
U64 input_size;
B32 input_editing;
// rjf: table column pcts
F32 key_pct;
F32 value_pct;
};
////////////////////////////////
//~ rjf: FilePathMap @view_types
typedef struct DF_FilePathMapViewState DF_FilePathMapViewState;
struct DF_FilePathMapViewState
{
B32 initialized;
Vec2S64 cursor;
TxtPt input_cursor;
TxtPt input_mark;
U8 input_buffer[1024];
U64 input_size;
B32 input_editing;
DF_Handle pick_file_dst_map;
Side pick_file_dst_side;
F32 src_column_pct;
F32 dst_column_pct;
};
////////////////////////////////
//~ rjf: Modules @view_types
typedef struct DF_ModulesViewState DF_ModulesViewState;
struct DF_ModulesViewState
{
B32 initialized;
DF_Handle selected_entity;
S64 selected_column;
B32 txt_editing;
TxtPt txt_cursor;
TxtPt txt_mark;
U8 txt_buffer[1024];
U64 txt_size;
DF_Handle pick_file_dst_entity;
F32 idx_col_pct;
F32 desc_col_pct;
F32 range_col_pct;
F32 dbg_col_pct;
};
////////////////////////////////
//~ rjf: Watch, Locals, Registers @view_types
typedef struct DF_EvalRoot DF_EvalRoot;
struct DF_EvalRoot
{
DF_EvalRoot *next;
DF_EvalRoot *prev;
U64 expr_buffer_string_size;
U64 expr_buffer_cap;
U8 *expr_buffer;
};
typedef enum DF_EvalWatchViewColumnKind
{
DF_EvalWatchViewColumnKind_Expr,
DF_EvalWatchViewColumnKind_Value,
DF_EvalWatchViewColumnKind_Type,
DF_EvalWatchViewColumnKind_ViewRule,
DF_EvalWatchViewColumnKind_COUNT
}
DF_EvalWatchViewColumnKind;
typedef enum DF_EvalWatchViewFillKind
{
DF_EvalWatchViewFillKind_Mutable,
DF_EvalWatchViewFillKind_Registers,
DF_EvalWatchViewFillKind_Locals,
DF_EvalWatchViewFillKind_Globals,
DF_EvalWatchViewFillKind_ThreadLocals,
DF_EvalWatchViewFillKind_Types,
DF_EvalWatchViewFillKind_Procedures,
DF_EvalWatchViewFillKind_COUNT
}
DF_EvalWatchViewFillKind;
typedef struct DF_EvalWatchViewPoint DF_EvalWatchViewPoint;
struct DF_EvalWatchViewPoint
{
DF_EvalWatchViewColumnKind column_kind;
DF_ExpandKey parent_key;
DF_ExpandKey key;
};
typedef struct DF_EvalWatchViewState DF_EvalWatchViewState;
struct DF_EvalWatchViewState
{
B32 initialized;
// rjf: fill kind (way that the contents of the watch view are computed)
DF_EvalWatchViewFillKind fill_kind;
// rjf; table cursor state
DF_EvalWatchViewPoint cursor;
DF_EvalWatchViewPoint mark;
// rjf: text input state
TxtPt input_cursor;
TxtPt input_mark;
U8 input_buffer[1024];
U64 input_size;
B32 input_editing;
// rjf: table column width state
F32 expr_column_pct;
F32 value_column_pct;
F32 type_column_pct;
F32 view_rule_column_pct;
// rjf: mutable fill-kind root expression state
DF_EvalRoot *first_root;
DF_EvalRoot *last_root;
DF_EvalRoot *first_free_root;
U64 root_count;
};
////////////////////////////////
//~ rjf: Code @view_types
typedef struct DF_CodeViewState DF_CodeViewState;
struct DF_CodeViewState
{
// rjf: stable state
B32 initialized;
TxtPt cursor;
TxtPt mark;
S64 preferred_column;
B32 drifted_for_search;
DF_Handle pick_file_override_target;
// rjf: per-frame command info
S64 goto_line_num;
B32 center_cursor;
B32 contain_cursor;
Arena *find_text_arena;
String8 find_text_fwd;
String8 find_text_bwd;
};
////////////////////////////////
//~ rjf: Disassembly @view_types
typedef struct DF_DisasmViewState DF_DisasmViewState;
struct DF_DisasmViewState
{
// rjf: stable state
B32 initialized;
DF_Handle process;
U64 base_vaddr;
TxtPt cursor;
TxtPt mark;
S64 preferred_column;
B32 drifted_for_search;
DASM_StyleFlags style_flags;
// rjf: per-frame command info
S64 goto_line_num;
U64 goto_vaddr;
B32 center_cursor;
B32 contain_cursor;
Arena *find_text_arena;
String8 find_text_fwd;
String8 find_text_bwd;
};
////////////////////////////////
//~ rjf: Memory @view_types
typedef struct DF_MemoryViewState DF_MemoryViewState;
struct DF_MemoryViewState
{
B32 initialized;
// rjf: last-viewed-memory cache
Arena *last_viewed_memory_cache_arena;
U8 *last_viewed_memory_cache_buffer;
Rng1U64 last_viewed_memory_cache_range;
U64 last_viewed_memory_cache_memgen_idx;
// rjf: control state
U64 cursor;
U64 mark;
// rjf: organization state
U64 num_columns;
U64 bytes_per_cell;
// rjf: command pass-through data
B32 center_cursor;
B32 contain_cursor;
};
////////////////////////////////
//~ rjf: Quick Sort Comparisons
internal int df_qsort_compare_file_info__default(DF_FileInfo *a, DF_FileInfo *b);
internal int df_qsort_compare_file_info__default_filtered(DF_FileInfo *a, DF_FileInfo *b);
internal int df_qsort_compare_file_info__filename(DF_FileInfo *a, DF_FileInfo *b);
internal int df_qsort_compare_file_info__last_modified(DF_FileInfo *a, DF_FileInfo *b);
internal int df_qsort_compare_file_info__size(DF_FileInfo *a, DF_FileInfo *b);
internal int df_qsort_compare_process_info(DF_ProcessInfo *a, DF_ProcessInfo *b);
internal int df_qsort_compare_cmd_lister__strength(DF_CmdListerItem *a, DF_CmdListerItem *b);
internal int df_qsort_compare_entity_lister__strength(DF_EntityListerItem *a, DF_EntityListerItem *b);
////////////////////////////////
//~ rjf: Command Lister
internal DF_CmdListerItemList df_cmd_lister_item_list_from_needle(Arena *arena, String8 needle);
internal DF_CmdListerItemArray df_cmd_lister_item_array_from_list(Arena *arena, DF_CmdListerItemList list);
internal void df_cmd_lister_item_array_sort_by_strength__in_place(DF_CmdListerItemArray array);
////////////////////////////////
//~ rjf: System Process Lister
internal DF_ProcessInfoList df_process_info_list_from_query(Arena *arena, String8 query);
internal DF_ProcessInfoArray df_process_info_array_from_list(Arena *arena, DF_ProcessInfoList list);
internal void df_process_info_array_sort_by_strength__in_place(DF_ProcessInfoArray array);
////////////////////////////////
//~ rjf: Entity Lister
internal DF_EntityListerItemList df_entity_lister_item_list_from_needle(Arena *arena, DF_EntityKind kind, DF_EntityFlags omit_flags, String8 needle);
internal DF_EntityListerItemArray df_entity_lister_item_array_from_list(Arena *arena, DF_EntityListerItemList list);
internal void df_entity_lister_item_array_sort_by_strength__in_place(DF_EntityListerItemArray array);
////////////////////////////////
//~ rjf: Eval/Watch Views
//- rjf: eval watch view instance -> eval view key
internal DF_EvalViewKey df_eval_view_key_from_eval_watch_view(DF_EvalWatchViewState *ewv);
//- rjf: root allocation/deallocation/mutation
internal DF_EvalRoot * df_eval_root_alloc(DF_View *view, DF_EvalWatchViewState *ews);
internal void df_eval_root_release(DF_EvalWatchViewState *ews, DF_EvalRoot *root);
internal void df_eval_root_equip_string(DF_EvalRoot *root, String8 string);
internal DF_EvalRoot * df_eval_root_from_string(DF_EvalWatchViewState *ews, String8 string);
internal DF_EvalRoot * df_eval_root_from_expand_key(DF_EvalWatchViewState *ews, DF_EvalView *eval_view, DF_ExpandKey expand_key);
internal String8 df_string_from_eval_root(DF_EvalRoot *root);
internal DF_ExpandKey df_parent_expand_key_from_eval_root(DF_EvalRoot *root);
internal DF_ExpandKey df_expand_key_from_eval_root(DF_EvalRoot *root);
//- rjf: windowed watch tree visualization
internal DF_EvalVizBlockList df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_View *view, DF_EvalWatchViewState *ews);
//- rjf: eval/watch views main hooks
internal void df_eval_watch_view_init(DF_EvalWatchViewState *ewv, DF_View *view, DF_EvalWatchViewFillKind fill_kind);
internal void df_eval_watch_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalWatchViewState *ewv, DF_CmdList *cmds);
internal void df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalWatchViewState *ewv, B32 modifiable, U32 default_radix, Rng2F32 rect);
#endif // DEBUG_FRONTEND_VIEWS_H
-885
View File
@@ -1,885 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
//- GENERATED CODE
C_LINKAGE_BEGIN
String8 df_g_theme_preset_display_string_table[9] =
{
str8_lit_comp("Default (Dark)"),
str8_lit_comp("Default (Light)"),
str8_lit_comp("VS (Dark)"),
str8_lit_comp("VS (Light)"),
str8_lit_comp("Solarized (Dark)"),
str8_lit_comp("Solarized (Light)"),
str8_lit_comp("Handmade Hero"),
str8_lit_comp("4coder"),
str8_lit_comp("Far Manager"),
};
String8 df_g_theme_preset_code_string_table[9] =
{
str8_lit_comp("default_dark"),
str8_lit_comp("default_light"),
str8_lit_comp("vs_dark"),
str8_lit_comp("vs_light"),
str8_lit_comp("solarized_dark"),
str8_lit_comp("solarized_light"),
str8_lit_comp("handmade_hero"),
str8_lit_comp("four_coder"),
str8_lit_comp("far_manager"),
};
Vec4F32 df_g_theme_preset_colors__default_dark[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x3333337f),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x7fcc99ff),
rgba_from_u32_lit_comp(0x66b2e5ff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0xf7bf5eff),
rgba_from_u32_lit_comp(0x994c32ff),
rgba_from_u32_lit_comp(0x4ce54cff),
rgba_from_u32_lit_comp(0xe5cc66ff),
rgba_from_u32_lit_comp(0xe54c4cff),
rgba_from_u32_lit_comp(0x7f7f7fff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xa87a4c99),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0xffffff7f),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32 df_g_theme_preset_colors__default_light[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0x383838ff),
rgba_from_u32_lit_comp(0xedededfe),
rgba_from_u32_lit_comp(0x0000001d),
rgba_from_u32_lit_comp(0x00000033),
rgba_from_u32_lit_comp(0x282828ff),
rgba_from_u32_lit_comp(0x2a7a45ff),
rgba_from_u32_lit_comp(0x2c688fff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0xa47729ff),
rgba_from_u32_lit_comp(0x6c2d18ff),
rgba_from_u32_lit_comp(0x2c7d2cff),
rgba_from_u32_lit_comp(0xcc5a0fff),
rgba_from_u32_lit_comp(0x8a0c0cff),
rgba_from_u32_lit_comp(0x7f7f7fff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0x535353ff),
rgba_from_u32_lit_comp(0xfefefebc),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xc7a27dff),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0xd76489cc),
rgba_from_u32_lit_comp(0x0000007f),
rgba_from_u32_lit_comp(0x7d98b34c),
rgba_from_u32_lit_comp(0x101010ff),
rgba_from_u32_lit_comp(0xb272189b),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x75db61ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xf27961ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xad7c34ff),
rgba_from_u32_lit_comp(0x639b2aff),
rgba_from_u32_lit_comp(0xa94c91ff),
rgba_from_u32_lit_comp(0x305398ff),
rgba_from_u32_lit_comp(0x339574ff),
rgba_from_u32_lit_comp(0xbf7416ff),
rgba_from_u32_lit_comp(0x57238bff),
rgba_from_u32_lit_comp(0x2a7e1cff),
rgba_from_u32_lit_comp(0x236481ff),
rgba_from_u32_lit_comp(0x0000000d),
rgba_from_u32_lit_comp(0x0000003b),
};
Vec4F32 df_g_theme_preset_colors__vs_dark[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x1e1e1eff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xd4d4d4ff),
rgba_from_u32_lit_comp(0xdcdcaaff),
rgba_from_u32_lit_comp(0x4ec9b0ff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0x569cd6ff),
rgba_from_u32_lit_comp(0xb4b4b4ff),
rgba_from_u32_lit_comp(0xb5cea8ff),
rgba_from_u32_lit_comp(0xd69d85ff),
rgba_from_u32_lit_comp(0x9b9b9bff),
rgba_from_u32_lit_comp(0x6a9955ff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0xf1f1f1ff),
rgba_from_u32_lit_comp(0x1b1b1cff),
rgba_from_u32_lit_comp(0x333337ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0x007accff),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0xffffff7f),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32 df_g_theme_preset_colors__vs_light[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0x1e1e1eff),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0xcccedb1d),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x000000ff),
rgba_from_u32_lit_comp(0x74531fff),
rgba_from_u32_lit_comp(0x2b91afff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0x0000ffff),
rgba_from_u32_lit_comp(0x000000ff),
rgba_from_u32_lit_comp(0x000000ff),
rgba_from_u32_lit_comp(0xc11515ff),
rgba_from_u32_lit_comp(0x808080ff),
rgba_from_u32_lit_comp(0x008000ff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0x535353ff),
rgba_from_u32_lit_comp(0xfefefebc),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0x007accff),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0x0000007f),
rgba_from_u32_lit_comp(0x7d98b34c),
rgba_from_u32_lit_comp(0x101010ff),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xad7c34ff),
rgba_from_u32_lit_comp(0x639b2aff),
rgba_from_u32_lit_comp(0xa94c91ff),
rgba_from_u32_lit_comp(0x305398ff),
rgba_from_u32_lit_comp(0x339574ff),
rgba_from_u32_lit_comp(0xbf7416ff),
rgba_from_u32_lit_comp(0x57238bff),
rgba_from_u32_lit_comp(0x2a7e1cff),
rgba_from_u32_lit_comp(0x236481ff),
rgba_from_u32_lit_comp(0x0000000d),
rgba_from_u32_lit_comp(0x0000003b),
};
Vec4F32 df_g_theme_preset_colors__solarized_dark[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x002b36ff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x839496ff),
rgba_from_u32_lit_comp(0x1c7dd1ff),
rgba_from_u32_lit_comp(0x1c7dd1ff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0x63980fff),
rgba_from_u32_lit_comp(0x839496ff),
rgba_from_u32_lit_comp(0xcb4b20ff),
rgba_from_u32_lit_comp(0x2aa198ff),
rgba_from_u32_lit_comp(0xe54c4cff),
rgba_from_u32_lit_comp(0x7f7f7fff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x002b36ff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0x28515eff),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0xffffff7f),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32 df_g_theme_preset_colors__solarized_light[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0x1e1e1eff),
rgba_from_u32_lit_comp(0xfcf6e2ff),
rgba_from_u32_lit_comp(0xcccedb1d),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x74878cff),
rgba_from_u32_lit_comp(0xc39d36ff),
rgba_from_u32_lit_comp(0x66b2e5ff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0xc39d36ff),
rgba_from_u32_lit_comp(0x2e5256ff),
rgba_from_u32_lit_comp(0x657b83ff),
rgba_from_u32_lit_comp(0x5ab4a9ff),
rgba_from_u32_lit_comp(0xe54c4cff),
rgba_from_u32_lit_comp(0xadafb2ff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0x535353ff),
rgba_from_u32_lit_comp(0xfcf6e2ff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xa87a4c99),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0x0000007f),
rgba_from_u32_lit_comp(0x7d98b34c),
rgba_from_u32_lit_comp(0x101010ff),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xad7c34ff),
rgba_from_u32_lit_comp(0x639b2aff),
rgba_from_u32_lit_comp(0xa94c91ff),
rgba_from_u32_lit_comp(0x305398ff),
rgba_from_u32_lit_comp(0x339574ff),
rgba_from_u32_lit_comp(0xbf7416ff),
rgba_from_u32_lit_comp(0x57238bff),
rgba_from_u32_lit_comp(0x2a7e1cff),
rgba_from_u32_lit_comp(0x236481ff),
rgba_from_u32_lit_comp(0x0000000d),
rgba_from_u32_lit_comp(0x0000003b),
};
Vec4F32 df_g_theme_preset_colors__handmade_hero[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0xa08563ff),
rgba_from_u32_lit_comp(0x0c0c0cff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xa08563ff),
rgba_from_u32_lit_comp(0xcc5735ff),
rgba_from_u32_lit_comp(0xd8a51dff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0xac7b0bff),
rgba_from_u32_lit_comp(0x994c32ff),
rgba_from_u32_lit_comp(0x6b8e23ff),
rgba_from_u32_lit_comp(0x6b8e23ff),
rgba_from_u32_lit_comp(0xdab98fff),
rgba_from_u32_lit_comp(0x686868ff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0xa08563ff),
rgba_from_u32_lit_comp(0x0c0c0cff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xa87a4c99),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0xa08563af),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32 df_g_theme_preset_colors__four_coder[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0x90b080ff),
rgba_from_u32_lit_comp(0x0c0c0cff),
rgba_from_u32_lit_comp(0x181818a0),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x90b080ff),
rgba_from_u32_lit_comp(0x7fcc99ff),
rgba_from_u32_lit_comp(0x66b2e5ff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0xd08f20ff),
rgba_from_u32_lit_comp(0x994c32ff),
rgba_from_u32_lit_comp(0x50ff30ff),
rgba_from_u32_lit_comp(0x50ff30ff),
rgba_from_u32_lit_comp(0x50ff30ff),
rgba_from_u32_lit_comp(0x2090f0ff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0x90b080ff),
rgba_from_u32_lit_comp(0x0c0c0cff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xa87a4c99),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0x90b080af),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32 df_g_theme_preset_colors__far_manager[54] =
{
rgba_from_u32_lit_comp(0xff00ffff),
rgba_from_u32_lit_comp(0x00ffffff),
rgba_from_u32_lit_comp(0x000082ff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x00ffffff),
rgba_from_u32_lit_comp(0x49b2ffff),
rgba_from_u32_lit_comp(0x49b2ffff),
rgba_from_u32_lit_comp(0xfe9548ff),
rgba_from_u32_lit_comp(0xd45d90ff),
rgba_from_u32_lit_comp(0xff0000ff),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x2cff50ff),
rgba_from_u32_lit_comp(0xe5cc66ff),
rgba_from_u32_lit_comp(0xffff00ff),
rgba_from_u32_lit_comp(0x7f7f7fff),
rgba_from_u32_lit_comp(0x99503d3f),
rgba_from_u32_lit_comp(0xfe82493f),
rgba_from_u32_lit_comp(0xffba173f),
rgba_from_u32_lit_comp(0xcefd693f),
rgba_from_u32_lit_comp(0x000000ff),
rgba_from_u32_lit_comp(0x008184ff),
rgba_from_u32_lit_comp(0xffffff19),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0x42474c7f),
rgba_from_u32_lit_comp(0xa87a4c99),
rgba_from_u32_lit_comp(0x4293cc99),
rgba_from_u32_lit_comp(0x8e2d4ccc),
rgba_from_u32_lit_comp(0xffffff7f),
rgba_from_u32_lit_comp(0x99ccff4c),
rgba_from_u32_lit_comp(0x66e566e5),
rgba_from_u32_lit_comp(0xb27219ff),
rgba_from_u32_lit_comp(0x327f19ff),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0x32b219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xe5e5e5ff),
rgba_from_u32_lit_comp(0xb23219ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffffff),
rgba_from_u32_lit_comp(0x327fb2ff),
rgba_from_u32_lit_comp(0xffffff33),
rgba_from_u32_lit_comp(0xffffff0c),
rgba_from_u32_lit_comp(0xffcb7fff),
rgba_from_u32_lit_comp(0xb2ff65ff),
rgba_from_u32_lit_comp(0xff99e5ff),
rgba_from_u32_lit_comp(0x6598ffff),
rgba_from_u32_lit_comp(0x65ffcbff),
rgba_from_u32_lit_comp(0xff9819ff),
rgba_from_u32_lit_comp(0x9932ffff),
rgba_from_u32_lit_comp(0x65ff4cff),
rgba_from_u32_lit_comp(0xb2ccd8ff),
rgba_from_u32_lit_comp(0x0000003f),
rgba_from_u32_lit_comp(0x0000007f),
};
Vec4F32* df_g_theme_preset_colors_table[9] =
{
df_g_theme_preset_colors__default_dark,
df_g_theme_preset_colors__default_light,
df_g_theme_preset_colors__vs_dark,
df_g_theme_preset_colors__vs_light,
df_g_theme_preset_colors__solarized_dark,
df_g_theme_preset_colors__solarized_light,
df_g_theme_preset_colors__handmade_hero,
df_g_theme_preset_colors__four_coder,
df_g_theme_preset_colors__far_manager,
};
DF_CmdParamSlot df_g_cmd_param_slot_2_view_spec_src_map[7] =
{
DF_CmdParamSlot_Entity,
DF_CmdParamSlot_EntityList,
DF_CmdParamSlot_FilePath,
DF_CmdParamSlot_CmdSpec,
DF_CmdParamSlot_ID,
DF_CmdParamSlot_String,
DF_CmdParamSlot_String,
};
String8 df_g_cmd_param_slot_2_view_spec_dst_map[7] =
{
str8_lit_comp("entity_lister"),
str8_lit_comp("entity_lister"),
str8_lit_comp("file_system"),
str8_lit_comp("commands"),
str8_lit_comp("system_processes"),
str8_lit_comp("symbol_lister"),
str8_lit_comp("symbol_lister"),
};
String8 df_g_cmd_param_slot_2_view_spec_cmd_map[7] =
{
str8_lit_comp(""),
str8_lit_comp(""),
str8_lit_comp(""),
str8_lit_comp(""),
str8_lit_comp(""),
str8_lit_comp("goto_name"),
str8_lit_comp("function_breakpoint"),
};
DF_StringBindingPair df_g_default_binding_table[97] =
{
{str8_lit_comp("kill_all"), {OS_Key_F5, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("step_into_inst"), {OS_Key_F11, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("step_over_inst"), {OS_Key_F10, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("step_out"), {OS_Key_F11, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("halt"), {OS_Key_X, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("halt"), {OS_Key_Pause, 0 }},
{str8_lit_comp("soft_halt_refresh"), {OS_Key_R, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("run"), {OS_Key_F5, 0 }},
{str8_lit_comp("restart"), {OS_Key_F5, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("step_into"), {OS_Key_F11, 0 }},
{str8_lit_comp("step_over"), {OS_Key_F10, 0 }},
{str8_lit_comp("run_to_cursor"), {OS_Key_F10, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("set_next_statement"), {OS_Key_F10, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("inc_ui_font_scale"), {OS_Key_Equal, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("dec_ui_font_scale"), {OS_Key_Minus, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("inc_code_font_scale"), {OS_Key_Equal, 0 |OS_EventFlag_Shift |OS_EventFlag_Alt}},
{str8_lit_comp("dec_code_font_scale"), {OS_Key_Minus, 0 |OS_EventFlag_Shift |OS_EventFlag_Alt}},
{str8_lit_comp("window"), {OS_Key_N, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("toggle_fullscreen"), {OS_Key_Return, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("new_panel_right"), {OS_Key_P, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("new_panel_down"), {OS_Key_Minus, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("rotate_panel_columns"), {OS_Key_2, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("next_panel"), {OS_Key_Comma, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("prev_panel"), {OS_Key_Comma, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("focus_panel_right"), {OS_Key_Right, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
{str8_lit_comp("focus_panel_left"), {OS_Key_Left, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
{str8_lit_comp("focus_panel_up"), {OS_Key_Up, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
{str8_lit_comp("focus_panel_down"), {OS_Key_Down, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
{str8_lit_comp("close_panel"), {OS_Key_P, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("next_tab"), {OS_Key_PageDown, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("prev_tab"), {OS_Key_PageUp, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("next_tab"), {OS_Key_Tab, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("prev_tab"), {OS_Key_Tab, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_tab_right"), {OS_Key_PageDown, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_tab_left"), {OS_Key_PageUp, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("close_tab"), {OS_Key_W, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("tab_bar_top"), {OS_Key_Up, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}},
{str8_lit_comp("tab_bar_bottom"), {OS_Key_Down, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}},
{str8_lit_comp("open"), {OS_Key_O, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("reload_active"), {OS_Key_R, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("switch"), {OS_Key_I, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("switch_to_partner_file"), {OS_Key_O, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("load_user"), {OS_Key_O, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}},
{str8_lit_comp("load_profile"), {OS_Key_O, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}},
{str8_lit_comp("move_left"), {OS_Key_Left, 0 }},
{str8_lit_comp("move_right"), {OS_Key_Right, 0 }},
{str8_lit_comp("move_up"), {OS_Key_Up, 0 }},
{str8_lit_comp("move_down"), {OS_Key_Down, 0 }},
{str8_lit_comp("move_left_select"), {OS_Key_Left, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_right_select"), {OS_Key_Right, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_up_select"), {OS_Key_Up, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_down_select"), {OS_Key_Down, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_left_chunk"), {OS_Key_Left, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_right_chunk"), {OS_Key_Right, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_up_chunk"), {OS_Key_Up, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_down_chunk"), {OS_Key_Down, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_up_page"), {OS_Key_PageUp, 0 }},
{str8_lit_comp("move_down_page"), {OS_Key_PageDown, 0 }},
{str8_lit_comp("move_up_whole"), {OS_Key_Home, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_down_whole"), {OS_Key_End, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("move_left_chunk_select"), {OS_Key_Left, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_right_chunk_select"), {OS_Key_Right, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_up_chunk_select"), {OS_Key_Up, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_down_chunk_select"), {OS_Key_Down, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_up_page_select"), {OS_Key_PageUp, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_down_page_select"), {OS_Key_PageDown, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_up_whole_select"), {OS_Key_Home, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_down_whole_select"), {OS_Key_End, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }},
{str8_lit_comp("move_home"), {OS_Key_Home, 0 }},
{str8_lit_comp("move_end"), {OS_Key_End, 0 }},
{str8_lit_comp("move_home_select"), {OS_Key_Home, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("move_end_select"), {OS_Key_End, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("select_all"), {OS_Key_A, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("delete_single"), {OS_Key_Delete, 0 }},
{str8_lit_comp("delete_chunk"), {OS_Key_Delete, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("backspace_single"), {OS_Key_Backspace, 0 }},
{str8_lit_comp("backspace_chunk"), {OS_Key_Backspace, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("copy"), {OS_Key_C, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("cut"), {OS_Key_X, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("paste"), {OS_Key_V, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("insert_text"), {OS_Key_Null, 0 }},
{str8_lit_comp("goto_line"), {OS_Key_G, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("goto_address"), {OS_Key_G, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("find_text_forward"), {OS_Key_F, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("find_text_backward"), {OS_Key_R, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("find_next"), {OS_Key_F3, 0 }},
{str8_lit_comp("find_prev"), {OS_Key_F3, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("find_selected_thread"), {OS_Key_F4, 0 }},
{str8_lit_comp("goto_name"), {OS_Key_J, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("goto_name_at_cursor"), {OS_Key_F12, 0 }},
{str8_lit_comp("toggle_watch_expr_at_cursor"), {OS_Key_W, 0 |OS_EventFlag_Alt}},
{str8_lit_comp("toggle_watch_pin_at_cursor"), {OS_Key_F9, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("toggle_breakpoint_cursor"), {OS_Key_F9, 0 }},
{str8_lit_comp("add_target"), {OS_Key_T, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("attach"), {OS_Key_F6, 0 |OS_EventFlag_Shift }},
{str8_lit_comp("filter"), {OS_Key_Slash, 0 |OS_EventFlag_Ctrl }},
{str8_lit_comp("run_command"), {OS_Key_F1, 0 }},
};
String8 df_g_binding_version_remap_old_name_table[3] =
{
str8_lit_comp("commands"),
str8_lit_comp("load_user"),
str8_lit_comp("load_profile"),
};
String8 df_g_binding_version_remap_new_name_table[3] =
{
str8_lit_comp("run_command"),
str8_lit_comp("open_user"),
str8_lit_comp("open_profile"),
};
DF_GfxViewRuleSpecInfo df_g_gfx_view_rule_spec_info_table[14] =
{
{ str8_lit_comp("array"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, 0, 0, 0, 0 },
{ str8_lit_comp("list"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*1)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), DF_GFX_VIEW_RULE_VIZ_ROW_PROD_FUNCTION_NAME(list) , 0, 0, 0, 0 },
{ str8_lit_comp("dec"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(dec) , 0, 0, 0 },
{ str8_lit_comp("bin"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(bin) , 0, 0, 0 },
{ str8_lit_comp("oct"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(oct) , 0, 0, 0 },
{ str8_lit_comp("hex"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(hex) , 0, 0, 0 },
{ str8_lit_comp("only"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*1)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), DF_GFX_VIEW_RULE_VIZ_ROW_PROD_FUNCTION_NAME(only) , DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(only) , 0, 0, 0 },
{ str8_lit_comp("omit"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*1)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), DF_GFX_VIEW_RULE_VIZ_ROW_PROD_FUNCTION_NAME(omit) , DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(omit) , 0, 0, 0 },
{ str8_lit_comp("no_addr"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*1)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*0), 0, DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(no_addr) , 0, 0, 0 },
{ str8_lit_comp("rgba"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*1)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*1), 0, 0, DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_NAME(rgba) , DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(rgba) , 0 },
{ str8_lit_comp("text"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*1), 0, 0, 0, DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(text) , 0 },
{ str8_lit_comp("disasm"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*0)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*1), 0, 0, 0, DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(disasm) , 0 },
{ str8_lit_comp("bitmap"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*1)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*1), 0, 0, DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_NAME(bitmap) , DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(bitmap) , DF_GFX_VIEW_RULE_WHOLE_UI_FUNCTION_NAME(bitmap) },
{ str8_lit_comp("geo"), (DF_GfxViewRuleSpecInfoFlag_VizRowProd*0)|(DF_GfxViewRuleSpecInfoFlag_LineStringize*0)|(DF_GfxViewRuleSpecInfoFlag_RowUI*1)|(DF_GfxViewRuleSpecInfoFlag_BlockUI*1), 0, 0, DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_NAME(geo) , DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(geo) , 0 },
};
DF_ViewSpecInfo df_g_gfx_view_kind_spec_info_table[30] =
{
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("null"), str8_lit_comp(""), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(Null), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Null), DF_VIEW_CMD_FUNCTION_NAME(Null), DF_VIEW_UI_FUNCTION_NAME(Null)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("empty"), str8_lit_comp(""), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(Empty), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Empty), DF_VIEW_CMD_FUNCTION_NAME(Empty), DF_VIEW_UI_FUNCTION_NAME(Empty)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("commands"), str8_lit_comp("Commands"), DF_NameKind_Null, DF_IconKind_List, DF_VIEW_SETUP_FUNCTION_NAME(Commands), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Commands), DF_VIEW_CMD_FUNCTION_NAME(Commands), DF_VIEW_UI_FUNCTION_NAME(Commands)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("file_system"), str8_lit_comp("File System"), DF_NameKind_Null, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(FileSystem), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(FileSystem), DF_VIEW_CMD_FUNCTION_NAME(FileSystem), DF_VIEW_UI_FUNCTION_NAME(FileSystem)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("system_processes"), str8_lit_comp("System Processes"), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(SystemProcesses), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(SystemProcesses), DF_VIEW_CMD_FUNCTION_NAME(SystemProcesses), DF_VIEW_UI_FUNCTION_NAME(SystemProcesses)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("entity_lister"), str8_lit_comp("Entity List"), DF_NameKind_EntityKindName, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(EntityLister), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(EntityLister), DF_VIEW_CMD_FUNCTION_NAME(EntityLister), DF_VIEW_UI_FUNCTION_NAME(EntityLister)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("symbol_lister"), str8_lit_comp("Symbols"), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(SymbolLister), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(SymbolLister), DF_VIEW_CMD_FUNCTION_NAME(SymbolLister), DF_VIEW_UI_FUNCTION_NAME(SymbolLister)},
{(0|1*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("target"), str8_lit_comp("Target"), DF_NameKind_EntityName, DF_IconKind_Target, DF_VIEW_SETUP_FUNCTION_NAME(Target), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Target), DF_VIEW_CMD_FUNCTION_NAME(Target), DF_VIEW_UI_FUNCTION_NAME(Target)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("targets"), str8_lit_comp("Targets"), DF_NameKind_Null, DF_IconKind_Target, DF_VIEW_SETUP_FUNCTION_NAME(Targets), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Targets), DF_VIEW_CMD_FUNCTION_NAME(Targets), DF_VIEW_UI_FUNCTION_NAME(Targets)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("file_path_map"), str8_lit_comp("File Path Map"), DF_NameKind_Null, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(FilePathMap), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(FilePathMap), DF_VIEW_CMD_FUNCTION_NAME(FilePathMap), DF_VIEW_UI_FUNCTION_NAME(FilePathMap)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("scheduler"), str8_lit_comp("Scheduler"), DF_NameKind_Null, DF_IconKind_Scheduler, DF_VIEW_SETUP_FUNCTION_NAME(Scheduler), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Scheduler), DF_VIEW_CMD_FUNCTION_NAME(Scheduler), DF_VIEW_UI_FUNCTION_NAME(Scheduler)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("call_stack"), str8_lit_comp("Call Stack"), DF_NameKind_Null, DF_IconKind_Thread, DF_VIEW_SETUP_FUNCTION_NAME(CallStack), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(CallStack), DF_VIEW_CMD_FUNCTION_NAME(CallStack), DF_VIEW_UI_FUNCTION_NAME(CallStack)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("modules"), str8_lit_comp("Modules"), DF_NameKind_Null, DF_IconKind_Module, DF_VIEW_SETUP_FUNCTION_NAME(Modules), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Modules), DF_VIEW_CMD_FUNCTION_NAME(Modules), DF_VIEW_UI_FUNCTION_NAME(Modules)},
{(0|1*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("pending_entity"), str8_lit_comp("Pending Entity"), DF_NameKind_EntityName, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(PendingEntity), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(PendingEntity), DF_VIEW_CMD_FUNCTION_NAME(PendingEntity), DF_VIEW_UI_FUNCTION_NAME(PendingEntity)},
{(0|1*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|1*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("code"), str8_lit_comp("Code"), DF_NameKind_EntityName, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(Code), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Code), DF_VIEW_CMD_FUNCTION_NAME(Code), DF_VIEW_UI_FUNCTION_NAME(Code)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("disassembly"), str8_lit_comp("Disassembly"), DF_NameKind_Null, DF_IconKind_Glasses, DF_VIEW_SETUP_FUNCTION_NAME(Disassembly), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Disassembly), DF_VIEW_CMD_FUNCTION_NAME(Disassembly), DF_VIEW_UI_FUNCTION_NAME(Disassembly)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("eval_viewer"), str8_lit_comp("Evaluation Viewer"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(EvalViewer), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(EvalViewer), DF_VIEW_CMD_FUNCTION_NAME(EvalViewer), DF_VIEW_UI_FUNCTION_NAME(EvalViewer)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("watch"), str8_lit_comp("Watch"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Watch), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Watch), DF_VIEW_CMD_FUNCTION_NAME(Watch), DF_VIEW_UI_FUNCTION_NAME(Watch)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("locals"), str8_lit_comp("Locals"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Locals), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Locals), DF_VIEW_CMD_FUNCTION_NAME(Locals), DF_VIEW_UI_FUNCTION_NAME(Locals)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("registers"), str8_lit_comp("Registers"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Registers), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Registers), DF_VIEW_CMD_FUNCTION_NAME(Registers), DF_VIEW_UI_FUNCTION_NAME(Registers)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("globals"), str8_lit_comp("Globals"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Globals), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Globals), DF_VIEW_CMD_FUNCTION_NAME(Globals), DF_VIEW_UI_FUNCTION_NAME(Globals)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("thread_locals"), str8_lit_comp("Thread Locals"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(ThreadLocals), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(ThreadLocals), DF_VIEW_CMD_FUNCTION_NAME(ThreadLocals), DF_VIEW_UI_FUNCTION_NAME(ThreadLocals)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("types"), str8_lit_comp("Types"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Types), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Types), DF_VIEW_CMD_FUNCTION_NAME(Types), DF_VIEW_UI_FUNCTION_NAME(Types)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("procedures"), str8_lit_comp("Procedures"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Procedures), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Procedures), DF_VIEW_CMD_FUNCTION_NAME(Procedures), DF_VIEW_UI_FUNCTION_NAME(Procedures)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("output"), str8_lit_comp("Output"), DF_NameKind_Null, DF_IconKind_List, DF_VIEW_SETUP_FUNCTION_NAME(Output), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Output), DF_VIEW_CMD_FUNCTION_NAME(Output), DF_VIEW_UI_FUNCTION_NAME(Output)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|1*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("memory"), str8_lit_comp("Memory"), DF_NameKind_Null, DF_IconKind_Grid, DF_VIEW_SETUP_FUNCTION_NAME(Memory), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Memory), DF_VIEW_CMD_FUNCTION_NAME(Memory), DF_VIEW_UI_FUNCTION_NAME(Memory)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("breakpoints"), str8_lit_comp("Breakpoints"), DF_NameKind_Null, DF_IconKind_CircleFilled, DF_VIEW_SETUP_FUNCTION_NAME(Breakpoints), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Breakpoints), DF_VIEW_CMD_FUNCTION_NAME(Breakpoints), DF_VIEW_UI_FUNCTION_NAME(Breakpoints)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("watch_pins"), str8_lit_comp("Watch Pins"), DF_NameKind_Null, DF_IconKind_Pin, DF_VIEW_SETUP_FUNCTION_NAME(WatchPins), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(WatchPins), DF_VIEW_CMD_FUNCTION_NAME(WatchPins), DF_VIEW_UI_FUNCTION_NAME(WatchPins)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("exception_filters"), str8_lit_comp("Exception Filters"), DF_NameKind_Null, DF_IconKind_Gear, DF_VIEW_SETUP_FUNCTION_NAME(ExceptionFilters), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(ExceptionFilters), DF_VIEW_CMD_FUNCTION_NAME(ExceptionFilters), DF_VIEW_UI_FUNCTION_NAME(ExceptionFilters)},
{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("theme"), str8_lit_comp("Theme"), DF_NameKind_Null, DF_IconKind_Palette, DF_VIEW_SETUP_FUNCTION_NAME(Theme), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Theme), DF_VIEW_CMD_FUNCTION_NAME(Theme), DF_VIEW_UI_FUNCTION_NAME(Theme)},
};
String8 df_g_theme_color_display_string_table[54] =
{
str8_lit_comp("Null"),
str8_lit_comp("Plain Text"),
str8_lit_comp("Plain Background"),
str8_lit_comp("Plain Border"),
str8_lit_comp("Plain Overlay"),
str8_lit_comp("Code (Default)"),
str8_lit_comp("Code (Function)"),
str8_lit_comp("Code (Type)"),
str8_lit_comp("Code (Local)"),
str8_lit_comp("Code (Register)"),
str8_lit_comp("Code (Keyword)"),
str8_lit_comp("Code (Symbol)"),
str8_lit_comp("Code (Numeric)"),
str8_lit_comp("Code (String)"),
str8_lit_comp("Code (Meta)"),
str8_lit_comp("Code (Comment)"),
str8_lit_comp("Line Info (0)"),
str8_lit_comp("Line Info (1)"),
str8_lit_comp("Line Info (2)"),
str8_lit_comp("Line Info (3)"),
str8_lit_comp("Alt Text"),
str8_lit_comp("Alt Background"),
str8_lit_comp("Alt Border"),
str8_lit_comp("Alt Overlay"),
str8_lit_comp("Inactive Tab"),
str8_lit_comp("Active Tab"),
str8_lit_comp("Entity Background"),
str8_lit_comp("Query Bar"),
str8_lit_comp("Weak Text"),
str8_lit_comp("Text Selection"),
str8_lit_comp("Cursor"),
str8_lit_comp("Highlight (0)"),
str8_lit_comp("Highlight (1)"),
str8_lit_comp("Success Text"),
str8_lit_comp("Success Background"),
str8_lit_comp("Success Border"),
str8_lit_comp("Failure Text"),
str8_lit_comp("Failure Background"),
str8_lit_comp("Failure Border"),
str8_lit_comp("Action Text"),
str8_lit_comp("Action Background"),
str8_lit_comp("Action Border"),
str8_lit_comp("Drop Site Overlay"),
str8_lit_comp("Thread (0)"),
str8_lit_comp("Thread (1)"),
str8_lit_comp("Thread (2)"),
str8_lit_comp("Thread (3)"),
str8_lit_comp("Thread (4)"),
str8_lit_comp("Thread (5)"),
str8_lit_comp("Thread (6)"),
str8_lit_comp("Thread (7)"),
str8_lit_comp("Thread (Unwound)"),
str8_lit_comp("Inactive Panel Overlay"),
str8_lit_comp("Drop Shadow"),
};
String8 df_g_theme_color_cfg_string_table[54] =
{
str8_lit_comp("null"),
str8_lit_comp("plain_text"),
str8_lit_comp("plain_background"),
str8_lit_comp("plain_border"),
str8_lit_comp("plain_overlay"),
str8_lit_comp("code_default"),
str8_lit_comp("code_function"),
str8_lit_comp("code_type"),
str8_lit_comp("code_local"),
str8_lit_comp("code_register"),
str8_lit_comp("code_keyword"),
str8_lit_comp("code_symbol"),
str8_lit_comp("code_numeric"),
str8_lit_comp("code_string"),
str8_lit_comp("code_meta"),
str8_lit_comp("code_comment"),
str8_lit_comp("line_info_0"),
str8_lit_comp("line_info_1"),
str8_lit_comp("line_info_2"),
str8_lit_comp("line_info_3"),
str8_lit_comp("alt_text"),
str8_lit_comp("alt_background"),
str8_lit_comp("alt_border"),
str8_lit_comp("alt_overlay"),
str8_lit_comp("tab_inactive"),
str8_lit_comp("tab_active"),
str8_lit_comp("entity_background"),
str8_lit_comp("query_bar"),
str8_lit_comp("weak_text"),
str8_lit_comp("text_selection"),
str8_lit_comp("cursor"),
str8_lit_comp("highlight_0"),
str8_lit_comp("highlight_1"),
str8_lit_comp("success_text"),
str8_lit_comp("success_background"),
str8_lit_comp("success_border"),
str8_lit_comp("failure_text"),
str8_lit_comp("failure_background"),
str8_lit_comp("failure_border"),
str8_lit_comp("action_text"),
str8_lit_comp("action_background"),
str8_lit_comp("action_border"),
str8_lit_comp("drop_site_overlay"),
str8_lit_comp("thread_0"),
str8_lit_comp("thread_1"),
str8_lit_comp("thread_2"),
str8_lit_comp("thread_3"),
str8_lit_comp("thread_4"),
str8_lit_comp("thread_5"),
str8_lit_comp("thread_6"),
str8_lit_comp("thread_7"),
str8_lit_comp("thread_unwound"),
str8_lit_comp("inactive_panel_overlay"),
str8_lit_comp("drop_shadow"),
};
C_LINKAGE_END
+142 -247
View File
@@ -4,24 +4,24 @@
//////////////////////////////// ////////////////////////////////
//~ rjf: Generated Code //~ rjf: Generated Code
#define D_StackPushImpl(name_upper, name_lower, type, val) \ #define DR_StackPushImpl(name_upper, name_lower, type, val) \
D_Bucket *bucket = d_top_bucket();\ DR_Bucket *bucket = dr_top_bucket();\
type old_val = bucket->top_##name_lower->v;\ type old_val = bucket->top_##name_lower->v;\
D_##name_upper##Node *node = push_array(d_thread_ctx->arena, D_##name_upper##Node, 1);\ DR_##name_upper##Node *node = push_array(dr_thread_ctx->arena, DR_##name_upper##Node, 1);\
node->v = (val);\ node->v = (val);\
SLLStackPush(bucket->top_##name_lower, node);\ SLLStackPush(bucket->top_##name_lower, node);\
bucket->stack_gen += 1;\ bucket->stack_gen += 1;\
return old_val return old_val
#define D_StackPopImpl(name_upper, name_lower, type) \ #define DR_StackPopImpl(name_upper, name_lower, type) \
D_Bucket *bucket = d_top_bucket();\ DR_Bucket *bucket = dr_top_bucket();\
type popped_val = bucket->top_##name_lower->v;\ type popped_val = bucket->top_##name_lower->v;\
SLLStackPop(bucket->top_##name_lower);\ SLLStackPop(bucket->top_##name_lower);\
bucket->stack_gen += 1;\ bucket->stack_gen += 1;\
return popped_val return popped_val
#define D_StackTopImpl(name_upper, name_lower, type) \ #define DR_StackTopImpl(name_upper, name_lower, type) \
D_Bucket *bucket = d_top_bucket();\ DR_Bucket *bucket = dr_top_bucket();\
type top_val = bucket->top_##name_lower->v;\ type top_val = bucket->top_##name_lower->v;\
return top_val return top_val
@@ -31,7 +31,7 @@ return top_val
//~ rjf: Basic Helpers //~ rjf: Basic Helpers
internal U64 internal U64
d_hash_from_string(String8 string) dr_hash_from_string(String8 string)
{ {
U64 result = 5381; U64 result = 5381;
for(U64 i = 0; i < string.size; i += 1) for(U64 i = 0; i < string.size; i += 1)
@@ -45,23 +45,40 @@ d_hash_from_string(String8 string)
//~ rjf: Fancy String Type Functions //~ rjf: Fancy String Type Functions
internal void internal void
d_fancy_string_list_push(Arena *arena, D_FancyStringList *list, D_FancyString *str) dr_fancy_string_list_push(Arena *arena, DR_FancyStringList *list, DR_FancyString *str)
{ {
D_FancyStringNode *n = push_array_no_zero(arena, D_FancyStringNode, 1); DR_FancyStringNode *n = push_array_no_zero(arena, DR_FancyStringNode, 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;
list->total_size += str->string.size; list->total_size += str->string.size;
} }
internal void
dr_fancy_string_list_concat_in_place(DR_FancyStringList *dst, DR_FancyStringList *to_push)
{
if(dst->last != 0 && to_push->first != 0)
{
dst->last->next = to_push->first;
dst->last = to_push->last;
dst->node_count += to_push->node_count;
dst->total_size += to_push->total_size;
}
else if(to_push->first != 0)
{
MemoryCopyStruct(dst, to_push);
}
MemoryZeroStruct(to_push);
}
internal String8 internal String8
d_string_from_fancy_string_list(Arena *arena, D_FancyStringList *list) dr_string_from_fancy_string_list(Arena *arena, DR_FancyStringList *list)
{ {
String8 result = {0}; String8 result = {0};
result.size = list->total_size; result.size = list->total_size;
result.str = push_array_no_zero(arena, U8, result.size); result.str = push_array_no_zero(arena, U8, result.size);
U64 idx = 0; U64 idx = 0;
for(D_FancyStringNode *n = list->first; n != 0; n = n->next) for(DR_FancyStringNode *n = list->first; n != 0; n = n->next)
{ {
MemoryCopy(result.str+idx, n->v.string.str, n->v.string.size); MemoryCopy(result.str+idx, n->v.string.str, n->v.string.size);
idx += n->v.string.size; idx += n->v.string.size;
@@ -69,15 +86,16 @@ d_string_from_fancy_string_list(Arena *arena, D_FancyStringList *list)
return result; return result;
} }
internal D_FancyRunList internal DR_FancyRunList
d_fancy_run_list_from_fancy_string_list(Arena *arena, D_FancyStringList *strs) dr_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, FNT_RasterFlags flags, DR_FancyStringList *strs)
{ {
ProfBeginFunction(); ProfBeginFunction();
D_FancyRunList run_list = {0}; DR_FancyRunList run_list = {0};
for(D_FancyStringNode *n = strs->first; n != 0; n = n->next) F32 base_align_px = 0;
for(DR_FancyStringNode *n = strs->first; n != 0; n = n->next)
{ {
D_FancyRunNode *dst_n = push_array(arena, D_FancyRunNode, 1); DR_FancyRunNode *dst_n = push_array(arena, DR_FancyRunNode, 1);
dst_n->v.run = f_push_run_from_string(arena, n->v.font, n->v.size, 0, n->v.string); 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.color = n->v.color; dst_n->v.color = n->v.color;
dst_n->v.underline_thickness = n->v.underline_thickness; dst_n->v.underline_thickness = n->v.underline_thickness;
dst_n->v.strikethrough_thickness = n->v.strikethrough_thickness; dst_n->v.strikethrough_thickness = n->v.strikethrough_thickness;
@@ -85,21 +103,22 @@ d_fancy_run_list_from_fancy_string_list(Arena *arena, D_FancyStringList *strs)
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;
run_list.dim.y = Max(run_list.dim.y, dst_n->v.run.dim.y); run_list.dim.y = Max(run_list.dim.y, dst_n->v.run.dim.y);
base_align_px += dst_n->v.run.dim.x;
} }
ProfEnd(); ProfEnd();
return run_list; return run_list;
} }
internal D_FancyRunList internal DR_FancyRunList
d_fancy_run_list_copy(Arena *arena, D_FancyRunList *src) dr_fancy_run_list_copy(Arena *arena, DR_FancyRunList *src)
{ {
D_FancyRunList dst = {0}; DR_FancyRunList dst = {0};
for(D_FancyRunNode *src_n = src->first; src_n != 0; src_n = src_n->next) for(DR_FancyRunNode *src_n = src->first; src_n != 0; src_n = src_n->next)
{ {
D_FancyRunNode *dst_n = push_array(arena, D_FancyRunNode, 1); DR_FancyRunNode *dst_n = push_array(arena, DR_FancyRunNode, 1);
SLLQueuePush(dst.first, dst.last, dst_n); SLLQueuePush(dst.first, dst.last, dst_n);
MemoryCopyStruct(&dst_n->v, &src_n->v); MemoryCopyStruct(&dst_n->v, &src_n->v);
dst_n->v.run.pieces = f_piece_array_copy(arena, &src_n->v.run.pieces); dst_n->v.run.pieces = fnt_piece_array_copy(arena, &src_n->v.run.pieces);
dst.node_count += 1; dst.node_count += 1;
} }
dst.dim = src->dim; dst.dim = src->dim;
@@ -112,22 +131,22 @@ d_fancy_run_list_copy(Arena *arena, D_FancyRunList *src)
// (Frame boundaries) // (Frame boundaries)
internal void internal void
d_begin_frame(void) dr_begin_frame(void)
{ {
if(d_thread_ctx == 0) if(dr_thread_ctx == 0)
{ {
Arena *arena = arena_alloc__sized(GB(64), MB(8)); Arena *arena = arena_alloc(.reserve_size = GB(64), .commit_size = MB(8));
d_thread_ctx = push_array(arena, D_ThreadCtx, 1); dr_thread_ctx = push_array(arena, DR_ThreadCtx, 1);
d_thread_ctx->arena = arena; dr_thread_ctx->arena = arena;
d_thread_ctx->arena_frame_start_pos = arena_pos(arena); dr_thread_ctx->arena_frame_start_pos = arena_pos(arena);
} }
arena_pop_to(d_thread_ctx->arena, d_thread_ctx->arena_frame_start_pos); arena_pop_to(dr_thread_ctx->arena, dr_thread_ctx->arena_frame_start_pos);
d_thread_ctx->free_bucket_selection = 0; dr_thread_ctx->free_bucket_selection = 0;
d_thread_ctx->top_bucket = 0; dr_thread_ctx->top_bucket = 0;
} }
internal void internal void
d_submit_bucket(OS_Handle os_window, R_Handle r_window, D_Bucket *bucket) dr_submit_bucket(OS_Handle os_window, R_Handle r_window, DR_Bucket *bucket)
{ {
r_window_submit(os_window, r_window, &bucket->passes); r_window_submit(os_window, r_window, &bucket->passes);
} }
@@ -137,45 +156,45 @@ d_submit_bucket(OS_Handle os_window, R_Handle r_window, D_Bucket *bucket)
// //
// (Bucket: Handle to sequence of many render passes, constructed by this layer) // (Bucket: Handle to sequence of many render passes, constructed by this layer)
internal D_Bucket * internal DR_Bucket *
d_bucket_make(void) dr_bucket_make(void)
{ {
D_Bucket *bucket = push_array(d_thread_ctx->arena, D_Bucket, 1); DR_Bucket *bucket = push_array(dr_thread_ctx->arena, DR_Bucket, 1);
D_BucketStackInits(bucket); DR_BucketStackInits(bucket);
return bucket; return bucket;
} }
internal void internal void
d_push_bucket(D_Bucket *bucket) dr_push_bucket(DR_Bucket *bucket)
{ {
D_BucketSelectionNode *node = d_thread_ctx->free_bucket_selection; DR_BucketSelectionNode *node = dr_thread_ctx->free_bucket_selection;
if(node) if(node)
{ {
SLLStackPop(d_thread_ctx->free_bucket_selection); SLLStackPop(dr_thread_ctx->free_bucket_selection);
} }
else else
{ {
node = push_array(d_thread_ctx->arena, D_BucketSelectionNode, 1); node = push_array(dr_thread_ctx->arena, DR_BucketSelectionNode, 1);
} }
SLLStackPush(d_thread_ctx->top_bucket, node); SLLStackPush(dr_thread_ctx->top_bucket, node);
node->bucket = bucket; node->bucket = bucket;
} }
internal void internal void
d_pop_bucket(void) dr_pop_bucket(void)
{ {
D_BucketSelectionNode *node = d_thread_ctx->top_bucket; DR_BucketSelectionNode *node = dr_thread_ctx->top_bucket;
SLLStackPop(d_thread_ctx->top_bucket); SLLStackPop(dr_thread_ctx->top_bucket);
SLLStackPush(d_thread_ctx->free_bucket_selection, node); SLLStackPush(dr_thread_ctx->free_bucket_selection, node);
} }
internal D_Bucket * internal DR_Bucket *
d_top_bucket(void) dr_top_bucket(void)
{ {
D_Bucket *bucket = 0; DR_Bucket *bucket = 0;
if(d_thread_ctx->top_bucket != 0) if(dr_thread_ctx->top_bucket != 0)
{ {
bucket = d_thread_ctx->top_bucket->bucket; bucket = dr_thread_ctx->top_bucket->bucket;
} }
return bucket; return bucket;
} }
@@ -195,10 +214,10 @@ d_top_bucket(void)
//- rjf: rectangles //- rjf: rectangles
internal inline R_Rect2DInst * internal inline R_Rect2DInst *
d_rect(Rng2F32 dst, Vec4F32 color, F32 corner_radius, F32 border_thickness, F32 edge_softness) dr_rect(Rng2F32 dst, Vec4F32 color, F32 corner_radius, F32 border_thickness, F32 edge_softness)
{ {
Arena *arena = d_thread_ctx->arena; Arena *arena = dr_thread_ctx->arena;
D_Bucket *bucket = d_top_bucket(); DR_Bucket *bucket = dr_top_bucket();
R_Pass *pass = r_pass_from_kind(arena, &bucket->passes, R_PassKind_UI); R_Pass *pass = r_pass_from_kind(arena, &bucket->passes, R_PassKind_UI);
R_PassParams_UI *params = pass->params_ui; R_PassParams_UI *params = pass->params_ui;
R_BatchGroup2DList *rects = &params->rects; R_BatchGroup2DList *rects = &params->rects;
@@ -236,10 +255,10 @@ d_rect(Rng2F32 dst, Vec4F32 color, F32 corner_radius, F32 border_thickness, F32
//- rjf: images //- rjf: images
internal inline R_Rect2DInst * internal inline R_Rect2DInst *
d_img(Rng2F32 dst, Rng2F32 src, R_Handle texture, Vec4F32 color, F32 corner_radius, F32 border_thickness, F32 edge_softness) dr_img(Rng2F32 dst, Rng2F32 src, R_Handle texture, Vec4F32 color, F32 corner_radius, F32 border_thickness, F32 edge_softness)
{ {
Arena *arena = d_thread_ctx->arena; Arena *arena = dr_thread_ctx->arena;
D_Bucket *bucket = d_top_bucket(); DR_Bucket *bucket = dr_top_bucket();
R_Pass *pass = r_pass_from_kind(arena, &bucket->passes, R_PassKind_UI); R_Pass *pass = r_pass_from_kind(arena, &bucket->passes, R_PassKind_UI);
R_PassParams_UI *params = pass->params_ui; R_PassParams_UI *params = pass->params_ui;
R_BatchGroup2DList *rects = &params->rects; R_BatchGroup2DList *rects = &params->rects;
@@ -281,13 +300,14 @@ d_img(Rng2F32 dst, Rng2F32 src, R_Handle texture, Vec4F32 color, F32 corner_radi
//- rjf: blurs //- rjf: blurs
internal R_PassParams_Blur * internal R_PassParams_Blur *
d_blur(Rng2F32 rect, F32 blur_size, F32 corner_radius) dr_blur(Rng2F32 rect, F32 blur_size, F32 corner_radius)
{ {
Arena *arena = d_thread_ctx->arena; Arena *arena = dr_thread_ctx->arena;
D_Bucket *bucket = d_top_bucket(); DR_Bucket *bucket = dr_top_bucket();
R_Pass *pass = r_pass_from_kind(arena, &bucket->passes, R_PassKind_Blur); R_Pass *pass = r_pass_from_kind(arena, &bucket->passes, R_PassKind_Blur);
R_PassParams_Blur *params = pass->params_blur; R_PassParams_Blur *params = pass->params_blur;
params->rect = rect; params->rect = rect;
params->clip = dr_top_clip();
params->blur_size = blur_size; params->blur_size = blur_size;
params->corner_radii[Corner_00] = corner_radius; params->corner_radii[Corner_00] = corner_radius;
params->corner_radii[Corner_01] = corner_radius; params->corner_radii[Corner_01] = corner_radius;
@@ -299,10 +319,10 @@ d_blur(Rng2F32 rect, F32 blur_size, F32 corner_radius)
//- rjf: 3d rendering pass params //- rjf: 3d rendering pass params
internal R_PassParams_Geo3D * internal R_PassParams_Geo3D *
d_geo3d_begin(Rng2F32 viewport, Mat4x4F32 view, Mat4x4F32 projection) dr_geo3d_begin(Rng2F32 viewport, Mat4x4F32 view, Mat4x4F32 projection)
{ {
Arena *arena = d_thread_ctx->arena; Arena *arena = dr_thread_ctx->arena;
D_Bucket *bucket = d_top_bucket(); DR_Bucket *bucket = dr_top_bucket();
R_Pass *pass = r_pass_from_kind(arena, &bucket->passes, R_PassKind_Geo3D); R_Pass *pass = r_pass_from_kind(arena, &bucket->passes, R_PassKind_Geo3D);
R_PassParams_Geo3D *params = pass->params_geo3d; R_PassParams_Geo3D *params = pass->params_geo3d;
params->viewport = viewport; params->viewport = viewport;
@@ -314,10 +334,10 @@ d_geo3d_begin(Rng2F32 viewport, Mat4x4F32 view, Mat4x4F32 projection)
//- rjf: meshes //- rjf: meshes
internal R_Mesh3DInst * internal R_Mesh3DInst *
d_mesh(R_Handle mesh_vertices, R_Handle mesh_indices, R_GeoTopologyKind mesh_geo_topology, R_GeoVertexFlags mesh_geo_vertex_flags, R_Handle albedo_tex, Mat4x4F32 inst_xform) dr_mesh(R_Handle mesh_vertices, R_Handle mesh_indices, R_GeoTopologyKind mesh_geo_topology, R_GeoVertexFlags mesh_geo_vertex_flags, R_Handle albedo_tex, Mat4x4F32 inst_xform)
{ {
Arena *arena = d_thread_ctx->arena; Arena *arena = dr_thread_ctx->arena;
D_Bucket *bucket = d_top_bucket(); DR_Bucket *bucket = dr_top_bucket();
R_Pass *pass = r_pass_from_kind(arena, &bucket->passes, R_PassKind_Geo3D); R_Pass *pass = r_pass_from_kind(arena, &bucket->passes, R_PassKind_Geo3D);
R_PassParams_Geo3D *params = pass->params_geo3d; R_PassParams_Geo3D *params = pass->params_geo3d;
@@ -342,9 +362,9 @@ d_mesh(R_Handle mesh_vertices, R_Handle mesh_indices, R_GeoTopologyKind mesh_geo
(U64)mesh_geo_vertex_flags, (U64)mesh_geo_vertex_flags,
albedo_tex.u64[0], albedo_tex.u64[0],
albedo_tex.u64[1], albedo_tex.u64[1],
(U64)d_top_tex2d_sample_kind(), (U64)dr_top_tex2d_sample_kind(),
}; };
hash = d_hash_from_string(str8((U8 *)buffer, sizeof(buffer))); hash = dr_hash_from_string(str8((U8 *)buffer, sizeof(buffer)));
slot_idx = hash%params->mesh_batches.slots_count; slot_idx = hash%params->mesh_batches.slots_count;
} }
@@ -373,7 +393,7 @@ d_mesh(R_Handle mesh_vertices, R_Handle mesh_indices, R_GeoTopologyKind mesh_geo
node->params.mesh_geo_topology = mesh_geo_topology; node->params.mesh_geo_topology = mesh_geo_topology;
node->params.mesh_geo_vertex_flags = mesh_geo_vertex_flags; node->params.mesh_geo_vertex_flags = mesh_geo_vertex_flags;
node->params.albedo_tex = albedo_tex; node->params.albedo_tex = albedo_tex;
node->params.albedo_tex_sample_kind = d_top_tex2d_sample_kind(); node->params.albedo_tex_sample_kind = dr_top_tex2d_sample_kind();
node->params.xform = mat_4x4f32(1.f); node->params.xform = mat_4x4f32(1.f);
} }
@@ -386,12 +406,12 @@ d_mesh(R_Handle mesh_vertices, R_Handle mesh_indices, R_GeoTopologyKind mesh_geo
//- rjf: collating one pre-prepped bucket into parent bucket //- rjf: collating one pre-prepped bucket into parent bucket
internal void internal void
d_sub_bucket(D_Bucket *bucket) dr_sub_bucket(DR_Bucket *bucket)
{ {
Arena *arena = d_thread_ctx->arena; Arena *arena = dr_thread_ctx->arena;
D_Bucket *src = bucket; DR_Bucket *src = bucket;
D_Bucket *dst = d_top_bucket(); DR_Bucket *dst = dr_top_bucket();
Rng2F32 dst_clip = d_top_clip(); Rng2F32 dst_clip = dr_top_clip();
B32 dst_clip_is_set = !(dst_clip.x0 == 0 && dst_clip.x1 == 0 && B32 dst_clip_is_set = !(dst_clip.x0 == 0 && dst_clip.x1 == 0 &&
dst_clip.y0 == 0 && dst_clip.y1 == 0); dst_clip.y0 == 0 && dst_clip.y1 == 0);
for(R_PassNode *n = src->passes.first; n != 0; n = n->next) for(R_PassNode *n = src->passes.first; n != 0; n = n->next)
@@ -414,7 +434,7 @@ d_sub_bucket(D_Bucket *bucket)
dst_ui->rects.count += 1; dst_ui->rects.count += 1;
MemoryCopyStruct(&dst_group_n->params, &src_group_n->params); MemoryCopyStruct(&dst_group_n->params, &src_group_n->params);
dst_group_n->batches = src_group_n->batches; dst_group_n->batches = src_group_n->batches;
dst_group_n->params.xform = d_top_xform2d(); dst_group_n->params.xform = dr_top_xform2d();
if(dst_clip_is_set) if(dst_clip_is_set)
{ {
B32 clip_is_set = !(dst_group_n->params.clip.x0 == 0 && B32 clip_is_set = !(dst_group_n->params.clip.x0 == 0 &&
@@ -435,35 +455,40 @@ d_sub_bucket(D_Bucket *bucket)
//- rjf: text //- rjf: text
internal void internal void
d_truncated_fancy_run_list(Vec2F32 p, D_FancyRunList *list, F32 max_x, F_Run trailer_run) dr_truncated_fancy_run_list(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FNT_Run trailer_run)
{ {
ProfBeginFunction(); ProfBeginFunction();
//- rjf: total advance > max? -> enable trailer //- rjf: total advance > max? -> enable trailer
B32 trailer_enabled = (list->dim.x >= max_x && trailer_run.dim.x < max_x); B32 trailer_enabled = (list->dim.x > max_x && trailer_run.dim.x < max_x);
//- rjf: draw runs //- rjf: draw runs
F32 advance = 0; F32 advance = 0;
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(D_FancyRunNode *n = list->first; n != 0; n = n->next) for(DR_FancyRunNode *n = list->first; n != 0; n = n->next)
{ {
D_FancyRun *fr = &n->v; DR_FancyRun *fr = &n->v;
F_Piece *piece_first = fr->run.pieces.v; Rng1F32 pixel_range = {0};
F_Piece *piece_opl = piece_first + fr->run.pieces.count; {
pixel_range.min = 100000;
pixel_range.max = 0;
}
FNT_Piece *piece_first = fr->run.pieces.v;
FNT_Piece *piece_opl = piece_first + fr->run.pieces.count;
F32 pre_advance = advance; F32 pre_advance = advance;
last_color = fr->color; last_color = fr->color;
for(F_Piece *piece = piece_first; for(FNT_Piece *piece = piece_first;
piece < piece_opl; piece < piece_opl;
piece += 1) piece += 1)
{ {
if(trailer_enabled && advance + piece->advance >= (max_x - trailer_run.dim.x)) if(trailer_enabled && advance + piece->advance > (max_x - trailer_run.dim.x))
{ {
trailer_found = 1; trailer_found = 1;
break; break;
} }
if(!trailer_enabled && advance + piece->advance >= max_x) if(!trailer_enabled && advance + piece->advance > max_x)
{ {
goto end_draw; goto end_draw;
} }
@@ -476,22 +501,24 @@ d_truncated_fancy_run_list(Vec2F32 p, D_FancyRunList *list, F32 max_x, F_Run tra
p.y + piece->offset.y + size.y); p.y + piece->offset.y + size.y);
if(!r_handle_match(texture, r_handle_zero())) if(!r_handle_match(texture, r_handle_zero()))
{ {
d_img(dst, src, texture, fr->color, 0, 0, 0); dr_img(dst, src, texture, fr->color, 0, 0, 0);
//d_rect(dst, v4f32(1, 0, 0, 1), 0, 1.f, 0.f); //dr_rect(dst, v4f32(0, 1, 0, 0.5f), 0, 1.f, 0.f);
} }
advance += piece->advance; advance += piece->advance;
pixel_range.min = Min(pre_advance, pixel_range.min);
pixel_range.max = Max(advance, pixel_range.max);
} }
if(fr->underline_thickness > 0) if(fr->underline_thickness > 0)
{ {
d_rect(r2f32p(p.x+pre_advance, dr_rect(r2f32p(p.x + pixel_range.min,
p.y+fr->run.descent+fr->run.descent/8, p.y+fr->run.descent+fr->run.descent/8,
p.x+advance + (advance-pre_advance)/8, p.x + pixel_range.max,
p.y+fr->run.descent+fr->run.descent/8+fr->underline_thickness), p.y+fr->run.descent+fr->run.descent/8+fr->underline_thickness),
fr->color, 0, 0, 1.f); fr->color, 0, 0, 0.8f);
} }
if(fr->strikethrough_thickness > 0) if(fr->strikethrough_thickness > 0)
{ {
d_rect(r2f32p(p.x+pre_advance, p.y+fr->run.descent - fr->run.ascent/2, p.x+advance, p.y+fr->run.descent - fr->run.ascent/2 + fr->strikethrough_thickness), fr->color, 0, 0, 1.f); dr_rect(r2f32p(p.x+pre_advance, p.y+fr->run.descent - fr->run.ascent/2, p.x+advance, p.y+fr->run.descent - fr->run.ascent/2 + fr->strikethrough_thickness), fr->color, 0, 0, 1.f);
} }
if(trailer_found) if(trailer_found)
{ {
@@ -503,11 +530,11 @@ d_truncated_fancy_run_list(Vec2F32 p, D_FancyRunList *list, F32 max_x, F_Run tra
//- rjf: draw trailer //- rjf: draw trailer
if(trailer_found) if(trailer_found)
{ {
F_Piece *piece_first = trailer_run.pieces.v; FNT_Piece *piece_first = trailer_run.pieces.v;
F_Piece *piece_opl = piece_first + trailer_run.pieces.count; FNT_Piece *piece_opl = piece_first + trailer_run.pieces.count;
F32 pre_advance = advance; F32 pre_advance = advance;
Vec4F32 trailer_piece_color = last_color; Vec4F32 trailer_piece_color = last_color;
for(F_Piece *piece = piece_first; for(FNT_Piece *piece = piece_first;
piece < piece_opl; piece < piece_opl;
piece += 1) piece += 1)
{ {
@@ -520,7 +547,7 @@ d_truncated_fancy_run_list(Vec2F32 p, D_FancyRunList *list, F32 max_x, F_Run tra
p.y + piece->offset.y + size.y); p.y + piece->offset.y + size.y);
if(!r_handle_match(texture, r_handle_zero())) if(!r_handle_match(texture, r_handle_zero()))
{ {
d_img(dst, src, texture, trailer_piece_color, 0, 0, 0); dr_img(dst, src, texture, trailer_piece_color, 0, 0, 0);
trailer_piece_color.w *= 0.5f; trailer_piece_color.w *= 0.5f;
} }
advance += piece->advance; advance += piece->advance;
@@ -531,7 +558,7 @@ d_truncated_fancy_run_list(Vec2F32 p, D_FancyRunList *list, F32 max_x, F_Run tra
} }
internal void internal void
d_truncated_fancy_run_fuzzy_matches(Vec2F32 p, D_FancyRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color) dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FancyRunList *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)
{ {
@@ -546,20 +573,19 @@ d_truncated_fancy_run_fuzzy_matches(Vec2F32 p, D_FancyRunList *list, F32 max_x,
F32 advance = 0; F32 advance = 0;
F32 ascent = 0; F32 ascent = 0;
F32 descent = 0; F32 descent = 0;
for(D_FancyRunNode *fr_n = list->first; fr_n != 0; fr_n = fr_n->next) for(DR_FancyRunNode *fr_n = list->first; fr_n != 0; fr_n = fr_n->next)
{ {
D_FancyRun *fr = &fr_n->v; DR_FancyRun *fr = &fr_n->v;
F_Run *run = &fr->run; FNT_Run *run = &fr->run;
ascent = run->ascent; ascent = run->ascent;
descent = run->descent; descent = run->descent;
for(U64 piece_idx = 0; piece_idx < run->pieces.count; piece_idx += 1) for(U64 piece_idx = 0; piece_idx < run->pieces.count; piece_idx += 1)
{ {
F_Piece *piece = &run->pieces.v[piece_idx]; FNT_Piece *piece = &run->pieces.v[piece_idx];
if(contains_1u64(byte_range, byte_off)) if(contains_1u64(byte_range, byte_off))
{ {
F32 pre_advance = advance+piece->offset.x; F32 pre_advance = advance + piece->offset.x;
F32 post_advance = advance+piece->advance; F32 post_advance = advance + piece->advance;
last_piece_end_pad = ((F32)piece->offset.x+(F32)dim_2s16(piece->subrect).x) - piece->advance;
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);
} }
@@ -569,22 +595,24 @@ d_truncated_fancy_run_fuzzy_matches(Vec2F32 p, D_FancyRunList *list, F32 max_x,
} }
if(pixel_range.min < pixel_range.max) if(pixel_range.min < pixel_range.max)
{ {
Rng2F32 rect = r2f32p(p.x + pixel_range.min, p.y - descent - ascent, Rng2F32 rect = r2f32p(p.x + pixel_range.min - ascent/4.f,
p.x + pixel_range.max + last_piece_end_pad/2, p.y - descent - ascent + list->dim.y); p.y - descent - ascent - ascent/8.f,
p.x + pixel_range.max + ascent/4.f,
p.y - descent - ascent + ascent/8.f + list->dim.y);
rect.x0 = Min(rect.x0, p.x+max_x); rect.x0 = Min(rect.x0, p.x+max_x);
rect.x1 = Min(rect.x1, p.x+max_x); rect.x1 = Min(rect.x1, p.x+max_x);
d_rect(rect, color, (descent+ascent)/4.f, 0, 1.f); dr_rect(rect, color, (descent+ascent)/4.f, 0, 1.f);
} }
} }
} }
internal void internal void
d_text_run(Vec2F32 p, Vec4F32 color, F_Run run) dr_text_run(Vec2F32 p, Vec4F32 color, FNT_Run run)
{ {
F32 advance = 0; F32 advance = 0;
F_Piece *piece_first = run.pieces.v; FNT_Piece *piece_first = run.pieces.v;
F_Piece *piece_opl = piece_first + run.pieces.count; FNT_Piece *piece_opl = piece_first + run.pieces.count;
for(F_Piece *piece = piece_first; for(FNT_Piece *piece = piece_first;
piece < piece_opl; piece < piece_opl;
piece += 1) piece += 1)
{ {
@@ -597,150 +625,17 @@ d_text_run(Vec2F32 p, Vec4F32 color, F_Run run)
p.y + piece->offset.y + size.y); p.y + piece->offset.y + size.y);
if(size.x != 0 && size.y != 0 && !r_handle_match(texture, r_handle_zero())) if(size.x != 0 && size.y != 0 && !r_handle_match(texture, r_handle_zero()))
{ {
d_img(dst, src, texture, color, 0, 0, 0); dr_img(dst, src, texture, color, 0, 0, 0);
} }
advance += piece->advance; advance += piece->advance;
} }
} }
internal void internal void
d_truncated_text_run(Vec2F32 p, Vec4F32 color, F32 max_x, F_Run text_run, F_Run trailer_run) dr_text(FNT_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, FNT_RasterFlags flags, Vec2F32 p, Vec4F32 color, String8 string)
{
B32 truncated = 0;
B32 set_truncation = 0;
F32 truncation_p = p.x;
F32 max_x_minus_ellipses = max_x - trailer_run.dim.x;
F32 available_space = max_x - p.x;
// rjf: find last piece before truncation
B32 truncation_needed = 0;
F_Piece *last_piece_before_truncation = 0;
F32 truncation_offset = 0;
if(available_space > text_run.dim.x || available_space > trailer_run.dim.x)
{
F32 advance = 0;
F_Piece *text_run_first = text_run.pieces.v;
F_Piece *text_run_opl = text_run_first + text_run.pieces.count;
for(F_Piece *piece = text_run_first;
piece < text_run_opl;
piece += 1)
{
Rng2F32 src = r2f32p((F32)piece->subrect.x0, (F32)piece->subrect.y0, (F32)piece->subrect.x1, (F32)piece->subrect.y1);
Vec2F32 size = dim_2f32(src);
Rng2F32 dst = r2f32p(p.x + piece->offset.x + advance,
p.y + piece->offset.y,
p.x + piece->offset.x + advance + size.x,
p.y + piece->offset.y + size.y);
advance += piece->advance;
if(last_piece_before_truncation == 0 && p.x + advance > max_x_minus_ellipses)
{
truncation_offset = advance - piece->advance;
last_piece_before_truncation = piece;
}
if(p.x + advance > max_x)
{
truncation_needed = 1;
}
}
}
// rjf: draw pieces
if(available_space > text_run.dim.x || available_space > trailer_run.dim.x)
{
F32 advance = 0;
F_Piece *text_run_first = text_run.pieces.v;
F_Piece *text_run_opl = text_run_first + text_run.pieces.count;
for(F_Piece *piece = text_run_first;
piece < text_run_opl;
piece += 1)
{
if(truncation_needed && piece == last_piece_before_truncation)
{
break;
}
R_Handle texture = piece->texture;
Rng2F32 src = r2f32p((F32)piece->subrect.x0, (F32)piece->subrect.y0, (F32)piece->subrect.x1, (F32)piece->subrect.y1);
Vec2F32 size = dim_2f32(src);
Rng2F32 dst = r2f32p(p.x + piece->offset.x + advance,
p.y + piece->offset.y,
p.x + piece->offset.x + advance + size.x,
p.y + piece->offset.y + size.y);
if(size.x != 0 && size.y != 0 && !r_handle_match(texture, r_handle_zero()))
{
d_img(dst, src, texture, color, 0, 0, 0);
}
advance += piece->advance;
}
}
// rjf: draw truncation ellipses
if(truncation_needed && last_piece_before_truncation != 0)
{
Vec2F32 ellipses_p = {p.x + truncation_offset, p.y};
Vec4F32 ellipses_color = color;
F32 advance = 0;
F_Piece *trailer_run_first = trailer_run.pieces.v;
F_Piece *trailer_run_opl = trailer_run_first + trailer_run.pieces.count;
for(F_Piece *piece = trailer_run_first;
piece < trailer_run_opl;
piece += 1)
{
R_Handle texture = piece->texture;
Rng2F32 src = r2f32p((F32)piece->subrect.x0, (F32)piece->subrect.y0, (F32)piece->subrect.x1, (F32)piece->subrect.y1);
Vec2F32 size = dim_2f32(src);
Rng2F32 dst = r2f32p(ellipses_p.x + piece->offset.x + advance,
ellipses_p.y + piece->offset.y,
ellipses_p.x + piece->offset.x + advance + size.x,
ellipses_p.y + piece->offset.y + size.y);
if(size.x != 0 && size.y != 0 && !r_handle_match(texture, r_handle_zero()))
{
d_img(dst, src, texture, ellipses_color, 0, 0, 0);
}
ellipses_color.w *= 0.5f;
advance += piece->advance;
}
}
}
internal void
d_text(F_Tag font, F32 size, Vec2F32 p, Vec4F32 color, String8 string)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
F_Run run = f_push_run_from_string(scratch.arena, font, size, 0, string); FNT_Run run = fnt_push_run_from_string(scratch.arena, font, size, base_align_px, tab_size_px, flags, string);
d_text_run(p, color, run); dr_text_run(p, color, run);
scratch_end(scratch);
}
internal void
d_textf(F_Tag font, F32 size, Vec2F32 p, Vec4F32 color, char *fmt, ...)
{
Temp scratch = scratch_begin(0, 0);
va_list args;
va_start(args, fmt);
String8 string = push_str8fv(scratch.arena, fmt, args);
va_end(args);
d_text(font, size, p, color, string);
scratch_end(scratch);
}
internal void
d_truncated_text(F_Tag font, F32 size, Vec2F32 p, Vec4F32 color, F32 max_x, String8 string)
{
Temp scratch = scratch_begin(0, 0);
F_Run run = f_push_run_from_string(scratch.arena, font, size, 0, string);
F_Run ellipses_run = f_push_run_from_string(scratch.arena, font, size, 0, str8_lit("..."));
d_truncated_text_run(p, color, max_x, run, ellipses_run);
scratch_end(scratch);
}
internal void
d_truncated_textf(F_Tag font, F32 size, Vec2F32 p, Vec4F32 color, F32 max_x, char *fmt, ...)
{
Temp scratch = scratch_begin(0, 0);
va_list args;
va_start(args, fmt);
String8 string = push_str8f(scratch.arena, fmt, args);
d_truncated_text(font, size, p, color, max_x, string);
va_end(args);
scratch_end(scratch); scratch_end(scratch);
} }
+74 -76
View File
@@ -7,10 +7,10 @@
//////////////////////////////// ////////////////////////////////
//~ rjf: Fancy String Types //~ rjf: Fancy String Types
typedef struct D_FancyString D_FancyString; typedef struct DR_FancyString DR_FancyString;
struct D_FancyString struct DR_FancyString
{ {
F_Tag font; FNT_Tag font;
String8 string; String8 string;
Vec4F32 color; Vec4F32 color;
F32 size; F32 size;
@@ -18,43 +18,43 @@ struct D_FancyString
F32 strikethrough_thickness; F32 strikethrough_thickness;
}; };
typedef struct D_FancyStringNode D_FancyStringNode; typedef struct DR_FancyStringNode DR_FancyStringNode;
struct D_FancyStringNode struct DR_FancyStringNode
{ {
D_FancyStringNode *next; DR_FancyStringNode *next;
D_FancyString v; DR_FancyString v;
}; };
typedef struct D_FancyStringList D_FancyStringList; typedef struct DR_FancyStringList DR_FancyStringList;
struct D_FancyStringList struct DR_FancyStringList
{ {
D_FancyStringNode *first; DR_FancyStringNode *first;
D_FancyStringNode *last; DR_FancyStringNode *last;
U64 node_count; U64 node_count;
U64 total_size; U64 total_size;
}; };
typedef struct D_FancyRun D_FancyRun; typedef struct DR_FancyRun DR_FancyRun;
struct D_FancyRun struct DR_FancyRun
{ {
F_Run run; FNT_Run run;
Vec4F32 color; Vec4F32 color;
F32 underline_thickness; F32 underline_thickness;
F32 strikethrough_thickness; F32 strikethrough_thickness;
}; };
typedef struct D_FancyRunNode D_FancyRunNode; typedef struct DR_FancyRunNode DR_FancyRunNode;
struct D_FancyRunNode struct DR_FancyRunNode
{ {
D_FancyRunNode *next; DR_FancyRunNode *next;
D_FancyRun v; DR_FancyRun v;
}; };
typedef struct D_FancyRunList D_FancyRunList; typedef struct DR_FancyRunList DR_FancyRunList;
struct D_FancyRunList struct DR_FancyRunList
{ {
D_FancyRunNode *first; DR_FancyRunNode *first;
D_FancyRunNode *last; DR_FancyRunNode *last;
U64 node_count; U64 node_count;
Vec2F32 dim; Vec2F32 dim;
}; };
@@ -67,93 +67,95 @@ struct D_FancyRunList
//////////////////////////////// ////////////////////////////////
//~ rjf: Draw Bucket Types //~ rjf: Draw Bucket Types
typedef struct D_Bucket D_Bucket; typedef struct DR_Bucket DR_Bucket;
struct D_Bucket struct DR_Bucket
{ {
R_PassList passes; R_PassList passes;
U64 stack_gen; U64 stack_gen;
U64 last_cmd_stack_gen; U64 last_cmd_stack_gen;
D_BucketStackDecls; DR_BucketStackDecls;
}; };
//////////////////////////////// ////////////////////////////////
//~ rjf: Thread Context //~ rjf: Thread Context
typedef struct D_BucketSelectionNode D_BucketSelectionNode; typedef struct DR_BucketSelectionNode DR_BucketSelectionNode;
struct D_BucketSelectionNode struct DR_BucketSelectionNode
{ {
D_BucketSelectionNode *next; DR_BucketSelectionNode *next;
D_Bucket *bucket; DR_Bucket *bucket;
}; };
typedef struct D_ThreadCtx D_ThreadCtx; typedef struct DR_ThreadCtx DR_ThreadCtx;
struct D_ThreadCtx struct DR_ThreadCtx
{ {
Arena *arena; Arena *arena;
U64 arena_frame_start_pos; U64 arena_frame_start_pos;
D_BucketSelectionNode *top_bucket; DR_BucketSelectionNode *top_bucket;
D_BucketSelectionNode *free_bucket_selection; DR_BucketSelectionNode *free_bucket_selection;
}; };
//////////////////////////////// ////////////////////////////////
//~ rjf: Globals //~ rjf: Globals
thread_static D_ThreadCtx *d_thread_ctx = 0; thread_static DR_ThreadCtx *dr_thread_ctx = 0;
//////////////////////////////// ////////////////////////////////
//~ rjf: Basic Helpers //~ rjf: Basic Helpers
internal U64 d_hash_from_string(String8 string); internal U64 dr_hash_from_string(String8 string);
//////////////////////////////// ////////////////////////////////
//~ rjf: Fancy String Type Functions //~ rjf: Fancy String Type Functions
internal void d_fancy_string_list_push(Arena *arena, D_FancyStringList *list, D_FancyString *str); internal void dr_fancy_string_list_push(Arena *arena, DR_FancyStringList *list, DR_FancyString *str);
internal String8 d_string_from_fancy_string_list(Arena *arena, D_FancyStringList *list); #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 D_FancyRunList d_fancy_run_list_from_fancy_string_list(Arena *arena, D_FancyStringList *strs); internal void dr_fancy_string_list_concat_in_place(DR_FancyStringList *dst, DR_FancyStringList *to_push);
internal D_FancyRunList d_fancy_run_list_copy(Arena *arena, D_FancyRunList *src); internal String8 dr_string_from_fancy_string_list(Arena *arena, DR_FancyStringList *list);
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_FancyRunList dr_fancy_run_list_copy(Arena *arena, DR_FancyRunList *src);
//////////////////////////////// ////////////////////////////////
//~ rjf: Top-Level API //~ rjf: Top-Level API
// //
// (Frame boundaries & bucket submission) // (Frame boundaries & bucket submission)
internal void d_begin_frame(void); internal void dr_begin_frame(void);
internal void d_submit_bucket(OS_Handle os_window, R_Handle r_window, D_Bucket *bucket); internal void dr_submit_bucket(OS_Handle os_window, R_Handle r_window, DR_Bucket *bucket);
//////////////////////////////// ////////////////////////////////
//~ rjf: Bucket Construction & Selection API //~ rjf: Bucket Construction & Selection API
// //
// (Bucket: Handle to sequence of many render passes, constructed by this layer) // (Bucket: Handle to sequence of many render passes, constructed by this layer)
internal D_Bucket *d_bucket_make(void); internal DR_Bucket *dr_bucket_make(void);
internal void d_push_bucket(D_Bucket *bucket); internal void dr_push_bucket(DR_Bucket *bucket);
internal void d_pop_bucket(void); internal void dr_pop_bucket(void);
internal D_Bucket *d_top_bucket(void); internal DR_Bucket *dr_top_bucket(void);
#define D_BucketScope(b) DeferLoop(d_push_bucket(b), d_pop_bucket()) #define D_BucketScope(b) DeferLoop(dr_push_bucket(b), dr_pop_bucket())
//////////////////////////////// ////////////////////////////////
//~ rjf: Bucket Stacks //~ rjf: Bucket Stacks
// //
// (Pushing/popping implicit draw parameters) // (Pushing/popping implicit draw parameters)
internal R_Tex2DSampleKind d_push_tex2d_sample_kind(R_Tex2DSampleKind v); internal R_Tex2DSampleKind dr_push_tex2d_sample_kind(R_Tex2DSampleKind v);
internal Mat3x3F32 d_push_xform2d(Mat3x3F32 v); internal Mat3x3F32 dr_push_xform2d(Mat3x3F32 v);
internal Rng2F32 d_push_clip(Rng2F32 v); internal Rng2F32 dr_push_clip(Rng2F32 v);
internal F32 d_push_transparency(F32 v); internal F32 dr_push_transparency(F32 v);
internal R_Tex2DSampleKind d_pop_tex2d_sample_kind(void); internal R_Tex2DSampleKind dr_pop_tex2d_sample_kind(void);
internal Mat3x3F32 d_pop_xform2d(void); internal Mat3x3F32 dr_pop_xform2d(void);
internal Rng2F32 d_pop_clip(void); internal Rng2F32 dr_pop_clip(void);
internal F32 d_pop_transparency(void); internal F32 dr_pop_transparency(void);
internal R_Tex2DSampleKind d_top_tex2d_sample_kind(void); internal R_Tex2DSampleKind dr_top_tex2d_sample_kind(void);
internal Mat3x3F32 d_top_xform2d(void); internal Mat3x3F32 dr_top_xform2d(void);
internal Rng2F32 d_top_clip(void); internal Rng2F32 dr_top_clip(void);
internal F32 d_top_transparency(void); internal F32 dr_top_transparency(void);
#define D_Tex2DSampleKindScope(v) DeferLoop(d_push_tex2d_sample_kind(v), d_pop_tex2d_sample_kind()) #define DR_Tex2DSampleKindScope(v) DeferLoop(dr_push_tex2d_sample_kind(v), dr_pop_tex2d_sample_kind())
#define D_XForm2DScope(v) DeferLoop(d_push_xform2d(v), d_pop_xform2d()) #define DR_XForm2DScope(v) DeferLoop(dr_push_xform2d(v), dr_pop_xform2d())
#define D_ClipScope(v) DeferLoop(d_push_clip(v), d_pop_clip()) #define DR_ClipScope(v) DeferLoop(dr_push_clip(v), dr_pop_clip())
#define D_TransparencyScope(v) DeferLoop(d_push_transparency(v), d_pop_transparency()) #define DR_TransparencyScope(v) DeferLoop(dr_push_transparency(v), dr_pop_transparency())
//////////////////////////////// ////////////////////////////////
//~ rjf: Core Draw Calls //~ rjf: Core Draw Calls
@@ -161,34 +163,30 @@ internal F32 d_top_transparency(void);
// (Apply to the calling thread's currently selected bucket) // (Apply to the calling thread's currently selected bucket)
//- rjf: rectangles //- rjf: rectangles
internal inline R_Rect2DInst *d_rect(Rng2F32 dst, Vec4F32 color, F32 corner_radius, F32 border_thickness, F32 edge_softness); internal inline R_Rect2DInst *dr_rect(Rng2F32 dst, Vec4F32 color, F32 corner_radius, F32 border_thickness, F32 edge_softness);
//- rjf: images //- rjf: images
internal inline R_Rect2DInst *d_img(Rng2F32 dst, Rng2F32 src, R_Handle texture, Vec4F32 color, F32 corner_radius, F32 border_thickness, F32 edge_softness); internal inline R_Rect2DInst *dr_img(Rng2F32 dst, Rng2F32 src, R_Handle texture, Vec4F32 color, F32 corner_radius, F32 border_thickness, F32 edge_softness);
//- rjf: blurs //- rjf: blurs
internal R_PassParams_Blur *d_blur(Rng2F32 rect, F32 blur_size, F32 corner_radius); internal R_PassParams_Blur *dr_blur(Rng2F32 rect, F32 blur_size, F32 corner_radius);
//- rjf: 3d rendering pass params //- rjf: 3d rendering pass params
internal R_PassParams_Geo3D *d_geo3d_begin(Rng2F32 viewport, Mat4x4F32 view, Mat4x4F32 projection); internal R_PassParams_Geo3D *dr_geo3d_begin(Rng2F32 viewport, Mat4x4F32 view, Mat4x4F32 projection);
//- rjf: meshes //- rjf: meshes
internal R_Mesh3DInst *d_mesh(R_Handle mesh_vertices, R_Handle mesh_indices, R_GeoTopologyKind mesh_geo_topology, R_GeoVertexFlags mesh_geo_vertex_flags, R_Handle albedo_tex, Mat4x4F32 inst_xform); internal R_Mesh3DInst *dr_mesh(R_Handle mesh_vertices, R_Handle mesh_indices, R_GeoTopologyKind mesh_geo_topology, R_GeoVertexFlags mesh_geo_vertex_flags, R_Handle albedo_tex, Mat4x4F32 inst_xform);
//- rjf: collating one pre-prepped bucket into parent bucket //- rjf: collating one pre-prepped bucket into parent bucket
internal void d_sub_bucket(D_Bucket *bucket); internal void dr_sub_bucket(DR_Bucket *bucket);
//////////////////////////////// ////////////////////////////////
//~ rjf: Draw Call Helpers //~ rjf: Draw Call Helpers
//- rjf: text //- rjf: text
internal void d_truncated_fancy_run_list(Vec2F32 p, D_FancyRunList *list, F32 max_x, F_Run trailer_run); internal void dr_truncated_fancy_run_list(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FNT_Run trailer_run);
internal void d_truncated_fancy_run_fuzzy_matches(Vec2F32 p, D_FancyRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color); internal void dr_truncated_fancy_run_fuzzy_matches(Vec2F32 p, DR_FancyRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color);
internal void d_text_run(Vec2F32 p, Vec4F32 color, F_Run run); internal void dr_text_run(Vec2F32 p, Vec4F32 color, FNT_Run run);
internal void d_truncated_text_run(Vec2F32 p, Vec4F32 color, F32 max_x, F_Run text_run, F_Run trailer_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 d_text(F_Tag font, F32 size, Vec2F32 p, Vec4F32 color, String8 string);
internal void d_textf(F_Tag font, F32 size, Vec2F32 p, Vec4F32 color, char *fmt, ...);
internal void d_truncated_text(F_Tag font, F32 size, Vec2F32 p, Vec4F32 color, F32 max_x, String8 string);
internal void d_truncated_textf(F_Tag font, F32 size, Vec2F32 p, Vec4F32 color, F32 max_x, char *fmt, ...);
#endif // DRAW_H #endif // DRAW_H
+14 -14
View File
@@ -2,7 +2,7 @@
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
@table(name, name_lower, type, default_init) @table(name, name_lower, type, default_init)
D_StackTable: DR_StackTable:
{ {
{Tex2DSampleKind tex2d_sample_kind R_Tex2DSampleKind `R_Tex2DSampleKind_Nearest` } {Tex2DSampleKind tex2d_sample_kind R_Tex2DSampleKind `R_Tex2DSampleKind_Nearest` }
{XForm2D xform2d Mat3x3F32 `{1, 0, 0, 0, 1, 0, 0, 0, 1}` } {XForm2D xform2d Mat3x3F32 `{1, 0, 0, 0, 1, 0, 0, 0, 1}` }
@@ -12,47 +12,47 @@ D_StackTable:
@gen @gen
{ {
@expand(D_StackTable a) `typedef struct D_$(a.name)Node D_$(a.name)Node; struct D_$(a.name)Node {D_$(a.name)Node *next; $(a.type) v;};`; @expand(DR_StackTable a) `typedef struct DR_$(a.name)Node DR_$(a.name)Node; struct DR_$(a.name)Node {DR_$(a.name)Node *next; $(a.type) v;};`;
} }
@gen @gen
{ {
`#define D_BucketStackDecls struct{\\`; `#define DR_BucketStackDecls struct{\\`;
@expand(D_StackTable a) `D_$(a.name)Node *top_$(a.name_lower);\\`; @expand(DR_StackTable a) `DR_$(a.name)Node *top_$(a.name_lower);\\`;
`}`; `}`;
} }
@gen @gen
{ {
@expand(D_StackTable a) `read_only global D_$(a.name)Node d_nil_$(a.name_lower) = {0, $(a.default_init)};`; @expand(DR_StackTable a) `read_only global DR_$(a.name)Node dr_nil_$(a.name_lower) = {0, $(a.default_init)};`;
} }
@gen @gen
{ {
`#define D_BucketStackInits(b) do{\\`; `#define DR_BucketStackInits(b) do{\\`;
@expand(D_StackTable a) `(b)->top_$(a.name_lower) = &d_nil_$(a.name_lower);\\`; @expand(DR_StackTable a) `(b)->top_$(a.name_lower) = &dr_nil_$(a.name_lower);\\`;
`}while(0)`; `}while(0)`;
} }
@gen @gen
{ {
`#if 0`; `#if 0`;
@expand(D_StackTable a) `internal $(a.type) $(=>35) d_push_$(a.name_lower)($(a.type) v);`; @expand(DR_StackTable a) `internal $(a.type) $(=>35) dr_push_$(a.name_lower)($(a.type) v);`;
@expand(D_StackTable a) `internal $(a.type) $(=>35) d_pop_$(a.name_lower)(void);`; @expand(DR_StackTable a) `internal $(a.type) $(=>35) dr_pop_$(a.name_lower)(void);`;
@expand(D_StackTable a) `internal $(a.type) $(=>35) d_top_$(a.name_lower)(void);`; @expand(DR_StackTable a) `internal $(a.type) $(=>35) dr_top_$(a.name_lower)(void);`;
`#endif`; `#endif`;
} }
@gen @c_file @gen @c_file
{ {
@expand(D_StackTable a) `internal $(a.type) $(=>35) d_push_$(a.name_lower)($(a.type) v) {D_StackPushImpl($(a.name), $(a.name_lower), $(a.type), v);}`; @expand(DR_StackTable a) `internal $(a.type) $(=>35) dr_push_$(a.name_lower)($(a.type) v) {DR_StackPushImpl($(a.name), $(a.name_lower), $(a.type), v);}`;
@expand(D_StackTable a) `internal $(a.type) $(=>35) d_pop_$(a.name_lower)(void) {D_StackPopImpl($(a.name), $(a.name_lower), $(a.type));}`; @expand(DR_StackTable a) `internal $(a.type) $(=>35) dr_pop_$(a.name_lower)(void) {DR_StackPopImpl($(a.name), $(a.name_lower), $(a.type));}`;
@expand(D_StackTable a) `internal $(a.type) $(=>35) d_top_$(a.name_lower)(void) {D_StackTopImpl($(a.name), $(a.name_lower), $(a.type));}`; @expand(DR_StackTable a) `internal $(a.type) $(=>35) dr_top_$(a.name_lower)(void) {DR_StackTopImpl($(a.name), $(a.name_lower), $(a.type));}`;
} }
@gen @gen
{ {
`#if 0`; `#if 0`;
@expand(D_StackTable a) `#define D_$(a.name)Scope(v) $(=>35) DeferLoop(d_push_$(a.name_lower)(v), d_pop_$(a.name_lower)())`; @expand(DR_StackTable a) `#define DR_$(a.name)Scope(v) $(=>35) DeferLoop(dr_push_$(a.name_lower)(v), dr_pop_$(a.name_lower)())`;
`#endif`; `#endif`;
} }
+12 -15
View File
@@ -3,18 +3,15 @@
//- GENERATED CODE //- GENERATED CODE
internal R_Tex2DSampleKind d_push_tex2d_sample_kind(R_Tex2DSampleKind v) {D_StackPushImpl(Tex2DSampleKind, tex2d_sample_kind, R_Tex2DSampleKind, v);} internal R_Tex2DSampleKind dr_push_tex2d_sample_kind(R_Tex2DSampleKind v) {DR_StackPushImpl(Tex2DSampleKind, tex2d_sample_kind, R_Tex2DSampleKind, v);}
internal Mat3x3F32 d_push_xform2d(Mat3x3F32 v) {D_StackPushImpl(XForm2D, xform2d, Mat3x3F32, v);} internal Mat3x3F32 dr_push_xform2d(Mat3x3F32 v) {DR_StackPushImpl(XForm2D, xform2d, Mat3x3F32, v);}
internal Rng2F32 d_push_clip(Rng2F32 v) {D_StackPushImpl(Clip, clip, Rng2F32, v);} internal Rng2F32 dr_push_clip(Rng2F32 v) {DR_StackPushImpl(Clip, clip, Rng2F32, v);}
internal F32 d_push_transparency(F32 v) {D_StackPushImpl(Transparency, transparency, F32, v);} internal F32 dr_push_transparency(F32 v) {DR_StackPushImpl(Transparency, transparency, F32, v);}
internal R_Tex2DSampleKind d_pop_tex2d_sample_kind(void) {D_StackPopImpl(Tex2DSampleKind, tex2d_sample_kind, R_Tex2DSampleKind);} internal R_Tex2DSampleKind dr_pop_tex2d_sample_kind(void) {DR_StackPopImpl(Tex2DSampleKind, tex2d_sample_kind, R_Tex2DSampleKind);}
internal Mat3x3F32 d_pop_xform2d(void) {D_StackPopImpl(XForm2D, xform2d, Mat3x3F32);} internal Mat3x3F32 dr_pop_xform2d(void) {DR_StackPopImpl(XForm2D, xform2d, Mat3x3F32);}
internal Rng2F32 d_pop_clip(void) {D_StackPopImpl(Clip, clip, Rng2F32);} internal Rng2F32 dr_pop_clip(void) {DR_StackPopImpl(Clip, clip, Rng2F32);}
internal F32 d_pop_transparency(void) {D_StackPopImpl(Transparency, transparency, F32);} internal F32 dr_pop_transparency(void) {DR_StackPopImpl(Transparency, transparency, F32);}
internal R_Tex2DSampleKind d_top_tex2d_sample_kind(void) {D_StackTopImpl(Tex2DSampleKind, tex2d_sample_kind, R_Tex2DSampleKind);} internal R_Tex2DSampleKind dr_top_tex2d_sample_kind(void) {DR_StackTopImpl(Tex2DSampleKind, tex2d_sample_kind, R_Tex2DSampleKind);}
internal Mat3x3F32 d_top_xform2d(void) {D_StackTopImpl(XForm2D, xform2d, Mat3x3F32);} internal Mat3x3F32 dr_top_xform2d(void) {DR_StackTopImpl(XForm2D, xform2d, Mat3x3F32);}
internal Rng2F32 d_top_clip(void) {D_StackTopImpl(Clip, clip, Rng2F32);} internal Rng2F32 dr_top_clip(void) {DR_StackTopImpl(Clip, clip, Rng2F32);}
internal F32 d_top_transparency(void) {D_StackTopImpl(Transparency, transparency, F32);} internal F32 dr_top_transparency(void) {DR_StackTopImpl(Transparency, transparency, F32);}
C_LINKAGE_BEGIN
C_LINKAGE_END
+34 -37
View File
@@ -6,47 +6,44 @@
#ifndef DRAW_META_H #ifndef DRAW_META_H
#define DRAW_META_H #define DRAW_META_H
typedef struct D_Tex2DSampleKindNode D_Tex2DSampleKindNode; struct D_Tex2DSampleKindNode {D_Tex2DSampleKindNode *next; R_Tex2DSampleKind v;}; typedef struct DR_Tex2DSampleKindNode DR_Tex2DSampleKindNode; struct DR_Tex2DSampleKindNode {DR_Tex2DSampleKindNode *next; R_Tex2DSampleKind v;};
typedef struct D_XForm2DNode D_XForm2DNode; struct D_XForm2DNode {D_XForm2DNode *next; Mat3x3F32 v;}; typedef struct DR_XForm2DNode DR_XForm2DNode; struct DR_XForm2DNode {DR_XForm2DNode *next; Mat3x3F32 v;};
typedef struct D_ClipNode D_ClipNode; struct D_ClipNode {D_ClipNode *next; Rng2F32 v;}; typedef struct DR_ClipNode DR_ClipNode; struct DR_ClipNode {DR_ClipNode *next; Rng2F32 v;};
typedef struct D_TransparencyNode D_TransparencyNode; struct D_TransparencyNode {D_TransparencyNode *next; F32 v;}; typedef struct DR_TransparencyNode DR_TransparencyNode; struct DR_TransparencyNode {DR_TransparencyNode *next; F32 v;};
#define D_BucketStackDecls struct{\ #define DR_BucketStackDecls struct{\
D_Tex2DSampleKindNode *top_tex2d_sample_kind;\ DR_Tex2DSampleKindNode *top_tex2d_sample_kind;\
D_XForm2DNode *top_xform2d;\ DR_XForm2DNode *top_xform2d;\
D_ClipNode *top_clip;\ DR_ClipNode *top_clip;\
D_TransparencyNode *top_transparency;\ DR_TransparencyNode *top_transparency;\
} }
read_only global D_Tex2DSampleKindNode d_nil_tex2d_sample_kind = {0, R_Tex2DSampleKind_Nearest}; read_only global DR_Tex2DSampleKindNode dr_nil_tex2d_sample_kind = {0, R_Tex2DSampleKind_Nearest};
read_only global D_XForm2DNode d_nil_xform2d = {0, {1, 0, 0, 0, 1, 0, 0, 0, 1}}; read_only global DR_XForm2DNode dr_nil_xform2d = {0, {1, 0, 0, 0, 1, 0, 0, 0, 1}};
read_only global D_ClipNode d_nil_clip = {0, {0}}; read_only global DR_ClipNode dr_nil_clip = {0, {0}};
read_only global D_TransparencyNode d_nil_transparency = {0, 0}; read_only global DR_TransparencyNode dr_nil_transparency = {0, 0};
#define D_BucketStackInits(b) do{\ #define DR_BucketStackInits(b) do{\
(b)->top_tex2d_sample_kind = &d_nil_tex2d_sample_kind;\ (b)->top_tex2d_sample_kind = &dr_nil_tex2d_sample_kind;\
(b)->top_xform2d = &d_nil_xform2d;\ (b)->top_xform2d = &dr_nil_xform2d;\
(b)->top_clip = &d_nil_clip;\ (b)->top_clip = &dr_nil_clip;\
(b)->top_transparency = &d_nil_transparency;\ (b)->top_transparency = &dr_nil_transparency;\
}while(0) }while(0)
#if 0 #if 0
internal R_Tex2DSampleKind d_push_tex2d_sample_kind(R_Tex2DSampleKind v); internal R_Tex2DSampleKind dr_push_tex2d_sample_kind(R_Tex2DSampleKind v);
internal Mat3x3F32 d_push_xform2d(Mat3x3F32 v); internal Mat3x3F32 dr_push_xform2d(Mat3x3F32 v);
internal Rng2F32 d_push_clip(Rng2F32 v); internal Rng2F32 dr_push_clip(Rng2F32 v);
internal F32 d_push_transparency(F32 v); internal F32 dr_push_transparency(F32 v);
internal R_Tex2DSampleKind d_pop_tex2d_sample_kind(void); internal R_Tex2DSampleKind dr_pop_tex2d_sample_kind(void);
internal Mat3x3F32 d_pop_xform2d(void); internal Mat3x3F32 dr_pop_xform2d(void);
internal Rng2F32 d_pop_clip(void); internal Rng2F32 dr_pop_clip(void);
internal F32 d_pop_transparency(void); internal F32 dr_pop_transparency(void);
internal R_Tex2DSampleKind d_top_tex2d_sample_kind(void); internal R_Tex2DSampleKind dr_top_tex2d_sample_kind(void);
internal Mat3x3F32 d_top_xform2d(void); internal Mat3x3F32 dr_top_xform2d(void);
internal Rng2F32 d_top_clip(void); internal Rng2F32 dr_top_clip(void);
internal F32 d_top_transparency(void); internal F32 dr_top_transparency(void);
#endif #endif
#if 0 #if 0
#define D_Tex2DSampleKindScope(v) DeferLoop(d_push_tex2d_sample_kind(v), d_pop_tex2d_sample_kind()) #define DR_Tex2DSampleKindScope(v) DeferLoop(dr_push_tex2d_sample_kind(v), dr_pop_tex2d_sample_kind())
#define D_XForm2DScope(v) DeferLoop(d_push_xform2d(v), d_pop_xform2d()) #define DR_XForm2DScope(v) DeferLoop(dr_push_xform2d(v), dr_pop_xform2d())
#define D_ClipScope(v) DeferLoop(d_push_clip(v), d_pop_clip()) #define DR_ClipScope(v) DeferLoop(dr_push_clip(v), dr_pop_clip())
#define D_TransparencyScope(v) DeferLoop(d_push_transparency(v), d_pop_transparency()) #define DR_TransparencyScope(v) DeferLoop(dr_push_transparency(v), dr_pop_transparency())
#endif #endif
C_LINKAGE_BEGIN
C_LINKAGE_END
#endif // DRAW_META_H #endif // DRAW_META_H
+168 -57
View File
@@ -1,63 +1,141 @@
// 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/)
@table(name num_children op_string) @table(name)
// num_children - # of children packed after this node kind E_TokenKindTable:
// op_string - string for quick display of the operator
EVAL_ExprKindTable:
{ {
{ Nil 0 "" } {Null}
{Identifier}
{Numeric}
{StringLiteral}
{CharLiteral}
{Symbol}
}
{ ArrayIndex 2 "[]" } @table(name basic_string basic_byte_size)
{ MemberAccess 2 "." } // NOTE(rjf): basic_byte_size == 0xFF? => address sized
{ Deref 1 "*" } E_TypeKindTable:
{ Address 1 "&" } {
{Null "" 0 }
{Void "void" 0 }
{Handle "HANDLE" 0xFF }
{HResult "HRESULT" 4 }
{Char8 "char8" 1 }
{Char16 "char16" 2 }
{Char32 "char32" 4 }
{UChar8 "uchar8" 1 }
{UChar16 "uchar16" 2 }
{UChar32 "uchar32" 4 }
{U8 "U8" 1 }
{U16 "U16" 2 }
{U32 "U32" 4 }
{U64 "U64" 8 }
{U128 "U128" 16 }
{U256 "U256" 32 }
{U512 "U512" 64 }
{S8 "S8" 1 }
{S16 "S16" 2 }
{S32 "S32" 4 }
{S64 "S64" 8 }
{S128 "S128" 16 }
{S256 "S256" 32 }
{S512 "S512" 64 }
{Bool "bool" 1 }
{F16 "F16" 2 }
{F32 "F32" 4 }
{F32PP "F32PP" 4 }
{F48 "F48" 6 }
{F64 "F64" 8 }
{F80 "F80" 10 }
{F128 "F128" 16 }
{ComplexF32 "ComplexF32" 8 }
{ComplexF64 "ComplexF64" 16 }
{ComplexF80 "ComplexF80" 20 }
{ComplexF128 "ComplexF128" 32 }
{Modifier "modifier" 0 }
{Ptr "ptr" 0 }
{LRef "lref" 0 }
{RRef "rref" 0 }
{Array "array" 0 }
{Function "function" 0 }
{Method "method" 0 }
{MemberPtr "member_ptr" 0 }
{Struct "struct" 0 }
{Class "class" 0 }
{Union "union" 0 }
{Enum "enum" 0 }
{Alias "typedef" 0 }
{IncompleteStruct "struct" 0 }
{IncompleteUnion "union" 0 }
{IncompleteClass "class" 0 }
{IncompleteEnum "enum" 0 }
{Bitfield "bitfield" 0 }
{Variadic "variadic" 0 }
{Collection "collection" 0 }
}
{ Cast 2 "cast" } @table(name op_kind precedence string op_pre op_sep op_pos)
{ Sizeof 1 "sizeof" } E_ExprKindTable:
{
{ Nil Null 0 "" "" "" "" }
{ Ref Null 0 "" "" "" "" }
{ Neg 1 "-" } { ArrayIndex Null 0 "[]" "" "[" "]"}
{ LogNot 1 "!" } { MemberAccess Null 0 "." "" "." "" }
{ BitNot 1 "~" } { Deref UnaryPrefix 2 "*" "*" "" "" }
{ Mul 2 "*" } { Address UnaryPrefix 2 "&" "&" "" "" }
{ Div 2 "/" }
{ Mod 2 "%" }
{ Add 2 "+" }
{ Sub 2 "-" }
{ LShift 2 "<<" }
{ RShift 2 ">>" }
{ Less 2 "<" }
{ LsEq 2 "<=" }
{ Grtr 2 ">" }
{ GrEq 2 ">=" }
{ EqEq 2 "==" }
{ NtEq 2 "!=" }
{ BitAnd 2 "&" } { Cast Null 1 "cast" "(" ")" "" }
{ BitXor 2 "^" } { Sizeof UnaryPrefix 1 "sizeof" "sizeof" "(" ")"}
{ BitOr 2 "|" } { Typeof UnaryPrefix 1 "typeof" "typeof" "(" ")"}
{ LogAnd 2 "&&" } { ByteSwap UnaryPrefix 1 "bswap" "bswap" "(" ")"}
{ LogOr 2 "||" }
{ Ternary 3 "? " } { Neg UnaryPrefix 2 "-" "-" "" "" }
{ LogNot UnaryPrefix 2 "!" "!" "" "" }
{ BitNot UnaryPrefix 2 "~" "~" "" "" }
{ Mul Binary 3 "*" "" "*" "" }
{ Div Binary 3 "/" "" "/" "" }
{ Mod Binary 3 "%" "" "%" "" }
{ Add Binary 4 "+" "" "+" "" }
{ Sub Binary 4 "-" "" "-" "" }
{ LShift Binary 5 "<<" "" "<<" "" }
{ RShift Binary 5 ">>" "" ">>" "" }
{ Less Binary 6 "<" "" "<" "" }
{ LsEq Binary 6 "<=" "" "<=" "" }
{ Grtr Binary 6 ">" "" ">" "" }
{ GrEq Binary 6 ">=" "" ">=" "" }
{ EqEq Binary 7 "==" "" "==" "" }
{ NtEq Binary 7 "!=" "" "!=" "" }
{ LeafBytecode 0 "bytecode" } { BitAnd Binary 8 "&" "" "&" "" }
{ LeafMember 0 "member" } { BitXor Binary 9 "^" "" "^" "" }
{ LeafU64 0 "U64" } { BitOr Binary 10 "|" "" "|" "" }
{ LeafF64 0 "F64" } { LogAnd Binary 11 "&&" "" "&&" "" }
{ LeafF32 0 "F32" } { LogOr Binary 12 "||" "" "||" "" }
{ TypeIdent 0 "type_ident" } { Ternary Null 0 "? " "" "?" ":"}
{ Ptr 1 "ptr" }
{ Array 2 "array" }
{ Func 1 "function" }
{ Define 2 "=" } { LeafBytecode Null 0 "bytecode" "" "" "" }
{ LeafIdent 0 "leaf_ident" } { 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" "" "" "" }
{ Ptr Null 0 "ptr" "" "" "" }
{ Array Null 0 "array" "" "" "" }
{ Func Null 0 "function" "" "" "" }
{ Define Binary 13 "=" "" "=" "" }
} }
@table(name display_string) @table(name display_string)
EVAL_ResultCodeTable: E_InterpretationCodeTable:
{ {
{ Good "" } { Good "" }
{ DivideByZero "Cannot divide by zero." } { DivideByZero "Cannot divide by zero." }
@@ -72,35 +150,68 @@ EVAL_ResultCodeTable:
{ MalformedBytecode "Malformed bytecode." } { MalformedBytecode "Malformed bytecode." }
} }
@enum(U32) EVAL_ExprKind: @enum E_TokenKind:
{ {
@expand(EVAL_ExprKindTable a) `$(a.name)`, @expand(E_TokenKindTable a) `$(a.name)`,
COUNT, COUNT,
} }
@enum EVAL_ResultCode: @enum E_TypeKind:
{ {
@expand(EVAL_ResultCodeTable a) `$(a.name)`, @expand(E_TypeKindTable a) `$(a.name)`,
COUNT,
`FirstBasic = E_TypeKind_Void`,
`LastBasic = E_TypeKind_ComplexF128`,
`FirstInteger = E_TypeKind_Char8`,
`LastInteger = E_TypeKind_S512`,
`FirstSigned1 = E_TypeKind_Char8`,
`LastSigned1 = E_TypeKind_Char32`,
`FirstSigned2 = E_TypeKind_S8`,
`LastSigned2 = E_TypeKind_S512`,
`FirstIncomplete = E_TypeKind_IncompleteStruct`,
`LastIncomplete = E_TypeKind_IncompleteEnum`,
}
@enum(U32) E_ExprKind:
{
@expand(E_ExprKindTable a) `$(a.name)`,
COUNT, COUNT,
} }
@data(U8) eval_expr_kind_child_counts: @enum E_InterpretationCode:
{ {
@expand(EVAL_ExprKindTable a) `$(a.num_children)` @expand(E_InterpretationCodeTable a) `$(a.name)`,
COUNT,
} }
@data(String8) @data(String8)
eval_expr_kind_strings: e_token_kind_strings:
{ {
@expand(EVAL_ExprKindTable a) `str8_lit_comp("$(a.name)")` @expand(E_TokenKindTable a) `str8_lit_comp("$(a.name)")`
} }
@data(String8) eval_result_code_display_strings: @data(String8)
e_expr_kind_strings:
{ {
@expand(EVAL_ResultCodeTable a) `str8_lit_comp("$(a.display_string)")` @expand(E_ExprKindTable a) `str8_lit_comp("$(a.name)")`
} }
@data(String8) eval_expr_op_strings: @data(String8) e_interpretation_code_display_strings:
{ {
@expand(EVAL_ExprKindTable a) `str8_lit_comp("$(a.op_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)")`;
} }
+260
View File
@@ -0,0 +1,260 @@
// 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_Eval eval =
{
.value = interp.value,
.mode = irtree.mode,
.space = irtree.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 |= (1<<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
@@ -0,0 +1,33 @@
// 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
File diff suppressed because it is too large Load Diff
-82
View File
@@ -1,82 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef EVAL_COMPILER_H
#define EVAL_COMPILER_H
////////////////////////////////
//~ allen: EVAL Bytecode Helpers
internal String8 eval_bytecode_from_oplist(Arena *arena, EVAL_OpList *list);
internal void eval_oplist_push_op(Arena *arena, EVAL_OpList *list, RDI_EvalOp op, U64 p);
internal void eval_oplist_push_uconst(Arena *arena, EVAL_OpList *list, U64 x);
internal void eval_oplist_push_sconst(Arena *arena, EVAL_OpList *list, S64 x);
internal void eval_oplist_push_bytecode(Arena *arena, EVAL_OpList *list, String8 bytecode);
internal void eval_oplist_concat_in_place(EVAL_OpList *left_dst, EVAL_OpList *right_destroyed);
////////////////////////////////
//~ allen: EVAL Expression Info Functions
internal RDI_EvalOp eval_opcode_from_expr_kind(EVAL_ExprKind kind);
internal B32 eval_expr_kind_is_comparison(EVAL_ExprKind kind);
////////////////////////////////
//~ allen: EVAL Expression Constructors
internal EVAL_Expr* eval_expr(Arena *arena, EVAL_ExprKind kind, void *location, EVAL_Expr *c0, EVAL_Expr *c1, EVAL_Expr *c2);
internal EVAL_Expr* eval_expr_u64(Arena *arena, void *location, U64 u64);
internal EVAL_Expr* eval_expr_f64(Arena *arena, void *location, F64 f64);
internal EVAL_Expr* eval_expr_f32(Arena *arena, void *location, F32 f32);
internal EVAL_Expr* eval_expr_child_and_u64(Arena *arena, EVAL_ExprKind kind, void *location, EVAL_Expr *child, U64 u64);
internal EVAL_Expr* eval_expr_leaf_member(Arena *arena, void *location, String8 name);
internal EVAL_Expr* eval_expr_leaf_ident(Arena *arena, void *location, String8 name);
internal EVAL_Expr* eval_expr_leaf_bytecode(Arena *arena, void *location, TG_Key type_key, String8 bytecode, EVAL_EvalMode mode);
internal EVAL_Expr* eval_expr_leaf_op_list(Arena *arena, void *location, TG_Key type_key, EVAL_OpList *ops, EVAL_EvalMode mode);
internal EVAL_Expr* eval_expr_leaf_type(Arena *arena, void *location, TG_Key type_key);
////////////////////////////////
//~ allen: EVAL Type Information Transformers
internal RDI_EvalTypeGroup eval_type_group_from_kind(TG_Kind kind);
internal TG_Key eval_type_unwrap_enum(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key);
internal TG_Key eval_type_promote(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key);
internal TG_Key eval_type_coerce(TG_Graph *graph, RDI_Parsed *rdi, TG_Key l, TG_Key r);
internal B32 eval_type_match(TG_Graph *graph, RDI_Parsed *rdi, TG_Key l, TG_Key r);
internal B32 eval_kind_is_integer(TG_Kind kind);
internal B32 eval_kind_is_signed(TG_Kind kind);
internal B32 eval_kind_is_basic_or_enum(TG_Kind kind);
////////////////////////////////
//~ allen: EVAL IR-Tree Constructors
internal EVAL_IRTree* eval_irtree_const_u(Arena *arena, U64 v);
internal EVAL_IRTree* eval_irtree_unary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, EVAL_IRTree *c);
internal EVAL_IRTree* eval_irtree_binary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, EVAL_IRTree *l, EVAL_IRTree *r);
internal EVAL_IRTree* eval_irtree_binary_op_u(Arena *arena, RDI_EvalOp op, EVAL_IRTree *l, EVAL_IRTree *r);
internal EVAL_IRTree* eval_irtree_conditional(Arena *arena, EVAL_IRTree *c, EVAL_IRTree *l, EVAL_IRTree *r);
internal EVAL_IRTree* eval_irtree_bytecode_no_copy(Arena *arena, String8 bytecode);
////////////////////////////////
//~ allen: EVAL IR-Tree High Level Helpers
internal EVAL_IRTree* eval_irtree_mem_read_type(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_IRTree *c, TG_Key type_key);
internal EVAL_IRTree* eval_irtree_convert_lo(Arena *arena, EVAL_IRTree *c, RDI_EvalTypeGroup out, RDI_EvalTypeGroup in);
internal EVAL_IRTree* eval_irtree_trunc(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_IRTree *c, TG_Key type_key);
internal EVAL_IRTree* eval_irtree_convert_hi(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_IRTree *c, TG_Key out, TG_Key in);
internal EVAL_IRTree* eval_irtree_resolve_to_value(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_EvalMode from_mode, EVAL_IRTree *tree, TG_Key type_key);
////////////////////////////////
//~ allen: EVAL Compiler Phases
internal void eval_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, EVAL_String2ExprMap *map, EVAL_Expr *expr, EVAL_ErrorList *eout);
internal TG_Key eval_type_from_type_expr(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_Expr *expr, EVAL_ErrorList *eout);
internal EVAL_IRTreeAndType eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_String2ExprMap *leaf_ident_expr_map, EVAL_Expr *expr, EVAL_ErrorList *eout);
internal void eval_oplist_from_irtree(Arena *arena, EVAL_IRTree *tree, EVAL_OpList *out);
#endif //EVAL_COMPILER_H
+31 -175
View File
@@ -4,15 +4,15 @@
//////////////////////////////// ////////////////////////////////
//~ rjf: Generated Code //~ rjf: Generated Code
#include "generated/eval.meta.c" #include "eval/generated/eval.meta.c"
//////////////////////////////// ////////////////////////////////
//~ rjf: Basic Functions //~ rjf: Basic Helper Functions
internal U64 internal U64
eval_hash_from_string(String8 string) e_hash_from_string(U64 seed, String8 string)
{ {
U64 result = 5381; U64 result = seed;
for(U64 i = 0; i < string.size; i += 1) for(U64 i = 0; i < string.size; i += 1)
{ {
result = ((result << 5) + result) + string.str[i]; result = ((result << 5) + result) + string.str[i];
@@ -21,198 +21,54 @@ eval_hash_from_string(String8 string)
} }
//////////////////////////////// ////////////////////////////////
//~ rjf: Error List Building Functions //~ rjf: Message Functions
internal void internal void
eval_error(Arena *arena, EVAL_ErrorList *list, EVAL_ErrorKind kind, void *location, String8 text){ e_msg(Arena *arena, E_MsgList *msgs, E_MsgKind kind, void *location, String8 text)
EVAL_Error *error = push_array_no_zero(arena, EVAL_Error, 1); {
SLLQueuePush(list->first, list->last, error); E_Msg *msg = push_array(arena, E_Msg, 1);
list->count += 1; SLLQueuePush(msgs->first, msgs->last, msg);
list->max_kind = Max(kind, list->max_kind); msgs->count += 1;
error->kind = kind; msgs->max_kind = Max(kind, msgs->max_kind);
error->location = location; msg->kind = kind;
error->text = text; msg->location = location;
msg->text = text;
} }
internal void internal void
eval_errorf(Arena *arena, EVAL_ErrorList *list, EVAL_ErrorKind kind, void *location, char *fmt, ...){ e_msgf(Arena *arena, E_MsgList *msgs, E_MsgKind kind, void *location, char *fmt, ...)
{
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
String8 text = push_str8fv(arena, fmt, args); String8 text = push_str8fv(arena, fmt, args);
va_end(args); va_end(args);
eval_error(arena, list, kind, location, text); e_msg(arena, msgs, kind, location, text);
} }
internal void internal void
eval_error_list_concat_in_place(EVAL_ErrorList *dst, EVAL_ErrorList *to_push){ e_msg_list_concat_in_place(E_MsgList *dst, E_MsgList *to_push)
if (dst->last != 0){ {
if (to_push->last != 0){ if(dst->last != 0 && to_push->first != 0)
{
dst->last->next = to_push->first; dst->last->next = to_push->first;
dst->last = to_push->last; dst->last = to_push->last;
dst->count += to_push->count; dst->count += to_push->count;
dst->max_kind = Max(dst->max_kind, to_push->max_kind);
} }
} else if(to_push->first != 0)
else{ {
*dst = *to_push; MemoryCopyStruct(dst, to_push);
} }
MemoryZeroStruct(to_push); MemoryZeroStruct(to_push);
} }
//////////////////////////////// ////////////////////////////////
//~ rjf: Map Functions //~ rjf: Space Functions
//- rjf: string -> num internal E_Space
e_space_make(E_SpaceKind kind)
internal EVAL_String2NumMap
eval_string2num_map_make(Arena *arena, U64 slot_count)
{ {
EVAL_String2NumMap map = {0}; E_Space space = {0};
map.slots_count = slot_count; space.kind = kind;
map.slots = push_array(arena, EVAL_String2NumMapSlot, map.slots_count); return space;
return map;
}
internal void
eval_string2num_map_insert(Arena *arena, EVAL_String2NumMap *map, String8 string, U64 num)
{
U64 hash = eval_hash_from_string(string);
U64 slot_idx = hash%map->slots_count;
EVAL_String2NumMapNode *existing_node = 0;
for(EVAL_String2NumMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next)
{
if(str8_match(node->string, string, 0) && node->num == num)
{
existing_node = node;
break;
}
}
if(existing_node == 0)
{
EVAL_String2NumMapNode *node = push_array(arena, EVAL_String2NumMapNode, 1);
SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next);
SLLQueuePush_N(map->first, map->last, node, order_next);
node->string = push_str8_copy(arena, string);
node->num = num;
}
}
internal U64
eval_num_from_string(EVAL_String2NumMap *map, String8 string)
{
U64 num = 0;
if(map->slots_count != 0)
{
U64 hash = eval_hash_from_string(string);
U64 slot_idx = hash%map->slots_count;
EVAL_String2NumMapNode *existing_node = 0;
for(EVAL_String2NumMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next)
{
if(str8_match(node->string, string, 0))
{
existing_node = node;
break;
}
}
if(existing_node != 0)
{
num = existing_node->num;
}
}
return num;
}
//- rjf: string -> expr
internal EVAL_String2ExprMap
eval_string2expr_map_make(Arena *arena, U64 slot_count)
{
EVAL_String2ExprMap map = {0};
map.slots_count = slot_count;
map.slots = push_array(arena, EVAL_String2ExprMapSlot, map.slots_count);
return map;
}
internal void
eval_string2expr_map_insert(Arena *arena, EVAL_String2ExprMap *map, String8 string, EVAL_Expr *expr)
{
U64 hash = eval_hash_from_string(string);
U64 slot_idx = hash%map->slots_count;
EVAL_String2ExprMapNode *existing_node = 0;
for(EVAL_String2ExprMapNode *node = map->slots[slot_idx].first;
node != 0;
node = node->hash_next)
{
if(str8_match(node->string, string, 0))
{
existing_node = node;
break;
}
}
if(existing_node == 0)
{
EVAL_String2ExprMapNode *node = push_array(arena, EVAL_String2ExprMapNode, 1);
SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next);
node->string = push_str8_copy(arena, string);
existing_node = node;
}
existing_node->expr = expr;
}
internal void
eval_string2expr_map_inc_poison(EVAL_String2ExprMap *map, String8 string)
{
U64 hash = eval_hash_from_string(string);
U64 slot_idx = hash%map->slots_count;
for(EVAL_String2ExprMapNode *node = map->slots[slot_idx].first;
node != 0;
node = node->hash_next)
{
if(str8_match(node->string, string, 0))
{
node->poison_count += 1;
break;
}
}
}
internal void
eval_string2expr_map_dec_poison(EVAL_String2ExprMap *map, String8 string)
{
U64 hash = eval_hash_from_string(string);
U64 slot_idx = hash%map->slots_count;
for(EVAL_String2ExprMapNode *node = map->slots[slot_idx].first;
node != 0;
node = node->hash_next)
{
if(str8_match(node->string, string, 0) && node->poison_count > 0)
{
node->poison_count -= 1;
break;
}
}
}
internal EVAL_Expr *
eval_expr_from_string(EVAL_String2ExprMap *map, String8 string)
{
EVAL_Expr *expr = &eval_expr_nil;
if(map->slots_count != 0)
{
U64 hash = eval_hash_from_string(string);
U64 slot_idx = hash%map->slots_count;
EVAL_String2ExprMapNode *existing_node = 0;
for(EVAL_String2ExprMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next)
{
if(str8_match(node->string, string, 0) && node->poison_count == 0)
{
existing_node = node;
break;
}
}
if(existing_node != 0)
{
expr = existing_node->expr;
}
}
return expr;
} }
+112 -172
View File
@@ -5,65 +5,134 @@
#define EVAL_CORE_H #define EVAL_CORE_H
//////////////////////////////// ////////////////////////////////
//~ rjf: Errors //~ rjf: Messages
typedef enum EVAL_ErrorKind typedef enum E_MsgKind
{ {
EVAL_ErrorKind_Null, E_MsgKind_Null,
EVAL_ErrorKind_MalformedInput, E_MsgKind_MalformedInput,
EVAL_ErrorKind_MissingInfo, E_MsgKind_MissingInfo,
EVAL_ErrorKind_ResolutionFailure, E_MsgKind_ResolutionFailure,
EVAL_ErrorKind_InterpretationError, E_MsgKind_InterpretationError,
EVAL_ErrorKind_COUNT E_MsgKind_COUNT
} }
EVAL_ErrorKind; E_MsgKind;
typedef struct EVAL_Error EVAL_Error; typedef struct E_Msg E_Msg;
struct EVAL_Error struct E_Msg
{ {
EVAL_Error *next; E_Msg *next;
EVAL_ErrorKind kind; E_MsgKind kind;
void *location; void *location;
String8 text; String8 text;
}; };
typedef struct EVAL_ErrorList EVAL_ErrorList; typedef struct E_MsgList E_MsgList;
struct EVAL_ErrorList struct E_MsgList
{ {
EVAL_Error *first; E_Msg *first;
EVAL_Error *last; E_Msg *last;
EVAL_ErrorKind max_kind; E_MsgKind max_kind;
U64 count; U64 count;
}; };
//////////////////////////////// ////////////////////////////////
//~ rjf: Operation Types //~ rjf: Register-Sized Value Type
enum typedef union E_Value E_Value;
union E_Value
{ {
EVAL_IRExtKind_Bytecode = RDI_EvalOp_COUNT, U64 u512[8];
EVAL_IRExtKind_COUNT U64 u256[4];
U128 u128;
U64 u64;
U32 u32;
U16 u16;
S64 s64;
S32 s32;
S32 s16;
F64 f64;
F32 f32;
}; };
typedef struct EVAL_Op EVAL_Op; ////////////////////////////////
struct EVAL_Op //~ rjf: Operator Info
typedef enum E_OpKind
{ {
EVAL_Op *next; E_OpKind_Null,
RDI_EvalOp opcode; E_OpKind_UnaryPrefix,
E_OpKind_Binary,
}
E_OpKind;
typedef struct E_OpInfo E_OpInfo;
struct E_OpInfo
{
E_OpKind kind;
S64 precedence;
String8 pre;
String8 sep;
String8 post;
};
////////////////////////////////
//~ rjf: Evaluation Spaces
//
// NOTE(rjf): Evaluations occur within the context of a "space". Each "space"
// refers to a different offset/address-space, but it's a bit looser of a
// concept than just address space, since it can also refer to offsets into
// a register block, and it is also used to refer to spaces of unique IDs for
// key-value stores, e.g. for information in the debugger.
//
// Effectively, when considering the result of an evaluation, you use the
// value for understanding a key *into* a space, e.g. 1+2 -> 3, in a null
// space, or &foo, in the space of PID: 1234.
typedef U64 E_SpaceKind;
enum
{
E_SpaceKind_Null,
E_SpaceKind_FileSystem,
E_SpaceKind_FirstUserDefined,
};
typedef struct E_Space E_Space;
struct E_Space
{
E_SpaceKind kind;
union union
{ {
U64 p; U64 u64s[3];
String8 bytecode; struct
{
U64 u64_0;
U128 u128;
};
}; };
}; };
typedef struct EVAL_OpList EVAL_OpList; ////////////////////////////////
struct EVAL_OpList //~ rjf: Evaluation Modes
typedef enum E_Mode
{ {
EVAL_Op *first_op; E_Mode_Null,
EVAL_Op *last_op; E_Mode_Value,
U32 op_count; E_Mode_Offset,
U32 encoded_size; }
E_Mode;
////////////////////////////////
//~ rjf: Modules
typedef struct E_Module E_Module;
struct E_Module
{
RDI_Parsed *rdi;
Rng1U64 vaddr_range;
Arch arch;
E_Space space;
}; };
//////////////////////////////// ////////////////////////////////
@@ -72,150 +141,21 @@ struct EVAL_OpList
#include "eval/generated/eval.meta.h" #include "eval/generated/eval.meta.h"
//////////////////////////////// ////////////////////////////////
//~ rjf: Expression Tree Types //~ rjf: Basic Helper Functions
typedef enum EVAL_EvalMode internal U64 e_hash_from_string(U64 seed, String8 string);
{ #define e_value_u64(v) (E_Value){.u64 = (v)}
EVAL_EvalMode_NULL,
EVAL_EvalMode_Value,
EVAL_EvalMode_Addr,
EVAL_EvalMode_Reg
}
EVAL_EvalMode;
typedef struct EVAL_Expr EVAL_Expr;
struct EVAL_Expr
{
EVAL_ExprKind kind;
void *location;
union
{
EVAL_Expr *children[3];
U32 u32;
U64 u64;
F32 f32;
F64 f64;
struct
{
EVAL_Expr *child;
U64 u64;
} child_and_constant;
String8 name;
struct
{
TG_Key type_key;
String8 bytecode;
EVAL_EvalMode mode;
};
};
};
//////////////////////////////// ////////////////////////////////
//~ rjf: IR Tree Types //~ rjf: Message Functions
typedef struct EVAL_IRTree EVAL_IRTree; internal void e_msg(Arena *arena, E_MsgList *msgs, E_MsgKind kind, void *location, String8 text);
struct EVAL_IRTree{ internal void e_msgf(Arena *arena, E_MsgList *msgs, E_MsgKind kind, void *location, char *fmt, ...);
RDI_EvalOp op; internal void e_msg_list_concat_in_place(E_MsgList *dst, E_MsgList *to_push);
EVAL_IRTree *children[3];
union{
U64 p;
String8 bytecode;
};
};
typedef struct EVAL_IRTreeAndType EVAL_IRTreeAndType;
struct EVAL_IRTreeAndType{
EVAL_IRTree *tree;
TG_Key type_key;
EVAL_EvalMode mode;
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Map Types //~ rjf: Space Functions
//- rjf: string -> num internal E_Space e_space_make(E_SpaceKind kind);
typedef struct EVAL_String2NumMapNode EVAL_String2NumMapNode;
struct EVAL_String2NumMapNode
{
EVAL_String2NumMapNode *order_next;
EVAL_String2NumMapNode *hash_next;
String8 string;
U64 num;
};
typedef struct EVAL_String2NumMapSlot EVAL_String2NumMapSlot;
struct EVAL_String2NumMapSlot
{
EVAL_String2NumMapNode *first;
EVAL_String2NumMapNode *last;
};
typedef struct EVAL_String2NumMap EVAL_String2NumMap;
struct EVAL_String2NumMap
{
U64 slots_count;
EVAL_String2NumMapSlot *slots;
EVAL_String2NumMapNode *first;
EVAL_String2NumMapNode *last;
};
//- rjf: string -> expr
typedef struct EVAL_String2ExprMapNode EVAL_String2ExprMapNode;
struct EVAL_String2ExprMapNode
{
EVAL_String2ExprMapNode *hash_next;
String8 string;
EVAL_Expr *expr;
U64 poison_count;
};
typedef struct EVAL_String2ExprMapSlot EVAL_String2ExprMapSlot;
struct EVAL_String2ExprMapSlot
{
EVAL_String2ExprMapNode *first;
EVAL_String2ExprMapNode *last;
};
typedef struct EVAL_String2ExprMap EVAL_String2ExprMap;
struct EVAL_String2ExprMap
{
U64 slots_count;
EVAL_String2ExprMapSlot *slots;
};
////////////////////////////////
//~ rjf: Globals
global read_only EVAL_Expr eval_expr_nil = {0};
global read_only EVAL_IRTree eval_irtree_nil = {0};
////////////////////////////////
//~ rjf: Basic Functions
internal U64 eval_hash_from_string(String8 string);
////////////////////////////////
//~ rjf: Error List Building Functions
internal void eval_error(Arena *arena, EVAL_ErrorList *list, EVAL_ErrorKind kind, void *location, String8 text);
internal void eval_errorf(Arena *arena, EVAL_ErrorList *list, EVAL_ErrorKind kind, void *location, char *fmt, ...);
internal void eval_error_list_concat_in_place(EVAL_ErrorList *dst, EVAL_ErrorList *to_push);
////////////////////////////////
//~ rjf: Map Functions
//- rjf: string -> num
internal EVAL_String2NumMap eval_string2num_map_make(Arena *arena, U64 slot_count);
internal void eval_string2num_map_insert(Arena *arena, EVAL_String2NumMap *map, String8 string, U64 num);
internal U64 eval_num_from_string(EVAL_String2NumMap *map, String8 string);
//- rjf: string -> expr
internal EVAL_String2ExprMap eval_string2expr_map_make(Arena *arena, U64 slot_count);
internal void eval_string2expr_map_insert(Arena *arena, EVAL_String2ExprMap *map, String8 string, EVAL_Expr *expr);
internal void eval_string2expr_map_inc_poison(EVAL_String2ExprMap *map, String8 string);
internal void eval_string2expr_map_dec_poison(EVAL_String2ExprMap *map, String8 string);
internal EVAL_Expr *eval_expr_from_string(EVAL_String2ExprMap *map, String8 string);
#endif // EVAL_CORE_H #endif // EVAL_CORE_H
-50
View File
@@ -1,50 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
// NOTE(allen): Eval Decode Function
internal void
eval_print_decode_from_bytecode(FILE *out, String8 bytecode){
U8 *ptr = bytecode.str;
U8 *opl = bytecode.str + bytecode.size;
for (;ptr < opl;){
// consume opcode
SYMS_EvalOp op = (SYMS_EvalOp)*ptr;
if (op >= SYMS_EvalOp_COUNT){
fprintf(out, "decode error: undefined op code\n");
goto done;
}
U8 ctrlbits = syms_eval_opcode_ctrlbits[op];
ptr += 1;
// decode
U64 imm = 0;
U32 decode_size = (ctrlbits >> SYMS_EvalOpCtrlBits_DecodeShft)&SYMS_EvalOpCtrlBits_DecodeMask;
{
U8 *next_ptr = ptr + decode_size;
if (next_ptr > opl){
fprintf(out, "decode error: expected constant goes past the end of bytecode\n");
goto done;
}
// TODO(allen): to improve this:
// gaurantee 8 bytes padding after the end of serialized bytecode
// read 8 bytes and mask
switch (decode_size){
case 1: imm = *ptr; break;
case 2: imm = *(U16*)ptr; break;
case 4: imm = *(U32*)ptr; break;
case 8: imm = *(U64*)ptr; break;
}
ptr = next_ptr;
}
// op string & control bits
SYMS_String8 op_string = syms_eval_opcode_strings[op];
// print
fprintf(out, "%.*s 0x%llx\n", str8_varg(op_string), imm);
}
done:;
}
-12
View File
@@ -1,12 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef EVAL_DECODE_H
#define EVAL_DECODE_H
////////////////////////////////
// NOTE(allen): Eval Decode Function
internal void eval_print_decode_from_bytecode(FILE *out, String8 bytecode);
#endif //EVAL_DECODE_H
+5 -3
View File
@@ -2,6 +2,8 @@
// Licensed under the MIT license (https://opensource.org/license/mit/) // Licensed under the MIT license (https://opensource.org/license/mit/)
#include "eval/eval_core.c" #include "eval/eval_core.c"
#include "eval/eval_compiler.c" #include "eval/eval_types.c"
#include "eval/eval_machine.c" #include "eval/eval_parse.c"
#include "eval/eval_parser.c" #include "eval/eval_ir.c"
#include "eval/eval_interpret.c"
#include "eval/eval_bundles.c"
+5 -3
View File
@@ -5,8 +5,10 @@
#define EVAL_INC_H #define EVAL_INC_H
#include "eval/eval_core.h" #include "eval/eval_core.h"
#include "eval/eval_compiler.h" #include "eval/eval_types.h"
#include "eval/eval_machine.h" #include "eval/eval_parse.h"
#include "eval/eval_parser.h" #include "eval/eval_ir.h"
#include "eval/eval_interpret.h"
#include "eval/eval_bundles.h"
#endif // EVAL_INC_H #endif // EVAL_INC_H
+817
View File
@@ -0,0 +1,817 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs)
internal E_InterpretCtx *
e_selected_interpret_ctx(void)
{
return e_interpret_ctx;
}
internal void
e_select_interpret_ctx(E_InterpretCtx *ctx)
{
e_interpret_ctx = ctx;
}
////////////////////////////////
//~ rjf: Space Reading Helpers
internal B32
e_space_read(E_Space space, void *out, Rng1U64 range)
{
ProfBeginFunction();
B32 result = 0;
if(e_interpret_ctx->space_read != 0)
{
result = e_interpret_ctx->space_read(e_interpret_ctx->space_rw_user_data, space, out, range);
}
ProfEnd();
return result;
}
internal B32
e_space_write(E_Space space, void *in, Rng1U64 range)
{
ProfBeginFunction();
B32 result = 0;
if(e_interpret_ctx->space_write != 0)
{
result = e_interpret_ctx->space_write(e_interpret_ctx->space_rw_user_data, space, in, range);
}
ProfEnd();
return result;
}
////////////////////////////////
//~ rjf: Interpretation Functions
internal E_Interpretation
e_interpret(String8 bytecode)
{
E_Interpretation result = {0};
Temp scratch = scratch_begin(0, 0);
//- rjf: allocate stack & "registers"
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);
U64 stack_count = 0;
E_Space selected_space = e_interpret_ctx->primary_space;
//- rjf: iterate bytecode & perform ops
U8 *ptr = bytecode.str;
U8 *opl = bytecode.str + bytecode.size;
for(;ptr < opl;)
{
// rjf: consume next opcode
RDI_EvalOp op = (RDI_EvalOp)*ptr;
U16 ctrlbits = 0;
if(op < RDI_EvalOp_COUNT)
{
ctrlbits = rdi_eval_op_ctrlbits_table[op];
}
else switch(op)
{
case E_IRExtKind_SetSpace:{ctrlbits = RDI_EVAL_CTRLBITS(32, 0, 0);}break;
default:
{
result.code = E_InterpretationCode_BadOp;
goto done;
}break;
}
ptr += 1;
// rjf: decode
E_Value imm = {0};
{
U32 decode_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits);
U8 *next_ptr = ptr + decode_size;
if(next_ptr > opl)
{
result.code = E_InterpretationCode_BadOp;
goto done;
}
// TODO(rjf): guarantee 8 bytes padding after the end of serialized
// bytecode; read 8 bytes and mask
MemoryCopy(&imm, ptr, decode_size);
ptr = next_ptr;
}
// rjf: pop
E_Value *svals = 0;
{
U32 pop_count = RDI_POPN_FROM_CTRLBITS(ctrlbits);
if(pop_count > stack_count)
{
result.code = E_InterpretationCode_BadOp;
goto done;
}
if(pop_count <= stack_count)
{
stack_count -= pop_count;
svals = stack + stack_count;
}
}
// rjf: interpret op, given decodes/pops
E_Value nval = {0};
switch(op)
{
case E_IRExtKind_SetSpace:
{
MemoryCopy(&selected_space, &imm, sizeof(selected_space));
}break;
case RDI_EvalOp_Stop:
{
goto done;
}break;
case RDI_EvalOp_Noop:
{
// do nothing
}break;
case RDI_EvalOp_Cond:
if(svals[0].u64)
{
ptr += imm.u64;
}break;
case RDI_EvalOp_Skip:
{
ptr += imm.u64;
}break;
case RDI_EvalOp_MemRead:
{
U64 addr = svals[0].u64;
U64 size = imm.u64;
B32 good_read = e_space_read(selected_space, &nval, r1u64(addr, addr+size));
if(!good_read)
{
result.code = E_InterpretationCode_BadMemRead;
goto done;
}
}break;
case RDI_EvalOp_RegRead:
{
U8 rdi_reg_code = (imm.u64&0x0000FF)>>0;
U8 byte_size = (imm.u64&0x00FF00)>>8;
U8 byte_off = (imm.u64&0xFF0000)>>16;
REGS_RegCode base_reg_code = regs_reg_code_from_arch_rdi_code(e_interpret_ctx->reg_arch, rdi_reg_code);
REGS_Rng rng = regs_reg_code_rng_table_from_arch(e_interpret_ctx->reg_arch)[base_reg_code];
U64 off = (U64)rng.byte_off + byte_off;
U64 size = (U64)byte_size;
B32 good_read = e_space_read(e_interpret_ctx->reg_space, &nval, r1u64(off, off+size));
if(!good_read)
{
result.code = E_InterpretationCode_BadRegRead;
goto done;
}
}break;
case RDI_EvalOp_RegReadDyn:
{
U64 off = svals[0].u64;
U64 size = bit_size_from_arch(e_interpret_ctx->reg_arch)/8;
B32 good_read = e_space_read(e_interpret_ctx->reg_space, &nval, r1u64(off, off+size));
if(!good_read)
{
result.code = E_InterpretationCode_BadRegRead;
goto done;
}
}break;
case RDI_EvalOp_FrameOff:
{
if(e_interpret_ctx->frame_base != 0)
{
nval.u64 = *e_interpret_ctx->frame_base + imm.u64;
}
else
{
result.code = E_InterpretationCode_BadFrameBase;
goto done;
}
}break;
case RDI_EvalOp_ModuleOff:
{
if(e_interpret_ctx->module_base != 0)
{
nval.u64 = *e_interpret_ctx->module_base + imm.u64;
}
else
{
result.code = E_InterpretationCode_BadModuleBase;
goto done;
}
}break;
case RDI_EvalOp_TLSOff:
{
if(e_interpret_ctx->tls_base != 0)
{
nval.u64 = *e_interpret_ctx->tls_base + imm.u64;
}
else
{
result.code = E_InterpretationCode_BadTLSBase;
goto done;
}
}break;
case RDI_EvalOp_ConstU8:
case RDI_EvalOp_ConstU16:
case RDI_EvalOp_ConstU32:
case RDI_EvalOp_ConstU64:
case RDI_EvalOp_ConstU128:
{
nval = imm;
}break;
case RDI_EvalOp_ConstString:
{
MemoryCopy(&nval, ptr, imm.u64);
ptr += imm.u64;
}break;
case RDI_EvalOp_Abs:
{
if(imm.u64 == RDI_EvalTypeGroup_F32)
{
nval.f32 = svals[0].f32;
if(svals[0].f32 < 0)
{
nval.f32 = -svals[0].f32;
}
}
else if(imm.u64 == RDI_EvalTypeGroup_F64)
{
nval.f64 = svals[0].f64;
if(svals[0].f64 < 0)
{
nval.f64 = -svals[0].f64;
}
}
else
{
nval.s64 = svals[0].s64;
if(svals[0].s64 < 0)
{
nval.s64 = -svals[0].s64;
}
}
}break;
case RDI_EvalOp_Neg:
{
if(imm.u64 == RDI_EvalTypeGroup_F32)
{
nval.f32 = -svals[0].f32;
}
else if(imm.u64 == RDI_EvalTypeGroup_F64)
{
nval.f64 = -svals[0].f64;
}
else
{
nval.u64 = (~svals[0].u64) + 1;
}
}break;
case RDI_EvalOp_Add:
{
if(imm.u64 == RDI_EvalTypeGroup_F32)
{
nval.f32 = svals[0].f32 + svals[1].f32;
}
else if(imm.u64 == RDI_EvalTypeGroup_F64)
{
nval.f64 = svals[0].f64 + svals[1].f64;
}
else
{
nval.u64 = svals[0].u64 + svals[1].u64;
}
}break;
case RDI_EvalOp_Sub:
{
if(imm.u64 == RDI_EvalTypeGroup_F32)
{
nval.f32 = svals[0].f32 - svals[1].f32;
}
else if(imm.u64 == RDI_EvalTypeGroup_F64)
{
nval.f64 = svals[0].f64 - svals[1].f64;
}
else
{
nval.u64 = svals[0].u64 - svals[1].u64;
}
}break;
case RDI_EvalOp_Mul:
{
if(imm.u64 == RDI_EvalTypeGroup_F32)
{
nval.f32 = svals[0].f32*svals[1].f32;
}
else if(imm.u64 == RDI_EvalTypeGroup_F64)
{
nval.f64 = svals[0].f64*svals[1].f64;
}
else
{
nval.u64 = svals[0].u64*svals[1].u64;
}
}break;
case RDI_EvalOp_Div:
{
if(imm.u64 == RDI_EvalTypeGroup_F32)
{
if(svals[1].f32 != 0.f)
{
nval.f32 = svals[0].f32/svals[1].f32;
}
else
{
result.code = E_InterpretationCode_DivideByZero;
goto done;
}
}
else if(imm.u64 == RDI_EvalTypeGroup_F64)
{
if(svals[1].f64 != 0.)
{
nval.f64 = svals[0].f64/svals[1].f64;
}
else
{
result.code = E_InterpretationCode_DivideByZero;
goto done;
}
}
else if(imm.u64 == RDI_EvalTypeGroup_U ||
imm.u64 == RDI_EvalTypeGroup_S)
{
if(svals[1].u64 != 0)
{
nval.u64 = svals[0].u64/svals[1].u64;
}
else
{
result.code = E_InterpretationCode_DivideByZero;
goto done;
}
}
else
{
result.code = E_InterpretationCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_Mod:
{
if(imm.u64 == RDI_EvalTypeGroup_U ||
imm.u64 == RDI_EvalTypeGroup_S)
{
if(svals[1].u64 != 0)
{
nval.u64 = svals[0].u64%svals[1].u64;
}
}
else
{
result.code = E_InterpretationCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_LShift:
{
if(imm.u64 == RDI_EvalTypeGroup_U ||
imm.u64 == RDI_EvalTypeGroup_S)
{
nval.u64 = svals[0].u64 << svals[1].u64;
}
else
{
result.code = E_InterpretationCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_RShift:
{
if(imm.u64 == RDI_EvalTypeGroup_U)
{
nval.u64 = svals[0].u64 >> svals[1].u64;
}
else if(imm.u64 == RDI_EvalTypeGroup_S)
{
nval.u64 = svals[0].s64 >> svals[1].u64;
}
else
{
result.code = E_InterpretationCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_BitAnd:
{
if(imm.u64 == RDI_EvalTypeGroup_U ||
imm.u64 == RDI_EvalTypeGroup_S)
{
nval.u64 = svals[0].u64&svals[1].u64;
}
else
{
result.code = E_InterpretationCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_BitOr:
{
if(imm.u64 == RDI_EvalTypeGroup_U ||
imm.u64 == RDI_EvalTypeGroup_S)
{
nval.u64 = svals[0].u64|svals[1].u64;
}
else
{
result.code = E_InterpretationCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_BitXor:
{
if(imm.u64 == RDI_EvalTypeGroup_U ||
imm.u64 == RDI_EvalTypeGroup_S)
{
nval.u64 = svals[0].u64^svals[1].u64;
}
else
{
result.code = E_InterpretationCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_BitNot:
{
if(imm.u64 == RDI_EvalTypeGroup_U ||
imm.u64 == RDI_EvalTypeGroup_S)
{
nval.u64 = ~svals[0].u64;
}
else
{
result.code = E_InterpretationCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_LogAnd:
{
if(imm.u64 == RDI_EvalTypeGroup_U ||
imm.u64 == RDI_EvalTypeGroup_S)
{
nval.u64 = (svals[0].u64 && svals[1].u64);
}
else
{
result.code = E_InterpretationCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_LogOr:
{
if(imm.u64 == RDI_EvalTypeGroup_U ||
imm.u64 == RDI_EvalTypeGroup_S)
{
nval.u64 = (svals[0].u64 || svals[1].u64);
}
else
{
result.code = E_InterpretationCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_LogNot:
{
if(imm.u64 == RDI_EvalTypeGroup_U ||
imm.u64 == RDI_EvalTypeGroup_S)
{
nval.u64 = (!svals[0].u64);
}
else
{
result.code = E_InterpretationCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_EqEq:
{
B32 result = MemoryMatchArray(svals[0].u512, svals[1].u512);
nval.u64 = !!result;
}break;
case RDI_EvalOp_NtEq:
{
B32 result = MemoryMatchArray(svals[0].u512, svals[1].u512);
nval.u64 = !result;
}break;
case RDI_EvalOp_LsEq:
{
if(imm.u64 == RDI_EvalTypeGroup_F32)
{
nval.u64 = (svals[0].f32 <= svals[1].f32);
}
else if(imm.u64 == RDI_EvalTypeGroup_F64)
{
nval.u64 = (svals[0].f64 <= svals[1].f64);
}
else if(imm.u64 == RDI_EvalTypeGroup_U)
{
nval.u64 = (svals[0].u64 <= svals[1].u64);
}
else if(imm.u64 == RDI_EvalTypeGroup_S)
{
nval.u64 = (svals[0].s64 <= svals[1].s64);
}
else
{
result.code = E_InterpretationCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_GrEq:
{
if(imm.u64 == RDI_EvalTypeGroup_F32)
{
nval.u64 = (svals[0].f32 >= svals[1].f32);
}
else if(imm.u64 == RDI_EvalTypeGroup_F64)
{
nval.u64 = (svals[0].f64 >= svals[1].f64);
}
else if(imm.u64 == RDI_EvalTypeGroup_U)
{
nval.u64 = (svals[0].u64 >= svals[1].u64);
}
else if(imm.u64 == RDI_EvalTypeGroup_S)
{
nval.u64 = (svals[0].s64 >= svals[1].s64);
}
else
{
result.code = E_InterpretationCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_Less:
{
if(imm.u64 == RDI_EvalTypeGroup_F32)
{
nval.u64 = (svals[0].f32 < svals[1].f32);
}
else if(imm.u64 == RDI_EvalTypeGroup_F64)
{
nval.u64 = (svals[0].f64 < svals[1].f64);
}
else if(imm.u64 == RDI_EvalTypeGroup_U)
{
nval.u64 = (svals[0].u64 < svals[1].u64);
}
else if(imm.u64 == RDI_EvalTypeGroup_S)
{
nval.u64 = (svals[0].s64 < svals[1].s64);
}
else
{
result.code = E_InterpretationCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_Grtr:
{
if(imm.u64 == RDI_EvalTypeGroup_F32)
{
nval.u64 = (svals[0].f32 > svals[1].f32);
}
else if(imm.u64 == RDI_EvalTypeGroup_F64)
{
nval.u64 = (svals[0].f64 > svals[1].f64);
}
else if(imm.u64 == RDI_EvalTypeGroup_U)
{
nval.u64 = (svals[0].u64 > svals[1].u64);
}
else if(imm.u64 == RDI_EvalTypeGroup_S)
{
nval.u64 = (svals[0].s64 > svals[1].s64);
}
else
{
result.code = E_InterpretationCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_Trunc:
{
if(0 < imm.u64)
{
U64 mask = 0;
if(imm.u64 < 64)
{
mask = max_U64 >> (64 - imm.u64);
}
nval.u64 = svals[0].u64&mask;
}
}break;
case RDI_EvalOp_TruncSigned:
{
if(0 < imm.u64)
{
U64 mask = 0;
if(imm.u64 < 64)
{
mask = max_U64 >> (64 - imm.u64);
}
U64 high = 0;
if(svals[0].u64 & (1 << (imm.u64 - 1)))
{
high = ~mask;
}
nval.u64 = high|(svals[0].u64&mask);
}
}break;
case RDI_EvalOp_Convert:
{
U32 in = imm.u64&0xFF;
U32 out = (imm.u64 >> 8)&0xFF;
if(in != out)
{
switch(in + out*RDI_EvalTypeGroup_COUNT)
{
case RDI_EvalTypeGroup_F32 + RDI_EvalTypeGroup_U*RDI_EvalTypeGroup_COUNT:
{
nval.u64 = (U64)svals[0].f32;
}break;
case RDI_EvalTypeGroup_F64 + RDI_EvalTypeGroup_U*RDI_EvalTypeGroup_COUNT:
{
nval.u64 = (U64)svals[0].f64;
}break;
case RDI_EvalTypeGroup_F32 + RDI_EvalTypeGroup_S*RDI_EvalTypeGroup_COUNT:
{
nval.s64 = (S64)svals[0].f32;
}break;
case RDI_EvalTypeGroup_F64 + RDI_EvalTypeGroup_S*RDI_EvalTypeGroup_COUNT:
{
nval.s64 = (S64)svals[0].f64;
}break;
case RDI_EvalTypeGroup_U + RDI_EvalTypeGroup_F32*RDI_EvalTypeGroup_COUNT:
{
nval.f32 = (F32)svals[0].u64;
}break;
case RDI_EvalTypeGroup_S + RDI_EvalTypeGroup_F32*RDI_EvalTypeGroup_COUNT:
{
nval.f32 = (F32)svals[0].s64;
}break;
case RDI_EvalTypeGroup_F64 + RDI_EvalTypeGroup_F32*RDI_EvalTypeGroup_COUNT:
{
nval.f32 = (F32)svals[0].f64;
}break;
case RDI_EvalTypeGroup_U + RDI_EvalTypeGroup_F64*RDI_EvalTypeGroup_COUNT:
{
nval.f64 = (F64)svals[0].u64;
}break;
case RDI_EvalTypeGroup_S + RDI_EvalTypeGroup_F64*RDI_EvalTypeGroup_COUNT:
{
nval.f64 = (F64)svals[0].s64;
}break;
case RDI_EvalTypeGroup_F32 + RDI_EvalTypeGroup_F64*RDI_EvalTypeGroup_COUNT:
{
nval.f64 = (F64)svals[0].f32;
}break;
}
}
}break;
case RDI_EvalOp_Pick:
{
if(stack_count > imm.u64)
{
nval = stack[stack_count - imm.u64 - 1];
}
else
{
result.code = E_InterpretationCode_BadOp;
goto done;
}
}break;
case RDI_EvalOp_Pop:
{
// do nothing - the pop is handled by the control bits
}break;
case RDI_EvalOp_Insert:
{
if(stack_count > imm.u64)
{
if(imm.u64 > 0)
{
E_Value tval = stack[stack_count - 1];
E_Value *dst = stack + stack_count - 1 - imm.u64;
E_Value *shift = dst + 1;
MemoryCopy(shift, dst, imm.u64*sizeof(E_Value));
*dst = tval;
}
}
else
{
result.code = E_InterpretationCode_BadOp;
goto done;
}
}break;
case RDI_EvalOp_ValueRead:
{
U64 bytes_to_read = imm.u64;
U64 offset = svals[0].u64;
if(offset + bytes_to_read <= sizeof(E_Value))
{
E_Value src_val = svals[1];
MemoryCopy(&nval.u512[0], (U8 *)(&src_val.u512[0]) + offset, bytes_to_read);
}
}break;
case RDI_EvalOp_ByteSwap:
{
U64 byte_size = imm.u64;
switch(byte_size)
{
default:
{
result.code = E_InterpretationCode_BadOp;
goto done;
}break;
case 2:{nval.u16 = bswap_u16(svals[0].u16);}break;
case 4:{nval.u32 = bswap_u32(svals[0].u32);}break;
case 8:{nval.u64 = bswap_u64(svals[0].u64);}break;
}
}break;
}
// rjf: push
{
U64 push_count = RDI_PUSHN_FROM_CTRLBITS(ctrlbits);
if(push_count == 1)
{
if(stack_count < stack_cap)
{
stack[stack_count] = nval;
stack_count += 1;
}
else
{
result.code = E_InterpretationCode_InsufficientStackSpace;
goto done;
}
}
}
}
done:;
if(stack_count >= 1)
{
result.value = stack[0];
}
scratch_end(scratch);
return result;
}
+59
View File
@@ -0,0 +1,59 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef 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
typedef B32 E_SpaceRWFunction(void *user_data, E_Space space, void *out, Rng1U64 offset_range);
typedef struct E_InterpretCtx E_InterpretCtx;
struct E_InterpretCtx
{
void *space_rw_user_data;
E_SpaceRWFunction *space_read;
E_SpaceRWFunction *space_write;
E_Space primary_space;
Arch reg_arch;
E_Space reg_space;
U64 reg_unwind_count;
U64 *module_base;
U64 *frame_base;
U64 *tls_base;
};
////////////////////////////////
//~ rjf: Globals
thread_static E_InterpretCtx *e_interpret_ctx = 0;
////////////////////////////////
//~ 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);
////////////////////////////////
//~ rjf: Space Reading Helpers
internal B32 e_space_read(E_Space space, void *out, Rng1U64 range);
internal B32 e_space_write(E_Space space, void *in, Rng1U64 range);
////////////////////////////////
//~ rjf: Interpretation Functions
internal E_Interpretation e_interpret(String8 bytecode);
#endif // EVAL_INTERPRET_H
+1535
View File
File diff suppressed because it is too large Load Diff
+125
View File
@@ -0,0 +1,125 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef EVAL_IR_H
#define EVAL_IR_H
////////////////////////////////
//~ rjf: Bytecode Operation Types
enum
{
E_IRExtKind_Bytecode = RDI_EvalOp_COUNT,
E_IRExtKind_SetSpace,
E_IRExtKind_COUNT
};
typedef struct E_Op E_Op;
struct E_Op
{
E_Op *next;
RDI_EvalOp opcode;
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
typedef struct E_IRNode E_IRNode;
struct E_IRNode
{
E_IRNode *first;
E_IRNode *last;
E_IRNode *next;
RDI_EvalOp op;
String8 string;
E_Value value;
};
typedef struct E_IRTreeAndType E_IRTreeAndType;
struct E_IRTreeAndType
{
E_IRNode *root;
E_TypeKey type_key;
E_Mode mode;
E_Space space;
E_MsgList msgs;
};
////////////////////////////////
//~ rjf: Parse Context
typedef struct E_IRCtx E_IRCtx;
struct E_IRCtx
{
E_String2ExprMap *macro_map;
};
////////////////////////////////
//~ rjf: Globals
global read_only E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil};
thread_static E_IRCtx *e_ir_ctx = 0;
////////////////////////////////
//~ rjf: Expr Kind Enum Functions
internal RDI_EvalOp e_opcode_from_expr_kind(E_ExprKind kind);
internal B32 e_expr_kind_is_comparison(E_ExprKind kind);
////////////////////////////////
//~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs)
internal E_IRCtx *e_selected_ir_ctx(void);
internal void e_select_ir_ctx(E_IRCtx *ctx);
////////////////////////////////
//~ rjf: IR-ization Functions
//- rjf: op list functions
internal void e_oplist_push_op(Arena *arena, E_OpList *list, RDI_EvalOp opcode, E_Value value);
internal void e_oplist_push_uconst(Arena *arena, E_OpList *list, U64 x);
internal void e_oplist_push_sconst(Arena *arena, E_OpList *list, S64 x);
internal void e_oplist_push_bytecode(Arena *arena, E_OpList *list, String8 bytecode);
internal void e_oplist_push_set_space(Arena *arena, E_OpList *list, E_Space space);
internal void e_oplist_push_string_literal(Arena *arena, E_OpList *list, String8 string);
internal void e_oplist_concat_in_place(E_OpList *dst, E_OpList *to_push);
//- rjf: ir tree core building helpers
internal E_IRNode *e_push_irnode(Arena *arena, RDI_EvalOp op);
internal void e_irnode_push_child(E_IRNode *parent, E_IRNode *child);
//- rjf: ir subtree building helpers
internal E_IRNode *e_irtree_const_u(Arena *arena, U64 v);
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_u(Arena *arena, RDI_EvalOp op, E_IRNode *l, E_IRNode *r);
internal E_IRNode *e_irtree_conditional(Arena *arena, E_IRNode *c, E_IRNode *l, E_IRNode *r);
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_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_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_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);
//- rjf: top-level irtree/type extraction
internal E_IRTreeAndType e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr);
//- rjf: irtree -> linear ops/bytecode
internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_OpList *out);
internal E_OpList e_oplist_from_irtree(Arena *arena, E_IRNode *root);
internal String8 e_bytecode_from_oplist(Arena *arena, E_OpList *oplist);
#endif // EVAL_IR_H
-648
View File
@@ -1,648 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ allen: Eval Machine Functions
internal EVAL_Result
eval_interpret(EVAL_Machine *machine, String8 bytecode)
{
ProfBeginFunction();
EVAL_Result result = {0};
// TODO(allen): We could scan the bytecode and figure out the
// maximum depth of the stack
Temp scratch = scratch_begin(0, 0);
U64 stack_cap = 128;
EVAL_Slot *stack = push_array_no_zero(scratch.arena, EVAL_Slot, stack_cap);
U64 stack_count = 0;
U8 *ptr = bytecode.str;
U8 *opl = bytecode.str + bytecode.size;
for (;ptr < opl;){
// consume opcode
RDI_EvalOp op = (RDI_EvalOp)*ptr;
if (op >= RDI_EvalOp_COUNT){
result.code = EVAL_ResultCode_BadOp;
goto done;
}
U8 ctrlbits = rdi_eval_opcode_ctrlbits[op];
ptr += 1;
// decode
U64 imm = 0;
{
U32 decode_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits);
U8 *next_ptr = ptr + decode_size;
if (next_ptr > opl){
result.code = EVAL_ResultCode_BadOp;
goto done;
}
// TODO(allen): to improve this:
// gaurantee 8 bytes padding after the end of serialized bytecode
// read 8 bytes and mask
switch (decode_size){
case 1: imm = *ptr; break;
case 2: imm = *(U16*)ptr; break;
case 4: imm = *(U32*)ptr; break;
case 8: imm = *(U64*)ptr; break;
}
ptr = next_ptr;
}
// pop
EVAL_Slot *svals = 0;
{
U32 pop_count = RDI_POPN_FROM_CTRLBITS(ctrlbits);
if (pop_count > stack_count){
result.code = EVAL_ResultCode_BadOp;
goto done;
}
if (pop_count <= stack_count){
stack_count -= pop_count;
svals = stack + stack_count;
}
}
// interpret
EVAL_Slot nval = {0};
switch (op){
case RDI_EvalOp_Stop:
{
goto done;
}break;
case RDI_EvalOp_Noop:
{
// do nothing
}break;
case RDI_EvalOp_Cond:
{
if (svals[0].u64){
ptr += imm;
}
}break;
case RDI_EvalOp_Skip:
{
ptr += imm;
}break;
case RDI_EvalOp_MemRead:
{
U64 addr = svals[0].u64;
U64 size = imm;
B32 good_read = 0;
if (machine->memory_read != 0 &&
machine->memory_read(machine->u, &nval, addr, size)){
good_read = 1;
}
if (!good_read){
result.code = EVAL_ResultCode_BadMemRead;
goto done;
}
}break;
case RDI_EvalOp_RegRead:
{
U8 rdi_reg_code = (imm&0x0000FF)>>0;
U8 byte_size = (imm&0x00FF00)>>8;
U8 byte_off = (imm&0xFF0000)>>16;
REGS_RegCode base_reg_code = regs_reg_code_from_arch_rdi_code(machine->arch, rdi_reg_code);
REGS_Rng rng = regs_reg_code_rng_table_from_architecture(machine->arch)[base_reg_code];
U64 off = (U64)rng.byte_off + byte_off;
U64 size = (U64)byte_size;
if (off + size <= machine->reg_size){
MemoryCopy(&nval, (U8*)machine->reg_data + off, size);
}
else{
result.code = EVAL_ResultCode_BadRegRead;
goto done;
}
}break;
case RDI_EvalOp_RegReadDyn:
{
U64 off = svals[0].u64;
U64 size = bit_size_from_arch(machine->arch)/8;
if (off + size <= machine->reg_size){
MemoryCopy(&nval, (U8*)machine->reg_data + off, size);
}
else{
result.code = EVAL_ResultCode_BadRegRead;
goto done;
}
}break;
case RDI_EvalOp_FrameOff:
{
if (machine->frame_base != 0){
nval.u64 = *machine->frame_base + imm;
}
else{
result.code = EVAL_ResultCode_BadFrameBase;
goto done;
}
}break;
case RDI_EvalOp_ModuleOff:
{
if (machine->module_base != 0){
nval.u64 = *machine->module_base + imm;
}
else{
result.code = EVAL_ResultCode_BadModuleBase;
goto done;
}
}break;
case RDI_EvalOp_TLSOff:
{
if (machine->tls_base != 0){
nval.u64 = *machine->tls_base + imm;
}
else{
result.code = EVAL_ResultCode_BadTLSBase;
goto done;
}
}break;
case RDI_EvalOp_ConstU8:
case RDI_EvalOp_ConstU16:
case RDI_EvalOp_ConstU32:
case RDI_EvalOp_ConstU64:
{
nval.u64 = imm;
}break;
case RDI_EvalOp_Abs:
{
if (imm == RDI_EvalTypeGroup_F32){
nval.f32 = svals[0].f32;
if (svals[0].f32 < 0){
nval.f32 = -svals[0].f32;
}
}
else if (imm == RDI_EvalTypeGroup_F64){
nval.f64 = svals[0].f64;
if (svals[0].f64 < 0){
nval.f64 = -svals[0].f64;
}
}
else{
nval.s64 = svals[0].s64;
if (svals[0].s64 < 0){
nval.s64 = -svals[0].s64;
}
}
}break;
case RDI_EvalOp_Neg:
{
if (imm == RDI_EvalTypeGroup_F32){
nval.f32 = -svals[0].f32;
}
else if (imm == RDI_EvalTypeGroup_F64){
nval.f64 = -svals[0].f64;
}
else{
nval.u64 = (~svals[0].u64) + 1;
}
}break;
case RDI_EvalOp_Add:
{
if (imm == RDI_EvalTypeGroup_F32){
nval.f32 = svals[0].f32 + svals[1].f32;
}
else if (imm == RDI_EvalTypeGroup_F64){
nval.f64 = svals[0].f64 + svals[1].f64;
}
else{
nval.u64 = svals[0].u64 + svals[1].u64;
}
}break;
case RDI_EvalOp_Sub:
{
if (imm == RDI_EvalTypeGroup_F32){
nval.f32 = svals[0].f32 - svals[1].f32;
}
else if (imm == RDI_EvalTypeGroup_F64){
nval.f64 = svals[0].f64 - svals[1].f64;
}
else{
nval.u64 = svals[0].u64 - svals[1].u64;
}
}break;
case RDI_EvalOp_Mul:
{
if (imm == RDI_EvalTypeGroup_F32){
nval.f32 = svals[0].f32*svals[1].f32;
}
else if (imm == RDI_EvalTypeGroup_F64){
nval.f64 = svals[0].f64*svals[1].f64;
}
else{
nval.u64 = svals[0].u64*svals[1].u64;
}
}break;
case RDI_EvalOp_Div:
{
if (imm == RDI_EvalTypeGroup_F32){
if (svals[1].f32 != 0.f){
nval.f32 = svals[0].f32/svals[1].f32;
}
else
{
result.code = EVAL_ResultCode_DivideByZero;
goto done;
}
}
else if (imm == RDI_EvalTypeGroup_F64){
if (svals[1].f64 != 0.){
nval.f64 = svals[0].f64/svals[1].f64;
}
else
{
result.code = EVAL_ResultCode_DivideByZero;
goto done;
}
}
else if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
if (svals[1].u64 != 0){
nval.u64 = svals[0].u64/svals[1].u64;
}
else
{
result.code = EVAL_ResultCode_DivideByZero;
goto done;
}
}
else{
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_Mod:
{
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
if (svals[1].u64 != 0){
nval.u64 = svals[0].u64%svals[1].u64;
}
}
else{
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_LShift:
{
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
nval.u64 = svals[0].u64 << svals[1].u64;
}
else{
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_RShift:
{
if (imm == RDI_EvalTypeGroup_U){
nval.u64 = svals[0].u64 >> svals[1].u64;
}
else if (imm == RDI_EvalTypeGroup_S){
nval.u64 = svals[0].s64 >> svals[1].u64;
}
else{
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_BitAnd:
{
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
nval.u64 = svals[0].u64&svals[1].u64;
}
else{
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_BitOr:
{
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
nval.u64 = svals[0].u64|svals[1].u64;
}
else{
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_BitXor:
{
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
nval.u64 = svals[0].u64^svals[1].u64;
}
else{
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_BitNot:
{
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
nval.u64 = ~svals[0].u64;
}
else{
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_LogAnd:
{
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
nval.u64 = (svals[0].u64 && svals[1].u64);
}
else{
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_LogOr:
{
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
nval.u64 = (svals[0].u64 || svals[1].u64);
}
else{
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_LogNot:
{
if (imm == RDI_EvalTypeGroup_U ||
imm == RDI_EvalTypeGroup_S){
nval.u64 = (!svals[0].u64);
}
else{
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_EqEq:
{
nval.u64 = (svals[0].u64 == svals[1].u64);
}break;
case RDI_EvalOp_NtEq:
{
nval.u64 = (svals[0].u64 != svals[1].u64);
}break;
case RDI_EvalOp_LsEq:
{
if (imm == RDI_EvalTypeGroup_F32){
nval.u64 = (svals[0].f32 <= svals[1].f32);
}
else if (imm == RDI_EvalTypeGroup_F64){
nval.u64 = (svals[0].f64 <= svals[1].f64);
}
else if (imm == RDI_EvalTypeGroup_U){
nval.u64 = (svals[0].u64 <= svals[1].u64);
}
else if (imm == RDI_EvalTypeGroup_S){
nval.u64 = (svals[0].s64 <= svals[1].s64);
}
else{
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_GrEq:
{
if (imm == RDI_EvalTypeGroup_F32){
nval.u64 = (svals[0].f32 >= svals[1].f32);
}
else if (imm == RDI_EvalTypeGroup_F64){
nval.u64 = (svals[0].f64 >= svals[1].f64);
}
else if (imm == RDI_EvalTypeGroup_U){
nval.u64 = (svals[0].u64 >= svals[1].u64);
}
else if (imm == RDI_EvalTypeGroup_S){
nval.u64 = (svals[0].s64 >= svals[1].s64);
}
else{
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_Less:
{
if (imm == RDI_EvalTypeGroup_F32){
nval.u64 = (svals[0].f32 < svals[1].f32);
}
else if (imm == RDI_EvalTypeGroup_F64){
nval.u64 = (svals[0].f64 < svals[1].f64);
}
else if (imm == RDI_EvalTypeGroup_U){
nval.u64 = (svals[0].u64 < svals[1].u64);
}
else if (imm == RDI_EvalTypeGroup_S){
nval.u64 = (svals[0].s64 < svals[1].s64);
}
else{
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_Grtr:
{
if (imm == RDI_EvalTypeGroup_F32){
nval.u64 = (svals[0].f32 > svals[1].f32);
}
else if (imm == RDI_EvalTypeGroup_F64){
nval.u64 = (svals[0].f64 > svals[1].f64);
}
else if (imm == RDI_EvalTypeGroup_U){
nval.u64 = (svals[0].u64 > svals[1].u64);
}
else if (imm == RDI_EvalTypeGroup_S){
nval.u64 = (svals[0].s64 > svals[1].s64);
}
else{
result.code = EVAL_ResultCode_BadOpTypes;
goto done;
}
}break;
case RDI_EvalOp_Trunc:
{
if (0 < imm){
U64 mask = 0;
if (imm < 64){
mask = max_U64 >> (64 - imm);
}
nval.u64 = svals[0].u64&mask;
}
}break;
case RDI_EvalOp_TruncSigned:
{
if (0 < imm){
U64 mask = 0;
if (imm < 64){
mask = max_U64 >> (64 - imm);
}
U64 high = 0;
if (svals[0].u64 & (1 << (imm - 1))){
high = ~mask;
}
nval.u64 = high|(svals[0].u64&mask);
}
}break;
case RDI_EvalOp_Convert:
{
U32 in = imm&0xFF;
U32 out = (imm >> 8)&0xFF;
if (in != out){
switch (in + out*RDI_EvalTypeGroup_COUNT){
case RDI_EvalTypeGroup_F32 + RDI_EvalTypeGroup_U*RDI_EvalTypeGroup_COUNT:
{
nval.u64 = (U64)svals[0].f32;
}break;
case RDI_EvalTypeGroup_F64 + RDI_EvalTypeGroup_U*RDI_EvalTypeGroup_COUNT:
{
nval.u64 = (U64)svals[0].f64;
}break;
case RDI_EvalTypeGroup_F32 + RDI_EvalTypeGroup_S*RDI_EvalTypeGroup_COUNT:
{
nval.s64 = (S64)svals[0].f32;
}break;
case RDI_EvalTypeGroup_F64 + RDI_EvalTypeGroup_S*RDI_EvalTypeGroup_COUNT:
{
nval.s64 = (S64)svals[0].f64;
}break;
case RDI_EvalTypeGroup_U + RDI_EvalTypeGroup_F32*RDI_EvalTypeGroup_COUNT:
{
nval.f32 = (F32)svals[0].u64;
}break;
case RDI_EvalTypeGroup_S + RDI_EvalTypeGroup_F32*RDI_EvalTypeGroup_COUNT:
{
nval.f32 = (F32)svals[0].s64;
}break;
case RDI_EvalTypeGroup_F64 + RDI_EvalTypeGroup_F32*RDI_EvalTypeGroup_COUNT:
{
nval.f32 = (F32)svals[0].f64;
}break;
case RDI_EvalTypeGroup_U + RDI_EvalTypeGroup_F64*RDI_EvalTypeGroup_COUNT:
{
nval.f64 = (F64)svals[0].u64;
}break;
case RDI_EvalTypeGroup_S + RDI_EvalTypeGroup_F64*RDI_EvalTypeGroup_COUNT:
{
nval.f64 = (F64)svals[0].s64;
}break;
case RDI_EvalTypeGroup_F32 + RDI_EvalTypeGroup_F64*RDI_EvalTypeGroup_COUNT:
{
nval.f64 = (F64)svals[0].f32;
}break;
}
}
}break;
case RDI_EvalOp_Pick:
{
if (stack_count > imm){
nval = stack[stack_count - imm - 1];
}
else{
result.code = EVAL_ResultCode_BadOp;
goto done;
}
}break;
case RDI_EvalOp_Pop:
{
// do nothing - the pop is handled by the control bits
}break;
case RDI_EvalOp_Insert:
{
if (stack_count > imm){
if (imm > 0){
EVAL_Slot tval = stack[stack_count - 1];
EVAL_Slot *dst = stack + stack_count - 1 - imm;
EVAL_Slot *shift = dst + 1;
MemoryCopy(shift, dst, imm*sizeof(EVAL_Slot));
*dst = tval;
}
}
else{
result.code = EVAL_ResultCode_BadOp;
goto done;
}
}break;
}
// push
{
U64 push_count = RDI_PUSHN_FROM_CTRLBITS(ctrlbits);
if (push_count == 1){
if (stack_count < stack_cap){
stack[stack_count] = nval;
stack_count += 1;
}
else{
result.code = EVAL_ResultCode_InsufficientStackSpace;
goto done;
}
}
}
}
done:;
if (stack_count == 1){
result.value = stack[0];
}
else if(result.code == EVAL_ResultCode_Good){
result.code = EVAL_ResultCode_MalformedBytecode;
}
scratch_end(scratch);
ProfEnd();
return(result);
}
-48
View File
@@ -1,48 +0,0 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef EVAL2_MACHINE_H
#define EVAL2_MACHINE_H
////////////////////////////////
//~ allen: Eval Machine Types
typedef B32 EVAL_MemoryRead(void *u, void *out, U64 addr, U64 size);
typedef struct EVAL_Machine EVAL_Machine;
struct EVAL_Machine
{
void *u;
Architecture arch;
EVAL_MemoryRead *memory_read;
void *reg_data;
U64 reg_size;
U64 *module_base;
U64 *frame_base;
U64 *tls_base;
};
typedef union EVAL_Slot EVAL_Slot;
union EVAL_Slot
{
U64 u256[4];
U64 u128[2];
U64 u64;
S64 s64;
F64 f64;
F32 f32;
};
typedef struct EVAL_Result EVAL_Result;
struct EVAL_Result
{
EVAL_Slot value;
EVAL_ResultCode code;
};
////////////////////////////////
//~ allen: Eval Machine Functions
internal EVAL_Result eval_interpret(EVAL_Machine *machine, String8 bytecode);
#endif //EVAL2_MACHINE_H
File diff suppressed because it is too large Load Diff

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