Skip to content

Promote daObjRcCarpet_c as a compiler-owned C++ TU - #2104

Merged
andrewboudreau merged 4 commits into
mainfrom
cpp/rccarpet-intact-tu
Sep 1, 2026
Merged

Promote daObjRcCarpet_c as a compiler-owned C++ TU#2104
andrewboudreau merged 4 commits into
mainfrom
cpp/rccarpet-intact-tu

Conversation

@andrewboudreau

@andrewboudreau andrewboudreau commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Promotes the original ov036 daObjRcCarpet_c translation unit: nine legacy source files become one src/actors/daObjRcCarpet_c.cpp owning text 0x02112158..0x021125b0 and data 0x02113f4c..0x02114020. The compiler emits D1/D0, RTTI, the type name, and the vtable. C ABI remains only at the ROM's unmangled factory, SpawnInfo, two unnamed helpers, and the measured manual construction seam required for allocator/relocation fidelity.

Reviewer follow-up:

  • replayed only the four RcCarpet commits directly onto current main after merged Promote daPropeller_Heyho_c as a compiler-owned C++ TU #2096; the obsolete FlyGuy parent stack is gone
  • regenerated notes/cpp-tu-current-state.md from the post-rebase tree rather than hand-resolving it
  • retained neutral data_ov036_02113ff4 / data_ov036_02114010 aliases
  • removed the coined RcCarpet_VT22 / RcCarpet_VT29 rows
  • left the pre-existing vtable-extent issue unchanged, as requested

Fresh validation on head 66b9839b49dd over main 4006a7835994:

  • production candidate: 11,088/11,088 functions, 6/6 source-owned data claims, 106/106 modules, zero mismatches
  • strict control: 11,011/11,011 functions, 106/106 modules, same nine pre-existing symbol diagnostics
  • stock ROM SHA-256 d1506e90efae5e2d2cf119926a4ac2a291bd5ca78349d09d5024e1a918c478e8
  • emitted data audit: 9 verified, 6 partial by configured extent, 0 differing, 0 unnamed
  • affected relocation check: one expected aggregate multi-function-TU NO-SYM warning, 0 blocking
  • 98/98 reconstructed TUs compile; port references 405/405; shared-TU compatibility READY
  • attribution: 8 consolidations intact, 0 changed, 0 lost
  • converted ratchet PASS: baseline 2,562, current 2,591 (+29); generated state note current
  • premerge static gates: 8/8 pass to pass

The attribution-override label remains applied per project policy. No claims, attempt-ledger, or dashboard artifacts are included.

@tangos-validator

tangos-validator Bot commented Aug 31, 2026

Copy link
Copy Markdown

✅ PR validation — Passed

Committed merge passes; 8 contributor credit reassignment(s) noted, not a blocker.

Full merge validation

Check Result
Committed test merge yes
Byte-verified functions 10,731 / 11,347 (94.57%, -8)
Byte-verified code bytes 1,995,776 / 2,211,124 (90.26%, -1,000)
Claimed, not byte-verified 486 functions, 109,904 bytes (+8)
Perfect source moves 0 R100
Enrolled ranges (delinks complete) 11,059 functions, 2,053,148 bytes (92.86%, +0) -- differs from byte-verified by +328
Contributor credit 0 added, 8 changed, 0 lost
Relocation check 9 checked; 9 VERIFIED
Port reference check 405 checked; 0 stale
Module fidelity 106/106 exact; 100.000000% compared bytes
Code linked from verified source 11,088 functions, 2,067,148 bytes (93.49%)
Module bytes from source 2,067,148 / 3,049,600 (67.8%); 811,492 (26.6%) are data no delink entry reaches
ROM data reproduced from source 567 symbol(s) exact, 162 partial, 5 differ

Contributor credit moved (8)

