• v0.32.0
    Release / build (amd64, linux) (push) Successful in 43s
    Release / build (arm64, linux) (push) Successful in 42s
    Release / build (loong64, linux) (push) Successful in 43s
    Release / build (riscv64, linux) (push) Successful in 43s
    Test / vet (push) Successful in 49s
    Release / release (push) Successful in 18s
    Test / test (push) Successful in 2m40s
    Test / build (push) Successful in 42s
    Stable

    petrbalvin released this 2026-08-31 11:10:53 +00:00 | 130 commits to main since this release

    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 <label> if <reg> <op> <val> now also
      compares two registers (break loop if RAX > RBX), not only a register
      against an immediate.
    • Instruction-level coverage. gasm debug --cover now sets a
      breakpoint on every instruction (walked by disassembly length), counts
      the hits per instruction and reports the executed instructions with
      their hit counts, with the label coverage derived from the same run.
      Expect the run to slow to ptrace speed.
    • FP register display on riscv64 and loong64. The debugger regs
      command shows the 32 FP registers plus fcsr (and fcc on loong64) via
      PTRACE_GETREGSET.
    • JIT execution trampolines. verify.Call now works on all four
      architectures via hand-written assembly trampolines
      (trampoline_{arm64,riscv64,loong64}.s) that save the Go stack, switch
      to a prepared stack, and branch to the JIT function.
    • ABI checks on arm64, riscv64 and loong64. gasm verify -abi and
      the ABI half of -fuzz now cover the non-amd64 architectures via
      per-architecture checked trampolines: sentinels planted in the
      registers the Go ABI fixes across calls (arm64 R29/R28, riscv64
      X27, loong64 R22; amd64 keeps BP/R14) are verified on return
      and the saved registers restored before Go code resumes, with the
      below-SP canary on every architecture. loong64 kernels are verified
      through the toolchain-comparison path only, pending hardware
      validation of their trampoline. verify.Load assembles each file
      with the encoder its name suffix calls for. The ABIReport fields
      are the architecture-neutral FPClobbered and GClobbered.
    • Hardware watchpoints on all architectures. arm64 uses DBGWVR/DBGWCR
      via PTRACE_SETREGSET with NT_ARM_HW_BREAK; riscv64 and loong64 use
      PTRACE_POKEUSER to access trigger/debug registers.
    • Cross-package GOOBJ resolution on arm64 and loong64.
      AssembleFileARM64 and AssembleFileLOONG64 mark external
      relocations and populate img.Externals, so GOOBJ output from those
      architectures resolves cross-package symbols like amd64 and riscv64
      already do.
    • gasm verify --args. Scalar arguments (name=value, decimal or
      0x hex) can now be supplied to a --call invocation alongside --buf
      buffers, closing the gap where only buffers could be supplied.
    • Fuzz corpus save and replay. gasm verify --fuzz --save-corpus dir
      records every input that crashes or mismatches as replayable JSON (buffer
      contents and scalars, not raw pointers), and gasm verify --replay dir
      re-runs the saved entries against the kernel in isolated child processes,
      reporting whether each one reproduces.
    • gasm audit-instructions. Black-box diff of a gasm encoder
      against the installed go tool asm, for amd64, arm64, riscv64 and
      loong64 (gasm audit-instructions <arch>): superset encodings
      (gasm-only, shippable via gasm asm --format goobj),
      known-but-unencodable names (the backlog) and go-only names
      (feature gaps).
    • gasm scaffold differential. Prints a differential test skeleton
      for every // func signature in a kernel file: random seed states, the
      kernel call and a portable reference (<name>Portable), compared
      byte-for-byte.
    • LSP: find references (textDocument/references).
    • LSP: rename symbol (textDocument/rename).
    • LSP: document formatting (textDocument/formatting) using the
      format package for canonical gofmt-style output.
    • LSP: inlay hints (textDocument/inlayHint): frame size hints after
      the TEXT directive's argument area.
    • LSP: workspace symbol search (workspace/symbol): substring search
      over the TEXT functions and GLOBL/DATA symbols of every open document.
    • LSP: code actions. Quick fixes for missing-ret (insert the RET)
      and unused-label (remove the label) diagnostics.
    • LSP: signature help (textDocument/signatureHelp): the callee's
      // func signature while the cursor is on a CALL.
    • LSP: document highlights: every reference to the function or label
      under the cursor is highlighted.
    • LSP: pull diagnostics (textDocument/diagnostic), #include
      document links
      (resolved against the document directory, then
      $GOROOT/pkg/include, so textflag.h opens) and folding ranges
      (one collapsible region per TEXT function body).
    • Lint: unused-label rule. Flags labels that are defined but never
      referenced by any jump (Hint severity).
    • Lint: invalid-textflag rule. Flags TEXT/GLOBL flags not in the
      known set from textflag.h (Warning severity).
    • Lint: stack-imbalance rule. Tracks SP changes and flags if the
      net delta at RET does not match the declared frame size.
    • Lint: register-width-mismatch rule. Flags amd64 operands whose
      register width does not match the width the mnemonic suffix prescribes
      (for example a 32-bit register in a MOVQ).
    • Lint: abi0-register-args rule. Flags kernels whose // func
      parameters are never read from the FP frame (for example arguments read
      from registers instead), which pass every test today and break on a
      toolchain upgrade. Shipped with the Go assembler's operand-width model.
    • Lint: nonportable-register-name rule. Flags the RAX/EAX-style
      register aliases gasm accepts but go tool asm rejects, so files using
      them only link through the gasm GOOBJ path.
    • Lint: unencodable-instruction rule. Flags mnemonics the
      architecture table knows but the encoder cannot yet emit, at edit time
      instead of at assembly time.
    • Lint: reserved-register-write rule. Flags writes to arm64 R18,
      the platform-reserved register the ABI checks cannot observe at runtime
      and the Go assembler cannot even spell. Reads and macro-using files
      are exempt.
    • DWARF5 debug sections in ELF output. All four ELF emitters now emit
      .debug_abbrev, .debug_info, .debug_line, and .debug_line_str
      sections, enabling addr2line and GDB/LLDB source-level debugging, and
      the amd64 emitter adds a .debug_frame CFI section for stack unwinding.
    • amd64: legacy SSE and conversion coverage. The encoder now handles
      the legacy (non-VEX) SSE packed binaries and immediate shuffles, the
      legacy SSE integer instructions and BSWAP, the scalar and packed
      double conversions (CVTSS2SD, CVTSD2SS, CVTPS2PD, CVTPD2PS) and
      the prefetch hints.
    • amd64: VPCMP and the full opmask set. The EVEX compare with an
      opmask destination and the remaining opmask-register instructions are
      encoded, byte for byte against the Go assembler.

    Changed

    • Parallel verify sweeps. The -smoke and -abi per-function checks
      now run in parallel instead of sequentially.

    Fixed

    • Reliable ptrace sessions. The debugger no longer mistakes runtime
      signal-delivery-stops (a Go tracee reports SIGURG preemption to the
      tracer) for its launch barrier, runs every ptrace request on the thread
      that forked the debuggee (requests from another thread fail with
      ESRCH), prefers the debuggee's reported code base over an RWX scan, and
      single-steps over a hit breakpoint so resuming cannot re-trap on the
      same instruction. A ptrace integration test
      (debug/ptrace_integration_test.go) drives a real session end to end.
    • arm64 BL relocation. BL sym(SB) now records a RelArm64Branch
      relocation instead of emitting a bare instruction with no relocation.
    • GOOBJ R_ADDRARM64 constant. Corrected from 9 (R_CALLARM64) to 3
      (R_ADDRARM64).
    • Subprocess-isolated smoke and ABI sweeps. A function that faults
      during the -smoke or -abi sweep is reported without killing the
      parent; each sweep runs in a child process.
    • BSF, BSR and POPCNT encodings. Corrected to the bytes
      go tool asm emits.
    • MOVQ immediates. Compressed to the toolchain's imm32 forms.
    • Frame adjustments of 128 to 255 bytes. Now use the imm8 ADDQ
      stack adjustment.
    • amd64 encoding parity. A broad pass aligned the remaining encoder
      outputs and operand strictness with go tool asm.
    • asm help text. Updated to list arm64 as a supported architecture.
    Downloads