From: Anthony Martin Date: Mon, 9 Dec 2013 23:41:48 +0000 (-0500) Subject: runtime: do not use memmove in the Plan 9 signal handler X-Git-Tag: go1.3beta1~1289 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=274a8e3f56358dd8ab93aad1bbd750bcb2750296;p=gostls13.git runtime: do not use memmove in the Plan 9 signal handler Fixes a regression introduced in revision 4cb93e2900d0. That revision changed runtime·memmove to use SSE MOVOU instructions for sizes between 17 and 256 bytes. We were using memmove to save a copy of the note string during the note handler. The Plan 9 kernel does not allow the use of floating point in note handlers (which includes MOVOU since it touches the XMM registers). Arguably, runtime·memmove should not be using MOVOU when GO386=387 but that wouldn't help us on amd64. It's very important that we guard against any future changes so we use a simple copy loop instead. This change is extracted from CL 9796043 (since that CL is still being ironed out). R=rsc CC=golang-dev https://golang.org/cl/34640045 --- diff --git a/src/pkg/runtime/os_plan9_386.c b/src/pkg/runtime/os_plan9_386.c index 0844d726b5..3a17b33b84 100644 --- a/src/pkg/runtime/os_plan9_386.c +++ b/src/pkg/runtime/os_plan9_386.c @@ -59,12 +59,18 @@ runtime·sighandler(void *v, int8 *s, G *gp) if(gp == nil || m->notesig == 0) goto Throw; - // Save error string from sigtramp's stack, - // into gsignal->sigcode0, so we can reliably - // access it from the panic routines. - if(len > ERRMAX) - len = ERRMAX; - runtime·memmove((void*)m->notesig, (void*)s, len); + // Copy the error string from sigtramp's stack into m->notesig so + // we can reliably access it from the panic routines. We can't use + // runtime·memmove here since it will use SSE instructions for big + // copies. The Plan 9 kernel doesn't allow floating point in note + // handlers. + // + // TODO(ality): revert back to memmove when the kernel is fixed. + if(len >= ERRMAX) + len = ERRMAX-1; + for(i = 0; i < len; i++) + m->notesig[i] = s[i]; + m->notesig[i] = '\0'; gp->sig = i; gp->sigpc = ureg->pc; diff --git a/src/pkg/runtime/os_plan9_amd64.c b/src/pkg/runtime/os_plan9_amd64.c index 58822ff848..4847dc6cef 100644 --- a/src/pkg/runtime/os_plan9_amd64.c +++ b/src/pkg/runtime/os_plan9_amd64.c @@ -67,12 +67,18 @@ runtime·sighandler(void *v, int8 *s, G *gp) if(gp == nil || m->notesig == 0) goto Throw; - // Save error string from sigtramp's stack, - // into gsignal->sigcode0, so we can reliably - // access it from the panic routines. - if(len > ERRMAX) - len = ERRMAX; - runtime·memmove((void*)m->notesig, (void*)s, len); + // Copy the error string from sigtramp's stack into m->notesig so + // we can reliably access it from the panic routines. We can't use + // runtime·memmove here since it will use SSE instructions for big + // copies. The Plan 9 kernel doesn't allow floating point in note + // handlers. + // + // TODO(ality): revert back to memmove when the kernel is fixed. + if(len >= ERRMAX) + len = ERRMAX-1; + for(i = 0; i < len; i++) + m->notesig[i] = s[i]; + m->notesig[i] = '\0'; gp->sig = i; gp->sigpc = ureg->ip;