Skip to content

fix: build callback_amd64.s on FreeBSD - #83

Open
unxed wants to merge 2 commits into
go-webgpu:mainfrom
unxed:feature/freebsd-amd64-callback-asm
Open

unxed wants to merge 2 commits into
go-webgpu:mainfrom
unxed:feature/freebsd-amd64-callback-asm

Conversation

@unxed

@unxed unxed commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

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: #76 (review)

@codecov

codecov Bot commented Sep 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Both Android arm64 jobs now fail in "Set up Android SDK", before any goffi
code runs:

    Warning: Failed to find package 'tools'
    Error: The process '/usr/local/lib/android/sdk/cmdline-tools/16.0/bin/sdkmanager' failed with exit code 1

android-actions/setup-android@v3 defaults its `packages` input to
`tools platform-tools` and runs `sdkmanager <pkg>` for each entry. Google's
SDK repository index (repository2-3.xml) no longer contains a `tools`
package, while `platform-tools` and `cmdline-tools` are still listed, so
the `tools` call exits 1. The same breakage is tracked upstream in
android-actions/setup-android#537. The last green run of these jobs on main
was for c8f74c6 on 2026-09-10; the workflow has not changed since, and the
failure is identical on a docs-only PR.

Nothing in this workflow or in scripts/check-android-arm64.sh uses the
`tools` package. Pass `packages: platform-tools`, which keeps everything
the step installed before except the package that no longer exists. The
action still accepts licenses, exports ANDROID_HOME and puts sdkmanager on
PATH, which the following NDK step relies on.
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)
@unxed
unxed force-pushed the feature/freebsd-amd64-callback-asm branch from 7768491 to 55f9278 Compare September 25, 2026 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant