Repository navigation
[AUTOMATED] Recover Rust string-literal records; stop the NUL scan gluing unterminated literals - #1274
Merged
Conversation
…str, analysis side) rustc packs unterminated literals back to back in .rodata, so the NUL-run string scan glues adjacent Rust literals into one wrong row: the measured witness reads its three literals as a single 39-byte "hello multilang, !world to decompile \n". The lengths were never lost - every Rust literal's length lives in a static (ptr, len) record (a PIE's R_*_RELATIVE slots in .data.rel.ro with the length in the unrelocated companion word, 458 of them on the witness; absolute word pairs on a non-PIE) - so StrRecordPass (id fatstrrecords, rustc-detected images only) re-reads those records as length-BOUNDED string facts and the commit plants them AHEAD of the NUL stream, retiring the glued rows: the data symbol at each literal spans exactly the literal. One option governs both recognizers: the facts commit under the same Architecture::fat_str gate the engine's (ptr,len) call-argument rule reads, so --option fatstr off drops them at the read-symbols boundary. Guards are the engine rule's own (read-only backing, 1..=4096, UTF-8 >=90% printable; the relocation-less direct arm keeps the NUL scan's minimum of four). No new settable, no catalog count changes; the fatstr row and spec chapters 01/05 describe the second recognizer. Triage context (the verification sweep's two findings): fatstr's call-arg pattern is starved on real rustc -O binaries - format! literals live in static &[&str] pieces records, and direct pair args are dropped upstream by Rust argument recovery - so the record form is the one that exists; and variantnames was found feature-correct on a real -g witness ((*s).tag == Circle) - the old corpus witness's only tagged-enum fn was const-folded out by rustc and Result<u32,String> is a niche layout, the documented stand-down. Gates: make test PARITY OK, make test-stages PARITY OK (no baseline change - no stage XML, no settable), make rust-test green, make check-spec OK, make test-cli 306/306, make lint clean, kuna catalog --check OK. E2E: verify_fatstr_records builds a real rustc PIE and pins the bounded 21-byte symbol under auto vs the glued >21 run under off; hermetic unit tests pin the matcher, bounds and dedup. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WoTv7T2Ep5hmbZcyYSMk1g
… integration.rs union, merged-tree artifact regen Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WoTv7T2Ep5hmbZcyYSMk1g
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.
Real rustc binaries keep
&strliterals as (pointer, length) records in.data.rel.ro, not as call arguments — and the NUL-run string scan glues the unterminated literal bytes into one wrong string:The fix:
StrRecordPass(rustc-detected images only): walks the&strrecord pairs — a relocated pointer slot whose companion word is a plausible in-rodata length (relocation arm for PIEs, absolute-pair arm otherwise, width-generic) — and emits length-bounded string facts committed ahead of the NUL stream, so each literal's symbol spans exactly the literal and the glued rows retire via the occupied-address guard.fatstrmode at the commit boundary — no new option, no catalog changes.variantnameswas verified correct on a runtime-dependent-gwitness ((*s).tag == Circle); the earlier zero reading came from a const-folded witness and a metric that missed constant renames.Tests:
verify_fatstr_recordsbuilds a real rustc PIE at test time and pins the bounded literal under auto and the glued form under off; hermetic unit tests pin the record matcher, bounds, dedup, and width handling. Datatests 675/675 and stage parity unchanged.🤖 Generated with Claude Code
https://claude.ai/code/session_01WoTv7T2Ep5hmbZcyYSMk1g