From da384766a053d851d912f04afaa1113b627a0822 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Mon, 13 Feb 2023 15:55:21 -0500 Subject: [PATCH] runtime: make unsafe.Slice usable from nowritebarrierrec Many compiler-generated panics are dynamically changed to a "throw" when they happen in the runtime. One effect of this is that they are allowed in nowritebarrierrec contexts. Currently, the unsafe.Slice panics don't have this treatment. We're about to expose more code that uses unsafe.Slice to the write barrier checker (it's actually already there and it just can't see through an indirect call), so give these panics the dynamic check. Very indirectly updates #54466. Change-Id: I65cb96fa17eb751041e4fa25a1c1bd03246c82ba Reviewed-on: https://go-review.googlesource.com/c/go/+/468296 TryBot-Result: Gopher Robot Run-TryBot: Austin Clements Reviewed-by: Michael Pratt --- src/runtime/unsafe.go | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/runtime/unsafe.go b/src/runtime/unsafe.go index 54649e8ff5..d2773bc56d 100644 --- a/src/runtime/unsafe.go +++ b/src/runtime/unsafe.go @@ -52,21 +52,21 @@ func panicunsafestringnilptr() { // Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice func unsafeslice(et *_type, ptr unsafe.Pointer, len int) { if len < 0 { - panicunsafeslicelen() + panicunsafeslicelen1(getcallerpc()) } if et.size == 0 { if ptr == nil && len > 0 { - panicunsafeslicenilptr() + panicunsafeslicenilptr1(getcallerpc()) } } mem, overflow := math.MulUintptr(et.size, uintptr(len)) if overflow || mem > -uintptr(ptr) { if ptr == nil { - panicunsafeslicenilptr() + panicunsafeslicenilptr1(getcallerpc()) } - panicunsafeslicelen() + panicunsafeslicelen1(getcallerpc()) } } @@ -74,7 +74,7 @@ func unsafeslice(et *_type, ptr unsafe.Pointer, len int) { func unsafeslice64(et *_type, ptr unsafe.Pointer, len64 int64) { len := int(len64) if int64(len) != len64 { - panicunsafeslicelen() + panicunsafeslicelen1(getcallerpc()) } unsafeslice(et, ptr, len) } @@ -90,9 +90,25 @@ func unsafeslicecheckptr(et *_type, ptr unsafe.Pointer, len64 int64) { } func panicunsafeslicelen() { + // This is called only from compiler-generated code, so we can get the + // source of the panic. + panicunsafeslicelen1(getcallerpc()) +} + +//go:yeswritebarrierrec +func panicunsafeslicelen1(pc uintptr) { + panicCheck1(pc, "unsafe.Slice: len out of range") panic(errorString("unsafe.Slice: len out of range")) } func panicunsafeslicenilptr() { + // This is called only from compiler-generated code, so we can get the + // source of the panic. + panicunsafeslicenilptr1(getcallerpc()) +} + +//go:yeswritebarrierrec +func panicunsafeslicenilptr1(pc uintptr) { + panicCheck1(pc, "unsafe.Slice: ptr is nil and len is not zero") panic(errorString("unsafe.Slice: ptr is nil and len is not zero")) } -- 2.48.1