## 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.
