Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Tier 2 platforms are supported by PureGo on a best-effort basis. Critical bugs o
- **FreeBSD**: amd64<sup>3,4</sup>, arm64<sup>3,4</sup>
- **Linux**: 386<sup>3</sup>, arm<sup>3</sup>, loong64<sup>2</sup>, ppc64le<sup>2</sup>, riscv64<sup>3</sup>, s390x<sup>3, 5</sup>
- **NetBSD**: amd64<sup>3,4</sup>, arm64<sup>3,4</sup>
- **OpenBSD**: amd64<sup>3,4</sup>, arm64<sup>3,4</sup>
- **Windows**: 386<sup>3,6</sup>, arm<sup>3,6,7</sup>

#### Support Notes
Expand Down
2 changes: 1 addition & 1 deletion cgo.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build cgo && (darwin || freebsd || linux || netbsd)
//go:build cgo && (darwin || freebsd || linux || netbsd || openbsd)

package purego

Expand Down
2 changes: 1 addition & 1 deletion dlerror.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023 The Ebitengine Authors

//go:build darwin || freebsd || linux || netbsd
//go:build darwin || freebsd || linux || netbsd || openbsd

package purego

Expand Down
2 changes: 1 addition & 1 deletion dlfcn.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build (darwin || freebsd || linux || netbsd) && !android && !faketime
//go:build (darwin || freebsd || linux || netbsd || openbsd) && !android && !faketime

package purego

Expand Down
18 changes: 18 additions & 0 deletions dlfcn_nocgo_openbsd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors

//go:build !cgo

package purego

// OpenBSD keeps dlopen and friends in libc -- there is no libdl -- and ships
// no unversioned libc.so FILE: /usr/lib holds libc.so.103.0 and nothing else.
// "libc.so" is still the right name to write here: the Go linker emits it as a
// DT_NEEDED and OpenBSD's ld.so resolves an unversioned soname to the highest
// version present. The Go runtime itself does exactly this in
// runtime/sys_openbsd.go, which is the proof that it works.

//go:cgo_import_dynamic purego_dlopen dlopen "libc.so"
//go:cgo_import_dynamic purego_dlsym dlsym "libc.so"
//go:cgo_import_dynamic purego_dlerror dlerror "libc.so"
//go:cgo_import_dynamic purego_dlclose dlclose "libc.so"
18 changes: 18 additions & 0 deletions dlfcn_openbsd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors

package purego

// Source for constants: https://github.com/openbsd/src/blob/master/include/dlfcn.h
//
// Read from /usr/include/dlfcn.h on OpenBSD 7.9/arm64 rather than copied from
// another BSD: they happen to agree with NetBSD's, and checking is cheaper
// than finding out they had stopped agreeing.
const (
intSize = 32 << (^uint(0) >> 63) // 32 or 64
RTLD_DEFAULT = 1<<intSize - 2 // Pseudo-handle for dlsym so search for any loaded symbol
RTLD_LAZY = 0x00000001 // Relocations are performed at an implementation-dependent time.
RTLD_NOW = 0x00000002 // Relocations are performed when the object is loaded.
RTLD_LOCAL = 0x00000000 // All symbols are not made available for relocation processing by other modules.
RTLD_GLOBAL = 0x00000100 // All symbols are available for relocation processing of other modules.
)
2 changes: 1 addition & 1 deletion dlfcn_stubs.s
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build darwin || !cgo && (freebsd || linux || netbsd) && !faketime
//go:build darwin || !cgo && (freebsd || linux || netbsd || openbsd) && !faketime

#include "textflag.h"

Expand Down
2 changes: 1 addition & 1 deletion dlfcn_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023 The Ebitengine Authors

//go:build darwin || freebsd || linux || netbsd
//go:build darwin || freebsd || linux || netbsd || openbsd

package purego_test

Expand Down
2 changes: 1 addition & 1 deletion examples/libc/main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build darwin || freebsd || linux || netbsd || windows
//go:build darwin || freebsd || linux || netbsd || openbsd || windows

package main

Expand Down
2 changes: 1 addition & 1 deletion examples/libc/main_unix.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023 The Ebitengine Authors

//go:build darwin || freebsd || linux || netbsd
//go:build darwin || freebsd || linux || netbsd || openbsd

package main

Expand Down
2 changes: 1 addition & 1 deletion export_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors

//go:build darwin || freebsd || linux || netbsd || windows
//go:build darwin || freebsd || linux || netbsd || openbsd || windows

package purego

Expand Down
2 changes: 1 addition & 1 deletion func.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build darwin || freebsd || linux || netbsd || windows
//go:build darwin || freebsd || linux || netbsd || openbsd || windows

package purego