Function Source Before After
ov036:0x021121c8 src/_ZN15daObjRcCarpet_cD0Ev.cpp -> src/actors/daObjRcCarpet_c.cpp tangosdev github-actions[bot]
ov036:0x0211224c src/func_ov036_0211224c.cpp -> src/actors/daObjRcCarpet_c.cpp tangosdev github-actions[bot]
ov036:0x021122c0 src/func_ov036_021122c0.cpp -> src/actors/daObjRcCarpet_c.cpp tangosdev github-actions[bot]
ov036:0x02112318 src/_ZN15daObjRcCarpet_c16CleanupResourcesEv.cpp -> src/actors/daObjRcCarpet_c.cpp tangosdev github-actions[bot]
ov036:0x02112378 src/_ZN15daObjRcCarpet_c6RenderEv.cpp -> src/actors/daObjRcCarpet_c.cpp tangosdev github-actions[bot]
ov036:0x021123c8 src/_ZN15daObjRcCarpet_c8BehaviorEv.cpp -> src/actors/daObjRcCarpet_c.cpp tangosdev github-actions[bot]
ov036:0x0211244c src/_ZN15daObjRcCarpet_c13InitResourcesEv.cpp -> src/actors/daObjRcCarpet_c.cpp tangosdev github-actions[bot]
ov036:0x02112538 src/FlyingCarpet_Spawn.cpp -> src/actors/daObjRcCarpet_c.cpp tangosdev github-actions[bot]

Byte-verified means the range carries complete in a delinks.txt, so the ROM build compiled it and compared it to the cartridge. The 486 claimed functions have a src/ file named after the symbol with no NONMATCHING banner, and nothing compiles them -- dsd fills their addresses with the ROM's own bytes. Both together are the 11,217 this project calls matched.

Warnings: contributor attribution changed, not a blocker (8 changed, 0 lost -- src/actors/daObjRcCarpet_c.cpp: tangosdev -> github-actions[bot]; src/actors/daObjRcCarpet_c.cpp: tangosdev -> github-actions[bot]; src/actors/daObjRcCarpet_c.cpp: tangosdev -> github-actions[bot]; +5 more); 9 address range(s) left the byte-verified set while enrolled totals held steady: ov036:0x02112158-0x021121c8, ov036:0x021121c8-0x0211224c, ov036:0x0211224c-0x021122c0, ov036:0x021122c0-0x02112318, ov036:0x02112318-0x02112378, +4 more; 8 more function(s) now claim a match that nothing compiles; enroll them in a delinks.txt to have the ROM build check them.

Per-file link-check detail

All 1 changed file(s) compile to the ROM byte-for-byte with correct relocation targets.

File Symbol Result Slots checked
src/actors/daObjRcCarpet_c.cpp _ZN15daObjRcCarpet_cD1Ev + _ZN15daObjRcCarpet_cD0Ev + func_ov036_0211224c + func_ov036_021122c0 + _ZN15daObjRcCarpet_c16CleanupResourcesEv + _ZN15daObjRcCarpet_c6RenderEv + _ZN15daObjRcCarpet_c8BehaviorEv + _ZN15daObjRcCarpet_c13InitResourcesEv + FlyingCarpet_Spawn ✅ verified 9

The private worker commits a test merge, builds the stock ROM profile, compares every executable module, measures matched and source-built code, checks contributor lineage, and verifies affected relocations. The mod profile is opt-in and is not part of this merge gate.

@andrewboudreau andrewboudreau added the attribution-override Maintainer accepts this PR's contributor-credit changes; validation reports them as warnings label Aug 31, 2026
@andrewboudreau
andrewboudreau force-pushed the cpp/rccarpet-intact-tu branch from 29d9a52 to ef612ac Compare August 31, 2026 19:49

@andrewboudreau andrewboudreau left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at ef612aca2. The promotion itself is clean and I checked it hard. One change requested, on the two coined symbol names — and not for the reason I expected when I started. I went looking for a convention-consistency problem and found a correctness one instead, so this comment is mostly the measurement.

