3.2 KiB
Deferred decisions
Design decisions deliberately postponed, with enough context to pick them up again without re-deriving the analysis. Each entry records what is deferred, why, the options on the table, and the trigger that should reopen it.
GOOBJ external (cross-package) symbol references
Status: resolved (v0.29.0+, 2026-08-07).
Approach taken. Instead of parsing the compiler's iexport data (which
would have required either golang.org/x/tools or an in-house parser), the
resolver reads the GOOBJ data directly from the target package's .a
archive. The .a file contains a _go_.o member whose GOOBJ format is the
same one gasm writes — the parser reuses the same layout (blkSymdef,
blkNonpkgdef, the string table), so no new dependency was needed.
How it works.
go list -json -export <pkg>finds the target package's.afile.extractGOOBJreads the ar archive, finds the_go_.omember, skips the"go object …\n!\n"preamble and parses the GOOBJ header.goobjFile.symbols()walksblkSymdefandblkNonpkgdefin definition order — the same order the linker uses — to build the symbol → index mapping.resolveExternalSymbolswires the resolved{PkgIdx, SymIdx}into the GOOBJ emission.
The resolver is invoked automatically when img.Externals is non-empty; it
runs go list as a subprocess (consistent with toolchainObjectPreamble
which already calls go tool asm). All symbol data is cached per package
for the lifetime of the GOOBJ emission.
2026-08-29 tooling round
lint abi0-register-args: flags kernels whose// funcparameters are never read from the FP frame. Motivated by a real latent bug: kernels reading arguments from registers pass every test while the autogeneratedF.abi0wrapper happens to leave the caller's register values intact, and break on a toolchain upgrade.lint nonportable-register-name: the RAX/EAX register spellings are a gasm extension; go tool asm rejects them, so files using them only link through the gasm goobj path.lint unencodable-instruction: a mnemonic in the architecture table thatasm.Encodablerejects is flagged at edit time instead of failing at assembly time.audit-instructions: black-box diff of the encoder against go tool asm. As of this round the tables fully overlap on names; the audit exists to catch drift in both directions (future supersets and future gaps).scaffold differential: generates the direct-call differential skeleton (two independent seed sets, output and in-place buffer comparison) that a pipeline-level fuzz can never replace.verify --args: scalar arguments for-call, closing the repro gap where only buffers could be supplied.debug --script/--timeout/--cover: headless debugging with a watchdog armed before the ptrace attach (untracing sandboxes hang the attach), and label-level block coverage for the "did my test ever enter that branch" question.- Superset policy remains: gasm may accept spellings and encodings go tool
asm lacks, but such kernels ship only via
gasm asm --format goobj; the audit reports the superset surface. The register-alias superset is warned about by lint because the defaultgo buildpath cannot consume it.