feat(docs): man pages for gasm and every command, guarded against CLI drift
Test / test (push) Successful in 2m4s
Test / test (push) Successful in 2m4s
Assisted-by: GLM 5.3 Flash
This commit is contained in:
@@ -39,6 +39,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- **Oracle parity as its own CI step.** The push pipeline already ran
|
- **Oracle parity as its own CI step.** The push pipeline already ran
|
||||||
the live go-tool-asm comparison inside the suite; a dedicated step
|
the live go-tool-asm comparison inside the suite; a dedicated step
|
||||||
now names that gate when it fails.
|
now names that gate when it fails.
|
||||||
|
- **Man pages.** docs/man carries gasm(1) and one page per command,
|
||||||
|
written in roff: synopsis, description, every flag with its default,
|
||||||
|
exit status, worked examples and cross-references.
|
||||||
|
`just install-man` compresses them into ~/.local/share/man (MANDIR
|
||||||
|
overrides) and `just uninstall-man` removes them. A test builds the
|
||||||
|
binary and compares every command's `-h` output with its page, so the
|
||||||
|
pages cannot drift from the CLI.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|||||||
@@ -241,8 +241,11 @@ recipe.
|
|||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md): components and data flow
|
|
||||||
- [docs/CLI.md](docs/CLI.md): full command reference
|
- [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
|
||||||
|
them
|
||||||
|
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md): components and data flow
|
||||||
- [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md): development setup and recipes
|
- [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md): development setup and recipes
|
||||||
- [CHANGELOG.md](CHANGELOG.md): release history
|
- [CHANGELOG.md](CHANGELOG.md): release history
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,157 @@
|
|||||||
|
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestManPagesTrackTheCLI builds the binary once, then compares every
|
||||||
|
// command's live `-h` output with its docs/man/gasm-<command>.1 page: the
|
||||||
|
// flag sets must agree both ways, and the page's SYNOPSIS line must carry
|
||||||
|
// the command's usage line. A flag or a usage change that skips the man
|
||||||
|
// page fails here, so the pages cannot drift from the binary.
|
||||||
|
func TestManPagesTrackTheCLI(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("builds the gasm binary")
|
||||||
|
}
|
||||||
|
bin := filepath.Join(t.TempDir(), "gasm")
|
||||||
|
if out, err := exec.Command("go", "build", "-o", bin, ".").CombinedOutput(); err != nil {
|
||||||
|
t.Fatalf("build gasm: %v\n%s", err, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, cmd := range []string{
|
||||||
|
"tokens", "parse", "fmt", "lint", "asm", "dis", "verify",
|
||||||
|
"debug", "diff", "profile", "audit-instructions", "scaffold", "lsp",
|
||||||
|
} {
|
||||||
|
t.Run(cmd, func(t *testing.T) {
|
||||||
|
raw, err := os.ReadFile(filepath.Join("..", "..", "docs", "man", "gasm-"+cmd+".1"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("read man page: %v", err)
|
||||||
|
}
|
||||||
|
page := string(raw)
|
||||||
|
|
||||||
|
out, _ := exec.Command(bin, cmd, "-h").CombinedOutput()
|
||||||
|
help := string(out)
|
||||||
|
|
||||||
|
binFlags := helpFlags(help)
|
||||||
|
pageFlags := roffFlags(page)
|
||||||
|
for f := range binFlags {
|
||||||
|
if !pageFlags[f] {
|
||||||
|
t.Errorf("flag -%s is in the binary's help but missing from the man page", f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for f := range pageFlags {
|
||||||
|
if !binFlags[f] {
|
||||||
|
t.Errorf("flag -%s is in the man page but the binary does not accept it", f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
want := helpUsage(help)
|
||||||
|
got := roffSynopsis(page)
|
||||||
|
if want != "" && got != want {
|
||||||
|
t.Errorf("SYNOPSIS drift:\n page: %s\nbinary: %s", got, want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// helpFlags extracts the flag names from a `gasm <cmd> -h` output.
|
||||||
|
func helpFlags(help string) map[string]bool {
|
||||||
|
m := map[string]bool{}
|
||||||
|
inFlags := false
|
||||||
|
for line := range strings.SplitSeq(help, "\n") {
|
||||||
|
if strings.TrimRight(line, " \t") == "Flags:" {
|
||||||
|
inFlags = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !inFlags {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !strings.HasPrefix(line, " -") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
token := strings.FieldsFunc(strings.TrimLeft(line, " "), func(r rune) bool {
|
||||||
|
return r == ' ' || r == '\t'
|
||||||
|
})
|
||||||
|
if len(token) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
m[strings.TrimLeft(token[0], "-")] = true
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
var roffEscape = regexp.MustCompile(`\\f[BIRP]`)
|
||||||
|
|
||||||
|
// roffFlags extracts the flag names from a man page's OPTIONS section.
|
||||||
|
func roffFlags(page string) map[string]bool {
|
||||||
|
m := map[string]bool{}
|
||||||
|
inOptions := false
|
||||||
|
for line := range strings.SplitSeq(page, "\n") {
|
||||||
|
if strings.HasPrefix(line, ".SH ") {
|
||||||
|
inOptions = strings.HasPrefix(line, ".SH OPTIONS")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !inOptions {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Flag entries are written as either `.B \-flag` or `\fB\-flag`.
|
||||||
|
var body string
|
||||||
|
switch {
|
||||||
|
case strings.HasPrefix(line, `.B \-`):
|
||||||
|
body = line[3:]
|
||||||
|
case strings.HasPrefix(line, `\fB\-`):
|
||||||
|
body = line[1:]
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name := roffEscape.ReplaceAllString(body, "")
|
||||||
|
name = strings.ReplaceAll(name, `\-`, "-")
|
||||||
|
name = strings.TrimSpace(name)
|
||||||
|
if i := strings.IndexAny(name, " \t"); i >= 0 {
|
||||||
|
name = name[:i]
|
||||||
|
}
|
||||||
|
m[strings.TrimLeft(name, "-")] = true
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
// helpUsage returns the command's usage line without the "Usage: " prefix.
|
||||||
|
func helpUsage(help string) string {
|
||||||
|
for line := range strings.SplitSeq(help, "\n") {
|
||||||
|
if strings.HasPrefix(line, "Usage: ") {
|
||||||
|
return normaliseUsage(line[len("Usage: "):])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// roffSynopsis returns the page's SYNOPSIS usage line, unescaped.
|
||||||
|
func roffSynopsis(page string) string {
|
||||||
|
inSyn := false
|
||||||
|
for line := range strings.SplitSeq(page, "\n") {
|
||||||
|
if strings.HasPrefix(line, ".SH ") {
|
||||||
|
inSyn = strings.HasPrefix(line, ".SH SYNOPSIS")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !inSyn || !strings.HasPrefix(line, ".B ") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return normaliseUsage(strings.ReplaceAll(line[3:], `\-`, "-"))
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// normaliseUsage flattens whitespace and drops the roff font escapes so that
|
||||||
|
// the binary's usage line and the page's SYNOPSIS line compare equal.
|
||||||
|
func normaliseUsage(s string) string {
|
||||||
|
s = roffEscape.ReplaceAllString(s, "")
|
||||||
|
return strings.Join(strings.Fields(s), " ")
|
||||||
|
}
|
||||||
@@ -3,6 +3,10 @@
|
|||||||
The reference below is taken from the program's own `--help`. If the two disagree, the
|
The reference below is taken from the program's own `--help`. If the two disagree, the
|
||||||
program is right and this file is a defect.
|
program is right and this file is a defect.
|
||||||
|
|
||||||
|
The same reference is installed as man pages: `just install-man` puts gasm(1) and one
|
||||||
|
page per command into ~/.local/share/man (`MANDIR` overrides), and a test compares each
|
||||||
|
page against the binary so the two cannot drift apart.
|
||||||
|
|
||||||
## Synopsis
|
## Synopsis
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
.TH GASM-ASM 1 "2026-09-19" "gasm 0.33.0" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
gasm-asm \- assemble Plan 9 assembly without the Go toolchain
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B gasm asm [\-\-format raw|elf|goobj] [\-p pkg] [\-GOARCH arch] [\-o out] <file>
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Assemble FILE without the Go toolchain: every TEXT function is encoded
|
||||||
|
to machine code and printed as a hex dump. Supported architectures:
|
||||||
|
amd64 (including VEX/AVX2 and EVEX/AVX-512), arm64 (AArch64 integer,
|
||||||
|
FP, conditional select, CRC32 and MOV pseudo), riscv64 (RV64IMAFDC and
|
||||||
|
RVC) and loong64 (LoongArch base ISA).
|
||||||
|
.PP
|
||||||
|
With
|
||||||
|
.B \-o
|
||||||
|
the output is written to a file instead. The
|
||||||
|
.B \-\-format
|
||||||
|
flag selects what is written:
|
||||||
|
.B raw
|
||||||
|
(the default) concatenates the functions and the data section into one
|
||||||
|
self-consistent image;
|
||||||
|
.B elf
|
||||||
|
emits a relocatable object (.text/.data sections, a symbol table and
|
||||||
|
one PC32 relocation per static-symbol reference) that links with the
|
||||||
|
system toolchain;
|
||||||
|
.B goobj
|
||||||
|
emits the Go toolchain's own object format, which cmd/link consumes
|
||||||
|
directly (it requires
|
||||||
|
.BR \-p ,
|
||||||
|
the package path, and the installed Go toolchain).
|
||||||
|
.PP
|
||||||
|
Framed functions receive the stack-split guard and the trailing
|
||||||
|
morestack block, byte-identical to the toolchain's output, so split
|
||||||
|
functions link too.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.B \-\-format \fIraw|elf|goobj\fR
|
||||||
|
Output format; the default is raw.
|
||||||
|
.TP
|
||||||
|
.B \-p \fIpkg\fR
|
||||||
|
Package path for --format goobj, qualifying the exported symbols.
|
||||||
|
.TP
|
||||||
|
.B \-GOARCH \fIarch\fR
|
||||||
|
Target architecture: amd64, arm64, riscv64 or loong64; overrides the
|
||||||
|
file-name suffix, which is how the suffix-less majority of GOROOT's
|
||||||
|
files (cpu_x86.s, stub.s, ...) become assemblable.
|
||||||
|
.TP
|
||||||
|
.B \-o \fIfile\fR
|
||||||
|
Write the output to this file instead of a hex dump on stdout.
|
||||||
|
.SH EXIT STATUS
|
||||||
|
Exits 0 on success, 1 when parsing or assembly fails, and 2 on a usage
|
||||||
|
error.
|
||||||
|
.SH EXAMPLES
|
||||||
|
.nf
|
||||||
|
gasm asm \-o hello.bin hello_amd64.s raw image
|
||||||
|
gasm asm \-\-format elf \-o k.o k.s linkable ELF object
|
||||||
|
gasm asm \-\-format goobj \-p pkg/path \-o k.o k.s Go object for go build
|
||||||
|
gasm asm \-GOARCH amd64 cpu_x86.s arch override
|
||||||
|
.fi
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR gasm (1),
|
||||||
|
.BR gasm\-dis (1),
|
||||||
|
.BR gasm\-verify (1)
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
.TH GASM-AUDIT-INSTRUCTIONS 1 "2026-09-19" "gasm 0.33.0" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
gasm-audit-instructions \- diff the encoder against the Go toolchain, or measure a corpus
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B gasm audit\-instructions [\-\-corpus [\fIdir\fR]] [amd64|arm64|riscv64|loong64]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Compare the gasm encoder for the given architecture (default amd64)
|
||||||
|
against
|
||||||
|
.B go tool asm
|
||||||
|
and print the diff: superset encodings (gasm-only, shippable via
|
||||||
|
.BR "gasm asm \-\-format goobj" ),
|
||||||
|
known-but-unencodable names (the backlog) and go-only names (feature
|
||||||
|
gaps). The Go side is probed black-box with a battery of bare
|
||||||
|
mnemonics, so the audit tracks whatever toolchain
|
||||||
|
.B go env GOROOT
|
||||||
|
provides.
|
||||||
|
.PP
|
||||||
|
With
|
||||||
|
.BR \-\-corpus ,
|
||||||
|
the audit changes shape: it assembles every
|
||||||
|
.I .s
|
||||||
|
file under the given directory (default GOROOT/src) with the gasm
|
||||||
|
encoder only, no toolchain probing. A file whose name carries a
|
||||||
|
recognisable _arch suffix is attempted for that architecture; a file
|
||||||
|
without one is attempted for all four, exactly as a GOARCH build would
|
||||||
|
compile it. The report gives the headline number (files that assemble
|
||||||
|
for every target architecture), the per-architecture pass rates and the
|
||||||
|
most common failure reasons, which drive the encodability backlog by
|
||||||
|
frequency rather than by table order. A run over GOROOT takes under a
|
||||||
|
second.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.B \-\-corpus [\fIdir\fR]
|
||||||
|
Assemble a corpus of .s files and report pass rates and failure
|
||||||
|
reasons.
|
||||||
|
.SH EXIT STATUS
|
||||||
|
The mnemonic-diff mode reports through its output and exits 0; a failed
|
||||||
|
probe or an unknown architecture exits non-zero.
|
||||||
|
.SH EXAMPLES
|
||||||
|
.nf
|
||||||
|
gasm audit\-instructions amd64
|
||||||
|
gasm audit\-instructions \-\-corpus
|
||||||
|
gasm audit\-instructions \-\-corpus "$(go env GOROOT)/src/crypto"
|
||||||
|
.fi
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR gasm (1),
|
||||||
|
.BR gasm\-asm (1)
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
.TH GASM-DEBUG 1 "2026-09-19" "gasm 0.33.0" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
gasm-debug \- interactive source-level debugger for JIT-assembled functions
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B gasm debug <file.s> \-\-func <name>
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Interactive debugger for JIT-assembled functions. Launches the function
|
||||||
|
in a traced subprocess (ptrace), then provides a REPL for
|
||||||
|
single-stepping, breakpoints, register and memory inspection.
|
||||||
|
.PP
|
||||||
|
With
|
||||||
|
.B \-\-script
|
||||||
|
the REPL commands run from a file and the session ends: the headless
|
||||||
|
mode CI and scripts use.
|
||||||
|
.B \-\-cover
|
||||||
|
runs to completion with a breakpoint on every instruction and reports
|
||||||
|
which executed and how often, the label-level coverage view.
|
||||||
|
.SH REPL COMMANDS
|
||||||
|
.TP
|
||||||
|
.B break \fIlabel|addr\fR [\fBif \fIreg op val\fR]
|
||||||
|
Set a breakpoint, optionally conditional on a register comparison
|
||||||
|
(register against register or immediate).
|
||||||
|
.TP
|
||||||
|
.B delete \fIlabel|addr\fR
|
||||||
|
Remove a breakpoint.
|
||||||
|
.TP
|
||||||
|
.B info break
|
||||||
|
List all breakpoints.
|
||||||
|
.TP
|
||||||
|
.BR step " [" n ], " s
|
||||||
|
Single-step n instructions; the default is 1.
|
||||||
|
.TP
|
||||||
|
.BR next ", " n
|
||||||
|
Step over a CALL.
|
||||||
|
.TP
|
||||||
|
.BR finish ", " fin
|
||||||
|
Run until the function returns.
|
||||||
|
.TP
|
||||||
|
.BR continue ", " c
|
||||||
|
Run until a breakpoint, watchpoint or exit.
|
||||||
|
.TP
|
||||||
|
.BR disas " [" n ], " u
|
||||||
|
Disassemble n instructions at PC.
|
||||||
|
.TP
|
||||||
|
.B regs
|
||||||
|
Print general-purpose and vector registers.
|
||||||
|
.TP
|
||||||
|
.B where
|
||||||
|
Show the source line and nearest label at PC.
|
||||||
|
.TP
|
||||||
|
.B stack
|
||||||
|
Show the stack near RSP (return address and ABI0 args).
|
||||||
|
.TP
|
||||||
|
.BR bt ", " backtrace
|
||||||
|
Backtrace: current frame plus return address.
|
||||||
|
.TP
|
||||||
|
.B x [\fIaddr\fR] [\fIlen\fR]
|
||||||
|
Hex-dump memory; the defaults are the current PC and 64 bytes.
|
||||||
|
.TP
|
||||||
|
.B w \fIaddr val...\fR
|
||||||
|
Write bytes to memory.
|
||||||
|
.TP
|
||||||
|
.B set \fIreg value\fR
|
||||||
|
Set a register.
|
||||||
|
.TP
|
||||||
|
.B watch \fIaddr\fR [\fBr|w\fR] [\fIsize\fR]
|
||||||
|
Set a hardware watchpoint; writes are watched by default.
|
||||||
|
.TP
|
||||||
|
.B unwatch [\fIslot\fR]
|
||||||
|
Clear one watchpoint, or all without an argument.
|
||||||
|
.TP
|
||||||
|
.BR labels ", " l
|
||||||
|
List function labels and offsets.
|
||||||
|
.TP
|
||||||
|
.BR help ", " h ", " ?
|
||||||
|
Show command help.
|
||||||
|
.TP
|
||||||
|
.BR quit ", " q
|
||||||
|
Kill the debuggee and exit.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.B \-args \fIfile\fR
|
||||||
|
File containing the ABI0 argument block.
|
||||||
|
.TP
|
||||||
|
.B \-buf \fIspec\fR
|
||||||
|
Buffer specification: name:size:pattern[,name:size:pattern...] where
|
||||||
|
pattern is zero, ones, seq, or hex.
|
||||||
|
.TP
|
||||||
|
.B \-cover
|
||||||
|
Run to completion with a breakpoint on every instruction and report
|
||||||
|
which executed and how often.
|
||||||
|
.TP
|
||||||
|
.B \-func \fIname\fR
|
||||||
|
Function to debug.
|
||||||
|
.TP
|
||||||
|
.B \-script \fIfile\fR
|
||||||
|
Run REPL commands from a file (one per line) and exit; - reads stdin.
|
||||||
|
.TP
|
||||||
|
.B \-timeout \fIduration\fR
|
||||||
|
Kill the debuggee after this duration (e.g. 30s); for headless --script
|
||||||
|
runs.
|
||||||
|
.SH EXIT STATUS
|
||||||
|
Exits 0 when the scripted session completes and 1 when the debuggee
|
||||||
|
crashes or a check fails; the debugger is Linux-only.
|
||||||
|
.SH EXAMPLES
|
||||||
|
.nf
|
||||||
|
gasm debug \-\-func name k.s
|
||||||
|
gasm debug \-\-func name \-\-script cmds.txt \-\-timeout 30s k.s
|
||||||
|
gasm debug \-\-func name \-\-cover k.s
|
||||||
|
.fi
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR gasm (1),
|
||||||
|
.BR gasm\-verify (1)
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
.TH GASM-DIFF 1 "2026-09-19" "gasm 0.33.0" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
gasm-diff \- compare the machine code of two assembly files
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B gasm diff [\-GOARCH arch] <file1.s> <file2.s>
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Compare the machine code produced by assembling two files. Shows which
|
||||||
|
functions differ and the byte-level differences. Useful for verifying
|
||||||
|
that two implementations produce identical code, or for tracking
|
||||||
|
encoding changes between Go assembler versions.
|
||||||
|
.PP
|
||||||
|
Functions are paired by exact name unless
|
||||||
|
.B \-\-map
|
||||||
|
says otherwise, so
|
||||||
|
.B \-\-map wideCopyAVX2=wideCopyAVX512
|
||||||
|
pairs two variants regardless of suffix.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.B \-GOARCH \fIarch\fR
|
||||||
|
Target architecture for both files: amd64, arm64, riscv64 or loong64;
|
||||||
|
overrides the file-name suffixes.
|
||||||
|
.TP
|
||||||
|
.B \-\-map \fIspec\fR
|
||||||
|
Comma-separated old=new pairs to match functions with different names.
|
||||||
|
.SH EXIT STATUS
|
||||||
|
Exits 0 when every paired function is identical and 1 when anything
|
||||||
|
differs; a usage error exits 2.
|
||||||
|
.SH EXAMPLES
|
||||||
|
.nf
|
||||||
|
gasm diff hello_amd64.s hello_amd64.s
|
||||||
|
gasm diff \-\-map wideCopyAVX2=wideCopyAVX512 avx2.s avx512.s
|
||||||
|
.fi
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR gasm (1),
|
||||||
|
.BR gasm\-asm (1)
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
.TH GASM-DIS 1 "2026-09-19" "gasm 0.33.0" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
gasm-dis \- disassemble machine code to instruction text
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B gasm dis [\-a arch] <file>
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Disassemble machine code to instruction text, decoded through
|
||||||
|
golang.org/x/arch.
|
||||||
|
.PP
|
||||||
|
With a
|
||||||
|
.I .s
|
||||||
|
file, the file is assembled first and the listing follows the real
|
||||||
|
layout: one block per TEXT function, local labels printed at their
|
||||||
|
offsets. The architecture comes from the file-name suffix, or from
|
||||||
|
.BR \-a .
|
||||||
|
.PP
|
||||||
|
With any other file, or
|
||||||
|
.B \-
|
||||||
|
for standard input, the bytes are disassembled linearly and
|
||||||
|
.B \-a
|
||||||
|
selects the architecture (amd64, arm64, riscv64 or loong64).
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.B \-a \fIarch\fR
|
||||||
|
Architecture for raw input: amd64, arm64, riscv64 or loong64.
|
||||||
|
.SH EXIT STATUS
|
||||||
|
Exits 0 on success, 1 when assembly or decoding fails, and 2 on a usage
|
||||||
|
error.
|
||||||
|
.SH EXAMPLES
|
||||||
|
.nf
|
||||||
|
gasm dis k.s assemble, then list each function
|
||||||
|
gasm dis \-a amd64 \- < dump.bin disassemble raw bytes from stdin
|
||||||
|
.fi
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR gasm (1),
|
||||||
|
.BR gasm\-asm (1)
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
.TH GASM-FMT 1 "2026-09-19" "gasm 0.33.0" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
gasm-fmt \- canonicalise the formatting of Plan 9 assembly sources
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B gasm fmt [\-w|\-l|\-d] [path...]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Canonicalise the formatting of Plan 9 assembly sources: indentation,
|
||||||
|
operand spacing, per-function mnemonic alignment and blank-line layout
|
||||||
|
(exactly one blank line before each label, TEXT and GLOBL block).
|
||||||
|
Formatting is idempotent and preserves every line, comments included.
|
||||||
|
.PP
|
||||||
|
With no paths, or a directory path, every
|
||||||
|
.I .s
|
||||||
|
file below it is reformatted in place and the changed files are listed,
|
||||||
|
the way
|
||||||
|
.B go fmt
|
||||||
|
does;
|
||||||
|
.B .
|
||||||
|
and
|
||||||
|
.B _
|
||||||
|
directories are skipped. Explicit file paths print to stdout unless
|
||||||
|
.B \-w
|
||||||
|
is given.
|
||||||
|
.PP
|
||||||
|
.B \-l
|
||||||
|
and
|
||||||
|
.B \-d
|
||||||
|
rewrite nothing:
|
||||||
|
.B \-l
|
||||||
|
prints the paths whose formatting differs from gasm's (empty output
|
||||||
|
means everything is formatted, which is what a CI check wants),
|
||||||
|
.B \-d
|
||||||
|
prints the diffs. They are mutually exclusive.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.B \-d
|
||||||
|
Print diffs instead of rewriting files.
|
||||||
|
.TP
|
||||||
|
.B \-l
|
||||||
|
List files whose formatting differs from gasm's.
|
||||||
|
.TP
|
||||||
|
.B \-w
|
||||||
|
Write the result to the source file.
|
||||||
|
.SH EXAMPLES
|
||||||
|
.nf
|
||||||
|
gasm fmt reformat every .s below here
|
||||||
|
gasm fmt \-w kernel_amd64.s canonicalise one file in place
|
||||||
|
gasm fmt \-l *.s list files whose formatting differs
|
||||||
|
gasm fmt \-d kernel_amd64.s print a unified diff instead
|
||||||
|
.fi
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR gasm (1)
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
.TH GASM-LINT 1 "2026-09-19" "gasm 0.33.0" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
gasm-lint \- run the static checks over assembly files
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B gasm lint <file...>
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Run the static checks over the given files and print diagnostics as
|
||||||
|
\fIfile:line:col: severity: message [code]\fR. The exit status is
|
||||||
|
non-zero when an error-severity diagnostic is found; warnings (e.g. the
|
||||||
|
register-clobber audit) do not affect it.
|
||||||
|
.PP
|
||||||
|
The checks are conservative: they report what can be proven wrong and
|
||||||
|
stay quiet otherwise, so a clean lint run is meaningful without
|
||||||
|
suppression lists.
|
||||||
|
.SH RULES
|
||||||
|
.TP
|
||||||
|
.B unknown-instruction
|
||||||
|
The mnemonic is not in the architecture's instruction table.
|
||||||
|
.TP
|
||||||
|
.B operand-count
|
||||||
|
The operand count disagrees with the instruction's declared arity.
|
||||||
|
.TP
|
||||||
|
.B undefined-label
|
||||||
|
A jump target names no label in the function.
|
||||||
|
.TP
|
||||||
|
.B duplicate-label
|
||||||
|
Two labels in one function share a name.
|
||||||
|
.TP
|
||||||
|
.B missing-ret
|
||||||
|
The function can fall off its end without a terminator.
|
||||||
|
.TP
|
||||||
|
.B missing-textflag-include
|
||||||
|
TEXT flags are used without including textflag.h.
|
||||||
|
.TP
|
||||||
|
.B abi-argsize
|
||||||
|
The declared frame or argument size disagrees with the
|
||||||
|
.B //\ function
|
||||||
|
signature.
|
||||||
|
.TP
|
||||||
|
.B unreachable-code
|
||||||
|
Code after RET and before the next label is dead; suppressed for
|
||||||
|
functions with PC-relative or register-indirect control flow.
|
||||||
|
.TP
|
||||||
|
.B register-clobber
|
||||||
|
A register the Go ABI fixes across calls is written without save and
|
||||||
|
restore, computed by liveness over the control-flow graph.
|
||||||
|
.TP
|
||||||
|
.B funcdata-pcdata
|
||||||
|
FUNCDATA and PCDATA indices are malformed.
|
||||||
|
.TP
|
||||||
|
.B unused-label
|
||||||
|
A label no jump reaches.
|
||||||
|
.TP
|
||||||
|
.B invalid-textflag
|
||||||
|
A TEXT flag combination the toolchain rejects.
|
||||||
|
.TP
|
||||||
|
.B stack-imbalance
|
||||||
|
The function does not restore the stack pointer on every path.
|
||||||
|
.TP
|
||||||
|
.B register-width-mismatch
|
||||||
|
An operand register has the wrong width for the instruction.
|
||||||
|
.TP
|
||||||
|
.B abi0-register-args
|
||||||
|
A call passes arguments in registers where ABI0 expects the stack
|
||||||
|
frame.
|
||||||
|
.TP
|
||||||
|
.B nonportable-register-name
|
||||||
|
A register spelling that does not exist on the target architecture.
|
||||||
|
.TP
|
||||||
|
.B unencodable-instruction
|
||||||
|
The mnemonic is known to the table but the encoder cannot assemble it
|
||||||
|
yet (amd64).
|
||||||
|
.TP
|
||||||
|
.B reserved-register-write
|
||||||
|
A write to the register the runtime reserves (arm64 R18).
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.B \-disable \fIcodes\fR
|
||||||
|
Comma-separated rule codes to disable.
|
||||||
|
.SH EXIT STATUS
|
||||||
|
Exits 0 when no error-severity diagnostic is found, 1 otherwise, and 2
|
||||||
|
on a usage error.
|
||||||
|
.SH EXAMPLES
|
||||||
|
.nf
|
||||||
|
gasm lint kernel_amd64.s
|
||||||
|
gasm lint \-disable register-clobber,unused-label *.s
|
||||||
|
.fi
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR gasm (1),
|
||||||
|
.BR gasm\-asm (1)
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
.TH GASM-LSP 1 "2026-09-19" "gasm 0.33.0" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
gasm-lsp \- run the Plan 9 assembly language server
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B gasm lsp
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Run the language server over standard input/output: JSON-RPC 2.0 with
|
||||||
|
Content-Length framing. Point an LSP-capable editor at the binary and
|
||||||
|
associate it with
|
||||||
|
.I .s
|
||||||
|
files; the target architecture is inferred from the file suffix
|
||||||
|
(_amd64.s, _arm64.s, _riscv64.s, _loong64.s).
|
||||||
|
.PP
|
||||||
|
Provides completion, hover, document symbols, push and pull
|
||||||
|
diagnostics, semantic-token highlighting, go-to-definition, find
|
||||||
|
references, rename, formatting, inlay hints, code actions, signature
|
||||||
|
help, document highlights, workspace symbol search, include document
|
||||||
|
links and folding ranges; definition, references and rename work across
|
||||||
|
every open document. Syntax highlighting is delivered as LSP semantic
|
||||||
|
tokens, so no editor-specific grammar is required.
|
||||||
|
.SH EXIT STATUS
|
||||||
|
Runs until the client closes the session; exits 0 on a clean shutdown.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR gasm (1)
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
.TH GASM-PARSE 1 "2026-09-19" "gasm 0.33.0" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
gasm-parse \- parse an assembly file and report syntax errors
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B gasm parse <file>
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Parse FILE and report syntax errors on stderr. The parser is
|
||||||
|
error-tolerant and line-oriented: a malformed line becomes a diagnostic
|
||||||
|
and parsing continues, so one run reports every syntax error in the
|
||||||
|
file rather than the first.
|
||||||
|
.PP
|
||||||
|
On success, print how many declarations and TEXT functions the file
|
||||||
|
contains. FILE may be
|
||||||
|
.B \-
|
||||||
|
to read standard input.
|
||||||
|
.SH EXIT STATUS
|
||||||
|
Exits 0 when the file parses without errors and 1 otherwise.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR gasm (1),
|
||||||
|
.BR gasm\-tokens (1)
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
.TH GASM-PROFILE 1 "2026-09-19" "gasm 0.33.0" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
gasm-profile \- show the basic-block structure of functions
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B gasm profile <file.s>
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Show the basic-block structure of functions in an assembly file: each
|
||||||
|
function's labels, their offsets, and the block boundaries. This is
|
||||||
|
the static structure; for runtime execution counts, use
|
||||||
|
.BR "gasm verify \-fuzz" ,
|
||||||
|
which exercises the code paths.
|
||||||
|
.SH EXIT STATUS
|
||||||
|
Exits 0 on success and 1 when the file cannot be assembled.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR gasm (1),
|
||||||
|
.BR gasm\-verify (1)
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
.TH GASM-SCAFFOLD 1 "2026-09-19" "gasm 0.33.0" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
gasm-scaffold \- generate a differential test skeleton for a kernel file
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B gasm scaffold differential <file.s>
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Print a differential test skeleton for every
|
||||||
|
.B //\ func
|
||||||
|
signature in FILE. The test seeds random states, drives the kernel and
|
||||||
|
a portable reference (\fI<name>Portable\fR), and compares outputs
|
||||||
|
byte-for-byte. Write the reference bodies, place the file in the
|
||||||
|
kernel's package, and run it in CI.
|
||||||
|
.SH EXIT STATUS
|
||||||
|
Exits 0 when the skeleton is written to stdout and 1 when the file
|
||||||
|
cannot be parsed; a usage error exits 2.
|
||||||
|
.SH EXAMPLES
|
||||||
|
.nf
|
||||||
|
gasm scaffold differential kernel_amd64.s > kernel_differential_test.go
|
||||||
|
.fi
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR gasm (1),
|
||||||
|
.BR gasm\-verify (1)
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
.TH GASM-TOKENS 1 "2026-09-19" "gasm 0.33.0" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
gasm-tokens \- print the lexical token stream of an assembly file
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B gasm tokens <file>
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Print the lexical token stream of FILE: position, token kind and text,
|
||||||
|
one token per line. FILE may be
|
||||||
|
.B \-
|
||||||
|
to read standard input.
|
||||||
|
.PP
|
||||||
|
This is the front end's raw view, for when the assembler's own
|
||||||
|
diagnostic is not enough: a mis-scanned operand or a swallowed comment
|
||||||
|
shows up here as the tokens the parser actually received.
|
||||||
|
.SH EXIT STATUS
|
||||||
|
Exits 0 on success and 1 when the file cannot be read.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR gasm (1),
|
||||||
|
.BR gasm\-parse (1)
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
.TH GASM-VERIFY 1 "2026-09-19" "gasm 0.33.0" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
gasm-verify \- JIT-assemble a file and run dynamic checks against it
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B gasm verify [\-smoke] [\-abi] [\-fuzz] [\-ground\-truth] [\-profile] [\-call] <file.s>
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Assemble FILE, map it into executable memory and report the available
|
||||||
|
functions. This confirms the assembled image is self-consistent (no
|
||||||
|
unresolved external symbols) and executable, the prerequisite for
|
||||||
|
dynamic testing.
|
||||||
|
.PP
|
||||||
|
With
|
||||||
|
.BR \-smoke ,
|
||||||
|
each NOSPLIT function is called with a zeroed argument block to confirm
|
||||||
|
the JIT trampoline works end-to-end. This is safe only for functions
|
||||||
|
that tolerate nil pointers and zero lengths in their arguments.
|
||||||
|
.PP
|
||||||
|
With
|
||||||
|
.BR \-abi ,
|
||||||
|
each function is called with sentinel values in the registers the Go
|
||||||
|
ABI fixes across calls (the frame pointer and the goroutine pointer)
|
||||||
|
plus a canary below SP; violations are reported. JIT-based checks run
|
||||||
|
when the host matches the file's architecture (all but loong64, which
|
||||||
|
is ground-truth only for now).
|
||||||
|
.PP
|
||||||
|
With
|
||||||
|
.BR \-fuzz ,
|
||||||
|
each function with a
|
||||||
|
.B //\ func
|
||||||
|
signature is differentially fuzzed against the go-tool-asm version in a
|
||||||
|
subprocess (so a crash on a partial function is reported, not fatal).
|
||||||
|
.PP
|
||||||
|
With
|
||||||
|
.BR \-ground\-truth ,
|
||||||
|
the assembled machine code is compared byte-for-byte against
|
||||||
|
.B go tool asm
|
||||||
|
(relocation sites masked), reporting any encoding drift.
|
||||||
|
.PP
|
||||||
|
With
|
||||||
|
.BR \-profile ,
|
||||||
|
the static basic-block structure is listed for each function.
|
||||||
|
.PP
|
||||||
|
With
|
||||||
|
.BR \-call ,
|
||||||
|
a single function is invoked with user-supplied buffers
|
||||||
|
.RB ( \-buf )
|
||||||
|
instead of the smoke/abi/fuzz sweeps. Useful for partial functions
|
||||||
|
(e.g. decoders) that crash on random input but should succeed on valid
|
||||||
|
data.
|
||||||
|
.PP
|
||||||
|
With
|
||||||
|
.B \-save\-corpus
|
||||||
|
(and
|
||||||
|
.BR \-fuzz ),
|
||||||
|
every input that crashes or mismatches is written to the directory as
|
||||||
|
replayable JSON.
|
||||||
|
.B \-replay
|
||||||
|
re-runs saved entries against the kernel, one child process per entry,
|
||||||
|
so an input that crashed the original run crashes only the child: the
|
||||||
|
report says whether each entry reproduces.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.B \-abi
|
||||||
|
Run ABI-checking calls (sentinel registers and red zone).
|
||||||
|
.TP
|
||||||
|
.B \-abi\-n \fIn\fR
|
||||||
|
Number of ABI check iterations with varied inputs; the default is 100.
|
||||||
|
.TP
|
||||||
|
.B \-args \fIspec\fR
|
||||||
|
Scalar args for -call: name=value[,name=value] (decimal or 0x hex).
|
||||||
|
.TP
|
||||||
|
.B \-buf \fIspec\fR
|
||||||
|
Buffer spec for -call: name:size:pattern[,name:size:pattern] where
|
||||||
|
pattern is zero, ones, seq, or hex.
|
||||||
|
.TP
|
||||||
|
.B \-call \fIname\fR
|
||||||
|
Call a single function with -buf instead of the sweeps.
|
||||||
|
.TP
|
||||||
|
.B \-fuzz
|
||||||
|
Differential fuzz: JIT both the gasm and the go-tool-asm versions and
|
||||||
|
compare outputs.
|
||||||
|
.TP
|
||||||
|
.B \-ground\-truth
|
||||||
|
Compare machine code byte-for-byte against go tool asm.
|
||||||
|
.TP
|
||||||
|
.B \-n \fIn\fR
|
||||||
|
Number of fuzz iterations per function; the default is 1000.
|
||||||
|
.TP
|
||||||
|
.B \-profile
|
||||||
|
List basic-block structure per function.
|
||||||
|
.TP
|
||||||
|
.B \-repeat \fIn\fR
|
||||||
|
Number of times to repeat a -call invocation; the default is 1.
|
||||||
|
.TP
|
||||||
|
.B \-replay \fIdir\fR
|
||||||
|
Replay saved corpus entries (JSON files in this directory) against the
|
||||||
|
kernel.
|
||||||
|
.TP
|
||||||
|
.B \-save\-corpus \fIdir\fR
|
||||||
|
With -fuzz: write each failing input to this directory as replayable
|
||||||
|
JSON.
|
||||||
|
.TP
|
||||||
|
.B \-smoke
|
||||||
|
Call each NOSPLIT function with zeroed args.
|
||||||
|
.SH EXIT STATUS
|
||||||
|
Exits 0 when every requested check passes and 1 when any check fails;
|
||||||
|
a file that cannot be assembled exits 1 and a usage error exits 2.
|
||||||
|
.SH EXAMPLES
|
||||||
|
.nf
|
||||||
|
gasm verify \-\-call add \-\-args a=2,b=3 hello_amd64.s
|
||||||
|
gasm verify \-\-ground\-truth k.s
|
||||||
|
gasm verify \-\-fuzz \-n 500 k.s
|
||||||
|
.fi
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR gasm (1),
|
||||||
|
.BR gasm\-asm (1),
|
||||||
|
.BR gasm\-debug (1)
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
.TH GASM 1 "2026-09-19" "gasm 0.33.0" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
gasm \- developer tooling for Go's Plan 9 assembler
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B gasm
|
||||||
|
.I command
|
||||||
|
.RI [ arguments ]
|
||||||
|
.br
|
||||||
|
.B gasm
|
||||||
|
.BR \-h | \-\-help
|
||||||
|
.br
|
||||||
|
.B gasm
|
||||||
|
.BR \-V | \-\-version
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.B gasm
|
||||||
|
bundles a lexer, parser, formatter, linter, standalone assembler and
|
||||||
|
language server for Plan 9 assembly into one self-contained binary. It
|
||||||
|
serves two purposes: it brings developer tooling to the
|
||||||
|
.I .s
|
||||||
|
files of Go programs, and it assembles Plan 9 assembly without the Go
|
||||||
|
toolchain at all, to raw images, linkable ELF objects with DWARF5 debug
|
||||||
|
sections, or the Go toolchain's own GOOBJ format, which
|
||||||
|
.B go build
|
||||||
|
consumes directly.
|
||||||
|
.PP
|
||||||
|
Four architectures are covered: amd64 (including VEX/AVX2 and
|
||||||
|
EVEX/AVX-512), arm64, riscv64 (RV64IMAFDC and RVC) and loong64. The
|
||||||
|
target architecture is inferred from the file-name suffix
|
||||||
|
(\fI_amd64.s\fR, \fI_arm64.s\fR, \fI_riscv64.s\fR, \fI_loong64.s\fR) or
|
||||||
|
named explicitly with \fB\-GOARCH\fR where the commands accept it.
|
||||||
|
.SH COMMANDS
|
||||||
|
.TP
|
||||||
|
.B gasm\-tokens(1)
|
||||||
|
Print the lexical token stream.
|
||||||
|
.TP
|
||||||
|
.B gasm\-parse(1)
|
||||||
|
Parse a file and report syntax errors.
|
||||||
|
.TP
|
||||||
|
.B gasm\-fmt(1)
|
||||||
|
Canonicalise formatting: gofmt for assembly.
|
||||||
|
.TP
|
||||||
|
.B gasm\-lint(1)
|
||||||
|
Run the static checks.
|
||||||
|
.TP
|
||||||
|
.B gasm\-asm(1)
|
||||||
|
Assemble \fI.s\fR files to machine code, raw images, ELF objects or GOOBJ.
|
||||||
|
.TP
|
||||||
|
.B gasm\-dis(1)
|
||||||
|
Disassemble machine code, raw bytes or an assembled \fI.s\fR file.
|
||||||
|
.TP
|
||||||
|
.B gasm\-verify(1)
|
||||||
|
JIT-assemble and run dynamic checks: smoke calls, ABI checks,
|
||||||
|
differential fuzzing, ground-truth comparison.
|
||||||
|
.TP
|
||||||
|
.B gasm\-debug(1)
|
||||||
|
Interactive source-level debugger.
|
||||||
|
.TP
|
||||||
|
.B gasm\-diff(1)
|
||||||
|
Compare the machine code of two files byte-for-byte.
|
||||||
|
.TP
|
||||||
|
.B gasm\-profile(1)
|
||||||
|
Show the basic-block structure of functions.
|
||||||
|
.TP
|
||||||
|
.B gasm\-audit\-instructions(1)
|
||||||
|
Diff the encoder against the Go toolchain's name table, or measure a
|
||||||
|
corpus of \fI.s\fR files.
|
||||||
|
.TP
|
||||||
|
.B gasm\-scaffold(1)
|
||||||
|
Generate a differential test skeleton for a kernel file.
|
||||||
|
.TP
|
||||||
|
.B gasm\-lsp(1)
|
||||||
|
Run the language server over standard input/output.
|
||||||
|
.TP
|
||||||
|
.B gasm version
|
||||||
|
Print the version, the same as \fB\-\-version\fR.
|
||||||
|
.SH GLOBAL FLAGS
|
||||||
|
.TP
|
||||||
|
.BR \-h ", " \-\-help
|
||||||
|
Show the command overview.
|
||||||
|
.TP
|
||||||
|
.BR \-V ", " \-\-version
|
||||||
|
Print the version the toolchain recorded at build time.
|
||||||
|
.SH EXIT STATUS
|
||||||
|
Exits 0 on success, 1 when a command fails, and 2 on a usage error. An
|
||||||
|
unknown command exits 2.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR gasm\-asm (1),
|
||||||
|
.BR gasm\-fmt (1),
|
||||||
|
.BR gasm\-lint (1),
|
||||||
|
.BR gasm\-verify (1),
|
||||||
|
.BR gasm\-debug (1)
|
||||||
|
.PP
|
||||||
|
The full command reference, with worked examples and every flag, is in
|
||||||
|
docs/CLI.md of the repository
|
||||||
|
.UR https://sourcedock.dev/petrbalvin/gasm-devkit
|
||||||
|
.UE .
|
||||||
@@ -13,6 +13,10 @@ packages := "./arch/... ./asm/... ./ast/... ./disasm/... ./format/... ./lexer/..
|
|||||||
|
|
||||||
bindir := env_var_or_default("BINDIR", env_var("HOME") / ".local" / "bin")
|
bindir := env_var_or_default("BINDIR", env_var("HOME") / ".local" / "bin")
|
||||||
|
|
||||||
|
# Where `install-man` puts the gzip-compressed pages (man1 below it). Exported because
|
||||||
|
# the Perl recipes read it from the environment.
|
||||||
|
export MANDIR := env_var_or_default("MANDIR", env_var("HOME") / ".local" / "share" / "man")
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@just --list
|
@just --list
|
||||||
|
|
||||||
@@ -84,6 +88,37 @@ install: build
|
|||||||
uninstall:
|
uninstall:
|
||||||
rm -f "{{bindir}}/{{binary}}"
|
rm -f "{{bindir}}/{{binary}}"
|
||||||
|
|
||||||
|
# Install the man pages under docs/man into mandir/man1, gzip-compressed. Not a gate: a
|
||||||
|
# convenience for the person at the keyboard; man finds them through ~/.local/share/man.
|
||||||
|
install-man:
|
||||||
|
#!/usr/bin/env perl
|
||||||
|
my $out = $ENV{MANDIR} . q{/man1};
|
||||||
|
system(q{mkdir}, q{-p}, $out) == 0 or die qq{mkdir $out: $!\n};
|
||||||
|
for my $p (glob q{docs/man/*.1}) {
|
||||||
|
open(my $g, q{-|}, q{gzip}, q{-c}, $p) or die qq{gzip $p: $!\n};
|
||||||
|
my $content = do { local $/; <$g> };
|
||||||
|
close($g);
|
||||||
|
my $base = $p;
|
||||||
|
$base =~ s{docs/man/}{};
|
||||||
|
open(my $o, q{>}, qq{$out/$base.gz}) or die qq{write $out/$base.gz: $!\n};
|
||||||
|
print {$o} $content;
|
||||||
|
close($o);
|
||||||
|
print qq{$out/$base.gz\n};
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove the installed man pages.
|
||||||
|
uninstall-man:
|
||||||
|
#!/usr/bin/env perl
|
||||||
|
for my $p (glob q{docs/man/*.1}) {
|
||||||
|
my $base = $p;
|
||||||
|
$base =~ s{docs/man/}{};
|
||||||
|
my $f = $ENV{MANDIR} . q{/man1/} . $base . q{.gz};
|
||||||
|
if (-f $f) {
|
||||||
|
unlink($f) or die qq{unlink $f: $!\n};
|
||||||
|
print qq{removed $f\n};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Run the program. The flag is there because `go run` does not stamp the build otherwise.
|
# Run the program. The flag is there because `go run` does not stamp the build otherwise.
|
||||||
run:
|
run:
|
||||||
go run -buildvcs=true {{package}}
|
go run -buildvcs=true {{package}}
|
||||||
|
|||||||
Reference in New Issue
Block a user