docs: record the development deltas in the changelog

Assisted-by: GLM 5.3
This commit is contained in:
2026-10-02 00:40:54 +02:00
parent fefb76beb9
commit c1bca7ce7e
2 changed files with 97 additions and 6 deletions
+96 -5
View File
@@ -10,10 +10,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- **The FreeBSD port of the debugger.** `gasm debug` runs on FreeBSD on - **The FreeBSD port of the debugger.** `gasm debug` runs on FreeBSD on
amd64, arm64 and riscv64: the same interactive surface as on Linux — amd64, arm64 and riscv64 with the same interactive surface as on Linux:
breakpoints, hardware watchpoints (x86 debug registers, the arm64 debug breakpoints, hardware watchpoints (x86 debug registers, the arm64 debug
register file), single-stepping, register and memory access — behind the register file), single-stepping, register and memory access, all behind
kernel's own ptrace requests, with tracee memory through `PT_IO` and the kernel's own ptrace requests, with tracee memory through `PT_IO` and
stop reports through `PT_LWPINFO`. The JIT substrate maps executable stop reports through `PT_LWPINFO`. The JIT substrate maps executable
memory through `golang.org/x/sys/unix`, so `verify` builds on FreeBSD memory through `golang.org/x/sys/unix`, so `verify` builds on FreeBSD
too. The pipeline compile-gates all three architectures; live too. The pipeline compile-gates all three architectures; live
@@ -29,6 +29,49 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
last one in the file, and the `abi-argsize` warning offers to set the last one in the file, and the `abi-argsize` warning offers to set the
TEXT argument area to the size the `// func` signature implies, computed TEXT argument area to the size the `// func` signature implies, computed
by the new `lint.ExpectedArgSize`. by the new `lint.ExpectedArgSize`.
- **Eleven new lint rules over the directives, the data section and the
sharpest addressing edges.** `missing-argsize` flags a TEXT that
declares no argument area its `// func` signature implies;
`noframe-frame-size` a NOFRAME with a positive frame;
`unnamed-fp-reference` a nameless `0(FP)`, which both assemblers
reject; `hardware-sp-addressing` a negative offset off the hardware SP
rather than the virtual frame; `vex-sse-mixing` a kernel that mixes VEX
and legacy SSE spellings and pays the transition penalty;
`unnamed-result` a `ret+N(FP)` the signature names; `data-width`,
`data-value-overflow`, `data-string-width`, `data-without-globl` and
`data-exceeds-globl` police the DATA width against its value type and
the GLOBL size behind it. `missing-ret` now also flags a function
whose tail can fall off its end even though a RET sits somewhere in the
body, and `invalid-textflag` also reports a flag misplaced between TEXT
and GLOBL.
- **Hover documentation and wider completions in the language server.**
Hovering a directive or pseudo-operation (TEXT, DATA, GLOBL, PCALIGN,
FUNCDATA, PCDATA, the BYTE family) shows its grammar and rules in
preference to the empty instruction-table entry, and completion offers
those names beside the instruction set. The `missing-argsize` warning
carries a quick fix that declares the argument area the signature
implies (`$0` becomes `$0-16`).
- **The GOOBJ link parity gate.** A regression test assembles a kernel
per architecture through `gasm asm --format goobj`, substitutes the
object into a real `go build`'s package archive, proves the archive
carries it byte for byte and re-links with cmd/link on amd64, arm64,
riscv64 and loong64. The binaries run, natively on amd64 and under
qemu-user on arm64 and riscv64, and their output must match the
toolchain-built baseline; loong64 is link-only. The pipeline installs
qemu-user and runs the gate on every push.
- **The amd64 and loong64 encoders close four more corpus files.** The
whole-tree measure moves to 272 of 322 (84.5 %): amd64 gains the
one-operand IMUL, the SSE compare family (CMPPD, CMPPS, CMPSS), RETFL,
the LOOP family, the MMX register bank with its bank-crossing moves,
MOVNTDQ, the CR and DR register moves, PUSH and POP of FS and GS, the
`(TLS)` pseudo-base, the wait and cache controls (CLWB, CLDEMOTE,
TPAUSE, UMONITOR, UMWAIT, RDPID, ENDBR64), indirect branches with the
star spelling (`JMP *(R12)(R13*4)`), `RET sym(SB)` as the tail jump,
the colon shift spelling (`SHLL CX, R11:AX`) and the EVEX and VEX forms
of the rounds, AES key assist, string compares, extracts, blends and
permutes; loong64 gains the acquire and release pair (LLACQ, SCREL,
with the vector widths), the VMOVQ and XVMOVQ lane forms and the BYTE
literal-data escape hatch the other architectures already take.
### Changed ### Changed
@@ -39,8 +82,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
instead of failing it. The headline now reads "assemble for every instead of failing it. The headline now reads "assemble for every
applicable target": every real-code GOROOT assembly file, the tree applicable target": every real-code GOROOT assembly file, the tree
without testdata, assembles for all four architectures (250 of 250, without testdata, assembles for all four architectures (250 of 250,
100 %); over the whole tree including testdata the measure is 271 of 100 %); over the whole tree including testdata the measure is 272 of
322 (84.2 %). 322 (84.5 %).
- **The module moves to `sourcedock.dev/petrbalvin/gasm-sdk`.** The - **The module moves to `sourcedock.dev/petrbalvin/gasm-sdk`.** The
repository and the module rename together with the product, now the repository and the module rename together with the product, now the
GAsm Software Development Kit. Fresh installs become GAsm Software Development Kit. Fresh installs become
@@ -66,6 +109,54 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
rejected; the toolchain picks the 16-bit lane from the 64-bit bit rejected; the toolchain picks the 16-bit lane from the 64-bit bit
pattern, so the encoder now does the same, and a zero immediate is pattern, so the encoder now does the same, and a zero immediate is
rejected where the toolchain rejects it. rejected where the toolchain rejects it.
- **NOPTR data emits its own symbol kind.** A GLOBL with NOPTR was
emitted as plain SDATA, the kind the linker holds to its Go type
information requirement, so every gasm object carrying runtime-shaped
data (`GLOBL ·x(SB), NOPTR, ...`) died in cmd/link with "missing Go
type information". NOPTR data is now SNOPTRDATA, the toolchain's kind
for pointer-free globals, and RODATA still wins where both flags
appear, exactly as the toolchain chooses. The three end-to-end link
tests that should have caught this substituted the gasm object after
the package archive was already packed, so they passed vacuously; they
now substitute inside the archive, prove the substitution byte for
byte and re-link.
- **Latent encoder divergences against the toolchain, found by the
whole-file differential harness.** On loong64, `MOVx $off(reg)` lost
its base register, SCQ swapped its operand fields, the vector lane
inserts did not scale offsets by the element width and two immediate
opcodes were mistyped; on amd64, NOP with operands encoded 0x90 where
the toolchain emits nothing at all, the VEX gather length bit ignored
the VSIB index width, four permute and extract families were pushed
into EVEX where the toolchain stays VEX, and a reference to a static
symbol no GLOBL defines failed where the toolchain defers it to the
linker as an external relocation.
- **Seven front-end defects found by fuzzing.** The formatter swallowed
the statement after a leading block comment (`/* head */ MOVQ AX, BX`
formatted to the comment alone), dropped trailing tokens after an
`#include` header, and trimmed the trailing whitespace inside a string
literal; the parser peeled only one label of a stacked pair (`a: b:`
parsed differently than it formatted); deeply nested parentheses in an
immediate overflowed the stack through the constant folder, which now
stops at a bounded depth and falls back to the ordinary operand paths;
macro expansion is linear in the invocation count instead of
quadratic; and amplifying macros (the billion-laughs shape) stop at a
work budget sized by the line and the macro table, reported as a
diagnostic instead of running for hours.
- **The debugger handles the edges its tests now reach.** Memory reads
and writes cover exactly the requested bytes, so a request ending in
the last page of a mapping no longer fails on the unmapped page behind
it; disassembly shrinks its instruction window at a mapping's end
instead of failing; a debuggee that dies before signalling readiness
writes a failure notice the launcher reads, so launch fails fast with
the reason instead of after the whole poll (and the poll no longer
waits on the child, which could consume the SIGSTOP park and hang the
launch); amd64 watchpoints acknowledge the sticky DR6 hit bits and
clear the address register on release; the breakpoint listing is
ordered by address so its numbering is stable; the REPL rejects bad
counts, sizes and watchpoint types instead of silently guessing,
reports stops on signals during stepping, and a breakpoint-class trap
that matches no breakpoint and leaves the PC in place surfaces instead
of spinning the continue loop and the coverage run forever.
## [0.35.0] - 2026-09-22 ## [0.35.0] - 2026-09-22
+1 -1
View File
@@ -580,7 +580,7 @@ AST, so neither depends on an encoding.
a GOOBJ object references, and `_gen` parses a GOOBJ object references, and `_gen` parses
`$GOROOT/src/cmd/internal/obj/<arch>/anames.go` to rebuild the tables. `$GOROOT/src/cmd/internal/obj/<arch>/anames.go` to rebuild the tables.
- **Linux and FreeBSD process interfaces** for the dynamic work: `mmap` and - **Linux and FreeBSD process interfaces** for the dynamic work: `mmap` and
`mprotect` for the JIT mapping, ptrace for the debugger — with tracee `mprotect` for the JIT mapping, ptrace for the debugger, with tracee
memory through `/proc/pid/mem` on Linux and through `PT_IO` on FreeBSD, memory through `/proc/pid/mem` on Linux and through `PT_IO` on FreeBSD,
and the tracee's stop reports read from `PT_LWPINFO` there. That is why and the tracee's stop reports read from `PT_LWPINFO` there. That is why
`verify` runs a JIT check only when the host architecture matches the `verify` runs a JIT check only when the host architecture matches the