detached d476432

internal/fakecgo: use libthr.so.3 instead of libpthread.so on FreeBSD (#481)

FreeBSD 15 removed the libpthread.so compatibility symlink to libthr.so
from base. This caused Go binaries built with CGO_ENABLED=0 using
purego's FreeBSD fakecgo path to have an unresolvable NEEDED entry for
libpthread.so.

libthr.so.3 is FreeBSD's actual threading implementation and has been
present since at least FreeBSD 12.x. Updated gen.go and regenerated
zsymbols_freebsd.go accordingly.

Tested on FreeBSD 15.1-STABLE amd64: examples/libc builds and runs
correctly with CGO_ENABLED=0, and readelf confirms the binary now links
against libthr.so.3 instead of libpthread.so.

Closes #480
commit
d476432ce7e3d8bb64b7cd257d332ee221ed6e7b
author
rcina · · 2026-07-18 13:34 UTC
committer
GitHub · · 2026-07-18 13:34 UTC
parent
b1a632f
signature
GPG UnverifiedB5690EEEBB952194 The key is unknown
refs
tag: v0.11.0-alpha.8
2 files · +11 -11
M internal/fakecgo/gen.go +1 -1
@@ -268,7 +268,7 @@ func run() error {
268268 pthreadSO = "/usr/lib/libSystem.B.dylib"
269269 case "freebsd":
270270 libcSO = "libc.so.7"
271- pthreadSO = "libpthread.so"
271+ pthreadSO = "libthr.so.3"
272272 case "linux":
273273 libcSO = "libc.so.6"
274274 pthreadSO = "libpthread.so.0"
@@ -268,7 +268,7 @@ func run() error {
268 pthreadSO = "/usr/lib/libSystem.B.dylib"268 pthreadSO = "/usr/lib/libSystem.B.dylib"
269 case "freebsd":269 case "freebsd":
270 libcSO = "libc.so.7"270 libcSO = "libc.so.7"
271- pthreadSO = "libpthread.so"271+ pthreadSO = "libthr.so.3"
272 case "linux":272 case "linux":
273 libcSO = "libc.so.6"273 libcSO = "libc.so.6"
274 pthreadSO = "libpthread.so.0"274 pthreadSO = "libpthread.so.0"
M internal/fakecgo/zsymbols_freebsd.go +10 -10
@@ -16,16 +16,16 @@ import "unsafe"
1616 //go:cgo_import_dynamic purego_sigfillset sigfillset "libc.so.7"
1717 //go:cgo_import_dynamic purego_nanosleep nanosleep "libc.so.7"
1818 //go:cgo_import_dynamic purego_abort abort "libc.so.7"
19-//go:cgo_import_dynamic purego_pthread_attr_init pthread_attr_init "libpthread.so"
20-//go:cgo_import_dynamic purego_pthread_create pthread_create "libpthread.so"
21-//go:cgo_import_dynamic purego_pthread_detach pthread_detach "libpthread.so"
22-//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "libpthread.so"
23-//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "libpthread.so"
24-//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "libpthread.so"
25-//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "libpthread.so"
26-//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "libpthread.so"
27-//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "libpthread.so"
28-//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "libpthread.so"
19+//go:cgo_import_dynamic purego_pthread_attr_init pthread_attr_init "libthr.so.3"
20+//go:cgo_import_dynamic purego_pthread_create pthread_create "libthr.so.3"
21+//go:cgo_import_dynamic purego_pthread_detach pthread_detach "libthr.so.3"
22+//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "libthr.so.3"
23+//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "libthr.so.3"
24+//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "libthr.so.3"
25+//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "libthr.so.3"
26+//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "libthr.so.3"
27+//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "libthr.so.3"
28+//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "libthr.so.3"
2929
3030 //go:nosplit
3131 //go:norace
@@ -16,16 +16,16 @@ import "unsafe"
16 //go:cgo_import_dynamic purego_sigfillset sigfillset "libc.so.7"16 //go:cgo_import_dynamic purego_sigfillset sigfillset "libc.so.7"
17 //go:cgo_import_dynamic purego_nanosleep nanosleep "libc.so.7"17 //go:cgo_import_dynamic purego_nanosleep nanosleep "libc.so.7"
18 //go:cgo_import_dynamic purego_abort abort "libc.so.7"18 //go:cgo_import_dynamic purego_abort abort "libc.so.7"
19-//go:cgo_import_dynamic purego_pthread_attr_init pthread_attr_init "libpthread.so"19+//go:cgo_import_dynamic purego_pthread_attr_init pthread_attr_init "libthr.so.3"
20-//go:cgo_import_dynamic purego_pthread_create pthread_create "libpthread.so"20+//go:cgo_import_dynamic purego_pthread_create pthread_create "libthr.so.3"
21-//go:cgo_import_dynamic purego_pthread_detach pthread_detach "libpthread.so"21+//go:cgo_import_dynamic purego_pthread_detach pthread_detach "libthr.so.3"
22-//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "libpthread.so"22+//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "libthr.so.3"
23-//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "libpthread.so"23+//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "libthr.so.3"
24-//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "libpthread.so"24+//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "libthr.so.3"
25-//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "libpthread.so"25+//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "libthr.so.3"
26-//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "libpthread.so"26+//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "libthr.so.3"
27-//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "libpthread.so"27+//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "libthr.so.3"
28-//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "libpthread.so"28+//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "libthr.so.3"
29 29
30 //go:nosplit30 //go:nosplit
31 //go:norace31 //go:norace

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 102

↑↓ moveenter openesc close