# Changelog All notable changes to gasm-devkit are documented here. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [development] ### Changed - **Canonical just recipes.** `just gates` is the definition of done (build, fmt-check, vet, test, race). `install` now builds and copies the binary into `~/.local/bin` (`BINDIR` overrides) instead of downloading module dependencies, and `install-bin` is gone. The test gate sweeps the logic packages (arch through verify; the hardware-bound `debug` and the thin `cmd/gasm` sit outside it), so the coverage floor is computed over the product code and the number is identical locally and in CI. `fuzz` requires its target package. - **The reported version comes from the build.** `gasm --version` prints the version the toolchain recorded: the tag on a tagged checkout, a pseudo-version naming the commit below one, `+dirty` on a dirty tree and `(devel)` outside version control. Nothing is injected with `-ldflags -X` any more. - **CI realigned with the gate set.** The push pipeline runs the gates minus race in one job, in the `gates` order, with a cached Go setup and the module as the version source; a superseded run of the same branch is cancelled instead of queueing; every `go test` runs under a ten-minute bound that matches its job's; the race detector moved to a hand-dispatched workflow and runs in the local gate before a tag is cut, never on a push or a tag; the release builds without injection and its smoke test requires the recorded tag and rejects `+dirty`. - **The documents follow the standard set.** `docs/ARCHITECTURE.md` is organised as Overview, Packages, Data flow, State and lifetime and Dependencies, and carries a sequence diagram of the assembly path; `docs/DEVELOPMENT.md` lists every recipe in one table and documents the coverage floor, the CI and the release flow; `docs/CLI.md` gives the synopsis, the commands, every flag with its default, the exit codes and worked examples; `CONTRIBUTING.md` carries the Contributor terms and states the commit trailer form, the one-logical-change rule and the licence header rule. The repository's own assembly (the `verify` trampolines and the test kernels) is in `gasm fmt` canonical form. - **The README states the project's purpose and status.** It opens with a warning that the tool is an experiment under active development, version 0.x.x, free to change without warning, with 1.0.0 far off, and already in active use on real assembly work. It describes both goals (tooling for Plan 9 assembly, and Plan 9 assembly outside the Go toolchain), argues the case for the syntax in a new Why Plan 9 assembly section, and carries a Direction section: extended instruction support, full GOOBJ and ELF compilation, Linux and FreeBSD, and the four architectures. ### Fixed - **The dependency statement was wrong.** `golang.org/x/arch` is not test-only: `gasm dis` and the debugger's listings decode through it, so it is linked into the binary. `CONTRIBUTING.md` and `docs/ARCHITECTURE.md` said otherwise. - **The CLI reference listed 17 of the 18 lint rules.** The missing `reserved-register-write` is documented with the rest. ## [0.33.0] - 2026-09-14 ### Added - **Stack-split guards in `gasm asm`.** Every framed function now gets the morestack prologue check and the trailing morestack block (`CALL runtime.morestack_noctxt`), byte-identical to the toolchain's `stacksplit` output on all four architectures: the small, medium and big frame classes, auto-NOSPLIT leaves, the materialised constants of large frames (arm64 `R27`, riscv64 `X31`, loong64 `R30`) and the arm64 extrasize rule. Assembled objects are therefore linkable for split functions, not only `NOSPLIT` leaves. - **`gasm dis`.** Standalone disassembly through `golang.org/x/arch`: a `.s` file is assembled and listed per `TEXT` function with local labels at their real offsets, or raw bytes from a file or stdin are disassembled linearly (`-a` selects the architecture). The debugger shares the same decoder instead of carrying its own. - **`gasm fmt -l` and `-d`.** Check mode lists files whose formatting differs; diff mode prints a unified diff from the project's own LCS-based differ, with GNU header semantics. - **LSP cross-file navigation.** Go-to-definition and find references fall back from local labels to the `TEXT` functions of every open document, and rename follows the same cross-file matching. - **Large frame offsets on riscv64 and arm64.** Frame-relative loads and stores beyond the signed 12-bit immediate range materialise the address through the toolchain temp register (riscv64 `X31`, arm64 `R27`) instead of silently truncating the offset (riscv64) or rejecting the instruction (arm64); arm64 frame sizes now add the toolchain's extrasize exactly (+8 when the frame leaves an alignment gap, +16 when it is already aligned). - **Tail calls `JMP sym(SB)`** on all four architectures (amd64 `E9`, arm64 `B`, riscv64 `JAL X0`, loong64 `B`) with the call relocation. - **Live oracle-parity tests.** Kernel files covering every guard class, large-offset pattern and tail call are assembled by gasm and by the installed `go tool asm` and compared byte-for-byte on all four architectures, alongside the existing pinned-byte tests. ### Fixed - The v0.32.0 review findings: the parser rejects malformed `TEXT` frames and parses signed frame sizes; amd64 frame adjustments above 127 bytes encode with imm32; arm64 and loong64 relocation encodings match the toolchain; the linter guards unnamed `TEXT` directives and refreshes its textflag table; the LSP recovers from handler panics and decodes client URIs; watchpoint slot state moved into the debug session; dead verify code removed; em and en dashes replaced across sources. - `gasm asm --format goobj`: internal calls to `TEXT` symbols of the same file resolve on every architecture (the reference check accepted only the amd64 call kind). - `gasm asm --format elf` on loong64: branch relocations now map to `R_LARCH_B26` instead of falling into `R_LARCH_PCALA_HI20`. - arm64 large-prologue `ADD`/`SUB` use the extended-register encoding the toolchain picks, and the morestack block saves the link register with the toolchain's `OR` form on loong64. ## [0.32.0] - 2026-08-31 ### Added - **Multi-architecture debugger.** `gasm debug` carries per-architecture ptrace register access, disassemblers (`golang.org/x/arch`), register display, FP register views and stop-info handlers for arm64, riscv64 and loong64, and the REPL is arch-neutral. Sessions are runtime-validated on amd64; the other hosts execute through the now-working JIT trampolines, but their ptrace loops have not seen hardware yet. - **Headless debugging.** `gasm debug --script` runs REPL commands from a file (or stdin) and exits; `--timeout` kills the debuggee when a run hangs, with the watchdog armed before the ptrace attach. - **Conditional breakpoints.** `break