Files
OpenMaidEngine/docs/superpowers/specs/2026-07-09-stl-crt-naming-design.md

5.3 KiB
Raw Blame History

STL/CRT auto-naming — de-noising the library layer — design

Date: 2026-07-09 Status: approved (design), plan pending Lever: #2 of 3 in the RE-front-loading program (after handler-labeling, import-map, ctx-struct; before the differential oracle). See the status memory. Home in the canonical map: results in docs/engine-re.md; if a curated registry is built, it becomes a NEW canonical source (vm-map/lib-functions.toml) with a row in the CLAUDE.md maps.

Motivation

3,660 of 4,415 functions in the /v2 image are still default-named (FUN_/LAB_), a large slice of which is statically-linked CRT/STL. We keep re-recognizing the same library functions by behavior (std::map::find = FUN_0047f280, the open-addressing hash insert = FUN_0042cf70, operator new, string/memcpy ops). Naming them lets the decompile stop burying real engine logic in unnamed library noise — the last cheap static front-loader before the dynamic oracle. This is explicitly a de-noising polish, lower-leverage than the first three levers, so it is scoped to stay light.

Approach (recon-first, decided in brainstorming)

Ghidra's Function ID analyzer is enabled but has named little so far (the bundled FidDbs may not cover this VC9/VS2008-era static runtime). So the recon decides the shape.

Task 1 — Function ID recon (THE GATE)

Re-run the Function ID analyzer against /v2, including a pass with "Always Apply FID Labels" enabled, and measure the delta: how many FUN_/LAB_ functions become named (source ANALYSIS/library names). Record the before (3,660 default) and after counts.

  • GATE — STRONG (names a meaningful number, say ≥ 100 new library names): Function ID is the win. Keep the labels, save_program, document the count, done. No curated registry needed.
  • GATE — WEAK (~0 new): the bundled FidDbs don't match this runtime → fall back to the curated hot-set (Task 2). Do not invest in generating a custom VC9 FidDb (out of scope — heavy, low return).

Function ID applies labels with ANALYSIS source, which never clobbers our USER_DEFINED names — so a strong result composes cleanly with the handler/ctx work.

Task 2 — curated hot-set (ONLY if Task 1 is WEAK)

A small canonical registry, same pattern as engine-ctx.toml:

vm-map/lib-functions.toml[[func]] entries { address, name, note, source, confidence } for the library functions we have already identified in our RE (seeded from engine-re.md): e.g. 0x47f280 → std_map_find, 0x42cf70 → hashmap_insert, plus operator new/delete, memcpy, and any string ops we've pinned. tools/lib_functions_build.py (--build/--lint) → build/lib-functions.json

  • docs/lib-functions-reference.md; a run_script_inline pass renames each function (skip if already USER_DEFINED). Grows one [[func]] at a time as we identify more — the durable home for "this worker is a known library function." Small by design (a handful to low-dozens), not a comprehensive sweep.

Validation

  • Task 1: report the newly-named count; spot-check 23 (e.g. does FUN_0047f280 now carry a std::map-family name? does a known operator new site read named?).
  • Task 2 (if taken): do not classify 0x47f280 or 0x42cf70 as generic STL helpers. Later RE proved they are purpose-specific gfx_object_query_source_slot and vm_lvalue_descriptor_hash_insert; decompile gfx_op_0x215_query_source_slot to verify the former remains named; --lint clean; 0 clobbers.
  • save_program succeeds.

Scope & boundaries

  • In: run Function ID + apply; (conditionally) a small curated registry of known library functions.
  • Out: generating a custom VC9/MSVCR90 FidDb (heavy, low marginal return); BSim; comprehensively naming all 3,660 (we take what Function ID gives + what we've RE'd, not a big-bang).
  • Regenerable: build/lib-functions.json + docs/lib-functions-reference.md are generated.

Acceptance criteria

  • Task 1 recon run; before/after default-function counts recorded; gate verdict explicit.
  • If STRONG: labels applied, saved, count documented. If WEAK: vm-map/lib-functions.toml seeded with the known hot functions, built (--lint clean), applied to /v2 (0 clobbers), saved.
  • ≥2 validation spot-checks read as named library calls.
  • docs/engine-re.md records the outcome; tools-reference.md + CLAUDE.md maps updated iff a registry was built; status memory records the milestone (and marks lever #2 done, #3 next).

Outcome (2026-07-09) — PIVOTED

Task 1 recon: Function ID = WEAK (0 new names; bundled FidDbs don't cover the VC9 runtime). Also discovered the library functions we actually touch are already USER_DEFINED (annotate-as-you-go). So the curated CRT/STL registry (Task 2 as specced) would have renamed already-named functions — near-zero value. Pivoted (user-approved) to naming the hot documented-but-unnamed helpers the recon surfaced by call-count: vm_operand_fetch@0x41b940 (1021 refs), vm_operand_write@0x425fb0, vm_operand_lvalue@0x415f30, __security_check_cookie@0x54f981 (692), operator_new@0x5502be (533) — ~2,400 call sites de-noised. No lib-functions.toml/builder built (the Ghidra name is the record for these; no tool consumes them), so CLAUDE.md/tools-reference were not touched. Full account: docs/engine-re.md "Hot-helper naming pass".