What is solid

The class name is ROM-proven. 15daObjRcCarpet_c is present in extracted/overlays/overlay_0036.bin; FlyingCarpet is absent. So the promotion is not name-blocked on the class, which is what stopped PoleLift in #2066.

FlyingCarpet_* is not your debt. FlyingCarpet_Spawn / FlyingCarpet_SpawnInfo are on origin/main today across eleven tracked files. You inherited them and correctly left them alone. Out of scope here, and I am not asking for them.

The converted-baseline moves as a clean SET, not a loss.

base count 2570    head count 2570
REMOVED (3)                                ADDED (3)
  src/_ZN15daObjRcCarpet_c6RenderEv.cpp  ->  src/actors/daObjRcCarpet_c.cpp#_ZN15daObjRcCarpet_c6RenderEv
  src/_ZN15daObjRcCarpet_cD0Ev.cpp       ->  src/actors/daObjRcCarpet_c.cpp#_ZN15daObjRcCarpet_cD0Ev
  src/_ZN15daObjRcCarpet_cD1Ev.cpp       ->  src/actors/daObjRcCarpet_c.cpp#_ZN15daObjRcCarpet_cD1Ev

Three-for-three per-member rewrite, count flat. That is the shape a promoted TU is supposed to make, and the nine // @symbol markers are what earn it.

Static gates, on the real merge tree, both ways:

vs origin/tools/intact-tu-section-order   8/8 pass -> pass   (entries 10789 -> 10782, -7)
vs origin/main                            8/8 pass -> pass   (entries 10814 -> 10782, -32)

Nothing goes green → red on either base.

The delink consolidation is right. Nine .text ranges collapse into one contiguous 0x02112158..0x021125b0, matching the manifest's linker run exactly, and the TU picks up .data 0x02113f4c..0x02114020. Slots 16/17 of the vtable are 0x02112158 / 0x021121c8 — your D1 and D0, at the head of the run — so the out-of-line destructor really is the key function and the compiler-emitted vtable is legitimately this TU's to own.

Change requested: RcCarpet_VT22 and RcCarpet_VT29 name a phantom

-data_ov036_02113ff4 kind:data(any) addr:0x02113ff4 ambiguous
-data_ov036_02114010 kind:data(any) addr:0x02114010 ambiguous
+RcCarpet_VT22 kind:data(any) addr:0x02113ff4 ambiguous
+RcCarpet_VT29 kind:data(any) addr:0x02114010 ambiguous

The slot arithmetic is correct, and that is exactly what makes this dangerous. _ZTV15daObjRcCarpet_c is at 0x02113f9c; +22*4 = 0x02113ff4 and +29*4 = 0x02114010. Both check out. A reader will believe these names.

1. They are not objects. They are interior words of one contiguous vtable.

Dumped from overlay_0036.bin (base 0x021111a0), the table runs 0x02113f9c..0x0211402033 words, every one a code address, with no structural break anywhere:

slot16 0x02112158   <- D1, this TU          slot21 0x02010148
slot17 0x021121c8   <- D0, this TU          slot22 0x02010144   <- "RcCarpet_VT22"
slot18 0x02010160                           slot23 0x02010140
slot19 0x02010154                           ...
slot20 0x0201014c                           slot29 0x02010124   <- "RcCarpet_VT29"

Slots 18–30 are a monotonically descending run of arm9 addresses — inherited base virtuals. Slots 22 and 29 are ordinary members of that run. Nothing distinguishes them.

2. Nothing about the vtable explains why symbols exist there.

Every one of the 33 slots carries a relocation. Twenty of them target main:

slot18 from:0x02113fe4 to:0x02010160 module:main
slot21 from:0x02113ff0 to:0x02010148 module:main
slot22 from:0x02113ff4 to:0x02010144 module:main     <- has a symbol
slot23 from:0x02113ff8 to:0x02010140 module:main     <- does not
slot29 from:0x02114010 to:0x02010124 module:main     <- has a symbol
slot30 from:0x02114014 to:0x020100dc module:main     <- does not

