diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2018-12-27 19:54:31 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2018-12-27 19:54:31 +0000 |
commit | c7b0250b3ac83f638de22e3428c56b95933c7740 (patch) | |
tree | ac5aee9a1580445002ef01e6859375a8c679d282 /sysdeps | |
parent | 9a47d57c4784163dcf838c7461c53de29ca7a61f (diff) | |
parent | 3fcbb67b7949a8b362de5558bf1c6dd7ec5d21cf (diff) |
Merge branch 't/tls-threadvar' into refs/top-bases/tschwinge/Roger_Whittaker
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/mach/hurd/i386/Makefile | 1 | ||||
-rw-r--r-- | sysdeps/mach/hurd/i386/makecontext-helper.c | 69 | ||||
-rw-r--r-- | sysdeps/mach/hurd/i386/makecontext.S | 8 |
3 files changed, 78 insertions, 0 deletions
diff --git a/sysdeps/mach/hurd/i386/Makefile b/sysdeps/mach/hurd/i386/Makefile index bebadd087a..1a53065ae7 100644 --- a/sysdeps/mach/hurd/i386/Makefile +++ b/sysdeps/mach/hurd/i386/Makefile @@ -9,6 +9,7 @@ endif ifeq ($(subdir),stdlib) gen-as-const-headers += ucontext_i.sym +sysdep_routines += makecontext-helper endif ifeq ($(subdir),csu) diff --git a/sysdeps/mach/hurd/i386/makecontext-helper.c b/sysdeps/mach/hurd/i386/makecontext-helper.c new file mode 100644 index 0000000000..6db3b7e018 --- /dev/null +++ b/sysdeps/mach/hurd/i386/makecontext-helper.c @@ -0,0 +1,69 @@ +/* Helper for makecontext: handle threadvars. + Copyright (C) 2013 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 + <http://www.gnu.org/licenses/>. */ + +#include <hurd/threadvar.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ucontext.h> + + +void +__makecontext_helper (ucontext_t *ucp) +{ + if (__hurd_threadvar_stack_mask == 0) + { + /* We are not using threads, so per init-first.c:init, the threadvars + live in a malloced space, addressed relative to the base of the + virtual address space. Just keep using that one. */ + } + else + { + /* The following is only prepared to work with libpthread, which only + keeps the threadvars at the bottom of the stack -- contrary to + libthreads, which also puts additional data there. */ + + void *s = ucp->uc_stack.ss_sp; + size_t s_size = ucp->uc_stack.ss_size; + + /* Is the new stack suitable? Check that that the last threadvar + occupies the last storage unit within the bounds of the new stack. + Alignment according to (sp & __hurd_threadvar_stack_mask) == sp is not + actually a requirement (though, in practice it often will be). */ + if (__hurd_threadvar_location_from_sp (_HURD_THREADVAR_MAX, s) + != s + s_size) + { + /* Instead of having makecontext return an error, we bail out the + hard way, as we can't expect its caller to be able to properly + react to this situation. */ + fprintf (stderr, + "*** makecontext: a stack at %p with size %#x is not " + "usable with threadvars\n", + s, s_size); + abort (); + } + + /* Copy the threadvars to the new stack. */ + void *t_old = __hurd_threadvar_location (0); + void *t_new = __hurd_threadvar_location_from_sp (0, s); + size_t t_size = __hurd_threadvar_max * sizeof (unsigned long int); + memcpy (t_new, t_old, t_size); + /* Account for the space taken by the threadvars. */ + ucp->uc_stack.ss_size -= t_size; + } +} diff --git a/sysdeps/mach/hurd/i386/makecontext.S b/sysdeps/mach/hurd/i386/makecontext.S index 8364fb98ee..072741a007 100644 --- a/sysdeps/mach/hurd/i386/makecontext.S +++ b/sysdeps/mach/hurd/i386/makecontext.S @@ -24,6 +24,14 @@ ENTRY(__makecontext) movl 4(%esp), %eax + subl $4, %esp + cfi_adjust_cfa_offset (4) + movl %eax, (%esp) + call HIDDEN_JUMPTARGET (__makecontext_helper) + addl $4, %esp + cfi_adjust_cfa_offset (-4) + + movl 4(%esp), %eax /* Load the address of the function we are supposed to run. */ movl 8(%esp), %ecx |