Expand Down
5 changes: 4 additions & 1 deletion func_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ func getSystemLibrary() (string, error) {
return "libc.so.7", nil
case "linux":
return "libc.so.6", nil
case "netbsd":
case "netbsd", "openbsd":
// Neither ships an unversioned libc.so FILE, but ld.so resolves the
// soname: on OpenBSD 7.9 this opens libc.so.103.0 and returns the
// same handle as naming the versioned file directly.
return "libc.so", nil
case "windows":
return "ucrtbase.dll", nil
Expand Down
2 changes: 1 addition & 1 deletion go_runtime.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build darwin || freebsd || linux || netbsd || windows
//go:build darwin || freebsd || linux || netbsd || openbsd || windows

package purego

Expand Down
4 changes: 2 additions & 2 deletions internal/cgo/dlfcn_cgo_unix.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2024 The Ebitengine Authors

//go:build freebsd || linux || netbsd
//go:build freebsd || linux || netbsd || openbsd

package cgo

/*
#cgo !netbsd LDFLAGS: -ldl
#cgo !netbsd,!openbsd LDFLAGS: -ldl

#include <dlfcn.h>
#include <stdlib.h>
Expand Down
4 changes: 2 additions & 2 deletions internal/cgo/syscall_cgo_unix.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build freebsd || (linux && !(386 || amd64 || arm || arm64 || loong64 || ppc64le || riscv64)) || netbsd
//go:build freebsd || (linux && !(386 || amd64 || arm || arm64 || loong64 || ppc64le || riscv64)) || netbsd || openbsd

package cgo

// this file is placed inside internal/cgo and not package purego
// because Cgo and assembly files can't be in the same package.

/*
#cgo !netbsd LDFLAGS: -ldl
#cgo !netbsd,!openbsd LDFLAGS: -ldl

#include <stdint.h>
#include <dlfcn.h>
Expand Down
2 changes: 1 addition & 1 deletion internal/fakecgo/callbacks.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build !cgo && (darwin || freebsd || linux || netbsd)
//go:build !cgo && (darwin || freebsd || linux || netbsd || openbsd)

package fakecgo

Expand Down
2 changes: 1 addition & 1 deletion internal/fakecgo/doc.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build !cgo && (darwin || freebsd || linux || netbsd)
//go:build !cgo && (darwin || freebsd || linux || netbsd || openbsd)

// Package fakecgo implements the Cgo runtime (runtime/cgo) entirely in Go.
// This allows code that calls into C to function properly when CGO_ENABLED=0.
Expand Down
2 changes: 1 addition & 1 deletion internal/fakecgo/fakecgo.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors

//go:build !cgo && (darwin || freebsd || linux || netbsd)
//go:build !cgo && (darwin || freebsd || linux || netbsd || openbsd)

package fakecgo

Expand Down
11 changes: 7 additions & 4 deletions internal/fakecgo/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ var (
{"sigfillset", [5]Arg{{"set", "*sigset_t"}}, "int32", nil},
{"nanosleep", [5]Arg{{"ts", "*syscall.Timespec"}, {"rem", "*syscall.Timespec"}}, "int32", nil},
{"abort", [5]Arg{}, "", nil},
{"sigaltstack", [5]Arg{{"ss", "*stack_t"}, {"old_ss", "*stack_t"}}, "int32", []string{"netbsd"}},
{"sigaltstack", [5]Arg{{"ss", "*stack_t"}, {"old_ss", "*stack_t"}}, "int32", []string{"netbsd", "openbsd"}},
{"__errno_location", [5]Arg{}, "uintptr", []string{"linux"}},
{"setegid", [5]Arg{{"egid", "uint32"}}, "int32", []string{"linux"}},
{"seteuid", [5]Arg{{"euid", "uint32"}}, "int32", []string{"linux"}},
Expand All @@ -139,9 +139,9 @@ var (
{"pthread_sigmask", [5]Arg{{"how", "sighow"}, {"ign", "*sigset_t"}, {"oset", "*sigset_t"}}, "int32", nil},
{"pthread_self", [5]Arg{}, "pthread_t", []string{"darwin"}},
{"pthread_get_stacksize_np", [5]Arg{{"thread", "pthread_t"}}, "size_t", []string{"darwin"}},
{"pthread_attr_getstacksize", [5]Arg{{"attr", "*pthread_attr_t"}, {"stacksize", "*size_t"}}, "int32", []string{"linux", "freebsd", "netbsd"}},
{"pthread_attr_getstacksize", [5]Arg{{"attr", "*pthread_attr_t"}, {"stacksize", "*size_t"}}, "int32", []string{"linux", "freebsd", "netbsd", "openbsd"}},
{"pthread_attr_setstacksize", [5]Arg{{"attr", "*pthread_attr_t"}, {"size", "size_t"}}, "int32", []string{"darwin"}},
{"pthread_attr_destroy", [5]Arg{{"attr", "*pthread_attr_t"}}, "int32", []string{"linux", "freebsd", "netbsd"}},
{"pthread_attr_destroy", [5]Arg{{"attr", "*pthread_attr_t"}}, "int32", []string{"linux", "freebsd", "netbsd", "openbsd"}},
{"pthread_mutex_lock", [5]Arg{{"mutex", "*pthread_mutex_t"}}, "int32", nil},
{"pthread_mutex_unlock", [5]Arg{{"mutex", "*pthread_mutex_t"}}, "int32", nil},
{"pthread_cond_broadcast", [5]Arg{{"cond", "*pthread_cond_t"}}, "int32", nil},
Expand All @@ -154,7 +154,7 @@ var funcs = map[string]any{
"imports": imports,
}

var GOOSes = []string{"darwin", "freebsd", "linux", "netbsd"}
var GOOSes = []string{"darwin", "freebsd", "linux", "netbsd", "openbsd"}

func imports(symbols []Symbol) string {
if len(symbols) == 0 {
Expand Down Expand Up @@ -275,6 +275,9 @@ func run() error {
case "netbsd":
libcSO = "libc.so"
pthreadSO = "libpthread.so"
case "openbsd":
libcSO = "libc.so"
pthreadSO = "libpthread.so"
default:
return fmt.Errorf("unsupported OS: %s", goos)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/fakecgo/go_libinit.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build !cgo && (darwin || freebsd || linux || netbsd)
//go:build !cgo && (darwin || freebsd || linux || netbsd || openbsd)

package fakecgo

Expand Down
83 changes: 83 additions & 0 deletions internal/fakecgo/go_openbsd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build !cgo && (amd64 || arm64)

package fakecgo

import "unsafe"

//go:nosplit
func _cgo_sys_thread_start(ts *ThreadStart) {
var attr pthread_attr_t
var ign, oset sigset_t
var p pthread_t
var size size_t
var err int

// fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug
sigfillset(&ign)
pthread_sigmask(SIG_SETMASK, &ign, &oset)

pthread_attr_init(&attr)
pthread_attr_getstacksize(&attr, &size)
// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
ts.g.stackhi = uintptr(size)

err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts)

pthread_sigmask(SIG_SETMASK, &oset, nil)

if err != 0 {
print("fakecgo: pthread_create failed: ")
println(err)
abort()
}
}

// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function
//
//go:linkname x_threadentry_trampoline threadentry_trampoline
var x_threadentry_trampoline byte
var threadentry_trampolineABI0 = &x_threadentry_trampoline

//go:nosplit
func threadentry(v unsafe.Pointer) unsafe.Pointer {
var ss stack_t
ts := *(*ThreadStart)(v)
free(v)

// On OpenBSD, a new thread inherits the signal stack of the
// creating thread. That confuses minit, so we remove that
// signal stack here before calling the regular mstart. It's
// a bit baroque to remove a signal stack here only to add one
// in minit, but it's a simple change that keeps OpenBSD
// working like other OS's. At this point all signals are
// blocked, so there is no race.
ss.ss_flags = SS_DISABLE
sigaltstack(&ss, nil)

setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g)))

callThreadEntryFn(ts.fn)

return nil
}

// here we will store a pointer to the provided setg func
var setg_func uintptr

//go:nosplit
func x_cgo_init(g *G, setg uintptr) {
var size size_t
var attr pthread_attr_t

setg_func = setg
pthread_attr_init(&attr)
pthread_attr_getstacksize(&attr, &size)
// runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))`
// but this should be OK since we are taking the address of the first variable in this function.
g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096
pthread_attr_destroy(&attr)
}
2 changes: 1 addition & 1 deletion internal/fakecgo/go_setenv.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build !cgo && (darwin || freebsd || linux || netbsd)
//go:build !cgo && (darwin || freebsd || linux || netbsd || openbsd)

package fakecgo

Expand Down
2 changes: 1 addition & 1 deletion internal/fakecgo/go_util.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build !cgo && (darwin || freebsd || linux || netbsd)
//go:build !cgo && (darwin || freebsd || linux || netbsd || openbsd)

package fakecgo

Expand Down
2 changes: 1 addition & 1 deletion internal/fakecgo/iscgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build !cgo && (darwin || freebsd || linux || netbsd)
//go:build !cgo && (darwin || freebsd || linux || netbsd || openbsd)

// The runtime package contains an uninitialized definition
// for runtime·iscgo. Override it to tell the runtime we're here.
Expand Down
2 changes: 1 addition & 1 deletion internal/fakecgo/libcgo.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build !cgo && (darwin || freebsd || linux || netbsd)
//go:build !cgo && (darwin || freebsd || linux || netbsd || openbsd)

package fakecgo

Expand Down
Loading