Repository navigation
fix: build callback_amd64.s on FreeBSD - #83
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
7768491 to
55f9278
Compare
kolkov
left a comment
There was a problem hiding this comment.
Thanks for picking this up from the #76 review.
Verified locally (Go 1.27.1, linux/amd64 host):
- Your
scripts/check-callback-trampolines.shrun against currentmainfails exactly where it should:freebsd/amd64: ffi.callbackTrampoline has type 'B', want T. The other five targets areT. - On this branch all six targets report
T. go vet ./...andgo test -count=1 ./...pass (CGO_ENABLED=0).
The gate is the valuable part here: a .s file with a narrower constraint than its .go counterpart compiles and links silently, and only the symbol type of a linked consumer shows it. Good catch on linking a real binary instead of relying on go build ./....
One nit for the CHANGELOG entry, since it's permanent text: the placeholder's symbol type depends on the toolchain and the binary — I see B (BSS) with Go 1.27.1 through your script and D in an ffi test binary built with Go 1.25.3. Could you word it as "a data symbol (B/D), not T" or similar? Not a blocker.
Approving. Please rebase onto main: #85 is merged, so the PR shrinks to its own commit, and #92 touched ci.yml, CHANGELOG.md and a comment in ffi/callback_amd64.s, so expect small conflicts there. After the rebase your PR also runs the new lint-on-every-target and native arm64/Intel-macOS test jobs.
ffi/callback.go is built for (linux || darwin || freebsd) && amd64, but
ffi/callback_amd64.s, which holds the 2000-entry trampoline table and
callbackDispatcher, was built only for (linux || darwin) && amd64.
The Go side takes the table's address through a placeholder:
//go:linkname _callbackTrampoline github.com/go-webgpu/goffi/ffi.callbackTrampoline
var _callbackTrampoline byte
With the assembly excluded, that one-byte variable becomes the definition
of ffi.callbackTrampoline. Nothing fails to compile or link. On a linked
freebsd/amd64 consumer, `go tool nm` reports
D github.com/go-webgpu/goffi/ffi.callbackTrampoline
and no callbackDispatcher or callbackWrap at all, where linux/amd64 and
freebsd/arm64 report T for all three. NewCallback therefore returns
addresses computed from a data-segment byte, not code.
The dispatcher is plain System V AMD64 (the same ABI FreeBSD uses) and
enters Go through crosscall2, which internal/fakecgo already provides on
FreeBSD, so the fix is adding freebsd to the constraint.
The existing cross-compile job could not catch this: `go build ./...`
links nothing, and the broken build compiles. scripts/check-callback-
trampolines.sh links a small NewCallback consumer for every target whose
callbacks come from goffi's own assembly (linux, darwin, freebsd x amd64,
arm64) and fails unless the symbol is T. Run against the tree before this
change it reports freebsd/amd64 as 'D'; after it, all six targets pass.
The Cross-Compile job now runs it.
Not verified on a FreeBSD host; the evidence is the symbol table of the
cross-linked binaries.
Refs: go-webgpu#76 (review)
55f9278 to
afd2d40
Compare
|
I rebased this onto current |
ffi/callback.go is built for (linux || darwin || freebsd) && amd64, but ffi/callback_amd64.s, which holds the 2000-entry trampoline table and callbackDispatcher, was built only for (linux || darwin) && amd64.
The Go side takes the table's address through a placeholder:
With the assembly excluded, that one-byte variable becomes the definition of ffi.callbackTrampoline. Nothing fails to compile or link. On a linked freebsd/amd64 consumer,
go tool nmreportsand no callbackDispatcher or callbackWrap at all, where linux/amd64 and freebsd/arm64 report T for all three. NewCallback therefore returns addresses computed from a data-segment byte, not code.
The dispatcher is plain System V AMD64 (the same ABI FreeBSD uses) and enters Go through crosscall2, which internal/fakecgo already provides on FreeBSD, so the fix is adding freebsd to the constraint.
The existing cross-compile job could not catch this:
go build ./...links nothing, and the broken build compiles. scripts/check-callback- trampolines.sh links a small NewCallback consumer for every target whose callbacks come from goffi's own assembly (linux, darwin, freebsd x amd64, arm64) and fails unless the symbol is T. Run against the tree before this change it reports freebsd/amd64 as 'D'; after it, all six targets pass. The Cross-Compile job now runs it.Not verified on a FreeBSD host; the evidence is the symbol table of the cross-linked binaries.
Refs: #76 (review)