aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorFangming.Fang <fangming.fang@arm.com>2018-04-08 07:32:43 +0000
committerIan Lance Taylor <iant@golang.org>2018-05-02 17:52:14 +0000
commite8d417d272290027e10e348f81cbc6bb5fe0ec13 (patch)
tree394e28ae3d04021ddffc8c6c22d16abd71c1479f /src/runtime
parenteff1e68528fc9052a7ff1ac7afe222696f85db8c (diff)
downloadgo-e8d417d272290027e10e348f81cbc6bb5fe0ec13.tar.xz
runtime: enable memory sanitizer on arm64
Changes include: 1. open compilation option -msan for arm64 2. modify doc to explain -msan is also supported on linux/arm64 3. wrap msan lib API in msan_arm64.s 4. use libc for sigaction syscalls when cgo is enabled 5. use libc for mmap syscalls when cgo is enabled Change-Id: I26ebe61ff7ce1906125f54a0182a720f9d58ec11 Reviewed-on: https://go-review.googlesource.com/109255 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/cgo/gcc_linux_arm64.c32
-rw-r--r--src/runtime/cgo/gcc_mmap.c2
-rw-r--r--src/runtime/cgo/gcc_sigaction.c2
-rw-r--r--src/runtime/cgo/mmap.go2
-rw-r--r--src/runtime/cgo/sigaction.go2
-rw-r--r--src/runtime/cgo_mmap.go2
-rw-r--r--src/runtime/cgo_sigaction.go2
-rw-r--r--src/runtime/mmap.go1
-rw-r--r--src/runtime/msan/msan.go3
-rw-r--r--src/runtime/msan_arm64.s62
-rw-r--r--src/runtime/rt0_linux_arm64.s7
-rw-r--r--src/runtime/sigaction.go2
-rw-r--r--src/runtime/sys_linux_arm64.s37
13 files changed, 140 insertions, 16 deletions
diff --git a/src/runtime/cgo/gcc_linux_arm64.c b/src/runtime/cgo/gcc_linux_arm64.c
index b328407f39..8630f2f03e 100644
--- a/src/runtime/cgo/gcc_linux_arm64.c
+++ b/src/runtime/cgo/gcc_linux_arm64.c
@@ -3,8 +3,10 @@
// license that can be found in the LICENSE file.
#include <pthread.h>
+#include <errno.h>
#include <string.h>
#include <signal.h>
+#include <stdlib.h>
#include "libcgo.h"
#include "libcgo_unix.h"
@@ -59,14 +61,34 @@ threadentry(void *v)
void
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
{
- pthread_attr_t attr;
+ pthread_attr_t *attr;
size_t size;
+ /* The memory sanitizer distributed with versions of clang
+ before 3.8 has a bug: if you call mmap before malloc, mmap
+ may return an address that is later overwritten by the msan
+ library. Avoid this problem by forcing a call to malloc
+ here, before we ever call malloc.
+
+ This is only required for the memory sanitizer, so it's
+ unfortunate that we always run it. It should be possible
+ to remove this when we no longer care about versions of
+ clang before 3.8. The test for this is
+ misc/cgo/testsanitizers.
+
+ GCC works hard to eliminate a seemingly unnecessary call to
+ malloc, so we actually use the memory we allocate. */
+
setg_gcc = setg;
- pthread_attr_init(&attr);
- pthread_attr_getstacksize(&attr, &size);
- g->stacklo = (uintptr)&attr - size + 4096;
- pthread_attr_destroy(&attr);
+ attr = (pthread_attr_t*)malloc(sizeof *attr);
+ if (attr == NULL) {
+ fatalf("malloc failed: %s", strerror(errno));
+ }
+ pthread_attr_init(attr);
+ pthread_attr_getstacksize(attr, &size);
+ g->stacklo = (uintptr)&size - size + 4096;
+ pthread_attr_destroy(attr);
+ free(attr);
if (x_cgo_inittls) {
x_cgo_inittls(tlsg, tlsbase);
diff --git a/src/runtime/cgo/gcc_mmap.c b/src/runtime/cgo/gcc_mmap.c
index 5cf6bdf8cf..e6a621d5a3 100644
--- a/src/runtime/cgo/gcc_mmap.c
+++ b/src/runtime/cgo/gcc_mmap.c
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build linux,amd64
+// +build linux,amd64 linux,arm64
#include <errno.h>
#include <stdint.h>
diff --git a/src/runtime/cgo/gcc_sigaction.c b/src/runtime/cgo/gcc_sigaction.c
index 72fb08d720..05dee2affe 100644
--- a/src/runtime/cgo/gcc_sigaction.c
+++ b/src/runtime/cgo/gcc_sigaction.c
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build linux,amd64
+// +build linux,amd64 linux,arm64
#include <errno.h>
#include <stddef.h>
diff --git a/src/runtime/cgo/mmap.go b/src/runtime/cgo/mmap.go
index ad5f6df70a..00fb7fced6 100644
--- a/src/runtime/cgo/mmap.go
+++ b/src/runtime/cgo/mmap.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build linux,amd64
+// +build linux,amd64 linux,arm64
package cgo
diff --git a/src/runtime/cgo/sigaction.go b/src/runtime/cgo/sigaction.go
index e25f4ff2f3..076fbc1a0a 100644
--- a/src/runtime/cgo/sigaction.go
+++ b/src/runtime/cgo/sigaction.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build linux,amd64 freebsd,amd64
+// +build linux,amd64 freebsd,amd64 linux,arm64
package cgo
diff --git a/src/runtime/cgo_mmap.go b/src/runtime/cgo_mmap.go
index b7c70c6fff..048621f306 100644
--- a/src/runtime/cgo_mmap.go
+++ b/src/runtime/cgo_mmap.go
@@ -4,7 +4,7 @@
// Support for memory sanitizer. See runtime/cgo/mmap.go.
-// +build linux,amd64
+// +build linux,amd64 linux,arm64
package runtime
diff --git a/src/runtime/cgo_sigaction.go b/src/runtime/cgo_sigaction.go
index 9832d35f03..3ef6800cd9 100644
--- a/src/runtime/cgo_sigaction.go
+++ b/src/runtime/cgo_sigaction.go
@@ -4,7 +4,7 @@
// Support for memory sanitizer. See runtime/cgo/sigaction.go.
-// +build linux,amd64 freebsd,amd64
+// +build linux,amd64 freebsd,amd64 linux,arm64
package runtime
diff --git a/src/runtime/mmap.go b/src/runtime/mmap.go
index e1333c62fe..152cbcdae5 100644
--- a/src/runtime/mmap.go
+++ b/src/runtime/mmap.go
@@ -7,6 +7,7 @@
// +build !windows
// +build !nacl
// +build !linux !amd64
+// +build !linux !arm64
package runtime
diff --git a/src/runtime/msan/msan.go b/src/runtime/msan/msan.go
index b6ea3f0d16..c81577ddda 100644
--- a/src/runtime/msan/msan.go
+++ b/src/runtime/msan/msan.go
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build msan,linux,amd64
+// +build msan,linux
+// +build amd64 arm64
package msan
diff --git a/src/runtime/msan_arm64.s b/src/runtime/msan_arm64.s
new file mode 100644
index 0000000000..4dfe5e3133
--- /dev/null
+++ b/src/runtime/msan_arm64.s
@@ -0,0 +1,62 @@
+// Copyright 2018 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
+
+#include "go_asm.h"
+#include "textflag.h"
+
+#define RARG0 R0
+#define RARG1 R1
+#define FARG R3
+
+// func runtime·domsanread(addr unsafe.Pointer, sz uintptr)
+// Called from msanread.
+TEXT runtime·domsanread(SB), NOSPLIT, $0-16
+ MOVD addr+0(FP), RARG0
+ MOVD size+8(FP), RARG1
+ // void __msan_read_go(void *addr, uintptr_t sz);
+ MOVD $__msan_read_go(SB), FARG
+ JMP msancall<>(SB)
+
+// func runtime·msanwrite(addr unsafe.Pointer, sz uintptr)
+// Called from instrumented code.
+TEXT runtime·msanwrite(SB), NOSPLIT, $0-16
+ MOVD addr+0(FP), RARG0
+ MOVD size+8(FP), RARG1
+ // void __msan_write_go(void *addr, uintptr_t sz);
+ MOVD $__msan_write_go(SB), FARG
+ JMP msancall<>(SB)
+
+// func runtime·msanmalloc(addr unsafe.Pointer, sz uintptr)
+TEXT runtime·msanmalloc(SB), NOSPLIT, $0-16
+ MOVD addr+0(FP), RARG0
+ MOVD size+8(FP), RARG1
+ // void __msan_malloc_go(void *addr, uintptr_t sz);
+ MOVD $__msan_malloc_go(SB), FARG
+ JMP msancall<>(SB)
+
+// func runtime·msanfree(addr unsafe.Pointer, sz uintptr)
+TEXT runtime·msanfree(SB), NOSPLIT, $0-16
+ MOVD addr+0(FP), RARG0
+ MOVD size+8(FP), RARG1
+ // void __msan_free_go(void *addr, uintptr_t sz);
+ MOVD $__msan_free_go(SB), FARG
+ JMP msancall<>(SB)
+
+// Switches SP to g0 stack and calls (FARG). Arguments already set.
+TEXT msancall<>(SB), NOSPLIT, $0-0
+ MOVD g_m(g), R10
+ MOVD m_g0(R10), R11
+ MOVD RSP, R19 // callee-saved
+ CMP R11, g
+ BEQ g0stack
+
+ MOVD (g_sched+gobuf_sp)(R11), R4
+ MOVD R4, RSP
+
+g0stack:
+ BL (FARG)
+ MOVD R19, RSP
+ RET
diff --git a/src/runtime/rt0_linux_arm64.s b/src/runtime/rt0_linux_arm64.s
index e81e598d3a..458f082159 100644
--- a/src/runtime/rt0_linux_arm64.s
+++ b/src/runtime/rt0_linux_arm64.s
@@ -11,7 +11,7 @@ TEXT _rt0_arm64_linux(SB),NOSPLIT|NOFRAME,$0
// When building with -buildmode=c-shared, this symbol is called when the shared
// library is loaded.
-TEXT _rt0_arm64_linux_lib(SB),NOSPLIT,$168
+TEXT _rt0_arm64_linux_lib(SB),NOSPLIT,$184
// Preserve callee-save registers.
MOVD R19, 24(RSP)
MOVD R20, 32(RSP)
@@ -30,6 +30,10 @@ TEXT _rt0_arm64_linux_lib(SB),NOSPLIT,$168
FMOVD F13, 136(RSP)
FMOVD F14, 144(RSP)
FMOVD F15, 152(RSP)
+ MOVD g, 160(RSP)
+
+ // Initialize g as null in case of using g later e.g. sigaction in cgo_sigaction.go
+ MOVD ZR, g
MOVD R0, _rt0_arm64_linux_lib_argc<>(SB)
MOVD R1, _rt0_arm64_linux_lib_argv<>(SB)
@@ -74,6 +78,7 @@ restore:
FMOVD 136(RSP), F13
FMOVD 144(RSP), F14
FMOVD 152(RSP), F15
+ MOVD 160(RSP), g
RET
TEXT _rt0_arm64_linux_lib_go(SB),NOSPLIT,$0
diff --git a/src/runtime/sigaction.go b/src/runtime/sigaction.go
index eb454f9327..3c888579d0 100644
--- a/src/runtime/sigaction.go
+++ b/src/runtime/sigaction.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build linux,!amd64 freebsd,!amd64
+// +build linux,!amd64,!arm64 freebsd,!amd64
package runtime
diff --git a/src/runtime/sys_linux_arm64.s b/src/runtime/sys_linux_arm64.s
index f930d1f044..c6afd76a65 100644
--- a/src/runtime/sys_linux_arm64.s
+++ b/src/runtime/sys_linux_arm64.s
@@ -292,6 +292,16 @@ TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36
MOVW R0, ret+32(FP)
RET
+// Call the function stored in _cgo_sigaction using the GCC calling convention.
+TEXT runtime·callCgoSigaction(SB),NOSPLIT,$0
+ MOVD sig+0(FP), R0
+ MOVD new+8(FP), R1
+ MOVD old+16(FP), R2
+ MOVD _cgo_sigaction(SB), R3
+ BL R3
+ MOVW R0, ret+24(FP)
+ RET
+
TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
MOVW sig+8(FP), R0
MOVD info+16(FP), R1
@@ -320,7 +330,7 @@ TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
MOVD $runtime·sigtramp(SB), R3
B (R3)
-TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0
+TEXT runtime·sysMmap(SB),NOSPLIT|NOFRAME,$0
MOVD addr+0(FP), R0
MOVD n+8(FP), R1
MOVW prot+16(FP), R2
@@ -341,7 +351,21 @@ ok:
MOVD $0, err+40(FP)
RET
-TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0
+// Call the function stored in _cgo_mmap using the GCC calling convention.
+// This must be called on the system stack.
+TEXT runtime·callCgoMmap(SB),NOSPLIT,$0
+ MOVD addr+0(FP), R0
+ MOVD n+8(FP), R1
+ MOVW prot+16(FP), R2
+ MOVW flags+20(FP), R3
+ MOVW fd+24(FP), R4
+ MOVW off+28(FP), R5
+ MOVD _cgo_mmap(SB), R9
+ BL R9
+ MOVD R0, ret+32(FP)
+ RET
+
+TEXT runtime·sysMunmap(SB),NOSPLIT|NOFRAME,$0
MOVD addr+0(FP), R0
MOVD n+8(FP), R1
MOVD $SYS_munmap, R8
@@ -352,6 +376,15 @@ TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0
cool:
RET
+// Call the function stored in _cgo_munmap using the GCC calling convention.
+// This must be called on the system stack.
+TEXT runtime·callCgoMunmap(SB),NOSPLIT,$0
+ MOVD addr+0(FP), R0
+ MOVD n+8(FP), R1
+ MOVD _cgo_munmap(SB), R9
+ BL R9
+ RET
+
TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
MOVD addr+0(FP), R0
MOVD n+8(FP), R1