]> Cypherpunks.ru repositories - gostls13.git/commitdiff
runtime, syscall: add calls to msan functions
authorIan Lance Taylor <iant@golang.org>
Wed, 21 Oct 2015 18:04:42 +0000 (11:04 -0700)
committerIan Lance Taylor <iant@golang.org>
Wed, 21 Oct 2015 19:17:46 +0000 (19:17 +0000)
Add explicit memory sanitizer instrumentation to the runtime and syscall
packages.  The compiler does not instrument the runtime package.  It
does instrument the syscall package, but we need to add a couple of
cases that it can't see.

Change-Id: I2d66073f713fe67e33a6720460d2bb8f72f31394
Reviewed-on: https://go-review.googlesource.com/16164
Reviewed-by: David Crawshaw <crawshaw@golang.org>
15 files changed:
src/runtime/chan.go
src/runtime/hashmap.go
src/runtime/iface.go
src/runtime/malloc.go
src/runtime/mbarrier.go
src/runtime/mgcsweep.go
src/runtime/proc.go
src/runtime/select.go
src/runtime/slice.go
src/runtime/stack.go
src/runtime/string.go
src/syscall/msan.go [new file with mode: 0644]
src/syscall/msan0.go [new file with mode: 0644]
src/syscall/syscall_unix.go
src/syscall/syscall_windows.go

