xref: /aosp_15_r20/external/libcap/psx/psx_cgo.go (revision 2810ac1b38eead2603277920c78344c84ddf3aff)
1*2810ac1bSKiyoung Kim// +build linux,cgo
2*2810ac1bSKiyoung Kim
3*2810ac1bSKiyoung Kimpackage psx // import "kernel.org/pub/linux/libs/security/libcap/psx"
4*2810ac1bSKiyoung Kim
5*2810ac1bSKiyoung Kimimport (
6*2810ac1bSKiyoung Kim	"runtime"
7*2810ac1bSKiyoung Kim	"sync"
8*2810ac1bSKiyoung Kim	"syscall"
9*2810ac1bSKiyoung Kim)
10*2810ac1bSKiyoung Kim
11*2810ac1bSKiyoung Kim// #cgo LDFLAGS: -lpthread -Wl,-wrap,pthread_create
12*2810ac1bSKiyoung Kim//
13*2810ac1bSKiyoung Kim// #include <errno.h>
14*2810ac1bSKiyoung Kim// #include "psx_syscall.h"
15*2810ac1bSKiyoung Kim//
16*2810ac1bSKiyoung Kim// long __errno_too(long set_errno) {
17*2810ac1bSKiyoung Kim//     long v = errno;
18*2810ac1bSKiyoung Kim//     if (set_errno >= 0) {
19*2810ac1bSKiyoung Kim//       errno = set_errno;
20*2810ac1bSKiyoung Kim//     }
21*2810ac1bSKiyoung Kim//     return v;
22*2810ac1bSKiyoung Kim// }
23*2810ac1bSKiyoung Kimimport "C"
24*2810ac1bSKiyoung Kim
25*2810ac1bSKiyoung Kim// setErrno returns the current C.errno value and, if v >= 0, sets the
26*2810ac1bSKiyoung Kim// CGo errno for a random pthread to value v. If you want some
27*2810ac1bSKiyoung Kim// consistency, this needs to be called from runtime.LockOSThread()
28*2810ac1bSKiyoung Kim// code. This function is only defined for testing purposes. The psx.c
29*2810ac1bSKiyoung Kim// code should properly handle the case that a non-zero errno is saved
30*2810ac1bSKiyoung Kim// and restored independently of what these Syscall[36]() functions
31*2810ac1bSKiyoung Kim// observe.
32*2810ac1bSKiyoung Kimfunc setErrno(v int) int {
33*2810ac1bSKiyoung Kim	return int(C.__errno_too(C.long(v)))
34*2810ac1bSKiyoung Kim}
35*2810ac1bSKiyoung Kim
36*2810ac1bSKiyoung Kimvar makeFatal sync.Once
37*2810ac1bSKiyoung Kim
38*2810ac1bSKiyoung Kim// forceFatal configures the psx_syscall mechanism to PSX_ERROR.
39*2810ac1bSKiyoung Kimfunc forceFatal() {
40*2810ac1bSKiyoung Kim	makeFatal.Do(func() {
41*2810ac1bSKiyoung Kim		C.psx_set_sensitivity(C.PSX_ERROR)
42*2810ac1bSKiyoung Kim	})
43*2810ac1bSKiyoung Kim}
44*2810ac1bSKiyoung Kim
45*2810ac1bSKiyoung Kim//go:uintptrescapes
46*2810ac1bSKiyoung Kim
47*2810ac1bSKiyoung Kim// Syscall3 performs a 3 argument syscall. Syscall3 differs from
48*2810ac1bSKiyoung Kim// syscall.[Raw]Syscall() insofar as it is simultaneously executed on
49*2810ac1bSKiyoung Kim// every thread of the combined Go and CGo runtimes. It works
50*2810ac1bSKiyoung Kim// differently depending on whether CGO_ENABLED is 1 or 0 at compile
51*2810ac1bSKiyoung Kim// time.
52*2810ac1bSKiyoung Kim//
53*2810ac1bSKiyoung Kim// If CGO_ENABLED=1 it uses the libpsx function C.psx_syscall3().
54*2810ac1bSKiyoung Kim//
55*2810ac1bSKiyoung Kim// If CGO_ENABLED=0 it redirects to the go1.16+
56*2810ac1bSKiyoung Kim// syscall.AllThreadsSyscall() function.
57*2810ac1bSKiyoung Kimfunc Syscall3(syscallnr, arg1, arg2, arg3 uintptr) (uintptr, uintptr, syscall.Errno) {
58*2810ac1bSKiyoung Kim	forceFatal()
59*2810ac1bSKiyoung Kim	// We lock to the OSThread here because we may need errno to
60*2810ac1bSKiyoung Kim	// be the one for this thread.
61*2810ac1bSKiyoung Kim	runtime.LockOSThread()
62*2810ac1bSKiyoung Kim	defer runtime.UnlockOSThread()
63*2810ac1bSKiyoung Kim
64*2810ac1bSKiyoung Kim	v := C.psx_syscall3(C.long(syscallnr), C.long(arg1), C.long(arg2), C.long(arg3))
65*2810ac1bSKiyoung Kim	var errno syscall.Errno
66*2810ac1bSKiyoung Kim	if v < 0 {
67*2810ac1bSKiyoung Kim		errno = syscall.Errno(C.__errno_too(-1))
68*2810ac1bSKiyoung Kim	}
69*2810ac1bSKiyoung Kim	return uintptr(v), uintptr(v), errno
70*2810ac1bSKiyoung Kim}
71*2810ac1bSKiyoung Kim
72*2810ac1bSKiyoung Kim//go:uintptrescapes
73*2810ac1bSKiyoung Kim
74*2810ac1bSKiyoung Kim// Syscall6 performs a 6 argument syscall on every thread of the
75*2810ac1bSKiyoung Kim// combined Go and CGo runtimes. Other than the number of syscall
76*2810ac1bSKiyoung Kim// arguments, its behavior is identical to that of Syscall3() - see
77*2810ac1bSKiyoung Kim// above for the full documentation.
78*2810ac1bSKiyoung Kimfunc Syscall6(syscallnr, arg1, arg2, arg3, arg4, arg5, arg6 uintptr) (uintptr, uintptr, syscall.Errno) {
79*2810ac1bSKiyoung Kim	forceFatal()
80*2810ac1bSKiyoung Kim	// We lock to the OSThread here because we may need errno to
81*2810ac1bSKiyoung Kim	// be the one for this thread.
82*2810ac1bSKiyoung Kim	runtime.LockOSThread()
83*2810ac1bSKiyoung Kim	defer runtime.UnlockOSThread()
84*2810ac1bSKiyoung Kim
85*2810ac1bSKiyoung Kim	v := C.psx_syscall6(C.long(syscallnr), C.long(arg1), C.long(arg2), C.long(arg3), C.long(arg4), C.long(arg5), C.long(arg6))
86*2810ac1bSKiyoung Kim	var errno syscall.Errno
87*2810ac1bSKiyoung Kim	if v < 0 {
88*2810ac1bSKiyoung Kim		errno = syscall.Errno(C.__errno_too(-1))
89*2810ac1bSKiyoung Kim	}
90*2810ac1bSKiyoung Kim	return uintptr(v), uintptr(v), errno
91*2810ac1bSKiyoung Kim}
92