diff options
author | Ayke van Laethem <[email protected]> | 2024-11-06 14:57:56 +0100 |
---|---|---|
committer | Ayke <[email protected]> | 2024-11-20 07:53:59 +0100 |
commit | 6593cf22fad6fab2a201ed00c2cc20c76e29161a (patch) | |
tree | 929fba3e751e9665844c2e7c8b2783a872ccb1dd /src/runtime | |
parent | 548fba82e691b125bdac71f6c393f67fcf4d769f (diff) | |
download | tinygo-6593cf22fad6fab2a201ed00c2cc20c76e29161a.tar.gz tinygo-6593cf22fad6fab2a201ed00c2cc20c76e29161a.zip |
cgo: support errno value as second return parameter
Making this work on all targets was interesting but there's now a test
in place to make sure this works on all targets that have the CGo test
enabled (which is almost all targets).
Diffstat (limited to 'src/runtime')
-rw-r--r-- | src/runtime/baremetal.go | 13 | ||||
-rw-r--r-- | src/runtime/os_darwin.go | 12 | ||||
-rw-r--r-- | src/runtime/os_windows.go | 3 | ||||
-rw-r--r-- | src/runtime/runtime.go | 5 | ||||
-rw-r--r-- | src/runtime/runtime_nintendoswitch.go | 6 | ||||
-rw-r--r-- | src/runtime/runtime_tinygowasm.go | 5 | ||||
-rw-r--r-- | src/runtime/runtime_tinygowasm_unknown.go | 6 | ||||
-rw-r--r-- | src/runtime/runtime_tinygowasmp2.go | 6 |
8 files changed, 50 insertions, 6 deletions
diff --git a/src/runtime/baremetal.go b/src/runtime/baremetal.go index 173d0db25..aecb18972 100644 --- a/src/runtime/baremetal.go +++ b/src/runtime/baremetal.go @@ -86,3 +86,16 @@ func AdjustTimeOffset(offset int64) { // TODO: do this atomically? timeOffset += offset } + +// Picolibc is not configured to define its own errno value, instead it calls +// __errno_location. +// TODO: a global works well enough for now (same as errno on Linux with +// -scheduler=tasks), but this should ideally be a thread-local variable stored +// in task.Task. +// Especially when we add multicore support for microcontrollers. +var errno int32 + +//export __errno_location +func libc_errno_location() *int32 { + return &errno +} diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go index 8338d0f18..e7f7b368f 100644 --- a/src/runtime/os_darwin.go +++ b/src/runtime/os_darwin.go @@ -151,7 +151,7 @@ func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { r1 = uintptr(result) if result == -1 { // Syscall returns -1 on failure. - err = uintptr(*libc___error()) + err = uintptr(*libc_errno_location()) } return } @@ -161,7 +161,7 @@ func syscall_syscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { r1 = call_syscallX(fn, a1, a2, a3) if int64(r1) == -1 { // Syscall returns -1 on failure. - err = uintptr(*libc___error()) + err = uintptr(*libc_errno_location()) } return } @@ -171,7 +171,7 @@ func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { r1 = call_syscallX(fn, a1, a2, a3) if r1 == 0 { // Syscall returns a pointer on success, or NULL on failure. - err = uintptr(*libc___error()) + err = uintptr(*libc_errno_location()) } return } @@ -182,7 +182,7 @@ func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) r1 = uintptr(result) if result == -1 { // Syscall returns -1 on failure. - err = uintptr(*libc___error()) + err = uintptr(*libc_errno_location()) } return } @@ -192,7 +192,7 @@ func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) r1 = call_syscall6X(fn, a1, a2, a3, a4, a5, a6) if int64(r1) == -1 { // Syscall returns -1 on failure. - err = uintptr(*libc___error()) + err = uintptr(*libc_errno_location()) } return } @@ -216,7 +216,7 @@ func libc_getpagesize() int32 // } // //export __error -func libc___error() *int32 +func libc_errno_location() *int32 //export tinygo_syscall func call_syscall(fn, a1, a2, a3 uintptr) int32 diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go index 3750d5194..a124e7ab1 100644 --- a/src/runtime/os_windows.go +++ b/src/runtime/os_windows.go @@ -113,3 +113,6 @@ func syscall_Getpagesize() int { _GetSystemInfo(unsafe.Pointer(&info)) return int(info.dwpagesize) } + +//export _errno +func libc_errno_location() *int32 diff --git a/src/runtime/runtime.go b/src/runtime/runtime.go index bb937f044..99ca34f2c 100644 --- a/src/runtime/runtime.go +++ b/src/runtime/runtime.go @@ -127,3 +127,8 @@ func write(fd uintptr, p unsafe.Pointer, n int32) int32 { func getAuxv() []uintptr { return nil } + +// Called from cgo to obtain the errno value. +func cgo_errno() uintptr { + return uintptr(*libc_errno_location()) +} diff --git a/src/runtime/runtime_nintendoswitch.go b/src/runtime/runtime_nintendoswitch.go index 7d67a8626..d2567b1cc 100644 --- a/src/runtime/runtime_nintendoswitch.go +++ b/src/runtime/runtime_nintendoswitch.go @@ -313,3 +313,9 @@ func hardwareRand() (n uint64, ok bool) { // TODO: see whether there is a RNG and use it. return 0, false } + +func libc_errno_location() *int32 { + // CGo is unavailable, so this function should be unreachable. + runtimePanic("runtime: no cgo errno") + return nil +} diff --git a/src/runtime/runtime_tinygowasm.go b/src/runtime/runtime_tinygowasm.go index 7bc65e9c4..67367b479 100644 --- a/src/runtime/runtime_tinygowasm.go +++ b/src/runtime/runtime_tinygowasm.go @@ -112,3 +112,8 @@ func hardwareRand() (n uint64, ok bool) { // //export arc4random func libc_arc4random() uint32 + +// int *__errno_location(void); +// +//export __errno_location +func libc_errno_location() *int32 diff --git a/src/runtime/runtime_tinygowasm_unknown.go b/src/runtime/runtime_tinygowasm_unknown.go index e426f36ff..b67d70aea 100644 --- a/src/runtime/runtime_tinygowasm_unknown.go +++ b/src/runtime/runtime_tinygowasm_unknown.go @@ -51,3 +51,9 @@ func procUnpin() { func hardwareRand() (n uint64, ok bool) { return 0, false } + +func libc_errno_location() *int32 { + // CGo is unavailable, so this function should be unreachable. + runtimePanic("runtime: no cgo errno") + return nil +} diff --git a/src/runtime/runtime_tinygowasmp2.go b/src/runtime/runtime_tinygowasmp2.go index 70b5a6d11..5565cb4ee 100644 --- a/src/runtime/runtime_tinygowasmp2.go +++ b/src/runtime/runtime_tinygowasmp2.go @@ -81,3 +81,9 @@ func procUnpin() { func hardwareRand() (n uint64, ok bool) { return random.GetRandomU64(), true } + +func libc_errno_location() *int32 { + // CGo is unavailable, so this function should be unreachable. + runtimePanic("runtime: no cgo errno") + return nil +} |