mirror of
https://github.com/golang/go
synced 2024-11-13 17:30:24 -07:00
runtime: check only up to ptrdata bytes for pointers
Fixes #14508. Change-Id: I237d0c5a79a73e6c97bdb2077d8ede613128b978 Reviewed-on: https://go-review.googlesource.com/23224 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
parent
ebbe4f8db7
commit
538537a28d
@ -290,6 +290,30 @@ var ptrTests = []ptrTest{
|
|||||||
},
|
},
|
||||||
fail: true,
|
fail: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// Don't check non-pointer data.
|
||||||
|
// Uses unsafe code to get a pointer we shouldn't check.
|
||||||
|
// Although we use unsafe, the uintptr represents an integer
|
||||||
|
// that happens to have the same representation as a pointer;
|
||||||
|
// that is, we are testing something that is not unsafe.
|
||||||
|
name: "ptrdata1",
|
||||||
|
c: `#include <stdlib.h>
|
||||||
|
void f(void* p) {}`,
|
||||||
|
imports: []string{"unsafe"},
|
||||||
|
support: `type S struct { p *int; a [8*8]byte; u uintptr }`,
|
||||||
|
body: `i := 0; p := &S{u:uintptr(unsafe.Pointer(&i))}; q := (*S)(C.malloc(C.size_t(unsafe.Sizeof(*p)))); *q = *p; C.f(unsafe.Pointer(q))`,
|
||||||
|
fail: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Like ptrdata1, but with a type that uses a GC program.
|
||||||
|
name: "ptrdata2",
|
||||||
|
c: `#include <stdlib.h>
|
||||||
|
void f(void* p) {}`,
|
||||||
|
imports: []string{"unsafe"},
|
||||||
|
support: `type S struct { p *int; a [32769*8]byte; q *int; u uintptr }`,
|
||||||
|
body: `i := 0; p := S{u:uintptr(unsafe.Pointer(&i))}; q := (*S)(C.malloc(C.size_t(unsafe.Sizeof(p)))); *q = p; C.f(unsafe.Pointer(q))`,
|
||||||
|
fail: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -94,6 +94,14 @@ func cgoCheckSliceCopy(typ *_type, dst, src slice, n int) {
|
|||||||
//go:nosplit
|
//go:nosplit
|
||||||
//go:nowritebarrier
|
//go:nowritebarrier
|
||||||
func cgoCheckTypedBlock(typ *_type, src unsafe.Pointer, off, size uintptr) {
|
func cgoCheckTypedBlock(typ *_type, src unsafe.Pointer, off, size uintptr) {
|
||||||
|
// Anything past typ.ptrdata is not a pointer.
|
||||||
|
if typ.ptrdata <= off {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ptrdataSize := typ.ptrdata - off; size > ptrdataSize {
|
||||||
|
size = ptrdataSize
|
||||||
|
}
|
||||||
|
|
||||||
if typ.kind&kindGCProg == 0 {
|
if typ.kind&kindGCProg == 0 {
|
||||||
cgoCheckBits(src, typ.gcdata, off, size)
|
cgoCheckBits(src, typ.gcdata, off, size)
|
||||||
return
|
return
|
||||||
@ -184,7 +192,7 @@ func cgoCheckBits(src unsafe.Pointer, gcbits *byte, off, size uintptr) {
|
|||||||
|
|
||||||
// cgoCheckUsingType is like cgoCheckTypedBlock, but is a last ditch
|
// cgoCheckUsingType is like cgoCheckTypedBlock, but is a last ditch
|
||||||
// fall back to look for pointers in src using the type information.
|
// fall back to look for pointers in src using the type information.
|
||||||
// We only this when looking at a value on the stack when the type
|
// We only use this when looking at a value on the stack when the type
|
||||||
// uses a GC program, because otherwise it's more efficient to use the
|
// uses a GC program, because otherwise it's more efficient to use the
|
||||||
// GC bits. This is called on the system stack.
|
// GC bits. This is called on the system stack.
|
||||||
//go:nowritebarrier
|
//go:nowritebarrier
|
||||||
@ -193,6 +201,15 @@ func cgoCheckUsingType(typ *_type, src unsafe.Pointer, off, size uintptr) {
|
|||||||
if typ.kind&kindNoPointers != 0 {
|
if typ.kind&kindNoPointers != 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Anything past typ.ptrdata is not a pointer.
|
||||||
|
if typ.ptrdata <= off {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ptrdataSize := typ.ptrdata - off; size > ptrdataSize {
|
||||||
|
size = ptrdataSize
|
||||||
|
}
|
||||||
|
|
||||||
if typ.kind&kindGCProg == 0 {
|
if typ.kind&kindGCProg == 0 {
|
||||||
cgoCheckBits(src, typ.gcdata, off, size)
|
cgoCheckBits(src, typ.gcdata, off, size)
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user