# 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. ### 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