3.0 KiB
§129 — Post-carve, rtu_match/match_one COUNT THE JUMP TABLE AS INSTRUCTIONS; and a carve must never be committed without its owner (P30 S28, func_8013BD74)
Two independent traps, both hit banking one reach-138 jr function. Neither is a compiler wall.
§129a — the target instruction count is INFLATED after a carve
jtbl_carve moves the function's jump table into a dotted .rodata subseg, and splat then emits the
function's .s with a leading .rodata section holding the table, followed by .text:
.section .rodata
dlabel jtbl_801D828C <- 28 entries
enddlabel jtbl_801D828C
.section .text
glabel func_8013BD74 <- the actual 198 instructions
rtu_match reported mine=198 ins, target=226 ins, 206 mismatched — a catastrophic-looking DIFF.
226 − 198 = 28, exactly the table's entry count: the tool counted the data words as
instructions and diffed the body against them.
So a post-carve verdict from rtu_match/match_one is meaningless. A draft that verified
cleanly before the carve will read as a total mismatch after it, and the number will look like
evidence of a deep codegen problem. Verify the body pre-carve; after the carve, let the
whole-binary byte-gate arbitrate (it always was the arbiter — §52b). This is §81's warning one
step further on: §81 says match_one masks relocations so a jr fn's MATCH is not a bank; §129a says
that after the carve its DIFF is not a diff either.
§129b — never commit a carve whose owner is still a stub (it strands the carve)
harvest_verify refuses to run on a dirty tree (§97), and the carve necessarily dirties config/.
The tempting resolution — commit the carve, then bank on a clean tree — creates a stranded carve:
a .rodata carve piece with no matched owner. jr_inventory refuses immediately (R32):
committed .rodata carve ownership is not 1:1 (R32/R33) — a stranded/duplicated carve: [('UNOWNED', '0x801d828c')]
That is a coverage oracle correctly rejecting a state the commit created, and it blocks every later jr operation on that overlay until reverted.
The route for a jr function is the INTEGRATED one: tools/jtbl_family_bank.py, which does
carve → extract → remap → whole-binary gate per sibling inside one uncommitted transaction and
reverts on failure. The §81 hand-chain is for diagnosis; it is not a banking path, because its two
constraints (carve-before-bank, clean-tree-to-bank) pull in opposite directions.
The real blocker underneath, for the record
With the carve applied, splicing the draft fails cc1 with
jtbl_rodata_pads: more rodata .align directives than pad specs (2) — table-count drift vs the carve
— §8e's pad-spec filter failing loud, as designed: the object's committed spec
(0,4 tables=+0x0,+0x70) does not account for the table the newly-matched function emits. That is
genuine §8e work (re-derive the multi-table pad spec including the new owner), not a wall — and it
was only reachable after §129a stopped the phantom 206-instruction "diff" from misdirecting the
diagnosis.