index cfee12a551263a75c53f6458d1c82e70fbec7987..96ac3066245e866dae5791abdc97456984c59309 100644 (file)
@@ -108,6 +108,9 @@ func chansend(t *chantype, c *hchan, ep unsafe.Pointer, block bool, callerpc uin
        if raceenabled {
                raceReadObjectPC(t.elem, ep, callerpc, funcPC(chansend))
        }
+       if msanenabled {
+               msanread(ep, t.elem.size)
+       }
 
        if c == nil {
                if !block {
index 2db73bc845ef00b8be15db33f801aed8949adacc..d59ad297f5732842f1c5d2400b0a4f3e90899051 100644 (file)
@@ -276,6 +276,9 @@ func mapaccess1(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
                racereadpc(unsafe.Pointer(h), callerpc, pc)
                raceReadObjectPC(t.key, key, callerpc, pc)
        }
+       if msanenabled && h != nil {
+               msanread(key, t.key.size)
+       }
        if h == nil || h.count == 0 {
                return atomicloadp(unsafe.Pointer(&zeroptr))
        }
@@ -324,6 +327,9 @@ func mapaccess2(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, bool)
                racereadpc(unsafe.Pointer(h), callerpc, pc)
                raceReadObjectPC(t.key, key, callerpc, pc)
        }
+       if msanenabled && h != nil {
+               msanread(key, t.key.size)
+       }
        if h == nil || h.count == 0 {
                return atomicloadp(unsafe.Pointer(&zeroptr)), false
        }
@@ -419,6 +425,10 @@ func mapassign1(t *maptype, h *hmap, key unsafe.Pointer, val unsafe.Pointer) {
                raceReadObjectPC(t.key, key, callerpc, pc)
                raceReadObjectPC(t.elem, val, callerpc, pc)
        }
+       if msanenabled {
+               msanread(key, t.key.size)
+               msanread(val, t.elem.size)
+       }
 
        alg := t.key.alg
        hash := alg.hash(key, uintptr(h.hash0))
@@ -517,6 +527,9 @@ func mapdelete(t *maptype, h *hmap, key unsafe.Pointer) {
                racewritepc(unsafe.Pointer(h), callerpc, pc)
                raceReadObjectPC(t.key, key, callerpc, pc)
        }
+       if msanenabled && h != nil {
+               msanread(key, t.key.size)
+       }
        if h == nil || h.count == 0 {
                return
        }
index 646f8789ebb172e37a7557b111049e6047bb64ea..f04cec0076accd3129cae48d3880971f52b618c6 100644 (file)
@@ -132,6 +132,9 @@ func convT2E(t *_type, elem unsafe.Pointer, x unsafe.Pointer) (e interface{}) {
        if raceenabled {
                raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2E))
        }
+       if msanenabled {
+               msanread(elem, t.size)
+       }
        ep := (*eface)(unsafe.Pointer(&e))
        if isDirectIface(t) {
                ep._type = t
@@ -153,6 +156,9 @@ func convT2I(t *_type, inter *interfacetype, cache **itab, elem unsafe.Pointer,
        if raceenabled {
                raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2I))
        }
+       if msanenabled {
+               msanread(elem, t.size)
+       }
        tab := (*itab)(atomicloadp(unsafe.Pointer(cache)))
        if tab == nil {
                tab = getitab(inter, t, false)
index 4ce159c267756d513712d070ac73985bb364eb6f..564e2296a2ae3395f9c62878aeec4a8d31025adf 100644 (file)
@@ -707,6 +707,9 @@ func mallocgc(size uintptr, typ *_type, flags uint32) unsafe.Pointer {
        if raceenabled {
                racemalloc(x, size)
        }
+       if msanenabled {
+               msanmalloc(x, size)
+       }
 
        mp.mallocing = 0
        releasem(mp)
index 0dbe1ffc9de7bda2f74566a954450e923e724f8a..6ca2672b8d0b57248ff082c3fdfed8e4699ab42f 100644 (file)
@@ -241,6 +241,10 @@ func typedslicecopy(typ *_type, dst, src slice) int {
                racewriterangepc(dstp, uintptr(n)*typ.size, callerpc, pc)
                racereadrangepc(srcp, uintptr(n)*typ.size, callerpc, pc)
        }
+       if msanenabled {
+               msanwrite(dstp, uintptr(n)*typ.size)
+               msanread(srcp, uintptr(n)*typ.size)
+       }
 
        // Note: No point in checking typ.kind&kindNoPointers here:
        // compiler only emits calls to typedslicecopy for types with pointers,
index 9468af941a88b8ca1d365d2041a2e88ade14a53e..7c7f1e858b1050044edc3469567896e594c6dae2 100644 (file)
@@ -233,6 +233,9 @@ func mSpan_Sweep(s *mspan, preserve bool) bool {
                if debug.allocfreetrace != 0 {
                        tracefree(unsafe.Pointer(p), size)
                }
+               if msanenabled {
+                       msanfree(unsafe.Pointer(p), size)
+               }
 
                // Reset to allocated+noscan.
                if cl == 0 {
index 24776375ca2adbae1240ef0e893a37aaf3f4c7ab..e4ca9407f663e44784339321d5eac9b0d2a63055 100644 (file)
@@ -2695,6 +2695,9 @@ retry:
                        if raceenabled {
                                racemalloc(unsafe.Pointer(gp.stack.lo), gp.stackAlloc)
                        }
+                       if msanenabled {
+                               msanmalloc(unsafe.Pointer(gp.stack.lo), gp.stackAlloc)
+                       }
                }
        }
        return gp
index b18b44ce61c71baa6c19c193fb64858babc1ef28..8b6c3ed4c0f5c5cb18f4c7630e8474a27fc6a1e4 100644 (file)
@@ -459,6 +459,13 @@ loop:
                        raceReadObjectPC(c.elemtype, cas.elem, cas.pc, chansendpc)
                }
        }
+       if msanenabled {
+               if cas.kind == caseRecv && cas.elem != nil {
+                       msanwrite(cas.elem, c.elemtype.size)
+               } else if cas.kind == caseSend {
+                       msanread(cas.elem, c.elemtype.size)
+               }
+       }
 
        selunlock(sel)
        goto retc
@@ -472,6 +479,9 @@ asyncrecv:
                raceacquire(chanbuf(c, c.recvx))
                racerelease(chanbuf(c, c.recvx))
        }
