// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build linux && (amd64 || arm64 || loong64 || ppc64le)
+//go:build linux && (386 || amd64 || arm64 || loong64 || ppc64le)
#include <errno.h>
#include <stddef.h>
// to and from struct sigaction — are specific to ${goos}/${goarch}.
typedef struct {
uintptr_t handler;
- uint64_t flags;
+ unsigned long flags;
#ifdef __loongarch__
uint64_t mask;
uintptr_t restorer;
sigaddset(&act.sa_mask, (int)(i+1));
}
}
- act.sa_flags = (int)(goact->flags & ~(uint64_t)SA_RESTORER);
+ act.sa_flags = (int)(goact->flags & ~(unsigned long)SA_RESTORER);
}
ret = sigaction((int)signum, goact ? &act : NULL, oldgoact ? &oldact : NULL);
oldgoact->mask |= (uint64_t)(1)<<i;
}
}
- oldgoact->flags = (uint64_t)oldact.sa_flags;
+ oldgoact->flags = (unsigned long)oldact.sa_flags;
}
_cgo_tsan_release();
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build (linux && (amd64 || arm64 || loong64 || ppc64le)) || (freebsd && amd64)
+//go:build (linux && (386 || amd64 || arm64 || loong64 || ppc64le)) || (freebsd && amd64)
package cgo
// license that can be found in the LICENSE file.
// Support for sanitizers. See runtime/cgo/sigaction.go.
+// Also used on linux/386 to clear the SA_RESTORER flag
+// when using cgo; see issue #75253.
-//go:build (linux && (amd64 || arm64 || loong64 || ppc64le)) || (freebsd && amd64)
+//go:build (linux && (386 || amd64 || arm64 || loong64 || ppc64le)) || (freebsd && amd64)
package runtime
var ret int32
+ fixSigactionForCgo(new)
+
var g *g
if mainStarted {
g = getg()
switch runtime.GOOS {
case "plan9", "windows":
t.Skipf("no EINTR on %s", runtime.GOOS)
- case "linux":
- if runtime.GOARCH == "386" {
- // On linux-386 the Go signal handler sets
- // a restorer function that is not preserved
- // by the C sigaction call in the test,
- // causing the signal handler to crash when
- // returning the normal code. The test is not
- // architecture-specific, so just skip on 386
- // rather than doing a complicated workaround.
- t.Skip("skipping on linux-386; C sigaction does not preserve Go restorer")
- }
}
if runtime.GOOS == "freebsd" && race.Enabled {
t.Skipf("race + cgo freebsd not supported. See https://go.dev/issue/73788.")
}
}
+// fixSigactionForCgo is needed for Linux.
+//
+//go:nosplit
+func fixSigactionForCgo(new *sigactiont) {
+}
+
// asmSigaction is implemented in assembly.
//
//go:noescape
sigfillset(&sa.sa_mask)
// Although Linux manpage says "sa_restorer element is obsolete and
// should not be used". x86_64 kernel requires it. Only use it on
- // x86.
+ // x86. Note that on 386 this is cleared when using the C sigaction
+ // function via cgo; see fixSigactionForCgo.
if GOARCH == "386" || GOARCH == "amd64" {
sa.sa_restorer = abi.FuncPCABI0(sigreturn__sigaction)
}
//go:noescape
func rt_sigaction(sig uintptr, new, old *sigactiont, size uintptr) int32
+// fixSigactionForCgo is called when we are using cgo to call the
+// C sigaction function. On 386 the C function does not expect the
+// SA_RESTORER flag to be set, and in some cases will fail if it is set:
+// it will pass the SA_RESTORER flag to the kernel without passing
+// the sa_restorer field. Since the C function will handle SA_RESTORER
+// for us, we need not pass it. See issue #75253.
+//
+//go:nosplit
+func fixSigactionForCgo(new *sigactiont) {
+ if GOARCH == "386" && new != nil {
+ new.sa_flags &^= _SA_RESTORER
+ new.sa_restorer = 0
+ }
+}
+
func getpid() int
func tgkill(tgid, tid, sig int)
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build (linux && !amd64 && !arm64 && !loong64 && !ppc64le) || (freebsd && !amd64)
+//go:build (linux && !386 && !amd64 && !arm64 && !loong64 && !ppc64le) || (freebsd && !amd64)
package runtime
MOVL AX, ret+16(FP)
RET
+// Call the function stored in _cgo_sigaction using the GCC calling convention.
+TEXT runtime·callCgoSigaction(SB),NOSPLIT,$0-16
+ MOVL _cgo_sigaction(SB), AX
+ MOVL sig+0(FP), BX
+ MOVL new+4(FP), CX
+ MOVL old+8(FP), DX
+ MOVL SP, SI // align stack to call C function
+ SUBL $32, SP
+ ANDL $~15, SP
+ MOVL BX, 0(SP)
+ MOVL CX, 4(SP)
+ MOVL DX, 8(SP)
+ MOVL SI, 12(SP)
+ CALL AX
+ MOVL 12(SP), BX
+ MOVL BX, SP
+ MOVL AX, ret+12(FP)
+ RET
+
TEXT runtime·sigfwd(SB),NOSPLIT,$12-16
MOVL fn+0(FP), AX
MOVL sig+4(FP), BX