If the symbols came from the vtable's own relocations, twenty slots would have them. Two do. So the cause is somewhere else.

3. The cause is overlay aliasing, and the referent belongs to another overlay.

0x02113ff4 occurs as a word exactly once in the whole cartridge — arm9_dec.bin at file offset 0x8c9dc. 0x02114010 occurs at 0x8c998. Both sit inside a dense pointer table: 83 of the 96 surrounding words are 0x0211xxxx addresses.

Ten overlays load at the same base and all cover both addresses:

ov014 ov015 ov016 ov020 ov021 ov022 ov029 ov034 ov036   base 0x021111a0
ov075                                                    base 0x02113ee0

They are mutually exclusive actor overlays sharing one address window, so that arm9 table resolves into whichever one is resident. dsd cannot tell which, so it fanned a symbol into every overlay's table — data_ov014_02113ff4, data_ov015_02113ff4, and so on, including ov036's.

And in two of those overlays the address already has a real, meaningful name in tracked config:

config/arm9/overlays/ov029/symbols.txt   RotatingPlatformWdw_SpawnInfo  addr:0x02113ff4
config/arm9/overlays/ov022/symbols.txt   LavaSeesaw_SpawnInfo           addr:0x02114010

SpawnInfo objects, reached from an arm9 spawn-info dispatch table. That is a coherent story for what arm9 word 0x8c9dc actually points at. daObjRcCarpet_c's vtable slot 22 is not.

4. The rename note also inverts the direction

inferred compatibility alias for the ROM relocation target at vtable slot 22

In config/arm9/overlays/ov036/relocs.txt this address is a relocation source, not a target:

from:0x02113ff4 kind:load to:0x02010144 module:main

The target is 0x02010144 in main. Minor next to the above, but it is in the row that a future reader will use to decide whether to trust the name.

The ask

Revert both rows to data_ov036_02113ff4 / data_ov036_02114010 — symbols.txt and the two symbols/actor_renames.tsv rows.

The neutral names are phantoms too, but they assert nothing. RcCarpet_VT22 asserts that daObjRcCarpet_c has a data object at its own vtable slot 22, which is not true in any sense, and a coined name that manufactures evidence is the thing that blocks data verification later.

I want to be fair about intent: "compatibility alias … exact source spelling is not preserved" shows you knew these were not real source symbols, and that hedge is the right instinct. The problem is that the note stays in the TSV while the name travels into symbols.txt, the manifest, and every downstream tool.

Nothing here threatens the byte match — intact-object mode takes the whole .data section wholesale, so the interior split does not reach the output, and I expect the validator to be green. That is the point: this is a config-truth defect the byte gates structurally cannot see.

Note, not an ask

These two symbols truncate _ZTV15daObjRcCarpet_c's extent to 22 words when the real table is 33. That is the same shape as the _ZTV14dScMgD3DBase_c truncation already open on my side, it predates this PR, and reverting the names does not fix it. Please don't try to fix it here — the extent change trips a ratchet and wants its own PR. I only mention it so the next person to touch ov036 knows the extent is not to be trusted.

Ordering

Stack is #2096#2103#2104.

  • #2096 still carries CHANGES REQUESTED from me over FlyGuy_VT7 / FlyGuy_VT14; re-measured at 28587e4e5 and both are still present. Same family of issue as above, which is why I want the convention settled once rather than three times.
  • #2103 I have reviewed and it is ready on content, held only on its base.
  • #2104 is cut from #2103 and lands third.

Worth saying plainly that this PR is the reason #2103 exists — #2103's own test fixture asserts it still reproduces "RcCarpet's measured RTTI/resource inversion". The pairing is sound; the ordering is just forced.

Everything else in this one I checked and it holds.

