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.
golang.org/x/tools/go/gcexportdataas a production dependency. The straightforward path: read each imported package's export file (paths from-importcfgorgo list -export), assign symbol indices in its symbol order, writePkgIndex/Autolibentries (fingerprints from the export files' build IDs) and positional references. Robust across toolchain versions —x/toolstracks 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.- 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.
- 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 nmsorts 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.