mirror of
https://github.com/golang/go.git
synced 2026-06-28 03:40:37 +00:00
runtime: clear X15 before calling cgocallbackg
CL 765581 uses ABIInternal to call from cgocallback to cgocallbackg. That CL restores the g to R14, but fails to zero X15 as required by ABIInternal. As a result, the undefined value of X15 from C leaks into Go code, causing all sorts of interesting crashes due to the broken invariant. For #78934. Change-Id: I70d131be66e971f7c238d18a84cc44b66a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/770560 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org> Auto-Submit: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
9b3f3ad17a
commit
52fd498a96
5 changed files with 82 additions and 1 deletions
|
|
@ -1105,7 +1105,8 @@ havem:
|
|||
// will seamlessly trace back into the earlier calls.
|
||||
MOVQ m_curg(BX), SI
|
||||
MOVQ SI, g(CX)
|
||||
MOVQ SI, R14 // set the g register
|
||||
MOVQ SI, R14 // set the g register, as required by ABIInternal.
|
||||
XORPS X15, X15 // clear X15, as required by ABIInternal.
|
||||
MOVQ (g_sched+gobuf_sp)(SI), DI // prepare stack as DI
|
||||
MOVQ (g_sched+gobuf_pc)(SI), BX
|
||||
MOVQ BX, -8(DI) // "push" return PC on the g stack
|
||||
|
|
|
|||
|
|
@ -103,6 +103,18 @@ func TestCgoCallbackPprof(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCgoCallbackX15(t *testing.T) {
|
||||
t.Parallel()
|
||||
if runtime.GOARCH != "amd64" {
|
||||
t.Skipf("X15 test only relevant on amd64")
|
||||
}
|
||||
|
||||
got := runTestProg(t, "testprogcgo", "CgoCallbackX15")
|
||||
if want := "OK\n"; got != want {
|
||||
t.Fatalf("expected %q, but got:\n%s", want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCgoExternalThreadPanic(t *testing.T) {
|
||||
t.Parallel()
|
||||
if runtime.GOOS == "plan9" {
|
||||
|
|
|
|||
50
src/runtime/testdata/testprogcgo/callback_amd64.go
vendored
Normal file
50
src/runtime/testdata/testprogcgo/callback_amd64.go
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
// Copyright 2026 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.
|
||||
|
||||
package main
|
||||
|
||||
// Regression test to verify that cgocallback restores X15 = 0 as required by
|
||||
// ABIInternal.
|
||||
|
||||
/*
|
||||
#include <stdint.h>
|
||||
|
||||
void go_callback_amd64();
|
||||
|
||||
static void call_go_callback_amd64() {
|
||||
// Clobber X15.
|
||||
uint64_t val = 42;
|
||||
asm volatile(
|
||||
"vmovdqu %0, %%xmm15;"
|
||||
:
|
||||
: "m" (val)
|
||||
: "xmm15");
|
||||
|
||||
go_callback_amd64();
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"runtime/testdata/testprogcgo/goasm"
|
||||
)
|
||||
|
||||
func init() {
|
||||
register("CgoCallbackX15", CgoCallbackX15)
|
||||
}
|
||||
|
||||
//export go_callback_amd64
|
||||
func go_callback_amd64() {
|
||||
v := goasm.ReadX15()
|
||||
if v != 0 {
|
||||
println("X15 =", v)
|
||||
panic("non-zero X15")
|
||||
}
|
||||
}
|
||||
|
||||
func CgoCallbackX15() {
|
||||
C.call_go_callback_amd64()
|
||||
|
||||
println("OK")
|
||||
}
|
||||
10
src/runtime/testdata/testprogcgo/goasm/x15_amd64.go
vendored
Normal file
10
src/runtime/testdata/testprogcgo/goasm/x15_amd64.go
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright 2026 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.
|
||||
|
||||
// Package goasm contains Go assembly functions used by testprogcgo because
|
||||
// packages using cgo can't also contain Go assembly.
|
||||
package goasm
|
||||
|
||||
// ReadX15 returns the lower 64-bits of X15.
|
||||
func ReadX15() uint64
|
||||
8
src/runtime/testdata/testprogcgo/goasm/x15_amd64.s
vendored
Normal file
8
src/runtime/testdata/testprogcgo/goasm/x15_amd64.s
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
// Copyright 2026 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.
|
||||
|
||||
// func ReadX15() uint64
|
||||
TEXT ·ReadX15(SB), $0-8
|
||||
MOVQ X15, ret+0(FP)
|
||||
RET
|
||||
Loading…
Add table
Add a link
Reference in a new issue