From b3c05f08a97ac89064d3edbf4efb7bea671c2c18 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 29 Jan 2016 15:43:24 -0800 Subject: [PATCH] runtime: avoid write barrier in cgo mmap code Tested by hand with a runtime/cgo modified to return an mmap failure after 10 calls. This is an interim patch. For 1.7 we should fix mmap properly to avoid using the same value as both a pointer and an errno value. Fixes #14149. Change-Id: I8f2bbd47d711e283001ba73296f1c34a26c59241 Reviewed-on: https://go-review.googlesource.com/19084 TryBot-Result: Gobot Gobot Reviewed-by: Russ Cox --- src/runtime/cgo_mmap.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/runtime/cgo_mmap.go b/src/runtime/cgo_mmap.go index ef5501ca5f7..c0396bdde51 100644 --- a/src/runtime/cgo_mmap.go +++ b/src/runtime/cgo_mmap.go @@ -15,12 +15,19 @@ import "unsafe" //go:linkname _cgo_mmap _cgo_mmap var _cgo_mmap unsafe.Pointer -func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (ret unsafe.Pointer) { +func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer { if _cgo_mmap != nil { + // Make ret a uintptr so that writing to it in the + // function literal does not trigger a write barrier. + // A write barrier here could break because of the way + // that mmap uses the same value both as a pointer and + // an errno value. + // TODO: Fix mmap to return two values. + var ret uintptr systemstack(func() { ret = callCgoMmap(addr, n, prot, flags, fd, off) }) - return + return unsafe.Pointer(ret) } return sysMmap(addr, n, prot, flags, fd, off) } @@ -31,4 +38,4 @@ func sysMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) // cgoMmap calls the mmap function in the runtime/cgo package on the // callCgoMmap calls the mmap function in the runtime/cgo package // using the GCC calling convention. It is implemented in assembly. -func callCgoMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer +func callCgoMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) uintptr