rrt/docs/control-loop-atlas/crt-and-process-startup.md

76 lines
6.3 KiB
Markdown
Raw Normal View History

## CRT and Process Startup
- Roots: `entry` at `0x005a313b`, CRT helpers in the `0x005a2d..0x005ad4..` range, and
`app_bootstrap_main` at `0x00484440`.
- Trigger/Cadence: single process startup path before shell or engine services exist.
- Key Dispatchers: `startup_init_tls_state`, `startup_init_file_handle_table`,
`startup_run_init_callback_table`, `__setenvp`, `startup_build_argv`,
`___crtGetEnvironmentStringsA`, then `app_bootstrap_main`.
- State Anchors: CRT heap and file-handle tables; process environment and argv storage.
- Subsystem Handoffs: exits the generic CRT path at `app_bootstrap_main`, which becomes the first
RT3-owned coordinator.
- Local CRT side seams are tighter now too: `0x005a2c30/0x005a2cb0/0x005a2cd8/0x005a2d10` own the
global on-exit callback table at `0x00dbb8dc/0x00dbb8d8`, `0x005a2d22` is the optional
`mscoree.dll!CorExitProcess` bridge before the normal process-exit tail,
`0x005a2dc9/0x005a2e9c/0x005a2ead/0x005a2ebe/0x005a2ecd` are the shared exit-cleanup owner plus
its four terminate-vs-return and cleanup-vs-skip variants, and `0x005a2d64` is now bounded as
the higher init owner that walks fixed callback tables `0x005ed018..0x005ed034` and
`0x005ed000..0x005ed014` before registering callback `0x005acaa1` into that dynamic on-exit
table. The same startup-owned table path is now tighter internally too: `0x005acaa1` is the
fixed callback-table walker over `0x005eab28..`, `0x005ac9e7` is the capacity query helper that
prefers the local CRT heap fast path over `KERNEL32!HeapSize`, and `0x005a6649` is the
region-descriptor probe under that fast path. The surrounding early-init side is tighter now
too: `__heap_init` `0x005a644d` is the real `HeapCreate + heap-mode + small-block-heap` owner,
and `startup_run_init_callback_table` `0x005aca5d` is the fixed startup callback walker over the
currently empty `0x005eab20..` band.
- the adjacent CRT runtime-report seam is explicit now too: `0x005acdb0` is the shared
runtime-error or math-error message emitter by code, selecting texts like `R6002`, `R6024`,
`DOMAIN error`, `SING error`, and `TLOSS error` from `0x0062aac0`, then emitting them through
the GUI report path or the console `WriteFile` path. `0x005acf27` is the smaller banner-pair
wrapper around that emitter, and `0x005acf60` is the registered floating-point exception
dispatcher that translates Windows exception codes into the local runtime math codes before
falling back to `UnhandledExceptionFilter`. The nearby unhandled-exception bridge is grounded now
too: `0x005b1ddd` is the top-level filter callback that first recognizes the VC++ exception
signature before tailing into the previously installed filter, and `0x005b1e23/0x005b1e36` are
its install and restore wrappers over `SetUnhandledExceptionFilter`. The neighboring fatal
security-report owner `0x005b1c31` is now explicit too: it formats either the buffer-overrun or
unknown-security-failure message, appends the current program path, emits that body through the
same GUI runtime-report path, and then forces CRT termination. The nearby startup helper
`0x005ad0c4` is the common command-line program-name-tail extractor used by the CRT argument
path. The adjacent locale-startup strip is grounded now too: `0x005ad524/0x005ad88b/0x005ada1b`
build, release, and publish the primary `0xb8` locale text record, while `0x005adad9` and
`0x005add7f` rebuild the narrower active locale-text bands rooted at `0x0062acd4`; those
owners all materialize their individual fields through `0x005b1a42`. The startup-side locale
option path is tighter now too: it resolves the older locale selector through `0x005ae9d5`,
which chooses one LCID pair plus codepage from the incoming locale strings, validates them, and
writes the resulting triple into `0x00dba060`.
- the adjacent startup argument and environment seam is explicit now too: `0x005ad1f4` is the
shared two-pass command-line parser that counts and optionally copies argv pointers plus bytes
while honoring quotes, backslashes, and the multibyte lead-byte table at `0x00dba541`.
`startup_build_argv` `0x005ad360` is the owner above it: it chooses either raw command line
`0x00dbb8d0` or the cached module-path fallback in `0x00dba1e8`, runs that parser once to size
the allocation and once to materialize the final table, then stores `argc-1` in `0x00dba024`
and the argv root in `0x00dba028`. On the environment side, `___crtGetEnvironmentStringsA`
`0x005ad402` materializes one CRT-owned multibyte copy of the Windows environment block using
`GetEnvironmentStringsW + WideCharToMultiByte` when available and `GetEnvironmentStringsA`
otherwise, and `__setenvp` `0x005ad12d` then filters that block into the final envp table by
skipping leading-`=` entries and cloning the admitted `name=value` strings into `0x00dba030`.
- the broader startup owners above those helpers are tighter now too: `startup_init_tls_state`
`0x005abd49` is the real `TlsAlloc + TlsSetValue + per-thread-block` bootstrap. Beneath it,
`startup_init_multithread_lock_table` `0x005a649e` seeds the fixed CRT lock table from the
static lock-storage band at `0x00dba078`, `startup_release_tls_slot_and_multithread_lock_table`
`0x005abcba` is the shared failure cleanup owner, and the adjacent `0x005a653c/0x005a6551/0x005a65d0`
strip now reads cleanly as the generic unlock, lazy-init, and lock-acquire helpers for those CRT
multithread slots. The neighboring `crt_get_or_create_current_thread_data_preserving_last_error`
`0x005abcd8` is also grounded now as the older CRT per-thread data getter that allocates a zeroed
`0x88`-byte record on first use while preserving `GetLastError`. `startup_init_file_handle_table`
`0x005abf1b` is the concrete CRT handle-table owner that seeds
the `0x00dba780` descriptor pages, imports inherited handles from `STARTUPINFO`, grows the table
in `0x20`-entry chunks, and finally backfills the three standard streams from `GetStdHandle`
plus `GetFileType`.
- Evidence: `artifacts/exports/rt3-1.06/startup-call-chain.md`,
`artifacts/exports/rt3-1.06/function-map.csv`.
- Current Boundary: the current startup boundary is now carried at `app_bootstrap_main`. The CRT
shims ahead of it still read as compiler-owned bring-up and import plumbing, and the local static
pass does not expose any earlier nontrivial game-owned callback that seeds globals before that
handoff.