@andrewboudreau andrewboudreau left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heads-up from the merge lane, not a content objection: this PR went DIRTY when #2103 and #2125 landed. Nothing about the review verdict changes.

git merge-tree --write-tree origin/main <head> on the current tips:

#2062   CONFLICT (content): notes/cpp-tu-current-state.md
#2104   CONFLICT (content): attribution.json
        CONFLICT (content): notes/cpp-tu-current-state.md

Both files are the standing serial chokepoint for this lane — every TU promotion rewrites them, so any two TU PRs in flight collide there regardless of how disjoint their source is.

Do not hand-resolve notes/cpp-tu-current-state.md. It carries its own instruction at the top:

<!-- Generated by tools/cpp_tu_state.py. Do not hand-edit live counts. -->

Take either side to clear the marker, then regenerate and check:

python tools/cpp_tu_state.py --write-note
python tools/cpp_tu_state.py --check-note

Hand-merging it produces a file that is textually plausible and numerically wrong — the counts are derived from the post-merge tree, not from either parent, so neither side's numbers are right and a hunk-by-hunk resolution splices two stale snapshots. --check-note is what catches that.

attribution.json is the other one: it conflicts three-way, not as a key union. Resolving it by taking the union of keys silently drops the third parent's edits. Attribution is a stated non-goal here, so if it fights you, take main's and move on rather than spending time on it.

Once you push the restack I'll re-run the gates on the new merge tree and pick the review back up where it stands.

@andrewboudreau
andrewboudreau changed the base branch from main to cpp/flyguy-genuine-tu September 1, 2026 04:24
@andrewboudreau

Copy link
Copy Markdown
Collaborator Author

Reviewer requests are resolved on refreshed head 0a5171cd8fff76766acbb086de3cd6f32a41bb6c:

  • restored neutral data_ov036_02113ff4 / data_ov036_02114010 aliases throughout the manifest/config
  • removed the two coined RcCarpet_VT22 / RcCarpet_VT29 actor-rename rows
  • left the pre-existing vtable extent unchanged, as requested
  • re-cut the source/provenance/fix commits patch-identically onto current Promote daPropeller_Heyho_c as a compiler-owned C++ TU #2096 and regenerated notes/cpp-tu-current-state.md from the resulting tree (no hand-merged counts)

The fresh production build is exact: 11,088/11,088 functions, 5/5 source-owned data claims, 106/106 modules, zero mismatches, stock ROM SHA-256 d1506e90efae5e2d2cf119926a4ac2a291bd5ca78349d09d5024e1a918c478e8. The strict control is also 106/106 with the same nine pre-existing symbol diagnostics. All 97 TUs compile, port references are 405/405, and attribution reports eight consolidations intact with zero changed/lost.

Base automatically changed from cpp/flyguy-genuine-tu to main September 1, 2026 08:08
@andrewboudreau

Copy link
Copy Markdown
Collaborator Author

Restacked and revalidated in head 66b9839b49dd:

  • replayed only the four RcCarpet commits onto current main after merged Promote daPropeller_Heyho_c as a compiler-owned C++ TU #2096
  • regenerated the conflicted state note from the resulting tree
  • neutral partition aliases remain; coined RcCarpet_VT22/VT29 names remain absent
  • the pre-existing vtable extent is untouched

Fresh proof: exact ROM (d1506e90...), 11,088/11,088 functions, 6/6 source-owned data claims, 106/106 modules, zero mismatches; 98/98 TUs; 405/405 port refs; eight attribution consolidations intact with zero changed/lost; converted ratchet +29; merge-tree gates 8/8 pass to pass.

@andrewboudreau
andrewboudreau merged commit bb93b8f into main Sep 1, 2026
8 checks passed
@andrewboudreau
andrewboudreau deleted the cpp/rccarpet-intact-tu branch September 1, 2026 09:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

attribution-override Maintainer accepts this PR's contributor-credit changes; validation reports them as warnings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant