2026-10-02 00:40:54 +02:00
|
|
|
.TH GASM-LINT 1 "2026-10-01" "gasm" "User Commands"
|
2026-09-19 21:18:43 +02:00
|
|
|
.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
|
2026-10-02 00:40:54 +02:00
|
|
|
The function has no RET, or has one but can still fall off its end: the
|
|
|
|
|
last instruction is neither RET nor an unconditional branch, so execution
|
|
|
|
|
continues into the next TEXT. Trailing labels, GC annotations and
|
|
|
|
|
padding are skipped, and traps (INT on amd64, BRK on arm64) count as
|
|
|
|
|
terminators.
|
2026-09-19 21:18:43 +02:00
|
|
|
.TP
|
|
|
|
|
.B missing-textflag-include
|
|
|
|
|
TEXT flags are used without including textflag.h.
|
|
|
|
|
.TP
|
|
|
|
|
.B abi-argsize
|
2026-09-20 01:40:51 +02:00
|
|
|
The declared argument area (the
|
|
|
|
|
.I \-args
|
|
|
|
|
part of
|
|
|
|
|
.IR $frame\-args )
|
|
|
|
|
disagrees with the
|
2026-09-19 21:18:43 +02:00
|
|
|
.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
|
2026-10-02 00:40:54 +02:00
|
|
|
An unknown TEXT or GLOBL flag, or a known one misplaced (NOSPLIT on
|
|
|
|
|
GLOBL, RODATA on TEXT), reported one flag at a time; numeric flags are
|
|
|
|
|
accepted as textflag.h constants.
|
2026-09-19 21:18:43 +02:00
|
|
|
.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
|
2026-09-20 01:40:51 +02:00
|
|
|
A function whose
|
|
|
|
|
.B //\ function
|
|
|
|
|
parameters are never read from their
|
|
|
|
|
.IR name+offset(FP)
|
|
|
|
|
frame slots, which usually means the body takes its arguments from
|
|
|
|
|
registers instead.
|
2026-09-19 21:18:43 +02:00
|
|
|
.TP
|
|
|
|
|
.B nonportable-register-name
|
2026-09-20 01:40:51 +02:00
|
|
|
An amd64 register alias gasm accepts but
|
|
|
|
|
.B go tool asm
|
|
|
|
|
rejects (the RAX/EAX family); the canonical spelling is named in the
|
|
|
|
|
diagnostic.
|
2026-09-19 21:18:43 +02:00
|
|
|
.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).
|
2026-10-02 00:40:54 +02:00
|
|
|
.TP
|
|
|
|
|
.B missing-argsize
|
|
|
|
|
A TEXT without NOSPLIT omits the argument area its
|
|
|
|
|
.B //\ function
|
|
|
|
|
signature implies; the object then records ArgsSizeUnknown and go vet
|
|
|
|
|
skips the size check.
|
|
|
|
|
.TP
|
|
|
|
|
.B noframe-frame-size
|
|
|
|
|
The NOFRAME flag against a positive frame size; NOFRAME is the
|
|
|
|
|
zero-frame spelling, and the negative frames of the arm64 BSD syscall
|
|
|
|
|
stubs are exempt.
|
|
|
|
|
.TP
|
|
|
|
|
.B unnamed-fp-reference
|
|
|
|
|
A numeric offset against FP, written
|
|
|
|
|
.IR 0(FP) ;
|
|
|
|
|
the assembler requires
|
|
|
|
|
.IR name+offset(FP) .
|
|
|
|
|
.TP
|
|
|
|
|
.B hardware-sp-addressing
|
|
|
|
|
A negative numeric offset against
|
|
|
|
|
.IR (SP) ,
|
|
|
|
|
which addresses the hardware stack pointer rather than the named
|
|
|
|
|
virtual frame; the runtime's deliberate hardware-SP references all
|
|
|
|
|
carry positive offsets.
|
|
|
|
|
.TP
|
|
|
|
|
.B vex-sse-mixing
|
|
|
|
|
VEX-encoded instructions and legacy SSE on X registers in one function;
|
|
|
|
|
each switch between the encodings pays a transition penalty
|
|
|
|
|
(informational).
|
|
|
|
|
.TP
|
|
|
|
|
.B unnamed-result
|
|
|
|
|
A result slot addressed with the generic
|
|
|
|
|
.I ret
|
|
|
|
|
spelling although the
|
|
|
|
|
.B //\ function
|
|
|
|
|
signature names the result (a hint).
|
|
|
|
|
.TP
|
|
|
|
|
.B data-width
|
|
|
|
|
A DATA width its value cannot take: 1, 2, 4 or 8 for an integer, 4 or 8
|
|
|
|
|
for a float, and the suffix itself is never optional; a string accepts
|
|
|
|
|
any width.
|
|
|
|
|
.TP
|
|
|
|
|
.B data-value-overflow
|
|
|
|
|
An integer initialiser wider than its DATA field; both assemblers
|
|
|
|
|
truncate it silently to the low bytes.
|
|
|
|
|
.TP
|
|
|
|
|
.B data-string-width
|
|
|
|
|
A string initialiser longer than its DATA field; both assemblers reject
|
|
|
|
|
it.
|
|
|
|
|
.TP
|
|
|
|
|
.B data-without-globl
|
|
|
|
|
A DATA initialiser whose symbol has no GLOBL declaration in the file;
|
|
|
|
|
gasm asm requires the pairing, go tool asm sizes the symbol implicitly.
|
|
|
|
|
.TP
|
|
|
|
|
.B data-exceeds-globl
|
|
|
|
|
A DATA initialiser writing past the GLOBL-declared size; go tool asm
|
|
|
|
|
grows the symbol silently, gasm asm rejects the file.
|
2026-09-19 21:18:43 +02:00
|
|
|
.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)
|