summaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2018-12-27 19:54:31 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2018-12-27 19:54:31 +0000
commitc7b0250b3ac83f638de22e3428c56b95933c7740 (patch)
treeac5aee9a1580445002ef01e6859375a8c679d282 /sysdeps
parent9a47d57c4784163dcf838c7461c53de29ca7a61f (diff)
parent3fcbb67b7949a8b362de5558bf1c6dd7ec5d21cf (diff)
Merge branch 't/tls-threadvar' into refs/top-bases/tschwinge/Roger_Whittaker
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/mach/hurd/i386/Makefile1
-rw-r--r--sysdeps/mach/hurd/i386/makecontext-helper.c69
-rw-r--r--sysdeps/mach/hurd/i386/makecontext.S8
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