+       if msanenabled && cas.elem != nil {
+               msanwrite(cas.elem, c.elemtype.size)
+       }
        if cas.receivedp != nil {
                *cas.receivedp = true
        }
@@ -504,6 +514,9 @@ asyncsend:
                racerelease(chanbuf(c, c.sendx))
                raceReadObjectPC(c.elemtype, cas.elem, cas.pc, chansendpc)
        }
+       if msanenabled {
+               msanread(cas.elem, c.elemtype.size)
+       }
        typedmemmove(c.elemtype, chanbuf(c, c.sendx), cas.elem)
        c.sendx++
        if c.sendx == c.dataqsiz {
@@ -531,6 +544,9 @@ syncrecv:
                }
                racesync(c, sg)
        }
+       if msanenabled && cas.elem != nil {
+               msanwrite(cas.elem, c.elemtype.size)
+       }
        selunlock(sel)
        if debugSelect {
                print("syncrecv: sel=", sel, " c=", c, "\n")
@@ -570,6 +586,9 @@ syncsend:
                raceReadObjectPC(c.elemtype, cas.elem, cas.pc, chansendpc)
                racesync(c, sg)
        }
+       if msanenabled {
+               msanread(cas.elem, c.elemtype.size)
+       }
        selunlock(sel)
        if debugSelect {
                print("syncsend: sel=", sel, " c=", c, "\n")
index b316cdd7b3f9b8380d2dee7676a824b9911b9d30..a0b0a7c91b21f111b6f3f31fc9c7264081a7626a 100644 (file)
@@ -57,6 +57,9 @@ func growslice(t *slicetype, old slice, cap int) slice {
                callerpc := getcallerpc(unsafe.Pointer(&t))
                racereadrangepc(old.array, uintptr(old.len*int(t.elem.size)), callerpc, funcPC(growslice))
        }
+       if msanenabled {
+               msanread(old.array, uintptr(old.len*int(t.elem.size)))
+       }
 
        et := t.elem
        if et.size == 0 {
@@ -127,6 +130,10 @@ func slicecopy(to, fm slice, width uintptr) int {
                racewriterangepc(to.array, uintptr(n*int(width)), callerpc, pc)
                racereadrangepc(fm.array, uintptr(n*int(width)), callerpc, pc)
        }
+       if msanenabled {
+               msanwrite(to.array, uintptr(n*int(width)))
+               msanread(fm.array, uintptr(n*int(width)))
+       }
 
        size := uintptr(n) * width
        if size == 1 { // common case worth about 2x to do here
@@ -153,6 +160,9 @@ func slicestringcopy(to []byte, fm string) int {
                pc := funcPC(slicestringcopy)
                racewriterangepc(unsafe.Pointer(&to[0]), uintptr(n), callerpc, pc)
        }
+       if msanenabled {
+               msanwrite(unsafe.Pointer(&to[0]), uintptr(n))
+       }
 
        memmove(unsafe.Pointer(&to[0]), unsafe.Pointer(stringStructOf(&fm).str), uintptr(n))
        return n
index 1809a4d9acf6cb81fe2e4f15ca82ad15ba68900c..e5cd09498c9fef37b87c24f89427611a9c77f362 100644 (file)
@@ -364,6 +364,9 @@ func stackalloc(n uint32) (stack, []stkbar) {
        if raceenabled {
                racemalloc(v, uintptr(n))
        }
+       if msanenabled {
+               msanmalloc(v, uintptr(n))
+       }
        if stackDebug >= 1 {
                print("  allocated ", v, "\n")
        }
@@ -393,6 +396,9 @@ func stackfree(stk stack, n uintptr) {
                }
                return
        }
+       if msanenabled {
+               msanfree(v, n)
+       }
        if stackCache != 0 && n < _FixedStack<<_NumStackOrders && n < _StackCacheSize {
                order := uint8(0)
                n2 := n
index 680001d8df10296da52ba587ada9ed3044c19bb2..03230a8b3e5e21d55bf23b7e09ae93ab4c00146a 100644 (file)
@@ -86,6 +86,9 @@ func slicebytetostring(buf *tmpBuf, b []byte) string {
                        getcallerpc(unsafe.Pointer(&b)),
                        funcPC(slicebytetostring))
        }
+       if msanenabled && l > 0 {
+               msanread(unsafe.Pointer(&b[0]), uintptr(l))
+       }
        s, c := rawstringtmp(buf, l)
        copy(c, b)
        return s
@@ -126,6 +129,9 @@ func slicebytetostringtmp(b []byte) string {
                        getcallerpc(unsafe.Pointer(&b)),
                        funcPC(slicebytetostringtmp))
        }
+       if msanenabled && len(b) > 0 {
+               msanread(unsafe.Pointer(&b[0]), uintptr(len(b)))
+       }
        return *(*string)(unsafe.Pointer(&b))
 }
 
@@ -185,6 +191,9 @@ func slicerunetostring(buf *tmpBuf, a []rune) string {
                        getcallerpc(unsafe.Pointer(&a)),
                        funcPC(slicerunetostring))
        }
