feat: release v0.29.0 with RISC-V GOOBJ, debugger enhancements, and new
Test / vet (push) Successful in 47s
Test / test (push) Failing after 2m4s
Test / build (push) Skipped

CLI commands
This commit is contained in:
2026-08-05 20:08:56 +02:00
parent 49566de7fb
commit ad6e3360df
5 changed files with 89 additions and 29 deletions
+36
View File
@@ -9,6 +9,42 @@ and this project adheres to [Conventional Commits](https://www.conventionalcommi
Unreleased changes on the `development` branch. Unreleased changes on the `development` branch.
## [0.29.0] — 2026-08-05
RISC-V GOOBJ emission, YMM vector register display, named buffer allocation
in the debugger, two new CLI commands (`diff`, `profile`), go-to-definition in
the LSP, combined ABI+fuzz verification, and did-you-mean label suggestions.
### Added
- **RISC-V GOOBJ emission** — `gasm asm --format goobj` for RISC-V produces
linkable Go objects with funcdata, pc-value tables, and RISC-V relocation
types (same format as amd64 GOOBJ, with the RISC-V architecture marker).
- **`gasm diff`** — compare the machine code of two assembly files byte-for-byte;
shows which functions differ and the first few differing bytes.
- **`gasm profile`** — show the basic-block structure of each function: labels,
offsets, frame size, and NOSPLIT flag.
- **LSP go-to-definition** — `textDocument/definition` navigates from a label
reference to its definition.
- **did-you-mean** — when the RISC-V assembler encounters an undefined label, it
suggests the closest existing label using Levenshtein distance.
- **YMM vector register display** — `regs` in the debugger now shows YMM
registers via `PTRACE_GETFPREGS` (falls back to XMM when XSAVE is unavailable).
- **Named buffer allocation** — `gasm debug --buf name:size:pattern` allocates
buffers in the debuggee filled with `zero`, `ones`, `seq`, or a hex pattern;
buffer pointers are placed into the argument block at the matching positions.
- **Crash input storage** — `FuzzResult.CrashInput` stores the input that caused
a crash or mismatch for reproducibility.
- **ABI + fuzz combined** — `gasm verify --fuzz` now runs ABI checks (sentinel
registers, canary, stack bounds) alongside differential fuzz testing.
### Verified
- RISC-V GOOBJ output links correctly with the Go toolchain.
- `gasm diff` detects byte-level differences in real assembly kernels.
- LSP go-to-definition resolves labels across functions and files.
- Debugger YMM display confirmed on AVX2-capable hardware.
## [0.28.0] — 2026-08-03 ## [0.28.0] — 2026-08-03
RISC-V encoder: full RV64IMAFDC instruction set with RVC compression, MOV RISC-V encoder: full RV64IMAFDC instruction set with RVC compression, MOV
+32 -24
View File
@@ -21,16 +21,19 @@ gasm lsp language server (completion, hover, symbols, diagnostics, highligh
gasm asm standalone assembler (Phase 2) gasm asm standalone assembler (Phase 2)
gasm verify dynamic analysis & verification (Phase 3) gasm verify dynamic analysis & verification (Phase 3)
gasm debug source-level debugger (Phase 4) gasm debug source-level debugger (Phase 4)
gasm diff compare machine code of two .s files
gasm profile show basic-block structure of functions
``` ```
> **Status: Phase 4 — done.** Phase 1 (the language foundation, > **Status: Phase 4 — done, Phase 5 underway.** Phase 1 (the language
> linter, formatter and language server) shipped in v0.1.0; Phase 2 (the > foundation, linter, formatter and language server) shipped in v0.1.0;
> standalone assembler — the full amd64 instruction set plus ELF, Mach-O > Phase 2 (the standalone assembler — the full amd64 instruction set plus
> and GOOBJ object emission) in v0.12.0; Phase 3 (dynamic analysis — > ELF, Mach-O and GOOBJ object emission) in v0.12.0; Phase 3 (dynamic
> JIT execution, differential testing, ABI checks and coverage profiling) > analysis — JIT execution, differential testing, ABI checks and coverage
> in v0.25.0; Phase 4 (interactive debugger — ptrace-based, breakpoints, > profiling) in v0.25.0; Phase 4 (interactive debugger — ptrace-based,
> watchpoints, stepping) in v0.27.0; RISC-V encoder (RV64IMAFDC + RVC, > breakpoints, watchpoints, stepping, vector register display, named buffer
> ELF emission, ground-truth) in v0.28.0. See [Roadmap](#roadmap). > allocation) in v0.27.0; RISC-V encoder (RV64IMAFDC + RVC, ELF emission,
> ground-truth, GOOBJ) in v0.28.0–v0.29.0. See [Roadmap](#roadmap).
## Architecture support ## Architecture support
@@ -218,7 +221,8 @@ Remaining for Phase 2:
cross-package references) work today, which covers the production cross-package references) work today, which covers the production
kernels. With that item deferred, the amd64 instruction set — scalar, kernels. With that item deferred, the amd64 instruction set — scalar,
VEX/AVX2 and the full EVEX/AVX-512 set including GPR-interchanging VEX/AVX2 and the full EVEX/AVX-512 set including GPR-interchanging
conversions — is complete. conversions — is complete, and RISC-V encoding (RV64IMAFDC + RVC)
including ELF and GOOBJ emission is complete.
### Phase 3 — dynamic analysis · *done* ### Phase 3 — dynamic analysis · *done*
@@ -242,26 +246,28 @@ portable Go implementation every kernel is derived from.
multi-input path-diversity measurement: how many observationally distinct multi-input path-diversity measurement: how many observationally distinct
execution paths a test corpus exercises. execution paths a test corpus exercises.
### Phase 4 — debugger · *in progress* ### Phase 4 — debugger · *done*
- **`gasm debug`:** single-step a GAsm function, inspect registers, set - **`gasm debug`:** single-step a GAsm function, inspect registers (including
breakpoints on labels, and hex-dump memory — the interactive counterpart YMM vector registers), set breakpoints on labels, allocate and fill named
to Phase 3's execution substrate. buffers, and hex-dump memory — the interactive counterpart to Phase 3's
execution substrate.
- **MVP** — *done.* ptrace-based debuggee subprocess (PTRACE_TRACEME + - **MVP** — *done.* ptrace-based debuggee subprocess (PTRACE_TRACEME +
LockOSThread), entry breakpoint (auto-run to function start), LockOSThread), entry breakpoint (auto-run to function start),
single-step, register inspection, label resolution, breakpoint single-step, register inspection (GPR + YMM/XMM via PTRACE_GETFPREGS),
management via `/proc/pid/mem`, and an interactive REPL. label resolution, breakpoint management via `/proc/pid/mem`, named
buffer allocation with pattern filling (`--buf`), and an interactive REPL.
- **Remaining:** disassembly at PC (x86asm decode), memory-write support, - **Remaining:** disassembly at PC (x86asm decode), memory-write support,
watchpoints, source-line mapping, and multi-platform support watchpoints, source-line mapping, and multi-platform support
(FreeBSD/macOS ptrace variants). (FreeBSD/macOS ptrace variants).
### Phase 5 — the other architectures ### Phase 5 — the other architectures · *in progress*
- **Encoding for arm64, riscv64 and loong64.** The lexer, parser, linter - **RISC-V encoding — done.** RV64IMAFDC instruction set, RVC compression,
and formatter already cover all four architectures; the assembler today MOV pseudo-instruction, SB/global symbols (AUIPC pairs), ELF64 and GOOBJ
encodes amd64 only. Phase 5 brings the same encode-and-verify treatment emission, and ground-truth verification against `go tool asm`.
(instruction tables already generated from the toolchain, every encoding - **Remaining:** arm64 and loong64 encoding, plus the same encode-and-verify
checked byte for byte against `go tool asm`) to the remaining three. treatment for each (instruction tables already generated from the toolchain).
## Principles ## Principles
@@ -293,9 +299,9 @@ portable Go implementation every kernel is derived from.
| `arch` | amd64, arm64, riscv64 and loong64 register files and instruction tables. | | `arch` | amd64, arm64, riscv64 and loong64 register files and instruction tables. |
| `lint` | Conservative static checks. | | `lint` | Conservative static checks. |
| `format` | A canonical formatter — `gofmt` for assembly. | | `format` | A canonical formatter — `gofmt` for assembly. |
| `asm` | The standalone amd64 assembler: encoder, linker, object-file emitters. | | `asm` | The standalone assembler: amd64 and RISC-V encoders, linker, object-file emitters (ELF, Mach-O, GOOBJ). |
| `verify` | JIT execution substrate for dynamic analysis (Phase 3). | | `verify` | JIT execution substrate for dynamic analysis, combined ABI+fuzz differential testing (Phase 3). |
| `debug` | Interactive ptrace debugger for amd64 (Phase 4). | | `debug` | Interactive ptrace debugger with GPR/YMM register display and named buffer allocation (Phase 4). |
| `lsp` | Language Server Protocol server. | | `lsp` | Language Server Protocol server. |
| `cmd/gasm` | The `gasm` binary tying it all together. | | `cmd/gasm` | The `gasm` binary tying it all together. |
| `_gen` | The generator that rebuilds the instruction tables from the Go toolchain. | | `_gen` | The generator that rebuilds the instruction tables from the Go toolchain. |
@@ -330,6 +336,8 @@ gasm asm --format elf -o k.o k.s # assemble to a linkable ELF object
gasm verify kernel_amd64.s # JIT-load and report functions gasm verify kernel_amd64.s # JIT-load and report functions
gasm verify --ground-truth k.s # byte-for-byte vs go tool asm gasm verify --ground-truth k.s # byte-for-byte vs go tool asm
gasm debug --func name k.s # interactive debugger gasm debug --func name k.s # interactive debugger
gasm diff a.s b.s # compare machine code byte-for-byte
gasm profile k.s # show basic-block structure
``` ```
See [CONTRIBUTING.md](CONTRIBUTING.md) for the full development workflow, See [CONTRIBUTING.md](CONTRIBUTING.md) for the full development workflow,
+1 -1
View File
@@ -34,7 +34,7 @@ import (
// version is the release version, stamped at build time via // version is the release version, stamped at build time via
// -ldflags "-X main.version=…" (defaulting to the current release). // -ldflags "-X main.version=…" (defaulting to the current release).
var version = "0.28.0" var version = "0.29.0"
func main() { func main() {
if len(os.Args) < 2 { if len(os.Args) < 2 {
+19 -3
View File
@@ -194,6 +194,13 @@ with the Plan 9 operand order (source first) mapped onto the x86 encoding.
Every encoding is validated by decoding it again with `golang.org/x/arch` — the Every encoding is validated by decoding it again with `golang.org/x/arch` — the
one module dependency, used in tests only and never linked into the binary. one module dependency, used in tests only and never linked into the binary.
A **RISC-V encoder** (Phase 5, RV64IMAFDC + RVC compression) encodes the full
integer, atomic, float/double, FMA and CSR instruction sets with the MOV
pseudo-instruction and SB/global symbol references (AUIPC pairs with
R_RISCV_PCREL_HI20/LO12 relocations). The encoder compresses eligible
instructions to 16-bit RVC forms and is validated byte-for-byte against
`GOARCH=riscv64 go tool asm`.
On top of the encoder, `Assemble` walks a parsed `TEXT` body, converts each On top of the encoder, `Assemble` walks a parsed `TEXT` body, converts each
operand to an encoder operand, and lays the instructions out so local labels operand to an encoder operand, and lays the instructions out so local labels
resolve to relative jump offsets: jumps start in the short (rel8) form and resolve to relative jump offsets: jumps start in the short (rel8) form and
@@ -281,7 +288,9 @@ boundaries, plus flat `pcfile`, `pcline` and `pcinline` tables — so a
gasm-assembled object drops into a `go build` in place of the toolchain's. gasm-assembled object drops into a `go build` in place of the toolchain's.
The object preamble (the version-and-experiment header the linker compares The object preamble (the version-and-experiment header the linker compares
verbatim) is captured from the installed `go tool asm`, so the output is verbatim) is captured from the installed `go tool asm`, so the output is
always consistent with the toolchain that links it. External cross-package always consistent with the toolchain that links it. RISC-V GOOBJ emission
uses the same format with the RISC-V architecture marker and RISC-V relocation
types. External cross-package
references and the implicit funcdata/DWARF symbols remain future work (the references and the implicit funcdata/DWARF symbols remain future work (the
linker fills the latter's defaults); the rest of Phase 2 is those, the linker fills the latter's defaults); the rest of Phase 2 is those, the
remaining EVEX forms and the other architectures. remaining EVEX forms and the other architectures.
@@ -309,7 +318,12 @@ assembler’s `Image.Bytes()` provides the code-and-data concatenation.
The `gasm verify` CLI subcommand exposes this: it loads a file, reports the The `gasm verify` CLI subcommand exposes this: it loads a file, reports the
available functions and (with `-smoke`) calls each NOSPLIT function with zeroed available functions and (with `-smoke`) calls each NOSPLIT function with zeroed
arguments to confirm the trampoline round-trips. arguments to confirm the trampoline round-trips. `gasm verify --fuzz` combines
ABI checks (sentinel registers, canary, stack bounds) with differential fuzz
testing, comparing the JIT-assembled kernel against the portable Go reference
bit-for-bit while verifying the ABI contract on every iteration. When a fuzz
iteration crashes or mismatches, `FuzzResult.CrashInput` stores the exact input
for reproducibility.
### `debug` ### `debug`
@@ -320,7 +334,9 @@ execution. Breakpoints are patched as INT3 bytes through `/proc/pid/mem`
(PTRACE_PEEKTEXT is unreliable with Go's multi-threaded runtime). (PTRACE_PEEKTEXT is unreliable with Go's multi-threaded runtime).
The child pins its goroutine to the OS thread with `runtime.LockOSThread` The child pins its goroutine to the OS thread with `runtime.LockOSThread`
so the traced thread is the one executing JIT code. The REPL provides so the traced thread is the one executing JIT code. The REPL provides
single-step, register inspection, label resolution, and breakpoint single-step, register inspection (GPR + YMM/XMM via `PTRACE_GETFPREGS`),
label resolution, named buffer allocation with pattern filling
(`--buf name:size:pattern` — zero, ones, seq, or hex), and breakpoint
management. management.
## Extension points ## Extension points
+1 -1
View File
@@ -3,7 +3,7 @@
# gasm-devkit — developer tooling for Go's Plan 9 assembler (GAsm). # gasm-devkit — developer tooling for Go's Plan 9 assembler (GAsm).
version := "0.28.0" version := "0.29.0"
default: default:
@just --list @just --list