1.6 KiB
§362 — TWO TRAPS WHEN A CARVE MOVES A STUB INTO THE -O0 TU (P31 S68; byte-proven, 6 fns / 2,547 ins across ov_MAIN_012 / ov_SC02_037 / ov_SC03_107)
Banking an -O0 function that sits inside an -O2 object needs o0_subsplit to cut it into its own
region (§116: opt level is per FILE). Two things then bite, both measured:
Trap A — rollout_o0.py goes BLIND to exactly the stubs you just carved. Its stub_file_of()
skips any file whose basename contains _o0, because its design assumes stub-in--O2-TU plus
def-appended-to--O0-TU. A carve that moves the stub INTO the -O0 TU makes both the same file, so
the driver reports no-stub / already banked? and banks nothing. Edit <ov>_o0d.c directly.
Trap B — do not keep the generated §8b carried decl layer. The carve emits
#include "../shared/engine_core.h" plus ~1,100 carried decls, which conflict with the shared -O0
header on 7 symbols (func_80015978 void*/s32, func_800CF854 void/s32, func_801336E8,
D_801274C8/CC/D0). Replace the TU wholesale with the minimal fleet-standard form — legitimate
precisely when the carved region holds only the functions the shared header defines (here
0xD44 = 0xC08 + 0x13C, exact).
Both carve and bank are byte-gated: the carve must be byte-NEUTRAL (sha1 == check.<ov>.sha,
interleave_check ALIGNED, config/overlays.mk unchanged), and only then does the bank get gated.
Derive AND carve under .run/auto/gate.<ov>.lock — a plan derived outside the lock can describe a
tree state that never existed (the c03cd6f3a rule; a concurrent recovery lane was observed editing
the very TU this carve splits, mid-analysis).