Commit Graph

1 Commits

Author SHA1 Message Date
Drew T 7d10fd7e20 fix(jtbl_carve): parse_config now implements its documented contract (md_* c-line corruption)
parse_config's docstring said 'the trailing run of {data,.rodata} pieces after
the last c piece'; its code took data_pieces[0], the first such piece anywhere in
the file. Those agree on 171 configs and disagree on 42: the md_* modules open
with the 154-A leading island - [0x0, .rodata, md_XXX] BEFORE their c piece, so
apply()'s splice lines[:lo] + region + lines[hi:] deleted the c line and wrote the
yaml to disk before the tool errored out for unrelated reasons.

Fixed by deriving the region from the last c piece, plus an R43 guard that refuses
outright if any c piece lands inside the window apply() rewrites wholesale.

Also, correcting what S58's blanket refusal had lumped together:
  * md_* (42 configs) was the whole corruption class.
  * main was never in it - its pieces are already [all c ..., data, .rodata, data].
    main's real defects were the config PATH (there is no config/splat.main.yaml,
    it is splat.us.exe.yaml) and the FILE BASE: the EXE has a 0x800 header, so the
    delta is 0x8000F800, not the yaml's first vram: 0x80010000, and with the naive
    value payload_word silently read 0x800 early. Both fixed; the base comes from
    the single derivation in family_remap.vram_of (R33).

The cfg_path class refusal is lifted and replaced by an operation-level one: a carve
whose table lies below the data region is in the leading island, which a tail carve
cannot reach, so build_carve refuses and names the island-split lane (R43).

tools/test_jtbl_parse_config.py proves all three, read-only:
  NC-1 regression 171/171 configs byte-unchanged by the fix
  NC-2 defect     42/42 md_* lose a c line under the historical derivation; 42/42
                  keep every c line under the fix
  NC-3 main       cfg=splat.us.exe.yaml base=0x8000F800, region starts after the last c
2026-08-24 10:42:11 -06:00