aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2024-11-06 14:57:56 +0100
committerAyke <[email protected]>2024-11-20 07:53:59 +0100
commit6593cf22fad6fab2a201ed00c2cc20c76e29161a (patch)
tree929fba3e751e9665844c2e7c8b2783a872ccb1dd /src
parent548fba82e691b125bdac71f6c393f67fcf4d769f (diff)
downloadtinygo-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')
-rw-r--r--src/runtime/baremetal.go13
-rw-r--r--src/runtime/os_darwin.go12
-rw-r--r--src/runtime/os_windows.go3
-rw-r--r--src/runtime/runtime.go5
-rw-r--r--src/runtime/runtime_nintendoswitch.go6
-rw-r--r--src/runtime/runtime_tinygowasm.go5
-rw-r--r--src/runtime/runtime_tinygowasm_unknown.go6
-rw-r--r--src/runtime/runtime_tinygowasmp2.go6
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
+}