re PR libgcc/86213 (-fsplit-stack runtime may clobber SSE input param reg)
libgcc/: PR libgcc/86213 * generic-morestack.c (allocate_segment): Move calls to getenv and getpagesize to __morestack_load_mmap. (__morestack_load_mmap) Initialize static_pagesize and use_guard_page here so as to avoid clobbering SSE regs during a __morestack call. gcc/testsuite/: * gcc.dg/split-8.c: New. From-SVN: r261823
This commit is contained in:
parent
d8e7bf49a8
commit
1f3fa52553
|
@ -1,3 +1,8 @@
|
||||||
|
2018-06-20 Than McIntosh <thanm@google.com>
|
||||||
|
|
||||||
|
PR libgcc/86213
|
||||||
|
* gcc.dg/split-8.c: New.
|
||||||
|
|
||||||
2018-06-20 Kelvin Nilsen <kelvin@gcc.gnu.org>
|
2018-06-20 Kelvin Nilsen <kelvin@gcc.gnu.org>
|
||||||
|
|
||||||
* gcc.target/powerpc/builtins-1.c: Adjust dg directives to scan
|
* gcc.target/powerpc/builtins-1.c: Adjust dg directives to scan
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/* { dg-do run } */
|
||||||
|
/* { dg-require-effective-target split_stack } */
|
||||||
|
/* { dg-options "-fsplit-stack" } */
|
||||||
|
|
||||||
|
/* Testcase for PR86213. On the first call to __morestack there is a live
|
||||||
|
value in xmm0, which was being clobbered by a call to getenv(). */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
double gd[8];
|
||||||
|
int z;
|
||||||
|
|
||||||
|
double bar(double q) __attribute__ ((noinline));
|
||||||
|
double foo(double q) __attribute__ ((noinline));
|
||||||
|
int ck(double q) __attribute__ ((noinline));
|
||||||
|
int main(int argc, char **argv) __attribute__ ((no_split_stack));
|
||||||
|
|
||||||
|
double bar(double q)
|
||||||
|
{
|
||||||
|
double d[8];
|
||||||
|
for (unsigned i = 0; i < 8; ++i)
|
||||||
|
d[i] = gd[8-i-1];
|
||||||
|
return q + d[z&3];
|
||||||
|
}
|
||||||
|
|
||||||
|
double foo(double d)
|
||||||
|
{
|
||||||
|
return bar(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ck(double d)
|
||||||
|
{
|
||||||
|
if (d != 64.0)
|
||||||
|
abort();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef double (*fp)(double);
|
||||||
|
fp g = foo;
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
return ck(g(64.0));
|
||||||
|
}
|
|
@ -1,3 +1,12 @@
|
||||||
|
2018-06-20 Than McIntosh <thanm@google.com>
|
||||||
|
|
||||||
|
PR libgcc/86213
|
||||||
|
* generic-morestack.c (allocate_segment): Move calls to getenv and
|
||||||
|
getpagesize to __morestack_load_mmap.
|
||||||
|
(__morestack_load_mmap) Initialize static_pagesize and
|
||||||
|
use_guard_page here so as to avoid clobbering SSE regs during a
|
||||||
|
__morestack call.
|
||||||
|
|
||||||
2018-06-18 Michael Meissner <meissner@linux.ibm.com>
|
2018-06-18 Michael Meissner <meissner@linux.ibm.com>
|
||||||
|
|
||||||
* config/rs6000/t-float128 (FP128_CFLAGS_SW): Compile float128
|
* config/rs6000/t-float128 (FP128_CFLAGS_SW): Compile float128
|
||||||
|
|
|
@ -243,6 +243,12 @@ __thread struct initial_sp __morestack_initial_sp
|
||||||
|
|
||||||
static sigset_t __morestack_fullmask;
|
static sigset_t __morestack_fullmask;
|
||||||
|
|
||||||
|
/* Page size, as returned from getpagesize(). Set on startup. */
|
||||||
|
static unsigned int static_pagesize;
|
||||||
|
|
||||||
|
/* Set on startup to non-zero value if SPLIT_STACK_GUARD env var is set. */
|
||||||
|
static int use_guard_page;
|
||||||
|
|
||||||
/* Convert an integer to a decimal string without using much stack
|
/* Convert an integer to a decimal string without using much stack
|
||||||
space. Return a pointer to the part of the buffer to use. We this
|
space. Return a pointer to the part of the buffer to use. We this
|
||||||
instead of sprintf because sprintf will require too much stack
|
instead of sprintf because sprintf will require too much stack
|
||||||
|
@ -320,8 +326,6 @@ __morestack_fail (const char *msg, size_t len, int err)
|
||||||
static struct stack_segment *
|
static struct stack_segment *
|
||||||
allocate_segment (size_t frame_size)
|
allocate_segment (size_t frame_size)
|
||||||
{
|
{
|
||||||
static unsigned int static_pagesize;
|
|
||||||
static int use_guard_page;
|
|
||||||
unsigned int pagesize;
|
unsigned int pagesize;
|
||||||
unsigned int overhead;
|
unsigned int overhead;
|
||||||
unsigned int allocate;
|
unsigned int allocate;
|
||||||
|
@ -329,27 +333,6 @@ allocate_segment (size_t frame_size)
|
||||||
struct stack_segment *pss;
|
struct stack_segment *pss;
|
||||||
|
|
||||||
pagesize = static_pagesize;
|
pagesize = static_pagesize;
|
||||||
if (pagesize == 0)
|
|
||||||
{
|
|
||||||
unsigned int p;
|
|
||||||
|
|
||||||
pagesize = getpagesize ();
|
|
||||||
|
|
||||||
#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
|
|
||||||
p = __sync_val_compare_and_swap (&static_pagesize, 0, pagesize);
|
|
||||||
#else
|
|
||||||
/* Just hope this assignment is atomic. */
|
|
||||||
static_pagesize = pagesize;
|
|
||||||
p = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
use_guard_page = getenv ("SPLIT_STACK_GUARD") != 0;
|
|
||||||
|
|
||||||
/* FIXME: I'm not sure this assert should be in the released
|
|
||||||
code. */
|
|
||||||
assert (p == 0 || p == pagesize);
|
|
||||||
}
|
|
||||||
|
|
||||||
overhead = sizeof (struct stack_segment);
|
overhead = sizeof (struct stack_segment);
|
||||||
|
|
||||||
allocate = pagesize;
|
allocate = pagesize;
|
||||||
|
@ -815,7 +798,10 @@ __generic_findstack (void *stack)
|
||||||
/* This function is called at program startup time to make sure that
|
/* This function is called at program startup time to make sure that
|
||||||
mmap, munmap, and getpagesize are resolved if linking dynamically.
|
mmap, munmap, and getpagesize are resolved if linking dynamically.
|
||||||
We want to resolve them while we have enough stack for them, rather
|
We want to resolve them while we have enough stack for them, rather
|
||||||
than calling into the dynamic linker while low on stack space. */
|
than calling into the dynamic linker while low on stack space.
|
||||||
|
Similarly, invoke getenv here to check for split-stack related control
|
||||||
|
variables, since doing do as part of the __morestack path can result
|
||||||
|
in unwanted use of SSE/AVX registers (see GCC PR 86213). */
|
||||||
|
|
||||||
void
|
void
|
||||||
__morestack_load_mmap (void)
|
__morestack_load_mmap (void)
|
||||||
|
@ -825,7 +811,12 @@ __morestack_load_mmap (void)
|
||||||
TLS accessor function is resolved. */
|
TLS accessor function is resolved. */
|
||||||
mmap (__morestack_current_segment, 0, PROT_READ, MAP_ANONYMOUS, -1, 0);
|
mmap (__morestack_current_segment, 0, PROT_READ, MAP_ANONYMOUS, -1, 0);
|
||||||
mprotect (NULL, 0, 0);
|
mprotect (NULL, 0, 0);
|
||||||
munmap (0, getpagesize ());
|
munmap (0, static_pagesize);
|
||||||
|
|
||||||
|
/* Initialize these values here, so as to avoid dynamic linker
|
||||||
|
activity as part of a __morestack call. */
|
||||||
|
static_pagesize = getpagesize();
|
||||||
|
use_guard_page = getenv ("SPLIT_STACK_GUARD") != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function may be used to iterate over the stack segments.
|
/* This function may be used to iterate over the stack segments.
|
||||||
|
|
Loading…
Reference in New Issue