Files
gasm-sdk/docs/DEFERRED.md
T

3.0 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: deferred (v0.15.0, 2026-08-02). The GOOBJ emitter resolves only symbols defined in the file being assembled; a reference to any other symbol is rejected.

Why it is deferred. GOOBJ symbol references are positional: a reference is a {PkgIdx, SymIdx} pair, where SymIdx is the index of the symbol in the referenced package's symbol-definition table. That ordering is not derivable from the reference site — it lives in the referenced package's gc export data (the iexport binary format, which evolves with the toolchain). cmd/asm reads it with cmd/internal readers gasm cannot import, so emitting external references means either parsing export data ourselves or taking a dependency that does.

What works today. Single-package objects: every symbol the file defines (as TEXT or GLOBL, static or exported) and every reference to them. This covers the production use case — the go-flac / go-lz4 kernels carry no FUNCDATA/PCDATA, hence no references into runtime, and the Go side references the assembly symbols, never the reverse. Such a package builds with its assembly object replaced by a gasm-emitted one.

The options, when we return.

  1. golang.org/x/tools/go/gcexportdata as a production dependency. The straightforward path: read each imported package's export file (paths from -importcfg or go list -export), assign symbol indices in its symbol order, write PkgIndex/Autolib entries (fingerprints from the export files' build IDs) and positional references. Robust across toolchain versions — x/tools tracks the format. Cost: the first production dependency beyond the standard library, an explicit deviation from the "production code depends only on the standard library" principle in the README. Requires the user's explicit agreement.
  2. A minimal iexport parser of our own. Preserves self-containment. Substantial effort and inherently fragile: the format is an internal contract that changes with Go releases, so the parser needs a version-gated fallback and regression tests against several toolchains.
  3. Shell out to the toolchain for symbol metadata. Consistent with the existing GOOBJ preamble probe (which already runs go tool asm), but no toolchain command exposes a package's symbols in definition-index order — go tool nm sorts differently — so this does not solve the core problem on its own; it would only feed option 1 or 2.

Trigger to reopen. An assembly file that needs a cross-package reference — in practice FUNCDATA $…, runtime·…(SB) (stack maps / GC metadata written in assembly), or any kernel that calls into another package directly. Until then, option 3's limitation is moot and the single-package emitter suffices.