xref: /netbsd-src/external/gpl3/gcc.old/dist/libgcc/generic-morestack.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg /* Library support for -fsplit-stack.  */
2*8feb0f0bSmrg /* Copyright (C) 2009-2020 Free Software Foundation, Inc.
31debfc3dSmrg    Contributed by Ian Lance Taylor <iant@google.com>.
41debfc3dSmrg 
51debfc3dSmrg This file is part of GCC.
61debfc3dSmrg 
71debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under
81debfc3dSmrg the terms of the GNU General Public License as published by the Free
91debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
101debfc3dSmrg version.
111debfc3dSmrg 
121debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
131debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
141debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
151debfc3dSmrg for more details.
161debfc3dSmrg 
171debfc3dSmrg Under Section 7 of GPL version 3, you are granted additional
181debfc3dSmrg permissions described in the GCC Runtime Library Exception, version
191debfc3dSmrg 3.1, as published by the Free Software Foundation.
201debfc3dSmrg 
211debfc3dSmrg You should have received a copy of the GNU General Public License and
221debfc3dSmrg a copy of the GCC Runtime Library Exception along with this program;
231debfc3dSmrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
241debfc3dSmrg <http://www.gnu.org/licenses/>.  */
251debfc3dSmrg 
26*8feb0f0bSmrg #pragma GCC optimize ("no-isolate-erroneous-paths-dereference")
27*8feb0f0bSmrg 
281debfc3dSmrg /* powerpc 32-bit not supported.  */
291debfc3dSmrg #if !defined __powerpc__ || defined __powerpc64__
301debfc3dSmrg 
311debfc3dSmrg #include "tconfig.h"
321debfc3dSmrg #include "tsystem.h"
331debfc3dSmrg #include "coretypes.h"
341debfc3dSmrg #include "tm.h"
351debfc3dSmrg #include "libgcc_tm.h"
361debfc3dSmrg 
371debfc3dSmrg /* If inhibit_libc is defined, we cannot compile this file.  The
381debfc3dSmrg    effect is that people will not be able to use -fsplit-stack.  That
391debfc3dSmrg    is much better than failing the build particularly since people
401debfc3dSmrg    will want to define inhibit_libc while building a compiler which
411debfc3dSmrg    can build glibc.  */
421debfc3dSmrg 
431debfc3dSmrg #ifndef inhibit_libc
441debfc3dSmrg 
451debfc3dSmrg #include <assert.h>
461debfc3dSmrg #include <errno.h>
471debfc3dSmrg #include <signal.h>
481debfc3dSmrg #include <stdlib.h>
491debfc3dSmrg #include <string.h>
501debfc3dSmrg #include <unistd.h>
511debfc3dSmrg #include <sys/mman.h>
521debfc3dSmrg #include <sys/uio.h>
531debfc3dSmrg 
541debfc3dSmrg #include "generic-morestack.h"
551debfc3dSmrg 
56*8feb0f0bSmrg /* Some systems use LD_PRELOAD or similar tricks to add hooks to
57*8feb0f0bSmrg    mmap/munmap.  That breaks this code, because when we call mmap
58*8feb0f0bSmrg    there is enough stack space for the system call but there is not,
59*8feb0f0bSmrg    in general, enough stack space to run a hook.  Try to avoid the
60*8feb0f0bSmrg    problem by calling syscall directly.  We only do this on GNU/Linux
61*8feb0f0bSmrg    for now, but it should be easy to add support for more systems with
62*8feb0f0bSmrg    testing.  */
63*8feb0f0bSmrg 
64*8feb0f0bSmrg #if defined(__gnu_linux__)
65*8feb0f0bSmrg 
66*8feb0f0bSmrg #include <sys/syscall.h>
67*8feb0f0bSmrg 
68*8feb0f0bSmrg #if defined(SYS_mmap) || defined(SYS_mmap2)
69*8feb0f0bSmrg 
70*8feb0f0bSmrg #ifdef SYS_mmap2
71*8feb0f0bSmrg #define MORESTACK_MMAP SYS_mmap2
72*8feb0f0bSmrg #define MORESTACK_ADJUST_OFFSET(x) ((x) / 4096ULL)
73*8feb0f0bSmrg #else
74*8feb0f0bSmrg #define MORESTACK_MMAP SYS_mmap
75*8feb0f0bSmrg #define MORESTACK_ADJUST_OFFSET(x) (x)
76*8feb0f0bSmrg #endif
77*8feb0f0bSmrg 
78*8feb0f0bSmrg static void *
morestack_mmap(void * addr,size_t length,int prot,int flags,int fd,off_t offset)79*8feb0f0bSmrg morestack_mmap (void *addr, size_t length, int prot, int flags, int fd,
80*8feb0f0bSmrg 		off_t offset)
81*8feb0f0bSmrg {
82*8feb0f0bSmrg   offset = MORESTACK_ADJUST_OFFSET (offset);
83*8feb0f0bSmrg 
84*8feb0f0bSmrg #ifdef __s390__
85*8feb0f0bSmrg   long args[6] = { (long) addr, (long) length, (long) prot, (long) flags,
86*8feb0f0bSmrg 		   (long) fd, (long) offset };
87*8feb0f0bSmrg   return (void *) syscall (MORESTACK_MMAP, args);
88*8feb0f0bSmrg #else
89*8feb0f0bSmrg   return (void *) syscall (MORESTACK_MMAP, addr, length, prot, flags, fd,
90*8feb0f0bSmrg 			   offset);
91*8feb0f0bSmrg #endif
92*8feb0f0bSmrg }
93*8feb0f0bSmrg 
94*8feb0f0bSmrg #define mmap morestack_mmap
95*8feb0f0bSmrg 
96*8feb0f0bSmrg #endif /* defined(SYS_MMAP) || defined(SYS_mmap2) */
97*8feb0f0bSmrg 
98*8feb0f0bSmrg #if defined(SYS_munmap)
99*8feb0f0bSmrg 
100*8feb0f0bSmrg static int
morestack_munmap(void * addr,size_t length)101*8feb0f0bSmrg morestack_munmap (void * addr, size_t length)
102*8feb0f0bSmrg {
103*8feb0f0bSmrg   return (int) syscall (SYS_munmap, addr, length);
104*8feb0f0bSmrg }
105*8feb0f0bSmrg 
106*8feb0f0bSmrg #define munmap morestack_munmap
107*8feb0f0bSmrg 
108*8feb0f0bSmrg #endif /* defined(SYS_munmap) */
109*8feb0f0bSmrg 
110*8feb0f0bSmrg #endif /* defined(__gnu_linux__) */
111*8feb0f0bSmrg 
1121debfc3dSmrg typedef unsigned uintptr_type __attribute__ ((mode (pointer)));
1131debfc3dSmrg 
1141debfc3dSmrg /* This file contains subroutines that are used by code compiled with
1151debfc3dSmrg    -fsplit-stack.  */
1161debfc3dSmrg 
1171debfc3dSmrg /* Declare functions to avoid warnings--there is no header file for
1181debfc3dSmrg    these internal functions.  We give most of these functions the
1191debfc3dSmrg    flatten attribute in order to minimize their stack usage--here we
1201debfc3dSmrg    must minimize stack usage even at the cost of code size, and in
1211debfc3dSmrg    general inlining everything will do that.  */
1221debfc3dSmrg 
1231debfc3dSmrg extern void
1241debfc3dSmrg __generic_morestack_set_initial_sp (void *sp, size_t len)
1251debfc3dSmrg   __attribute__ ((no_split_stack, flatten, visibility ("hidden")));
1261debfc3dSmrg 
1271debfc3dSmrg extern void *
1281debfc3dSmrg __generic_morestack (size_t *frame_size, void *old_stack, size_t param_size)
1291debfc3dSmrg   __attribute__ ((no_split_stack, flatten, visibility ("hidden")));
1301debfc3dSmrg 
1311debfc3dSmrg extern void *
1321debfc3dSmrg __generic_releasestack (size_t *pavailable)
1331debfc3dSmrg   __attribute__ ((no_split_stack, flatten, visibility ("hidden")));
1341debfc3dSmrg 
1351debfc3dSmrg extern void
1361debfc3dSmrg __morestack_block_signals (void)
1371debfc3dSmrg   __attribute__ ((no_split_stack, flatten, visibility ("hidden")));
1381debfc3dSmrg 
1391debfc3dSmrg extern void
1401debfc3dSmrg __morestack_unblock_signals (void)
1411debfc3dSmrg   __attribute__ ((no_split_stack, flatten, visibility ("hidden")));
1421debfc3dSmrg 
1431debfc3dSmrg extern size_t
1441debfc3dSmrg __generic_findstack (void *stack)
1451debfc3dSmrg   __attribute__ ((no_split_stack, flatten, visibility ("hidden")));
1461debfc3dSmrg 
1471debfc3dSmrg extern void
1481debfc3dSmrg __morestack_load_mmap (void)
1491debfc3dSmrg   __attribute__ ((no_split_stack, visibility ("hidden")));
1501debfc3dSmrg 
1511debfc3dSmrg extern void *
1521debfc3dSmrg __morestack_allocate_stack_space (size_t size)
1531debfc3dSmrg   __attribute__ ((visibility ("hidden")));
1541debfc3dSmrg 
1551debfc3dSmrg /* These are functions which -fsplit-stack code can call.  These are
1561debfc3dSmrg    not called by the compiler, and are not hidden.  FIXME: These
1571debfc3dSmrg    should be in some header file somewhere, somehow.  */
1581debfc3dSmrg 
1591debfc3dSmrg extern void *
1601debfc3dSmrg __splitstack_find (void *, void *, size_t *, void **, void **, void **)
1611debfc3dSmrg   __attribute__ ((visibility ("default")));
1621debfc3dSmrg 
1631debfc3dSmrg extern void
1641debfc3dSmrg __splitstack_block_signals (int *, int *)
1651debfc3dSmrg   __attribute__ ((visibility ("default")));
1661debfc3dSmrg 
1671debfc3dSmrg extern void
1681debfc3dSmrg __splitstack_getcontext (void *context[10])
1691debfc3dSmrg   __attribute__ ((no_split_stack, visibility ("default")));
1701debfc3dSmrg 
1711debfc3dSmrg extern void
1721debfc3dSmrg __splitstack_setcontext (void *context[10])
1731debfc3dSmrg   __attribute__ ((no_split_stack, visibility ("default")));
1741debfc3dSmrg 
1751debfc3dSmrg extern void *
1761debfc3dSmrg __splitstack_makecontext (size_t, void *context[10], size_t *)
1771debfc3dSmrg   __attribute__ ((visibility ("default")));
1781debfc3dSmrg 
1791debfc3dSmrg extern void *
1801debfc3dSmrg __splitstack_resetcontext (void *context[10], size_t *)
1811debfc3dSmrg   __attribute__ ((visibility ("default")));
1821debfc3dSmrg 
1831debfc3dSmrg extern void
1841debfc3dSmrg __splitstack_releasecontext (void *context[10])
1851debfc3dSmrg   __attribute__ ((visibility ("default")));
1861debfc3dSmrg 
1871debfc3dSmrg extern void
1881debfc3dSmrg __splitstack_block_signals_context (void *context[10], int *, int *)
1891debfc3dSmrg   __attribute__ ((visibility ("default")));
1901debfc3dSmrg 
1911debfc3dSmrg extern void *
1921debfc3dSmrg __splitstack_find_context (void *context[10], size_t *, void **, void **,
1931debfc3dSmrg 			   void **)
1941debfc3dSmrg   __attribute__ ((visibility ("default")));
1951debfc3dSmrg 
1961debfc3dSmrg /* These functions must be defined by the processor specific code.  */
1971debfc3dSmrg 
1981debfc3dSmrg extern void *__morestack_get_guard (void)
1991debfc3dSmrg   __attribute__ ((no_split_stack, visibility ("hidden")));
2001debfc3dSmrg 
2011debfc3dSmrg extern void __morestack_set_guard (void *)
2021debfc3dSmrg   __attribute__ ((no_split_stack, visibility ("hidden")));
2031debfc3dSmrg 
2041debfc3dSmrg extern void *__morestack_make_guard (void *, size_t)
2051debfc3dSmrg   __attribute__ ((no_split_stack, visibility ("hidden")));
2061debfc3dSmrg 
2071debfc3dSmrg /* When we allocate a stack segment we put this header at the
2081debfc3dSmrg    start.  */
2091debfc3dSmrg 
2101debfc3dSmrg struct stack_segment
2111debfc3dSmrg {
2121debfc3dSmrg   /* The previous stack segment--when a function running on this stack
2131debfc3dSmrg      segment returns, it will run on the previous one.  */
2141debfc3dSmrg   struct stack_segment *prev;
2151debfc3dSmrg   /* The next stack segment, if it has been allocated--when a function
2161debfc3dSmrg      is running on this stack segment, the next one is not being
2171debfc3dSmrg      used.  */
2181debfc3dSmrg   struct stack_segment *next;
2191debfc3dSmrg   /* The total size of this stack segment.  */
2201debfc3dSmrg   size_t size;
2211debfc3dSmrg   /* The stack address when this stack was created.  This is used when
2221debfc3dSmrg      popping the stack.  */
2231debfc3dSmrg   void *old_stack;
2241debfc3dSmrg   /* A list of memory blocks allocated by dynamic stack
2251debfc3dSmrg      allocation.  */
2261debfc3dSmrg   struct dynamic_allocation_blocks *dynamic_allocation;
2271debfc3dSmrg   /* A list of dynamic memory blocks no longer needed.  */
2281debfc3dSmrg   struct dynamic_allocation_blocks *free_dynamic_allocation;
2291debfc3dSmrg   /* An extra pointer in case we need some more information some
2301debfc3dSmrg      day.  */
2311debfc3dSmrg   void *extra;
2321debfc3dSmrg };
2331debfc3dSmrg 
2341debfc3dSmrg /* This structure holds the (approximate) initial stack pointer and
2351debfc3dSmrg    size for the system supplied stack for a thread.  This is set when
2361debfc3dSmrg    the thread is created.  We also store a sigset_t here to hold the
2371debfc3dSmrg    signal mask while splitting the stack, since we don't want to store
2381debfc3dSmrg    that on the stack.  */
2391debfc3dSmrg 
2401debfc3dSmrg struct initial_sp
2411debfc3dSmrg {
2421debfc3dSmrg   /* The initial stack pointer.  */
2431debfc3dSmrg   void *sp;
2441debfc3dSmrg   /* The stack length.  */
2451debfc3dSmrg   size_t len;
2461debfc3dSmrg   /* A signal mask, put here so that the thread can use it without
2471debfc3dSmrg      needing stack space.  */
2481debfc3dSmrg   sigset_t mask;
2491debfc3dSmrg   /* Non-zero if we should not block signals.  This is a reversed flag
2501debfc3dSmrg      so that the default zero value is the safe value.  The type is
2511debfc3dSmrg      uintptr_type because it replaced one of the void * pointers in
2521debfc3dSmrg      extra.  */
2531debfc3dSmrg   uintptr_type dont_block_signals;
2541debfc3dSmrg   /* Some extra space for later extensibility.  */
2551debfc3dSmrg   void *extra[4];
2561debfc3dSmrg };
2571debfc3dSmrg 
2581debfc3dSmrg /* A list of memory blocks allocated by dynamic stack allocation.
2591debfc3dSmrg    This is used for code that calls alloca or uses variably sized
2601debfc3dSmrg    arrays.  */
2611debfc3dSmrg 
2621debfc3dSmrg struct dynamic_allocation_blocks
2631debfc3dSmrg {
2641debfc3dSmrg   /* The next block in the list.  */
2651debfc3dSmrg   struct dynamic_allocation_blocks *next;
2661debfc3dSmrg   /* The size of the allocated memory.  */
2671debfc3dSmrg   size_t size;
2681debfc3dSmrg   /* The allocated memory.  */
2691debfc3dSmrg   void *block;
2701debfc3dSmrg };
2711debfc3dSmrg 
2721debfc3dSmrg /* These thread local global variables must be shared by all split
2731debfc3dSmrg    stack code across shared library boundaries.  Therefore, they have
2741debfc3dSmrg    default visibility.  They have extensibility fields if needed for
2751debfc3dSmrg    new versions.  If more radical changes are needed, new code can be
2761debfc3dSmrg    written using new variable names, while still using the existing
2771debfc3dSmrg    variables in a backward compatible manner.  Symbol versioning is
2781debfc3dSmrg    also used, although, since these variables are only referenced by
2791debfc3dSmrg    code in this file and generic-morestack-thread.c, it is likely that
2801debfc3dSmrg    simply using new names will suffice.  */
2811debfc3dSmrg 
2821debfc3dSmrg /* The first stack segment allocated for this thread.  */
2831debfc3dSmrg 
2841debfc3dSmrg __thread struct stack_segment *__morestack_segments
2851debfc3dSmrg   __attribute__ ((visibility ("default")));
2861debfc3dSmrg 
2871debfc3dSmrg /* The stack segment that we think we are currently using.  This will
2881debfc3dSmrg    be correct in normal usage, but will be incorrect if an exception
2891debfc3dSmrg    unwinds into a different stack segment or if longjmp jumps to a
2901debfc3dSmrg    different stack segment.  */
2911debfc3dSmrg 
2921debfc3dSmrg __thread struct stack_segment *__morestack_current_segment
2931debfc3dSmrg   __attribute__ ((visibility ("default")));
2941debfc3dSmrg 
2951debfc3dSmrg /* The initial stack pointer and size for this thread.  */
2961debfc3dSmrg 
2971debfc3dSmrg __thread struct initial_sp __morestack_initial_sp
2981debfc3dSmrg   __attribute__ ((visibility ("default")));
2991debfc3dSmrg 
3001debfc3dSmrg /* A static signal mask, to avoid taking up stack space.  */
3011debfc3dSmrg 
3021debfc3dSmrg static sigset_t __morestack_fullmask;
3031debfc3dSmrg 
304a2dc1f3fSmrg /* Page size, as returned from getpagesize(). Set on startup. */
305a2dc1f3fSmrg static unsigned int static_pagesize;
306a2dc1f3fSmrg 
307a2dc1f3fSmrg /* Set on startup to non-zero value if SPLIT_STACK_GUARD env var is set. */
308a2dc1f3fSmrg static int use_guard_page;
309a2dc1f3fSmrg 
3101debfc3dSmrg /* Convert an integer to a decimal string without using much stack
3111debfc3dSmrg    space.  Return a pointer to the part of the buffer to use.  We this
3121debfc3dSmrg    instead of sprintf because sprintf will require too much stack
3131debfc3dSmrg    space.  */
3141debfc3dSmrg 
3151debfc3dSmrg static char *
print_int(int val,char * buf,int buflen,size_t * print_len)3161debfc3dSmrg print_int (int val, char *buf, int buflen, size_t *print_len)
3171debfc3dSmrg {
3181debfc3dSmrg   int is_negative;
3191debfc3dSmrg   int i;
3201debfc3dSmrg   unsigned int uval;
3211debfc3dSmrg 
3221debfc3dSmrg   uval = (unsigned int) val;
3231debfc3dSmrg   if (val >= 0)
3241debfc3dSmrg     is_negative = 0;
3251debfc3dSmrg   else
3261debfc3dSmrg     {
3271debfc3dSmrg       is_negative = 1;
3281debfc3dSmrg       uval = - uval;
3291debfc3dSmrg     }
3301debfc3dSmrg 
3311debfc3dSmrg   i = buflen;
3321debfc3dSmrg   do
3331debfc3dSmrg     {
3341debfc3dSmrg       --i;
3351debfc3dSmrg       buf[i] = '0' + (uval % 10);
3361debfc3dSmrg       uval /= 10;
3371debfc3dSmrg     }
3381debfc3dSmrg   while (uval != 0 && i > 0);
3391debfc3dSmrg 
3401debfc3dSmrg   if (is_negative)
3411debfc3dSmrg     {
3421debfc3dSmrg       if (i > 0)
3431debfc3dSmrg 	--i;
3441debfc3dSmrg       buf[i] = '-';
3451debfc3dSmrg     }
3461debfc3dSmrg 
3471debfc3dSmrg   *print_len = buflen - i;
3481debfc3dSmrg   return buf + i;
3491debfc3dSmrg }
3501debfc3dSmrg 
3511debfc3dSmrg /* Print the string MSG/LEN, the errno number ERR, and a newline on
3521debfc3dSmrg    stderr.  Then crash.  */
3531debfc3dSmrg 
3541debfc3dSmrg void
3551debfc3dSmrg __morestack_fail (const char *, size_t, int) __attribute__ ((noreturn));
3561debfc3dSmrg 
3571debfc3dSmrg void
__morestack_fail(const char * msg,size_t len,int err)3581debfc3dSmrg __morestack_fail (const char *msg, size_t len, int err)
3591debfc3dSmrg {
3601debfc3dSmrg   char buf[24];
3611debfc3dSmrg   static const char nl[] = "\n";
3621debfc3dSmrg   struct iovec iov[3];
3631debfc3dSmrg   union { char *p; const char *cp; } const_cast;
3641debfc3dSmrg 
3651debfc3dSmrg   const_cast.cp = msg;
3661debfc3dSmrg   iov[0].iov_base = const_cast.p;
3671debfc3dSmrg   iov[0].iov_len = len;
3681debfc3dSmrg   /* We can't call strerror, because it may try to translate the error
3691debfc3dSmrg      message, and that would use too much stack space.  */
3701debfc3dSmrg   iov[1].iov_base = print_int (err, buf, sizeof buf, &iov[1].iov_len);
3711debfc3dSmrg   const_cast.cp = &nl[0];
3721debfc3dSmrg   iov[2].iov_base = const_cast.p;
3731debfc3dSmrg   iov[2].iov_len = sizeof nl - 1;
3741debfc3dSmrg   /* FIXME: On systems without writev we need to issue three write
3751debfc3dSmrg      calls, or punt on printing errno.  For now this is irrelevant
3761debfc3dSmrg      since stack splitting only works on GNU/Linux anyhow.  */
3771debfc3dSmrg   writev (2, iov, 3);
3781debfc3dSmrg   abort ();
3791debfc3dSmrg }
3801debfc3dSmrg 
3811debfc3dSmrg /* Allocate a new stack segment.  FRAME_SIZE is the required frame
3821debfc3dSmrg    size.  */
3831debfc3dSmrg 
3841debfc3dSmrg static struct stack_segment *
allocate_segment(size_t frame_size)3851debfc3dSmrg allocate_segment (size_t frame_size)
3861debfc3dSmrg {
3871debfc3dSmrg   unsigned int pagesize;
3881debfc3dSmrg   unsigned int overhead;
3891debfc3dSmrg   unsigned int allocate;
3901debfc3dSmrg   void *space;
3911debfc3dSmrg   struct stack_segment *pss;
3921debfc3dSmrg 
3931debfc3dSmrg   pagesize = static_pagesize;
3941debfc3dSmrg   overhead = sizeof (struct stack_segment);
3951debfc3dSmrg 
3961debfc3dSmrg   allocate = pagesize;
3971debfc3dSmrg   if (allocate < MINSIGSTKSZ)
3981debfc3dSmrg     allocate = ((MINSIGSTKSZ + overhead + pagesize - 1)
3991debfc3dSmrg 		& ~ (pagesize - 1));
4001debfc3dSmrg   if (allocate < frame_size)
4011debfc3dSmrg     allocate = ((frame_size + overhead + pagesize - 1)
4021debfc3dSmrg 		& ~ (pagesize - 1));
4031debfc3dSmrg 
4041debfc3dSmrg   if (use_guard_page)
4051debfc3dSmrg     allocate += pagesize;
4061debfc3dSmrg 
4071debfc3dSmrg   /* FIXME: If this binary requires an executable stack, then we need
4081debfc3dSmrg      to set PROT_EXEC.  Unfortunately figuring that out is complicated
4091debfc3dSmrg      and target dependent.  We would need to use dl_iterate_phdr to
4101debfc3dSmrg      see if there is any object which does not have a PT_GNU_STACK
4111debfc3dSmrg      phdr, though only for architectures which use that mechanism.  */
4121debfc3dSmrg   space = mmap (NULL, allocate, PROT_READ | PROT_WRITE,
4131debfc3dSmrg 		MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
4141debfc3dSmrg   if (space == MAP_FAILED)
4151debfc3dSmrg     {
4161debfc3dSmrg       static const char msg[] =
4171debfc3dSmrg 	"unable to allocate additional stack space: errno ";
4181debfc3dSmrg       __morestack_fail (msg, sizeof msg - 1, errno);
4191debfc3dSmrg     }
4201debfc3dSmrg 
4211debfc3dSmrg   if (use_guard_page)
4221debfc3dSmrg     {
4231debfc3dSmrg       void *guard;
4241debfc3dSmrg 
4251debfc3dSmrg #ifdef __LIBGCC_STACK_GROWS_DOWNWARD__
4261debfc3dSmrg       guard = space;
4271debfc3dSmrg       space = (char *) space + pagesize;
4281debfc3dSmrg #else
4291debfc3dSmrg       guard = space + allocate - pagesize;
4301debfc3dSmrg #endif
4311debfc3dSmrg 
4321debfc3dSmrg       mprotect (guard, pagesize, PROT_NONE);
4331debfc3dSmrg       allocate -= pagesize;
4341debfc3dSmrg     }
4351debfc3dSmrg 
4361debfc3dSmrg   pss = (struct stack_segment *) space;
4371debfc3dSmrg 
4381debfc3dSmrg   pss->prev = NULL;
4391debfc3dSmrg   pss->next = NULL;
4401debfc3dSmrg   pss->size = allocate - overhead;
4411debfc3dSmrg   pss->dynamic_allocation = NULL;
4421debfc3dSmrg   pss->free_dynamic_allocation = NULL;
4431debfc3dSmrg   pss->extra = NULL;
4441debfc3dSmrg 
4451debfc3dSmrg   return pss;
4461debfc3dSmrg }
4471debfc3dSmrg 
4481debfc3dSmrg /* Free a list of dynamic blocks.  */
4491debfc3dSmrg 
4501debfc3dSmrg static void
free_dynamic_blocks(struct dynamic_allocation_blocks * p)4511debfc3dSmrg free_dynamic_blocks (struct dynamic_allocation_blocks *p)
4521debfc3dSmrg {
4531debfc3dSmrg   while (p != NULL)
4541debfc3dSmrg     {
4551debfc3dSmrg       struct dynamic_allocation_blocks *next;
4561debfc3dSmrg 
4571debfc3dSmrg       next = p->next;
4581debfc3dSmrg       free (p->block);
4591debfc3dSmrg       free (p);
4601debfc3dSmrg       p = next;
4611debfc3dSmrg     }
4621debfc3dSmrg }
4631debfc3dSmrg 
4641debfc3dSmrg /* Merge two lists of dynamic blocks.  */
4651debfc3dSmrg 
4661debfc3dSmrg static struct dynamic_allocation_blocks *
merge_dynamic_blocks(struct dynamic_allocation_blocks * a,struct dynamic_allocation_blocks * b)4671debfc3dSmrg merge_dynamic_blocks (struct dynamic_allocation_blocks *a,
4681debfc3dSmrg 		      struct dynamic_allocation_blocks *b)
4691debfc3dSmrg {
4701debfc3dSmrg   struct dynamic_allocation_blocks **pp;
4711debfc3dSmrg 
4721debfc3dSmrg   if (a == NULL)
4731debfc3dSmrg     return b;
4741debfc3dSmrg   if (b == NULL)
4751debfc3dSmrg     return a;
4761debfc3dSmrg   for (pp = &a->next; *pp != NULL; pp = &(*pp)->next)
4771debfc3dSmrg     ;
4781debfc3dSmrg   *pp = b;
4791debfc3dSmrg   return a;
4801debfc3dSmrg }
4811debfc3dSmrg 
4821debfc3dSmrg /* Release stack segments.  If FREE_DYNAMIC is non-zero, we also free
4831debfc3dSmrg    any dynamic blocks.  Otherwise we return them.  */
4841debfc3dSmrg 
4851debfc3dSmrg struct dynamic_allocation_blocks *
__morestack_release_segments(struct stack_segment ** pp,int free_dynamic)4861debfc3dSmrg __morestack_release_segments (struct stack_segment **pp, int free_dynamic)
4871debfc3dSmrg {
4881debfc3dSmrg   struct dynamic_allocation_blocks *ret;
4891debfc3dSmrg   struct stack_segment *pss;
4901debfc3dSmrg 
4911debfc3dSmrg   ret = NULL;
4921debfc3dSmrg   pss = *pp;
4931debfc3dSmrg   while (pss != NULL)
4941debfc3dSmrg     {
4951debfc3dSmrg       struct stack_segment *next;
4961debfc3dSmrg       unsigned int allocate;
4971debfc3dSmrg 
4981debfc3dSmrg       next = pss->next;
4991debfc3dSmrg 
5001debfc3dSmrg       if (pss->dynamic_allocation != NULL
5011debfc3dSmrg 	  || pss->free_dynamic_allocation != NULL)
5021debfc3dSmrg 	{
5031debfc3dSmrg 	  if (free_dynamic)
5041debfc3dSmrg 	    {
5051debfc3dSmrg 	      free_dynamic_blocks (pss->dynamic_allocation);
5061debfc3dSmrg 	      free_dynamic_blocks (pss->free_dynamic_allocation);
5071debfc3dSmrg 	    }
5081debfc3dSmrg 	  else
5091debfc3dSmrg 	    {
5101debfc3dSmrg 	      ret = merge_dynamic_blocks (pss->dynamic_allocation, ret);
5111debfc3dSmrg 	      ret = merge_dynamic_blocks (pss->free_dynamic_allocation, ret);
5121debfc3dSmrg 	    }
5131debfc3dSmrg 	}
5141debfc3dSmrg 
5151debfc3dSmrg       allocate = pss->size + sizeof (struct stack_segment);
5161debfc3dSmrg       if (munmap (pss, allocate) < 0)
5171debfc3dSmrg 	{
5181debfc3dSmrg 	  static const char msg[] = "munmap of stack space failed: errno ";
5191debfc3dSmrg 	  __morestack_fail (msg, sizeof msg - 1, errno);
5201debfc3dSmrg 	}
5211debfc3dSmrg 
5221debfc3dSmrg       pss = next;
5231debfc3dSmrg     }
5241debfc3dSmrg   *pp = NULL;
5251debfc3dSmrg 
5261debfc3dSmrg   return ret;
5271debfc3dSmrg }
5281debfc3dSmrg 
5291debfc3dSmrg /* This function is called by a processor specific function to set the
5301debfc3dSmrg    initial stack pointer for a thread.  The operating system will
5311debfc3dSmrg    always create a stack for a thread.  Here we record a stack pointer
5321debfc3dSmrg    near the base of that stack.  The size argument lets the processor
5331debfc3dSmrg    specific code estimate how much stack space is available on this
5341debfc3dSmrg    initial stack.  */
5351debfc3dSmrg 
5361debfc3dSmrg void
__generic_morestack_set_initial_sp(void * sp,size_t len)5371debfc3dSmrg __generic_morestack_set_initial_sp (void *sp, size_t len)
5381debfc3dSmrg {
5391debfc3dSmrg   /* The stack pointer most likely starts on a page boundary.  Adjust
5401debfc3dSmrg      to the nearest 512 byte boundary.  It's not essential that we be
5411debfc3dSmrg      precise here; getting it wrong will just leave some stack space
5421debfc3dSmrg      unused.  */
5431debfc3dSmrg #ifdef __LIBGCC_STACK_GROWS_DOWNWARD__
5441debfc3dSmrg   sp = (void *) ((((__UINTPTR_TYPE__) sp + 511U) / 512U) * 512U);
5451debfc3dSmrg #else
5461debfc3dSmrg   sp = (void *) ((((__UINTPTR_TYPE__) sp - 511U) / 512U) * 512U);
5471debfc3dSmrg #endif
5481debfc3dSmrg 
5491debfc3dSmrg   __morestack_initial_sp.sp = sp;
5501debfc3dSmrg   __morestack_initial_sp.len = len;
5511debfc3dSmrg   sigemptyset (&__morestack_initial_sp.mask);
5521debfc3dSmrg 
5531debfc3dSmrg   sigfillset (&__morestack_fullmask);
5541debfc3dSmrg #if defined(__GLIBC__) && defined(__linux__)
5551debfc3dSmrg   /* In glibc, the first two real time signals are used by the NPTL
5561debfc3dSmrg      threading library.  By taking them out of the set of signals, we
5571debfc3dSmrg      avoiding copying the signal mask in pthread_sigmask.  More
5581debfc3dSmrg      importantly, pthread_sigmask uses less stack space on x86_64.  */
5591debfc3dSmrg   sigdelset (&__morestack_fullmask, __SIGRTMIN);
5601debfc3dSmrg   sigdelset (&__morestack_fullmask, __SIGRTMIN + 1);
5611debfc3dSmrg #endif
5621debfc3dSmrg }
5631debfc3dSmrg 
5641debfc3dSmrg /* This function is called by a processor specific function which is
5651debfc3dSmrg    run in the prologue when more stack is needed.  The processor
5661debfc3dSmrg    specific function handles the details of saving registers and
5671debfc3dSmrg    frobbing the actual stack pointer.  This function is responsible
5681debfc3dSmrg    for allocating a new stack segment and for copying a parameter
5691debfc3dSmrg    block from the old stack to the new one.  On function entry
5701debfc3dSmrg    *PFRAME_SIZE is the size of the required stack frame--the returned
5711debfc3dSmrg    stack must be at least this large.  On function exit *PFRAME_SIZE
5721debfc3dSmrg    is the amount of space remaining on the allocated stack.  OLD_STACK
5731debfc3dSmrg    points at the parameters the old stack (really the current one
5741debfc3dSmrg    while this function is running).  OLD_STACK is saved so that it can
5751debfc3dSmrg    be returned by a later call to __generic_releasestack.  PARAM_SIZE
5761debfc3dSmrg    is the size in bytes of parameters to copy to the new stack.  This
5771debfc3dSmrg    function returns a pointer to the new stack segment, pointing to
5781debfc3dSmrg    the memory after the parameters have been copied.  The returned
5791debfc3dSmrg    value minus the returned *PFRAME_SIZE (or plus if the stack grows
5801debfc3dSmrg    upward) is the first address on the stack which should not be used.
5811debfc3dSmrg 
5821debfc3dSmrg    This function is running on the old stack and has only a limited
5831debfc3dSmrg    amount of stack space available.  */
5841debfc3dSmrg 
5851debfc3dSmrg void *
__generic_morestack(size_t * pframe_size,void * old_stack,size_t param_size)5861debfc3dSmrg __generic_morestack (size_t *pframe_size, void *old_stack, size_t param_size)
5871debfc3dSmrg {
5881debfc3dSmrg   size_t frame_size = *pframe_size;
5891debfc3dSmrg   struct stack_segment *current;
5901debfc3dSmrg   struct stack_segment **pp;
5911debfc3dSmrg   struct dynamic_allocation_blocks *dynamic;
5921debfc3dSmrg   char *from;
5931debfc3dSmrg   char *to;
5941debfc3dSmrg   void *ret;
5951debfc3dSmrg   size_t i;
5961debfc3dSmrg   size_t aligned;
5971debfc3dSmrg 
5981debfc3dSmrg   current = __morestack_current_segment;
5991debfc3dSmrg 
6001debfc3dSmrg   pp = current != NULL ? &current->next : &__morestack_segments;
6011debfc3dSmrg   if (*pp != NULL && (*pp)->size < frame_size)
6021debfc3dSmrg     dynamic = __morestack_release_segments (pp, 0);
6031debfc3dSmrg   else
6041debfc3dSmrg     dynamic = NULL;
6051debfc3dSmrg   current = *pp;
6061debfc3dSmrg 
6071debfc3dSmrg   if (current == NULL)
6081debfc3dSmrg     {
6091debfc3dSmrg       current = allocate_segment (frame_size + param_size);
6101debfc3dSmrg       current->prev = __morestack_current_segment;
6111debfc3dSmrg       *pp = current;
6121debfc3dSmrg     }
6131debfc3dSmrg 
6141debfc3dSmrg   current->old_stack = old_stack;
6151debfc3dSmrg 
6161debfc3dSmrg   __morestack_current_segment = current;
6171debfc3dSmrg 
6181debfc3dSmrg   if (dynamic != NULL)
6191debfc3dSmrg     {
6201debfc3dSmrg       /* Move the free blocks onto our list.  We don't want to call
6211debfc3dSmrg 	 free here, as we are short on stack space.  */
6221debfc3dSmrg       current->free_dynamic_allocation =
6231debfc3dSmrg 	merge_dynamic_blocks (dynamic, current->free_dynamic_allocation);
6241debfc3dSmrg     }
6251debfc3dSmrg 
6261debfc3dSmrg   *pframe_size = current->size - param_size;
6271debfc3dSmrg 
6281debfc3dSmrg   /* Align the returned stack to a 32-byte boundary.  */
6291debfc3dSmrg   aligned = (param_size + 31) & ~ (size_t) 31;
6301debfc3dSmrg 
6311debfc3dSmrg #ifdef __LIBGCC_STACK_GROWS_DOWNWARD__
6321debfc3dSmrg   {
6331debfc3dSmrg     char *bottom = (char *) (current + 1) + current->size;
6341debfc3dSmrg     to = bottom - aligned;
6351debfc3dSmrg     ret = bottom - aligned;
6361debfc3dSmrg   }
6371debfc3dSmrg #else
6381debfc3dSmrg   to = current + 1;
6391debfc3dSmrg   to += aligned - param_size;
6401debfc3dSmrg   ret = (char *) (current + 1) + aligned;
6411debfc3dSmrg #endif
6421debfc3dSmrg 
6431debfc3dSmrg   /* We don't call memcpy to avoid worrying about the dynamic linker
6441debfc3dSmrg      trying to resolve it.  */
6451debfc3dSmrg   from = (char *) old_stack;
6461debfc3dSmrg   for (i = 0; i < param_size; i++)
6471debfc3dSmrg     *to++ = *from++;
6481debfc3dSmrg 
6491debfc3dSmrg   return ret;
6501debfc3dSmrg }
6511debfc3dSmrg 
6521debfc3dSmrg /* This function is called by a processor specific function when it is
6531debfc3dSmrg    ready to release a stack segment.  We don't actually release the
6541debfc3dSmrg    stack segment, we just move back to the previous one.  The current
6551debfc3dSmrg    stack segment will still be available if we need it in
6561debfc3dSmrg    __generic_morestack.  This returns a pointer to the new stack
6571debfc3dSmrg    segment to use, which is the one saved by a previous call to
6581debfc3dSmrg    __generic_morestack.  The processor specific function is then
6591debfc3dSmrg    responsible for actually updating the stack pointer.  This sets
6601debfc3dSmrg    *PAVAILABLE to the amount of stack space now available.  */
6611debfc3dSmrg 
6621debfc3dSmrg void *
__generic_releasestack(size_t * pavailable)6631debfc3dSmrg __generic_releasestack (size_t *pavailable)
6641debfc3dSmrg {
6651debfc3dSmrg   struct stack_segment *current;
6661debfc3dSmrg   void *old_stack;
6671debfc3dSmrg 
6681debfc3dSmrg   current = __morestack_current_segment;
6691debfc3dSmrg   old_stack = current->old_stack;
6701debfc3dSmrg   current = current->prev;
6711debfc3dSmrg   __morestack_current_segment = current;
6721debfc3dSmrg 
6731debfc3dSmrg   if (current != NULL)
6741debfc3dSmrg     {
6751debfc3dSmrg #ifdef __LIBGCC_STACK_GROWS_DOWNWARD__
6761debfc3dSmrg       *pavailable = (char *) old_stack - (char *) (current + 1);
6771debfc3dSmrg #else
6781debfc3dSmrg       *pavailable = (char *) (current + 1) + current->size - (char *) old_stack;
6791debfc3dSmrg #endif
6801debfc3dSmrg     }
6811debfc3dSmrg   else
6821debfc3dSmrg     {
6831debfc3dSmrg       size_t used;
6841debfc3dSmrg 
6851debfc3dSmrg       /* We have popped back to the original stack.  */
6861debfc3dSmrg #ifdef __LIBGCC_STACK_GROWS_DOWNWARD__
6871debfc3dSmrg       if ((char *) old_stack >= (char *) __morestack_initial_sp.sp)
6881debfc3dSmrg 	used = 0;
6891debfc3dSmrg       else
6901debfc3dSmrg 	used = (char *) __morestack_initial_sp.sp - (char *) old_stack;
6911debfc3dSmrg #else
6921debfc3dSmrg       if ((char *) old_stack <= (char *) __morestack_initial_sp.sp)
6931debfc3dSmrg 	used = 0;
6941debfc3dSmrg       else
6951debfc3dSmrg 	used = (char *) old_stack - (char *) __morestack_initial_sp.sp;
6961debfc3dSmrg #endif
6971debfc3dSmrg 
6981debfc3dSmrg       if (used > __morestack_initial_sp.len)
6991debfc3dSmrg 	*pavailable = 0;
7001debfc3dSmrg       else
7011debfc3dSmrg 	*pavailable = __morestack_initial_sp.len - used;
7021debfc3dSmrg     }
7031debfc3dSmrg 
7041debfc3dSmrg   return old_stack;
7051debfc3dSmrg }
7061debfc3dSmrg 
7071debfc3dSmrg /* Block signals while splitting the stack.  This avoids trouble if we
7081debfc3dSmrg    try to invoke a signal handler which itself wants to split the
7091debfc3dSmrg    stack.  */
7101debfc3dSmrg 
7111debfc3dSmrg extern int pthread_sigmask (int, const sigset_t *, sigset_t *)
7121debfc3dSmrg   __attribute__ ((weak));
7131debfc3dSmrg 
7141debfc3dSmrg void
__morestack_block_signals(void)7151debfc3dSmrg __morestack_block_signals (void)
7161debfc3dSmrg {
7171debfc3dSmrg   if (__morestack_initial_sp.dont_block_signals)
7181debfc3dSmrg     ;
7191debfc3dSmrg   else if (pthread_sigmask)
7201debfc3dSmrg     pthread_sigmask (SIG_BLOCK, &__morestack_fullmask,
7211debfc3dSmrg 		     &__morestack_initial_sp.mask);
7221debfc3dSmrg   else
7231debfc3dSmrg     sigprocmask (SIG_BLOCK, &__morestack_fullmask,
7241debfc3dSmrg 		 &__morestack_initial_sp.mask);
7251debfc3dSmrg }
7261debfc3dSmrg 
7271debfc3dSmrg /* Unblock signals while splitting the stack.  */
7281debfc3dSmrg 
7291debfc3dSmrg void
__morestack_unblock_signals(void)7301debfc3dSmrg __morestack_unblock_signals (void)
7311debfc3dSmrg {
7321debfc3dSmrg   if (__morestack_initial_sp.dont_block_signals)
7331debfc3dSmrg     ;
7341debfc3dSmrg   else if (pthread_sigmask)
7351debfc3dSmrg     pthread_sigmask (SIG_SETMASK, &__morestack_initial_sp.mask, NULL);
7361debfc3dSmrg   else
7371debfc3dSmrg     sigprocmask (SIG_SETMASK, &__morestack_initial_sp.mask, NULL);
7381debfc3dSmrg }
7391debfc3dSmrg 
7401debfc3dSmrg /* This function is called to allocate dynamic stack space, for alloca
7411debfc3dSmrg    or a variably sized array.  This is a regular function with
7421debfc3dSmrg    sufficient stack space, so we just use malloc to allocate the
7431debfc3dSmrg    space.  We attach the allocated blocks to the current stack
7441debfc3dSmrg    segment, so that they will eventually be reused or freed.  */
7451debfc3dSmrg 
7461debfc3dSmrg void *
__morestack_allocate_stack_space(size_t size)7471debfc3dSmrg __morestack_allocate_stack_space (size_t size)
7481debfc3dSmrg {
7491debfc3dSmrg   struct stack_segment *seg, *current;
7501debfc3dSmrg   struct dynamic_allocation_blocks *p;
7511debfc3dSmrg 
7521debfc3dSmrg   /* We have to block signals to avoid getting confused if we get
7531debfc3dSmrg      interrupted by a signal whose handler itself uses alloca or a
7541debfc3dSmrg      variably sized array.  */
7551debfc3dSmrg   __morestack_block_signals ();
7561debfc3dSmrg 
7571debfc3dSmrg   /* Since we don't want to call free while we are low on stack space,
7581debfc3dSmrg      we may have a list of already allocated blocks waiting to be
7591debfc3dSmrg      freed.  Release them all, unless we find one that is large
7601debfc3dSmrg      enough.  We don't look at every block to see if one is large
7611debfc3dSmrg      enough, just the first one, because we aren't trying to build a
7621debfc3dSmrg      memory allocator here, we're just trying to speed up common
7631debfc3dSmrg      cases.  */
7641debfc3dSmrg 
7651debfc3dSmrg   current = __morestack_current_segment;
7661debfc3dSmrg   p = NULL;
7671debfc3dSmrg   for (seg = __morestack_segments; seg != NULL; seg = seg->next)
7681debfc3dSmrg     {
7691debfc3dSmrg       p = seg->free_dynamic_allocation;
7701debfc3dSmrg       if (p != NULL)
7711debfc3dSmrg 	{
7721debfc3dSmrg 	  if (p->size >= size)
7731debfc3dSmrg 	    {
7741debfc3dSmrg 	      seg->free_dynamic_allocation = p->next;
7751debfc3dSmrg 	      break;
7761debfc3dSmrg 	    }
7771debfc3dSmrg 
7781debfc3dSmrg 	  free_dynamic_blocks (p);
7791debfc3dSmrg 	  seg->free_dynamic_allocation = NULL;
7801debfc3dSmrg 	  p = NULL;
7811debfc3dSmrg 	}
7821debfc3dSmrg     }
7831debfc3dSmrg 
7841debfc3dSmrg   if (p == NULL)
7851debfc3dSmrg     {
7861debfc3dSmrg       /* We need to allocate additional memory.  */
7871debfc3dSmrg       p = malloc (sizeof (*p));
7881debfc3dSmrg       if (p == NULL)
7891debfc3dSmrg 	abort ();
7901debfc3dSmrg       p->size = size;
7911debfc3dSmrg       p->block = malloc (size);
7921debfc3dSmrg       if (p->block == NULL)
7931debfc3dSmrg 	abort ();
7941debfc3dSmrg     }
7951debfc3dSmrg 
7961debfc3dSmrg   /* If we are still on the initial stack, then we have a space leak.
7971debfc3dSmrg      FIXME.  */
7981debfc3dSmrg   if (current != NULL)
7991debfc3dSmrg     {
8001debfc3dSmrg       p->next = current->dynamic_allocation;
8011debfc3dSmrg       current->dynamic_allocation = p;
8021debfc3dSmrg     }
8031debfc3dSmrg 
8041debfc3dSmrg   __morestack_unblock_signals ();
8051debfc3dSmrg 
8061debfc3dSmrg   return p->block;
8071debfc3dSmrg }
8081debfc3dSmrg 
8091debfc3dSmrg /* Find the stack segment for STACK and return the amount of space
8101debfc3dSmrg    available.  This is used when unwinding the stack because of an
8111debfc3dSmrg    exception, in order to reset the stack guard correctly.  */
8121debfc3dSmrg 
8131debfc3dSmrg size_t
__generic_findstack(void * stack)8141debfc3dSmrg __generic_findstack (void *stack)
8151debfc3dSmrg {
8161debfc3dSmrg   struct stack_segment *pss;
8171debfc3dSmrg   size_t used;
8181debfc3dSmrg 
8191debfc3dSmrg   for (pss = __morestack_current_segment; pss != NULL; pss = pss->prev)
8201debfc3dSmrg     {
8211debfc3dSmrg       if ((char *) pss < (char *) stack
8221debfc3dSmrg 	  && (char *) pss + pss->size > (char *) stack)
8231debfc3dSmrg 	{
8241debfc3dSmrg 	  __morestack_current_segment = pss;
8251debfc3dSmrg #ifdef __LIBGCC_STACK_GROWS_DOWNWARD__
8261debfc3dSmrg 	  return (char *) stack - (char *) (pss + 1);
8271debfc3dSmrg #else
8281debfc3dSmrg 	  return (char *) (pss + 1) + pss->size - (char *) stack;
8291debfc3dSmrg #endif
8301debfc3dSmrg 	}
8311debfc3dSmrg     }
8321debfc3dSmrg 
8331debfc3dSmrg   /* We have popped back to the original stack.  */
8341debfc3dSmrg 
8351debfc3dSmrg   if (__morestack_initial_sp.sp == NULL)
8361debfc3dSmrg     return 0;
8371debfc3dSmrg 
8381debfc3dSmrg #ifdef __LIBGCC_STACK_GROWS_DOWNWARD__
8391debfc3dSmrg   if ((char *) stack >= (char *) __morestack_initial_sp.sp)
8401debfc3dSmrg     used = 0;
8411debfc3dSmrg   else
8421debfc3dSmrg     used = (char *) __morestack_initial_sp.sp - (char *) stack;
8431debfc3dSmrg #else
8441debfc3dSmrg   if ((char *) stack <= (char *) __morestack_initial_sp.sp)
8451debfc3dSmrg     used = 0;
8461debfc3dSmrg   else
8471debfc3dSmrg     used = (char *) stack - (char *) __morestack_initial_sp.sp;
8481debfc3dSmrg #endif
8491debfc3dSmrg 
8501debfc3dSmrg   if (used > __morestack_initial_sp.len)
8511debfc3dSmrg     return 0;
8521debfc3dSmrg   else
8531debfc3dSmrg     return __morestack_initial_sp.len - used;
8541debfc3dSmrg }
8551debfc3dSmrg 
8561debfc3dSmrg /* This function is called at program startup time to make sure that
8571debfc3dSmrg    mmap, munmap, and getpagesize are resolved if linking dynamically.
8581debfc3dSmrg    We want to resolve them while we have enough stack for them, rather
859a2dc1f3fSmrg    than calling into the dynamic linker while low on stack space.
860a2dc1f3fSmrg    Similarly, invoke getenv here to check for split-stack related control
861a2dc1f3fSmrg    variables, since doing do as part of the __morestack path can result
862a2dc1f3fSmrg    in unwanted use of SSE/AVX registers (see GCC PR 86213). */
8631debfc3dSmrg 
8641debfc3dSmrg void
__morestack_load_mmap(void)8651debfc3dSmrg __morestack_load_mmap (void)
8661debfc3dSmrg {
8671debfc3dSmrg   /* Call with bogus values to run faster.  We don't care if the call
8681debfc3dSmrg      fails.  Pass __MORESTACK_CURRENT_SEGMENT to make sure that any
8691debfc3dSmrg      TLS accessor function is resolved.  */
8701debfc3dSmrg   mmap (__morestack_current_segment, 0, PROT_READ, MAP_ANONYMOUS, -1, 0);
8711debfc3dSmrg   mprotect (NULL, 0, 0);
872a2dc1f3fSmrg   munmap (0, static_pagesize);
873a2dc1f3fSmrg 
874a2dc1f3fSmrg   /* Initialize these values here, so as to avoid dynamic linker
875a2dc1f3fSmrg      activity as part of a __morestack call. */
876a2dc1f3fSmrg   static_pagesize = getpagesize();
877a2dc1f3fSmrg   use_guard_page = getenv ("SPLIT_STACK_GUARD") != 0;
8781debfc3dSmrg }
8791debfc3dSmrg 
8801debfc3dSmrg /* This function may be used to iterate over the stack segments.
8811debfc3dSmrg    This can be called like this.
8821debfc3dSmrg      void *next_segment = NULL;
8831debfc3dSmrg      void *next_sp = NULL;
8841debfc3dSmrg      void *initial_sp = NULL;
8851debfc3dSmrg      void *stack;
8861debfc3dSmrg      size_t stack_size;
8871debfc3dSmrg      while ((stack = __splitstack_find (next_segment, next_sp, &stack_size,
8881debfc3dSmrg                                         &next_segment, &next_sp,
8891debfc3dSmrg 					&initial_sp)) != NULL)
8901debfc3dSmrg        {
8911debfc3dSmrg          // Stack segment starts at stack and is stack_size bytes long.
8921debfc3dSmrg        }
8931debfc3dSmrg 
8941debfc3dSmrg    There is no way to iterate over the stack segments of a different
8951debfc3dSmrg    thread.  However, what is permitted is for one thread to call this
8961debfc3dSmrg    with the first two values NULL, to pass next_segment, next_sp, and
8971debfc3dSmrg    initial_sp to a different thread, and then to suspend one way or
8981debfc3dSmrg    another.  A different thread may run the subsequent
8991debfc3dSmrg    __morestack_find iterations.  Of course, this will only work if the
9001debfc3dSmrg    first thread is suspended during the __morestack_find iterations.
9011debfc3dSmrg    If not, the second thread will be looking at the stack while it is
9021debfc3dSmrg    changing, and anything could happen.
9031debfc3dSmrg 
9041debfc3dSmrg    FIXME: This should be declared in some header file, but where?  */
9051debfc3dSmrg 
9061debfc3dSmrg void *
__splitstack_find(void * segment_arg,void * sp,size_t * len,void ** next_segment,void ** next_sp,void ** initial_sp)9071debfc3dSmrg __splitstack_find (void *segment_arg, void *sp, size_t *len,
9081debfc3dSmrg 		   void **next_segment, void **next_sp,
9091debfc3dSmrg 		   void **initial_sp)
9101debfc3dSmrg {
9111debfc3dSmrg   struct stack_segment *segment;
9121debfc3dSmrg   void *ret;
9131debfc3dSmrg   char *nsp;
9141debfc3dSmrg 
9151debfc3dSmrg   if (segment_arg == (void *) (uintptr_type) 1)
9161debfc3dSmrg     {
9171debfc3dSmrg       char *isp = (char *) *initial_sp;
9181debfc3dSmrg 
9191debfc3dSmrg       if (isp == NULL)
9201debfc3dSmrg 	return NULL;
9211debfc3dSmrg 
9221debfc3dSmrg       *next_segment = (void *) (uintptr_type) 2;
9231debfc3dSmrg       *next_sp = NULL;
9241debfc3dSmrg #ifdef __LIBGCC_STACK_GROWS_DOWNWARD__
9251debfc3dSmrg       if ((char *) sp >= isp)
9261debfc3dSmrg 	return NULL;
9271debfc3dSmrg       *len = (char *) isp - (char *) sp;
9281debfc3dSmrg       return sp;
9291debfc3dSmrg #else
9301debfc3dSmrg       if ((char *) sp <= (char *) isp)
9311debfc3dSmrg 	return NULL;
9321debfc3dSmrg       *len = (char *) sp - (char *) isp;
9331debfc3dSmrg       return (void *) isp;
9341debfc3dSmrg #endif
9351debfc3dSmrg     }
9361debfc3dSmrg   else if (segment_arg == (void *) (uintptr_type) 2)
9371debfc3dSmrg     return NULL;
9381debfc3dSmrg   else if (segment_arg != NULL)
9391debfc3dSmrg     segment = (struct stack_segment *) segment_arg;
9401debfc3dSmrg   else
9411debfc3dSmrg     {
9421debfc3dSmrg       *initial_sp = __morestack_initial_sp.sp;
9431debfc3dSmrg       segment = __morestack_current_segment;
9441debfc3dSmrg       sp = (void *) &segment;
9451debfc3dSmrg       while (1)
9461debfc3dSmrg 	{
9471debfc3dSmrg 	  if (segment == NULL)
9481debfc3dSmrg 	    return __splitstack_find ((void *) (uintptr_type) 1, sp, len,
9491debfc3dSmrg 				      next_segment, next_sp, initial_sp);
9501debfc3dSmrg 	  if ((char *) sp >= (char *) (segment + 1)
9511debfc3dSmrg 	      && (char *) sp <= (char *) (segment + 1) + segment->size)
9521debfc3dSmrg 	    break;
9531debfc3dSmrg 	  segment = segment->prev;
9541debfc3dSmrg 	}
9551debfc3dSmrg     }
9561debfc3dSmrg 
9571debfc3dSmrg   if (segment->prev == NULL)
9581debfc3dSmrg     *next_segment = (void *) (uintptr_type) 1;
9591debfc3dSmrg   else
9601debfc3dSmrg     *next_segment = segment->prev;
9611debfc3dSmrg 
9621debfc3dSmrg   /* The old_stack value is the address of the function parameters of
9631debfc3dSmrg      the function which called __morestack.  So if f1 called f2 which
9641debfc3dSmrg      called __morestack, the stack looks like this:
9651debfc3dSmrg 
9661debfc3dSmrg          parameters       <- old_stack
9671debfc3dSmrg          return in f1
9681debfc3dSmrg 	 return in f2
9691debfc3dSmrg 	 registers pushed by __morestack
9701debfc3dSmrg 
9711debfc3dSmrg      The registers pushed by __morestack may not be visible on any
9721debfc3dSmrg      other stack, if we are being called by a signal handler
9731debfc3dSmrg      immediately after the call to __morestack_unblock_signals.  We
9741debfc3dSmrg      want to adjust our return value to include those registers.  This
9751debfc3dSmrg      is target dependent.  */
9761debfc3dSmrg 
9771debfc3dSmrg   nsp = (char *) segment->old_stack;
9781debfc3dSmrg 
9791debfc3dSmrg   if (nsp == NULL)
9801debfc3dSmrg     {
9811debfc3dSmrg       /* We've reached the top of the stack.  */
9821debfc3dSmrg       *next_segment = (void *) (uintptr_type) 2;
9831debfc3dSmrg     }
9841debfc3dSmrg   else
9851debfc3dSmrg     {
9861debfc3dSmrg #if defined (__x86_64__)
9871debfc3dSmrg       nsp -= 12 * sizeof (void *);
9881debfc3dSmrg #elif defined (__i386__)
9891debfc3dSmrg       nsp -= 6 * sizeof (void *);
9901debfc3dSmrg #elif defined __powerpc64__
9911debfc3dSmrg #elif defined __s390x__
9921debfc3dSmrg       nsp -= 2 * 160;
9931debfc3dSmrg #elif defined __s390__
9941debfc3dSmrg       nsp -= 2 * 96;
9951debfc3dSmrg #else
9961debfc3dSmrg #error "unrecognized target"
9971debfc3dSmrg #endif
9981debfc3dSmrg 
9991debfc3dSmrg       *next_sp = (void *) nsp;
10001debfc3dSmrg     }
10011debfc3dSmrg 
10021debfc3dSmrg #ifdef __LIBGCC_STACK_GROWS_DOWNWARD__
10031debfc3dSmrg   *len = (char *) (segment + 1) + segment->size - (char *) sp;
10041debfc3dSmrg   ret = (void *) sp;
10051debfc3dSmrg #else
10061debfc3dSmrg   *len = (char *) sp - (char *) (segment + 1);
10071debfc3dSmrg   ret = (void *) (segment + 1);
10081debfc3dSmrg #endif
10091debfc3dSmrg 
10101debfc3dSmrg   return ret;
10111debfc3dSmrg }
10121debfc3dSmrg 
10131debfc3dSmrg /* Tell the split stack code whether it has to block signals while
10141debfc3dSmrg    manipulating the stack.  This is for programs in which some threads
10151debfc3dSmrg    block all signals.  If a thread already blocks signals, there is no
10161debfc3dSmrg    need for the split stack code to block them as well.  If NEW is not
10171debfc3dSmrg    NULL, then if *NEW is non-zero signals will be blocked while
10181debfc3dSmrg    splitting the stack, otherwise they will not.  If OLD is not NULL,
10191debfc3dSmrg    *OLD will be set to the old value.  */
10201debfc3dSmrg 
10211debfc3dSmrg void
__splitstack_block_signals(int * new,int * old)10221debfc3dSmrg __splitstack_block_signals (int *new, int *old)
10231debfc3dSmrg {
10241debfc3dSmrg   if (old != NULL)
10251debfc3dSmrg     *old = __morestack_initial_sp.dont_block_signals ? 0 : 1;
10261debfc3dSmrg   if (new != NULL)
10271debfc3dSmrg     __morestack_initial_sp.dont_block_signals = *new ? 0 : 1;
10281debfc3dSmrg }
10291debfc3dSmrg 
10301debfc3dSmrg /* The offsets into the arrays used by __splitstack_getcontext and
10311debfc3dSmrg    __splitstack_setcontext.  */
10321debfc3dSmrg 
10331debfc3dSmrg enum __splitstack_context_offsets
10341debfc3dSmrg {
10351debfc3dSmrg   MORESTACK_SEGMENTS = 0,
10361debfc3dSmrg   CURRENT_SEGMENT = 1,
10371debfc3dSmrg   CURRENT_STACK = 2,
10381debfc3dSmrg   STACK_GUARD = 3,
10391debfc3dSmrg   INITIAL_SP = 4,
10401debfc3dSmrg   INITIAL_SP_LEN = 5,
10411debfc3dSmrg   BLOCK_SIGNALS = 6,
10421debfc3dSmrg 
10431debfc3dSmrg   NUMBER_OFFSETS = 10
10441debfc3dSmrg };
10451debfc3dSmrg 
10461debfc3dSmrg /* Get the current split stack context.  This may be used for
10471debfc3dSmrg    coroutine switching, similar to getcontext.  The argument should
10481debfc3dSmrg    have at least 10 void *pointers for extensibility, although we
10491debfc3dSmrg    don't currently use all of them.  This would normally be called
10501debfc3dSmrg    immediately before a call to getcontext or swapcontext or
10511debfc3dSmrg    setjmp.  */
10521debfc3dSmrg 
10531debfc3dSmrg void
__splitstack_getcontext(void * context[NUMBER_OFFSETS])10541debfc3dSmrg __splitstack_getcontext (void *context[NUMBER_OFFSETS])
10551debfc3dSmrg {
10561debfc3dSmrg   memset (context, 0, NUMBER_OFFSETS * sizeof (void *));
10571debfc3dSmrg   context[MORESTACK_SEGMENTS] = (void *) __morestack_segments;
10581debfc3dSmrg   context[CURRENT_SEGMENT] = (void *) __morestack_current_segment;
10591debfc3dSmrg   context[CURRENT_STACK] = (void *) &context;
10601debfc3dSmrg   context[STACK_GUARD] = __morestack_get_guard ();
10611debfc3dSmrg   context[INITIAL_SP] = (void *) __morestack_initial_sp.sp;
10621debfc3dSmrg   context[INITIAL_SP_LEN] = (void *) (uintptr_type) __morestack_initial_sp.len;
10631debfc3dSmrg   context[BLOCK_SIGNALS] = (void *) __morestack_initial_sp.dont_block_signals;
10641debfc3dSmrg }
10651debfc3dSmrg 
10661debfc3dSmrg /* Set the current split stack context.  The argument should be a
10671debfc3dSmrg    context previously passed to __splitstack_getcontext.  This would
10681debfc3dSmrg    normally be called immediately after a call to getcontext or
10691debfc3dSmrg    swapcontext or setjmp if something jumped to it.  */
10701debfc3dSmrg 
10711debfc3dSmrg void
__splitstack_setcontext(void * context[NUMBER_OFFSETS])10721debfc3dSmrg __splitstack_setcontext (void *context[NUMBER_OFFSETS])
10731debfc3dSmrg {
10741debfc3dSmrg   __morestack_segments = (struct stack_segment *) context[MORESTACK_SEGMENTS];
10751debfc3dSmrg   __morestack_current_segment =
10761debfc3dSmrg     (struct stack_segment *) context[CURRENT_SEGMENT];
10771debfc3dSmrg   __morestack_set_guard (context[STACK_GUARD]);
10781debfc3dSmrg   __morestack_initial_sp.sp = context[INITIAL_SP];
10791debfc3dSmrg   __morestack_initial_sp.len = (size_t) context[INITIAL_SP_LEN];
10801debfc3dSmrg   __morestack_initial_sp.dont_block_signals =
10811debfc3dSmrg     (uintptr_type) context[BLOCK_SIGNALS];
10821debfc3dSmrg }
10831debfc3dSmrg 
10841debfc3dSmrg /* Create a new split stack context.  This will allocate a new stack
10851debfc3dSmrg    segment which may be used by a coroutine.  STACK_SIZE is the
10861debfc3dSmrg    minimum size of the new stack.  The caller is responsible for
10871debfc3dSmrg    actually setting the stack pointer.  This would normally be called
10881debfc3dSmrg    before a call to makecontext, and the returned stack pointer and
10891debfc3dSmrg    size would be used to set the uc_stack field.  A function called
10901debfc3dSmrg    via makecontext on a stack created by __splitstack_makecontext may
10911debfc3dSmrg    not return.  Note that the returned pointer points to the lowest
10921debfc3dSmrg    address in the stack space, and thus may not be the value to which
10931debfc3dSmrg    to set the stack pointer.  */
10941debfc3dSmrg 
10951debfc3dSmrg void *
__splitstack_makecontext(size_t stack_size,void * context[NUMBER_OFFSETS],size_t * size)10961debfc3dSmrg __splitstack_makecontext (size_t stack_size, void *context[NUMBER_OFFSETS],
10971debfc3dSmrg 			  size_t *size)
10981debfc3dSmrg {
10991debfc3dSmrg   struct stack_segment *segment;
11001debfc3dSmrg   void *initial_sp;
11011debfc3dSmrg 
11021debfc3dSmrg   memset (context, 0, NUMBER_OFFSETS * sizeof (void *));
11031debfc3dSmrg   segment = allocate_segment (stack_size);
11041debfc3dSmrg   context[MORESTACK_SEGMENTS] = segment;
11051debfc3dSmrg   context[CURRENT_SEGMENT] = segment;
11061debfc3dSmrg #ifdef __LIBGCC_STACK_GROWS_DOWNWARD__
11071debfc3dSmrg   initial_sp = (void *) ((char *) (segment + 1) + segment->size);
11081debfc3dSmrg #else
11091debfc3dSmrg   initial_sp = (void *) (segment + 1);
11101debfc3dSmrg #endif
11111debfc3dSmrg   context[STACK_GUARD] = __morestack_make_guard (initial_sp, segment->size);
11121debfc3dSmrg   context[INITIAL_SP] = NULL;
11131debfc3dSmrg   context[INITIAL_SP_LEN] = 0;
11141debfc3dSmrg   *size = segment->size;
11151debfc3dSmrg   return (void *) (segment + 1);
11161debfc3dSmrg }
11171debfc3dSmrg 
11181debfc3dSmrg /* Given an existing split stack context, reset it back to the start
11191debfc3dSmrg    of the stack.  Return the stack pointer and size, appropriate for
11201debfc3dSmrg    use with makecontext.  This may be used if a coroutine exits, in
11211debfc3dSmrg    order to reuse the stack segments for a new coroutine.  */
11221debfc3dSmrg 
11231debfc3dSmrg void *
__splitstack_resetcontext(void * context[10],size_t * size)11241debfc3dSmrg __splitstack_resetcontext (void *context[10], size_t *size)
11251debfc3dSmrg {
11261debfc3dSmrg   struct stack_segment *segment;
11271debfc3dSmrg   void *initial_sp;
11281debfc3dSmrg   size_t initial_size;
11291debfc3dSmrg   void *ret;
11301debfc3dSmrg 
11311debfc3dSmrg   /* Reset the context assuming that MORESTACK_SEGMENTS, INITIAL_SP
11321debfc3dSmrg      and INITIAL_SP_LEN are correct.  */
11331debfc3dSmrg 
11341debfc3dSmrg   segment = context[MORESTACK_SEGMENTS];
11351debfc3dSmrg   context[CURRENT_SEGMENT] = segment;
11361debfc3dSmrg   context[CURRENT_STACK] = NULL;
11371debfc3dSmrg   if (segment == NULL)
11381debfc3dSmrg     {
11391debfc3dSmrg       initial_sp = context[INITIAL_SP];
11401debfc3dSmrg       initial_size = (uintptr_type) context[INITIAL_SP_LEN];
11411debfc3dSmrg       ret = initial_sp;
11421debfc3dSmrg #ifdef __LIBGCC_STACK_GROWS_DOWNWARD__
11431debfc3dSmrg       ret = (void *) ((char *) ret - initial_size);
11441debfc3dSmrg #endif
11451debfc3dSmrg     }
11461debfc3dSmrg   else
11471debfc3dSmrg     {
11481debfc3dSmrg #ifdef __LIBGCC_STACK_GROWS_DOWNWARD__
11491debfc3dSmrg       initial_sp = (void *) ((char *) (segment + 1) + segment->size);
11501debfc3dSmrg #else
11511debfc3dSmrg       initial_sp = (void *) (segment + 1);
11521debfc3dSmrg #endif
11531debfc3dSmrg       initial_size = segment->size;
11541debfc3dSmrg       ret = (void *) (segment + 1);
11551debfc3dSmrg     }
11561debfc3dSmrg   context[STACK_GUARD] = __morestack_make_guard (initial_sp, initial_size);
11571debfc3dSmrg   context[BLOCK_SIGNALS] = NULL;
11581debfc3dSmrg   *size = initial_size;
11591debfc3dSmrg   return ret;
11601debfc3dSmrg }
11611debfc3dSmrg 
11621debfc3dSmrg /* Release all the memory associated with a splitstack context.  This
11631debfc3dSmrg    may be used if a coroutine exits and the associated stack should be
11641debfc3dSmrg    freed.  */
11651debfc3dSmrg 
11661debfc3dSmrg void
__splitstack_releasecontext(void * context[10])11671debfc3dSmrg __splitstack_releasecontext (void *context[10])
11681debfc3dSmrg {
11691debfc3dSmrg   __morestack_release_segments (((struct stack_segment **)
11701debfc3dSmrg 				 &context[MORESTACK_SEGMENTS]),
11711debfc3dSmrg 				1);
11721debfc3dSmrg }
11731debfc3dSmrg 
11741debfc3dSmrg /* Like __splitstack_block_signals, but operating on CONTEXT, rather
11751debfc3dSmrg    than on the current state.  */
11761debfc3dSmrg 
11771debfc3dSmrg void
__splitstack_block_signals_context(void * context[NUMBER_OFFSETS],int * new,int * old)11781debfc3dSmrg __splitstack_block_signals_context (void *context[NUMBER_OFFSETS], int *new,
11791debfc3dSmrg 				    int *old)
11801debfc3dSmrg {
11811debfc3dSmrg   if (old != NULL)
11821debfc3dSmrg     *old = ((uintptr_type) context[BLOCK_SIGNALS]) != 0 ? 0 : 1;
11831debfc3dSmrg   if (new != NULL)
11841debfc3dSmrg     context[BLOCK_SIGNALS] = (void *) (uintptr_type) (*new ? 0 : 1);
11851debfc3dSmrg }
11861debfc3dSmrg 
11871debfc3dSmrg /* Find the stack segments associated with a split stack context.
11881debfc3dSmrg    This will return the address of the first stack segment and set
11891debfc3dSmrg    *STACK_SIZE to its size.  It will set next_segment, next_sp, and
11901debfc3dSmrg    initial_sp which may be passed to __splitstack_find to find the
11911debfc3dSmrg    remaining segments.  */
11921debfc3dSmrg 
11931debfc3dSmrg void *
__splitstack_find_context(void * context[NUMBER_OFFSETS],size_t * stack_size,void ** next_segment,void ** next_sp,void ** initial_sp)11941debfc3dSmrg __splitstack_find_context (void *context[NUMBER_OFFSETS], size_t *stack_size,
11951debfc3dSmrg 			   void **next_segment, void **next_sp,
11961debfc3dSmrg 			   void **initial_sp)
11971debfc3dSmrg {
11981debfc3dSmrg   void *sp;
11991debfc3dSmrg   struct stack_segment *segment;
12001debfc3dSmrg 
12011debfc3dSmrg   *initial_sp = context[INITIAL_SP];
12021debfc3dSmrg 
12031debfc3dSmrg   sp = context[CURRENT_STACK];
12041debfc3dSmrg   if (sp == NULL)
12051debfc3dSmrg     {
12061debfc3dSmrg       /* Most likely this context was created but was never used.  The
12071debfc3dSmrg 	 value 2 is a code used by __splitstack_find to mean that we
12081debfc3dSmrg 	 have reached the end of the list of stacks.  */
12091debfc3dSmrg       *next_segment = (void *) (uintptr_type) 2;
12101debfc3dSmrg       *next_sp = NULL;
12111debfc3dSmrg       *initial_sp = NULL;
12121debfc3dSmrg       return NULL;
12131debfc3dSmrg     }
12141debfc3dSmrg 
12151debfc3dSmrg   segment = context[CURRENT_SEGMENT];
12161debfc3dSmrg   if (segment == NULL)
12171debfc3dSmrg     {
12181debfc3dSmrg       /* Most likely this context was saved by a thread which was not
12191debfc3dSmrg 	 created using __splistack_makecontext and which has never
12201debfc3dSmrg 	 split the stack.  The value 1 is a code used by
12211debfc3dSmrg 	 __splitstack_find to look at the initial stack.  */
12221debfc3dSmrg       segment = (struct stack_segment *) (uintptr_type) 1;
12231debfc3dSmrg     }
12241debfc3dSmrg 
12251debfc3dSmrg   return __splitstack_find (segment, sp, stack_size, next_segment, next_sp,
12261debfc3dSmrg 			    initial_sp);
12271debfc3dSmrg }
12281debfc3dSmrg 
12291debfc3dSmrg #endif /* !defined (inhibit_libc) */
12301debfc3dSmrg #endif /* not powerpc 32-bit */
1231