Function ID recon = WEAK (0 matches; bundled FidDbs don't cover the VC9 static runtime) and our library workers are already named. Pivoted to naming the hottest documented-but-unnamed helpers by call-count: named 5 (~2400 call sites) in Ghidra — vm_operand_fetch@0x41b940 (1021 refs), vm_operand_write@0x425fb0, vm_operand_lvalue@0x415f30, __security_check_cookie@0x54f981 (692), operator_new@0x5502be (533). Validated: gfx_op_0x215 reads near source-level. Spec/plan + engine-re.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.2 KiB
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; arun_script_inlinepass renames each function (skip if alreadyUSER_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 2–3 (e.g. does
FUN_0047f280now carry astd::map-family name? does a knownoperator newsite read named?). - Task 2 (if taken): decompile
gfx_op_0x215_register_query— itsgfx_registry_map_find(...)/FUN_0047f280call should read as the curatedstd_map_find;--lintclean; 0 clobbers. save_programsucceeds.
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.mdare 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.tomlseeded with the known hot functions, built (--lintclean), applied to/v2(0 clobbers), saved. - ≥2 validation spot-checks read as named library calls.
docs/engine-re.mdrecords 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".