diff options
Diffstat (limited to 'sysdeps/unix/sysv')
-rw-r--r-- | sysdeps/unix/sysv/linux/bits/sigstksz.h | 33 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h | 27 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sysconf-sigstksz.h | 38 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sysconf.c | 9 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h | 83 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h | 5 |
6 files changed, 195 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/bits/sigstksz.h b/sysdeps/unix/sysv/linux/bits/sigstksz.h new file mode 100644 index 0000000..926508f --- /dev/null +++ b/sysdeps/unix/sysv/linux/bits/sigstksz.h @@ -0,0 +1,33 @@ +/* Definition of MINSIGSTKSZ and SIGSTKSZ. Linux version. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#ifndef _SIGNAL_H +# error "Never include <bits/sigstksz.h> directly; use <signal.h> instead." +#endif + +#if defined __USE_SC_SIGSTKSZ && __USE_SC_SIGSTKSZ +# include <unistd.h> + +/* Default stack size for a signal handler: sysconf (SC_SIGSTKSZ). */ +# undef SIGSTKSZ +# define SIGSTKSZ sysconf (_SC_SIGSTKSZ) + +/* Minimum stack size for a signal handler: SIGSTKSZ. */ +# undef MINSIGSTKSZ +# define MINSIGSTKSZ SIGSTKSZ +#endif diff --git a/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h b/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h new file mode 100644 index 0000000..7e5ceba --- /dev/null +++ b/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h @@ -0,0 +1,27 @@ +/* sysconf_sigstksz (). Linux/ia64 version. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +/* Return sysconf (_SC_SIGSTKSZ). */ + +static long int +sysconf_sigstksz (void) +{ + _Static_assert (__builtin_constant_p (SIGSTKSZ), + "SIGSTKSZ is constant"); + return SIGSTKSZ; +} diff --git a/sysdeps/unix/sysv/linux/sysconf-sigstksz.h b/sysdeps/unix/sysv/linux/sysconf-sigstksz.h new file mode 100644 index 0000000..64d450b --- /dev/null +++ b/sysdeps/unix/sysv/linux/sysconf-sigstksz.h @@ -0,0 +1,38 @@ +/* sysconf_sigstksz (). Linux version. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +/* Return sysconf (_SC_SIGSTKSZ). */ + +static long int +sysconf_sigstksz (void) +{ + long int minsigstacksize = GLRO(dl_minsigstacksize); + assert (minsigstacksize != 0); + _Static_assert (__builtin_constant_p (MINSIGSTKSZ), + "MINSIGSTKSZ is constant"); + if (minsigstacksize < MINSIGSTKSZ) + minsigstacksize = MINSIGSTKSZ; + /* MAX (MINSIGSTKSZ, sysconf (_SC_MINSIGSTKSZ)) * 4. */ + long int sigstacksize = minsigstacksize * 4; + /* Return MAX (SIGSTKSZ, sigstacksize). */ + _Static_assert (__builtin_constant_p (SIGSTKSZ), + "SIGSTKSZ is constant"); + if (sigstacksize < SIGSTKSZ) + sigstacksize = SIGSTKSZ; + return sigstacksize; +} diff --git a/sysdeps/unix/sysv/linux/sysconf.c b/sysdeps/unix/sysv/linux/sysconf.c index bfad5b6..366fcef 100644 --- a/sysdeps/unix/sysv/linux/sysconf.c +++ b/sysdeps/unix/sysv/linux/sysconf.c @@ -16,6 +16,7 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ +#include <assert.h> #include <errno.h> #include <fcntl.h> #include <stdlib.h> @@ -26,6 +27,7 @@ #include <sys/param.h> #include <not-cancel.h> #include <ldsodefs.h> +#include <sysconf-sigstksz.h> /* Legacy value of ARG_MAX. The macro is now not defined since the actual value varies based on the stack size. */ @@ -75,6 +77,13 @@ __sysconf (int name) } break; + case _SC_MINSIGSTKSZ: + assert (GLRO(dl_minsigstacksize) != 0); + return GLRO(dl_minsigstacksize); + + case _SC_SIGSTKSZ: + return sysconf_sigstksz (); + default: break; } diff --git a/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h b/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h new file mode 100644 index 0000000..6088bbc --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h @@ -0,0 +1,83 @@ +/* Emulate AT_MINSIGSTKSZ. Linux/x86 version. + Copyright (C) 2020 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +/* Emulate AT_MINSIGSTKSZ with XSAVE. */ + +static inline void +dl_check_minsigstacksize (const struct cpu_features *cpu_features) +{ + /* Return if AT_MINSIGSTKSZ is provide by kernel. */ + if (GLRO(dl_minsigstacksize) != 0) + return; + + if (cpu_features->basic.max_cpuid >= 0xd + && CPU_FEATURES_CPU_P (cpu_features, OSXSAVE)) + { + /* Emulate AT_MINSIGSTKSZ. In Linux kernel, the signal frame data + with XSAVE is composed of the following areas and laid out as: + ------------------------------ + | alignment padding | + ------------------------------ + | xsave buffer | + ------------------------------ + | fsave header (32-bit only) | + ------------------------------ + | siginfo + ucontext | + ------------------------------ + */ + + unsigned int sigframe_size; + +#ifdef __x86_64__ + /* NB: sizeof(struct rt_sigframe) + 8-byte return address in Linux + kernel. */ + sigframe_size = 440 + 8; +#else + /* NB: sizeof(struct sigframe_ia32) + sizeof(struct fregs_state)) + + 4-byte return address + 3 * 4-byte arguments in Linux kernel. */ + sigframe_size = 736 + 112 + 4 + 3 * 4; +#endif + + /* Add 15 bytes to align the stack to 16 bytes. */ + sigframe_size += 15; + + /* Make the space before xsave buffer multiple of 16 bytes. */ + sigframe_size = ALIGN_UP (sigframe_size, 16); + + /* Add (64 - 16)-byte padding to align xsave buffer at 64 bytes. */ + sigframe_size += 64 - 16; + + unsigned int eax, ebx, ecx, edx; + __cpuid_count (0xd, 0, eax, ebx, ecx, edx); + + /* Add the size of xsave buffer. */ + sigframe_size += ebx; + + /* Add the size of FP_XSTATE_MAGIC2. */ +#define FP_XSTATE_MAGIC2 0x46505845U + sigframe_size += sizeof (FP_XSTATE_MAGIC2); + + GLRO(dl_minsigstacksize) = sigframe_size; + } + else + { + /* NB: Default to a constant MINSIGSTKSZ. */ + _Static_assert (__builtin_constant_p (MINSIGSTKSZ), + "MINSIGSTKSZ is constant"); + GLRO(dl_minsigstacksize) = MINSIGSTKSZ; + } +} diff --git a/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h b/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h new file mode 100644 index 0000000..208754c --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h @@ -0,0 +1,5 @@ +#include_next <bits/sigstack.h> + +#ifndef _ISOMAC +# define CONSTANT_MINSIGSTKSZ 0 +#endif |