+       if msanenabled && len(a) > 0 {
+               msanread(unsafe.Pointer(&a[0]), uintptr(len(a))*unsafe.Sizeof(a[0]))
+       }
        var dum [4]byte
        size1 := 0
        for _, r := range a {
diff --git a/src/syscall/msan.go b/src/syscall/msan.go
new file mode 100644 (file)
index 0000000..edd8d1e
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2015 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.
+
+// +build msan
+
+package syscall
+
+import (
+       "runtime"
+       "unsafe"
+)
+
+const msanenabled = true
+
+func msanRead(addr unsafe.Pointer, len int) {
+       runtime.MSanRead(addr, len)
+}
+
+func msanWrite(addr unsafe.Pointer, len int) {
+       runtime.MSanWrite(addr, len)
+}
diff --git a/src/syscall/msan0.go b/src/syscall/msan0.go
new file mode 100644 (file)
index 0000000..7617494
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+// +build !msan
+
+package syscall
+
+import (
+       "unsafe"
+)
+
+const msanenabled = false
+
+func msanRead(addr unsafe.Pointer, len int) {
+}
+
+func msanWrite(addr unsafe.Pointer, len int) {
+}
index b133ea70ab27aad5e2890fbc7db5e57d6df860d6..1db1193ac425818e6903b2d53171ae937b1f9635 100644 (file)
@@ -166,6 +166,9 @@ func Read(fd int, p []byte) (n int, err error) {
                        raceAcquire(unsafe.Pointer(&ioSync))
                }
        }
+       if msanenabled && n > 0 {
+               msanWrite(unsafe.Pointer(&p[0]), n)
+       }
        return
 }
 
@@ -177,6 +180,9 @@ func Write(fd int, p []byte) (n int, err error) {
        if raceenabled && n > 0 {
                raceReadRange(unsafe.Pointer(&p[0]), n)
        }
+       if msanenabled && n > 0 {
+               msanRead(unsafe.Pointer(&p[0]), n)
+       }
        return
 }
 
index 1006a9b72a662f1469021160cf30d3c997a916c4..71fdf29e2d18170b7cfc893a8540c8633a865e02 100644 (file)
@@ -310,6 +310,9 @@ func Read(fd Handle, p []byte) (n int, err error) {
                }
                raceAcquire(unsafe.Pointer(&ioSync))
        }
+       if msanenabled && done > 0 {
+               msanWrite(unsafe.Pointer(&p[0]), int(done))
+       }
        return int(done), nil
 }
 
@@ -325,6 +328,9 @@ func Write(fd Handle, p []byte) (n int, err error) {
        if raceenabled && done > 0 {
                raceReadRange(unsafe.Pointer(&p[0]), int(done))
        }
+       if msanenabled && done > 0 {
+               msanRead(unsafe.Pointer(&p[0]), int(done))
+       }
        return int(done), nil
 }