docs: state the validation status and correct claims the material contradicts
Assisted-by: DeepSeek V4.1 Flash
This commit is contained in:
@@ -5,23 +5,25 @@
|
||||
> output formats and behaviour can change without warning at any time.
|
||||
> A 1.0.0 release is light years away. Nothing in this document is a
|
||||
> stability promise. For all of that, this is not a paper project: gasm
|
||||
> is already in active use and is tested on real assembly work.
|
||||
> is already in active use and is tested on real assembly work. Only
|
||||
> amd64 is validated on real hardware; the other three architectures run
|
||||
> under emulation ([Validation status](#validation-status)).
|
||||
|
||||
**GAsm** is Go's Plan 9 assembler, and Go ships it without tooling:
|
||||
there is no formatter, no linter, no static analyser, no standalone
|
||||
assembler and no debugger for `.s` files. Developers write assembly
|
||||
blind, validate it by benchmark, and debug it by print statement.
|
||||
gasm-devkit is the missing toolkit: a single, self-contained binary,
|
||||
`gasm`, that serves both purposes.
|
||||
there is no formatter, no linter and no debugger for `.s` files, and no
|
||||
assembler that works without a Go installation. Developers write
|
||||
assembly blind, validate it by benchmark, and debug it by print
|
||||
statement. gasm-devkit is the missing toolkit: a single, self-contained
|
||||
binary, `gasm`, that serves both purposes.
|
||||
|
||||
- **Help develop Plan 9 assembly.** Formatting, linting, disassembly,
|
||||
dynamic verification, a source-level debugger and a language server,
|
||||
for `.s` files in Go programs.
|
||||
- **Use Plan 9 assembly outside the Go toolchain.** `gasm asm` encodes
|
||||
on its own, with no Go installation in the loop, and writes raw
|
||||
images, linkable ELF objects with DWARF5 debug sections, or the Go
|
||||
on its own and writes raw images or linkable ELF objects with DWARF5
|
||||
debug sections, with no Go installation in the loop; the Go
|
||||
toolchain's own GOOBJ format, which `go build` consumes in place of
|
||||
the toolchain's output.
|
||||
the toolchain's output, needs the installed toolchain.
|
||||
|
||||
## Why Plan 9 assembly
|
||||
|
||||
@@ -69,12 +71,14 @@ to give that syntax the tooling it deserves.
|
||||
operating recursively on directories the way `go fmt` does. `-l` lists
|
||||
files whose formatting differs and `-d` prints a unified diff.
|
||||
- **Linter.** `gasm lint` runs 18 conservative static checks, among them
|
||||
`undefined-label`, `abi-argsize` (declared frame vs the `// func` signature),
|
||||
`register-clobber` (Go ABI register liveness over the control-flow graph),
|
||||
`stack-imbalance`, `abi0-register-args` and `unencodable-instruction`.
|
||||
`undefined-label`, `abi-argsize` (declared argument area vs the `// func`
|
||||
signature), `register-clobber` (Go ABI register liveness over the
|
||||
control-flow graph), `stack-imbalance`, `abi0-register-args` and
|
||||
`unencodable-instruction`.
|
||||
- **Standalone assembler.** `gasm asm` encodes all four architectures without
|
||||
the Go toolchain and writes raw images, linkable ELF objects (with DWARF5
|
||||
debug sections) or the Go toolchain's own GOOBJ format, which `go build`
|
||||
the Go toolchain and writes raw images or linkable ELF objects (with DWARF5
|
||||
debug sections) with no Go installation needed, or the Go toolchain's own
|
||||
GOOBJ format, which needs the installed toolchain and which `go build`
|
||||
consumes in place of the toolchain's output. Framed functions get the
|
||||
stack-split guard and the morestack block, byte-identical to the
|
||||
toolchain's, so split functions link too.
|
||||
@@ -86,7 +90,8 @@ to give that syntax the tooling it deserves.
|
||||
byte-for-byte ground-truth comparison of the machine code.
|
||||
- **Debugger.** `gasm debug` is a source-level ptrace debugger with
|
||||
breakpoints (optionally conditional), hardware watchpoints, register and
|
||||
memory inspection, and headless script runs with label-level coverage.
|
||||
memory inspection, and headless script runs that report instruction and
|
||||
label coverage.
|
||||
- **Language server.** `gasm lsp` serves completion, hover, document symbols,
|
||||
push and pull diagnostics, semantic-token highlighting, go-to-definition,
|
||||
find references, rename, formatting, inlay hints, code actions, signature
|
||||
@@ -123,6 +128,34 @@ The same measurement runs over GOROOT's whole assembly corpus:
|
||||
assembling for every target architecture today, with the top failure
|
||||
reasons per architecture; the number moves with every release.
|
||||
|
||||
### Validation status
|
||||
|
||||
**Only amd64 is validated on real hardware.** The other three
|
||||
architectures are validated under qemu-user emulation, because the
|
||||
project owns no arm64, riscv64 or loong64 machine, and emulation is the
|
||||
only substitute available for the hardware. The distinction matters and
|
||||
is stated rather than implied: everything below is a claim about what has
|
||||
actually been executed.
|
||||
|
||||
| Layer | amd64 | arm64, riscv64, loong64 |
|
||||
|---|---|---|
|
||||
| Encoding: byte-for-byte against `go tool asm` | native hardware | native hardware (the toolchain cross-assembles any GOARCH on any host) |
|
||||
| Execution: JIT calls, ABI checks, differential fuzzing | native hardware | qemu-user emulation |
|
||||
| Debugger: ptrace tracing, breakpoints, watchpoints, coverage | native hardware | emulation cannot run ptrace; the layer compiles and its architecture-neutral units run under `go test ./...`, nothing more |
|
||||
|
||||
Consequences, stated plainly. An emulator is a model of a CPU, not the
|
||||
CPU: instruction semantics are implemented in software and can differ
|
||||
from silicon in ways a test suite does not reveal. A kernel that passes
|
||||
under qemu-user is therefore not proven correct on real hardware, and a
|
||||
discrepancy found on real hardware is a defect in gasm, reported like any
|
||||
other. Encoding parity is the exception: the byte comparison against the
|
||||
toolchain runs on the host for every architecture, so no emulator stands
|
||||
between the claim and the evidence. The debugger is the weakest case: on
|
||||
the three emulated architectures its per-architecture ptrace code has
|
||||
been compiled and read, never executed. Its architecture-neutral units
|
||||
run under `go test ./...`, which the race workflow and a manual run
|
||||
perform; the default `just test` gate does not sweep `./debug/...`.
|
||||
|
||||
## Direction
|
||||
|
||||
The plan, in the order it is being worked:
|
||||
@@ -134,7 +167,8 @@ The plan, in the order it is being worked:
|
||||
an extended instruction set the toolchain does not know at all. The
|
||||
toolchain-derived tables stay generated and untouched; only the
|
||||
extended instructions are hand-maintained, with their own spellings
|
||||
and encoders, verified by execution on real hardware because the
|
||||
and encoders, verified by execution (on real hardware for amd64, under
|
||||
emulation for the rest, per the validation status above) because the
|
||||
toolchain offers no ground truth to compare against. The gaps exist
|
||||
on every architecture, amd64 included.
|
||||
- **Full GOOBJ and ELF compilation.** The destination is a complete,
|
||||
@@ -205,7 +239,7 @@ gasm verify --ground-truth k.s # byte-for-byte vs go tool asm
|
||||
gasm verify --fuzz k.s # differential fuzz vs the go tool asm build
|
||||
gasm debug --func name k.s # interactive debugger
|
||||
gasm debug --func name --script cmds.txt --timeout 30s k.s # headless run
|
||||
gasm debug --func name --cover k.s # which labels did execution reach?
|
||||
gasm debug --func name --cover k.s # instruction and label coverage
|
||||
gasm diff a.s b.s # compare machine code byte-for-byte
|
||||
gasm diff --map wideCopyAVX2=wideCopyAVX512 avx2.s avx512.s
|
||||
gasm profile k.s # show basic-block structure
|
||||
@@ -243,7 +277,8 @@ recipe.
|
||||
|
||||
- [docs/CLI.md](docs/CLI.md): full command reference
|
||||
- man pages: `just install-man` installs gasm(1) and one page per command
|
||||
into ~/.local/share/man (MANDIR overrides); `just uninstall-man` removes
|
||||
except `version`, which is documented inside gasm(1) instead, into
|
||||
~/.local/share/man (MANDIR overrides); `just uninstall-man` removes
|
||||
them
|
||||
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md): components and data flow
|
||||
- [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md): development setup and recipes
|
||||
|
||||
Reference in New Issue
Block a user