Skip to content

[AUTOMATED] Recover Go string records from writable data sections (fatstr Go arm) - #1277

Merged
mahaloz merged 2 commits into
mainfrom
multilang-go-strings
Oct 26, 2026
Merged

mahaloz merged 2 commits into
mainfrom
multilang-go-strings

Conversation

@mahaloz

@mahaloz mahaloz commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

Go keeps its string data as one unterminated blob, so almost no Go function decompiled with a readable string literal — 164 functions across the 12-binary Go corpus, against thousands of real string uses:

kuna decompile vet <fn> --json --option fatstr off | grep '"'     # raw pointers + magic lengths
kuna decompile vet <fn> --json                                     # "no required module provides package %q", ...

The fix:

  • The string-record pass ([AUTOMATED] Recover Rust string-literal records; stop the NUL scan gluing unterminated literals #1274) gains a Go registration: measured on real go1.22 binaries (non-PIE, zero relocations), 480 of 545 of the hello witness's (ptr,len) headers sit in .data/.noptrdata, not read-only data — so the Go arm widens only the slot regions; the target test is unchanged (text must sit in genuinely read-only data), and the rustc registration is byte-identical to before. Go's substring sharing is handled longest-first with the existing occupied-address guard.
  • Same fatstr gate, registered before gopclntab so that pass keeps its appended-last contract. No new option.

Measured (12 Go corpus binaries, on vs off): functions containing a string literal 164 → 7,046 (vet 3→1,075, gofmt 5→560, test2json 0→471); wall +1.2% aggregate (budget 5%).

Tests: the records e2e family gains a Go arm (stripped go build at test time; auto commits the literal's exact extent, off states nothing); unit tests pin the slot/target split and the dedup; pass-set tests updated. Datatests 675/675 unchanged.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WoTv7T2Ep5hmbZcyYSMk1g

mahaloz and others added 2 commits October 26, 2026 02:01
… record pass's Go arm)

Go packs string data as one unterminated .rodata blob, so the NUL scan
recovers almost nothing: 164 functions across the 12-binary Go corpus carry
a string literal today. The headers are there - the measured non-PIE go1.22
toolchain binaries keep (ptr, len) pairs as absolute words, 480 of the hello
witness's 545 in .data and the rest in .rodata - and they are the same
record shape the fatstr pass already walks for rustc.

The Go arm registers the existing StrRecordPass for Go-detected images with
the direct arm's SLOT regions widened to .data/.noptrdata; the TARGET test
is unchanged (text must sit in genuinely read-only data), which keeps a
writable slot's mutability irrelevant. Same-start records dedup
longest-first (Go shares literal bytes between headers), and a record
starting inside an earlier one is retired by the commit arm's
occupied-address guard. Same option, same commit gate, no new settable; the
fatstr row's registration prose now names both languages (fixture/options
regenerated, no counts moved).

Measured (12 Go corpus rows, decompile-all --max-fn-seconds 10): functions
containing a string literal 164 -> 7,046; aggregate wall 839.7 s -> 849.4 s
(+1.2%, budget 5%); the `kuna strings` INVENTORY count is unchanged by
design (that surface scans with Termination::Any, independent of committed
facts). E2E: the fatstr-records family gains a Go arm - a stripped go build
of the same runtime-indexed table commits the literal's exact 21 bytes
under auto and nothing states that extent under off. Unit tests pin the
slot/target split and the longest-first dedup.

Gates: make test PARITY OK, make test-stages PARITY OK (no baseline change),
make rust-test green (one documented decompile_budget_cli wall-clock flake,
idle-green), check-spec OK, test-cli 306/306, lint clean, catalog --check OK.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WoTv7T2Ep5hmbZcyYSMk1g
@mahaloz
mahaloz merged commit 6adbb57 into main Oct 26, 2026
9 checks passed
@mahaloz
mahaloz deleted the multilang-go-strings branch October 26, 2026 02:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant