Mangle alloc-body private labels per-alloc to stop jmp.w collisions - #89
Merged
Merged
Conversation
Underscore-private labels in sibling allocs of one module exported the same bare name, so a jmp.w to a local bound to whichever duplicate the linker placed last (a layout-dependent wild branch). Export them per-alloc-mangled.
|
Deploying a816 with
|
| Latest commit: |
0faa6a7
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://b7d24c37.a816.pages.dev |
| Branch Preview URL: | https://fix-jmpw-local-alloc-collisi.a816.pages.dev |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Why
jmp.w <local>to a label inside the same.allocsilently jumped into a different routine. Underscore-private labels (_loop,_done,_scan) in sibling allocs of one module all exported the same bare LOCAL name, so they collided in the flat symbol table — only one survived. Ajmp.w _looprelocation (absolute, resolved at link) then bound to whichever duplicate the linker placed last: a layout-dependent wild branch that presented as "random memory corruption" / "vwf8 breaks build_menu" downstream.bra/bccwere unaffected (relative, resolved in-module at assemble time); only the link-deferred absolutejmp.whit the colliding symbol.PR #88 fixed the cross-module half of this (resolve a relocation's LOCAL operands against the emitting object). This is the cross-alloc-within-one-module half — the actual reported shape (8 allocs each declaring
_done).What
Resolver._export_name: underscore-private labels in anAllocBodyScopenow export under a per-alloc-mangled name (__sc<idx>__name) instead of bare. Public (non-underscore) labels stay bare so cross-alloc refs +.externstill resolve by source name. The relocation renamer routes through the same path, so ajmp.w _looprelocation gets the matching mangled name and resolves to its own alloc's label.Test plan
_loop/_done; eachjmp.w _looptargets its own alloc's_loop(verified in the linked bytes), not the sibling's.jmp.w _loop(PR Stabilize module pipeline: direct-mode out, sections in, paired-import dedup #88 case) still resolves per-object._foostill classifies LOCAL (now__sc1___foo); no bare private name leaks as GLOBAL.Not in this PR
brl(16-bit PC-relative long branch) is still unaccepted — the report notes it as the natural primitive for long intra-routine jumps. Separate follow-up.