diff options
Diffstat (limited to 'main/libc0.9.32/0001-libc-add-get-set-swap-make-context-user-context-mani.patch')
-rw-r--r-- | main/libc0.9.32/0001-libc-add-get-set-swap-make-context-user-context-mani.patch | 2550 |
1 files changed, 0 insertions, 2550 deletions
diff --git a/main/libc0.9.32/0001-libc-add-get-set-swap-make-context-user-context-mani.patch b/main/libc0.9.32/0001-libc-add-get-set-swap-make-context-user-context-mani.patch deleted file mode 100644 index 98bb707b01..0000000000 --- a/main/libc0.9.32/0001-libc-add-get-set-swap-make-context-user-context-mani.patch +++ /dev/null @@ -1,2550 +0,0 @@ -From a8dc90eaaa5e6474beac828558d969b1aafee4af Mon Sep 17 00:00:00 2001 -From: Florian Fainelli <florian@openwrt.org> -Date: Wed, 9 Jan 2013 16:17:21 +0100 -Subject: [PATCH] libc: add {get,set,swap,make}context user context - manipulation functions - -Add the obsolescent SUSv3 family of user context manipulating functions -for arm, i386, mips, x86_64. - -Signed-off-by: Timon ter Braak <timonterbraak@gmail.com> -Signed-off-by: Florian Fainelli <florian@openwrt.org> -Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> -Signed-off-by: Natanael Copa <ncopa@alpinelinux.org> -Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> ---- - Rules.mak | 2 + - extra/Configs/Config.arm | 1 + - extra/Configs/Config.i386 | 1 + - extra/Configs/Config.in | 16 ++ - extra/Configs/Config.mips | 1 + - extra/Configs/Config.x86_64 | 1 + - include/ucontext.h | 32 +++- - libc/.gitignore | 1 + - libc/sysdeps/linux/Makefile.commonarch | 20 +- - libc/sysdeps/linux/arm/Makefile.arch | 5 + - libc/sysdeps/linux/arm/getcontext.S | 80 ++++++++ - libc/sysdeps/linux/arm/makecontext.c | 73 +++++++ - libc/sysdeps/linux/arm/setcontext.S | 76 ++++++++ - libc/sysdeps/linux/arm/swapcontext.S | 63 ++++++ - libc/sysdeps/linux/arm/ucontext_i.sym | 30 +++ - libc/sysdeps/linux/i386/Makefile.arch | 4 + - libc/sysdeps/linux/i386/getcontext.S | 84 ++++++++ - libc/sysdeps/linux/i386/makecontext.S | 123 ++++++++++++ - libc/sysdeps/linux/i386/setcontext.S | 96 ++++++++++ - libc/sysdeps/linux/i386/swapcontext.S | 110 +++++++++++ - libc/sysdeps/linux/i386/ucontext_i.sym | 30 +++ - libc/sysdeps/linux/mips/Makefile.arch | 4 + - libc/sysdeps/linux/mips/getcontext.S | 148 +++++++++++++++ - libc/sysdeps/linux/mips/kernel_rt_sigframe.h | 10 + - libc/sysdeps/linux/mips/makecontext.S | 188 ++++++++++++++++++ - libc/sysdeps/linux/mips/setcontext.S | 191 +++++++++++++++++++ - libc/sysdeps/linux/mips/swapcontext.S | 211 +++++++++++++++++++++ - libc/sysdeps/linux/mips/ucontext_i.sym | 52 +++++ - libc/sysdeps/linux/x86_64/Makefile.arch | 5 + - libc/sysdeps/linux/x86_64/__start_context.S | 49 +++++ - libc/sysdeps/linux/x86_64/getcontext.S | 88 +++++++++ - libc/sysdeps/linux/x86_64/makecontext.c | 121 ++++++++++++ - libc/sysdeps/linux/x86_64/setcontext.S | 103 ++++++++++ - libc/sysdeps/linux/x86_64/swapcontext.S | 121 ++++++++++++ - libc/sysdeps/linux/x86_64/ucontext_i.sym | 37 ++++ - libpthread/nptl/sysdeps/Makefile.commonarch | 3 +- - .../sysdeps/unix/sysv/linux/Makefile.commonarch | 2 - - 37 files changed, 2174 insertions(+), 8 deletions(-) - create mode 100644 libc/.gitignore - create mode 100644 libc/sysdeps/linux/arm/getcontext.S - create mode 100644 libc/sysdeps/linux/arm/makecontext.c - create mode 100644 libc/sysdeps/linux/arm/setcontext.S - create mode 100644 libc/sysdeps/linux/arm/swapcontext.S - create mode 100644 libc/sysdeps/linux/arm/ucontext_i.sym - create mode 100644 libc/sysdeps/linux/i386/getcontext.S - create mode 100644 libc/sysdeps/linux/i386/makecontext.S - create mode 100644 libc/sysdeps/linux/i386/setcontext.S - create mode 100644 libc/sysdeps/linux/i386/swapcontext.S - create mode 100644 libc/sysdeps/linux/i386/ucontext_i.sym - create mode 100644 libc/sysdeps/linux/mips/getcontext.S - create mode 100644 libc/sysdeps/linux/mips/kernel_rt_sigframe.h - create mode 100644 libc/sysdeps/linux/mips/makecontext.S - create mode 100644 libc/sysdeps/linux/mips/setcontext.S - create mode 100644 libc/sysdeps/linux/mips/swapcontext.S - create mode 100644 libc/sysdeps/linux/mips/ucontext_i.sym - create mode 100644 libc/sysdeps/linux/x86_64/__start_context.S - create mode 100644 libc/sysdeps/linux/x86_64/getcontext.S - create mode 100644 libc/sysdeps/linux/x86_64/makecontext.c - create mode 100644 libc/sysdeps/linux/x86_64/setcontext.S - create mode 100644 libc/sysdeps/linux/x86_64/swapcontext.S - create mode 100644 libc/sysdeps/linux/x86_64/ucontext_i.sym - -diff --git a/Rules.mak b/Rules.mak -index 96871e1..8943fbf 100644 ---- a/Rules.mak -+++ b/Rules.mak -@@ -813,3 +813,5 @@ SHARED_END_FILES:=$(LIBGCC_DIR)crtendS.o $(top_builddir)lib/crtn.o - endif - - LOCAL_INSTALL_PATH := install_dir -+ -+PTHREAD_GENERATE_MANGLE ?= -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*\$$/\#define \1 \2/p" -diff --git a/extra/Configs/Config.arm b/extra/Configs/Config.arm -index 0bb2971..dc53643 100644 ---- a/extra/Configs/Config.arm -+++ b/extra/Configs/Config.arm -@@ -11,6 +11,7 @@ config FORCE_OPTIONS_FOR_ARCH - bool - default y - select ARCH_ANY_ENDIAN -+ select ARCH_HAS_UCONTEXT - - config CONFIG_ARM_EABI - bool "Build for EABI" -diff --git a/extra/Configs/Config.i386 b/extra/Configs/Config.i386 -index 288aa5e..92cee3b 100644 ---- a/extra/Configs/Config.i386 -+++ b/extra/Configs/Config.i386 -@@ -12,6 +12,7 @@ config FORCE_OPTIONS_FOR_ARCH - default y - select ARCH_LITTLE_ENDIAN - select ARCH_HAS_MMU -+ select ARCH_HAS_UCONTEXT - - choice - prompt "Target x86 Processor Family" -diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in -index 4bb6812..62bcd9b 100644 ---- a/extra/Configs/Config.in -+++ b/extra/Configs/Config.in -@@ -261,6 +261,9 @@ config ARCH_HAS_NO_LDSO - bool - select ARCH_HAS_NO_SHARED - -+config ARCH_HAS_UCONTEXT -+ bool -+ - config HAVE_SHARED - bool "Enable shared libraries" - depends on !ARCH_HAS_NO_SHARED -@@ -678,6 +681,19 @@ config UCLIBC_SUSV3_LEGACY - - WARNING! ABI incompatibility. - -+config UCLIBC_HAS_CONTEXT_FUNCS -+ bool "Use obsolescent context control functions" -+ depends on UCLIBC_SUSV3_LEGACY && ARCH_HAS_UCONTEXT -+ help -+ Add into library the SuSv3 obsolescent functions used for context -+ control. The setcontext family allows the implementation in C of -+ advanced control flow patterns such as iterators, fibers, and -+ coroutines. They may be viewed as an advanced version of -+ setjmp/longjmp; whereas the latter allows only a single non-local jump -+ up the stack, setcontext allows the creation of multiple cooperative -+ threads of control, each with its own stack. -+ These functions are: setcontext, getcontext, makecontext, swapcontext. -+ - config UCLIBC_SUSV3_LEGACY_MACROS - bool "Enable SuSv3 LEGACY macros" - help -diff --git a/extra/Configs/Config.mips b/extra/Configs/Config.mips -index 063b07c..48e0b64 100644 ---- a/extra/Configs/Config.mips -+++ b/extra/Configs/Config.mips -@@ -11,6 +11,7 @@ config FORCE_OPTIONS_FOR_ARCH - bool - default y - select ARCH_ANY_ENDIAN -+ select ARCH_HAS_UCONTEXT - - choice - prompt "Target ABI" -diff --git a/extra/Configs/Config.x86_64 b/extra/Configs/Config.x86_64 -index 1b28088..4c8c3a9 100644 ---- a/extra/Configs/Config.x86_64 -+++ b/extra/Configs/Config.x86_64 -@@ -12,3 +12,4 @@ config FORCE_OPTIONS_FOR_ARCH - default y - select ARCH_LITTLE_ENDIAN - select ARCH_HAS_MMU -+ select ARCH_HAS_UCONTEXT -diff --git a/include/ucontext.h b/include/ucontext.h -index 14a1270..f11db77 100644 ---- a/include/ucontext.h -+++ b/include/ucontext.h -@@ -15,17 +15,43 @@ - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -+/* The System V ABI user-level context switching support functions -+ are marked obsolescent by SuSv3. */ -+ - #ifndef _UCONTEXT_H - #define _UCONTEXT_H 1 - - #include <features.h> - -+#ifdef __UCLIBC_HAS_CONTEXT_FUNCS__ -+ - /* Get machine dependent definition of data structures. */ - #include <sys/ucontext.h> - --/* The System V ABI user-level context switching support functions -- * are marked obsolescent by SuSv3, and are not implemented by -- * uClibc. This header is therefore empty. */ -+__BEGIN_DECLS -+ -+/* Get user context and store it in variable pointed to by UCP. */ -+extern int getcontext (ucontext_t *__ucp) __THROW; -+ -+/* Set user context from information of variable pointed to by UCP. */ -+extern int setcontext (const ucontext_t *__ucp) __THROW; -+ -+/* Save current context in context variable pointed to by OUCP and set -+ context from variable pointed to by UCP. */ -+extern int swapcontext (ucontext_t *__restrict __oucp, -+ const ucontext_t *__restrict __ucp) __THROW; -+ -+/* Manipulate user context UCP to continue with calling functions FUNC -+ and the ARGC-1 parameters following ARGC when the context is used -+ the next time in `setcontext' or `swapcontext'. -+ -+ We cannot say anything about the parameters FUNC takes; `void' -+ is as good as any other choice. */ -+extern void makecontext (ucontext_t *__ucp, void (*__func) (void), -+ int __argc, ...) __THROW; -+ -+__END_DECLS - -+#endif - - #endif /* ucontext.h */ -diff --git a/libc/.gitignore b/libc/.gitignore -new file mode 100644 -index 0000000..f4c0305 ---- /dev/null -+++ b/libc/.gitignore -@@ -0,0 +1 @@ -+ucontext_i.[chs] -diff --git a/libc/sysdeps/linux/Makefile.commonarch b/libc/sysdeps/linux/Makefile.commonarch -index c1bc5df..ac89e72 100644 ---- a/libc/sysdeps/linux/Makefile.commonarch -+++ b/libc/sysdeps/linux/Makefile.commonarch -@@ -37,5 +37,23 @@ headers-y += $(ARCH_HEADERS_OUT) - headers_clean-y += HEADERCLEAN_$(subst $(top_builddir),,$(ARCH_OUT)) - HEADERCLEAN_$(subst $(top_builddir),,$(ARCH_OUT)): - $(do_rm) $(ARCH_HEADERS_OUT) -- - endif -+ -+CFLAGS-ucontext_i.c = -S -+ -+$(ARCH_OUT)/ucontext_i.c: $(ARCH_DIR)/ucontext_i.sym -+ $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@ -+ -+$(ARCH_OUT)/ucontext_i.s: $(ARCH_OUT)/ucontext_i.c -+ $(compile.c) -+ -+$(ARCH_OUT)/ucontext_i.h: $(ARCH_OUT)/ucontext_i.s -+ $(do_sed) $(PTHREAD_GENERATE_MANGLE) $< > $@ -+ -+pregen-headers-$(UCLIBC_HAS_CONTEXT_FUNCS) += $(ARCH_OUT)/ucontext_i.h -+ -+headers_clean-$(UCLIBC_HAS_CONTEXT_FUNCS) += \ -+ HEADERCLEAN_$(subst $(top_builddir),,$(ARCH_OUT)/ucontext_i) -+ -+HEADERCLEAN_$(subst $(top_builddir),,$(ARCH_OUT)/ucontext_i): -+ $(do_rm) $(addprefix $(ARCH_OUT)/ucontext_i., c h s) -diff --git a/libc/sysdeps/linux/arm/Makefile.arch b/libc/sysdeps/linux/arm/Makefile.arch -index 5fc3e54..36d988b 100644 ---- a/libc/sysdeps/linux/arm/Makefile.arch -+++ b/libc/sysdeps/linux/arm/Makefile.arch -@@ -43,3 +43,8 @@ libc-static-y += $(ARCH_OUT)/aeabi_lcsts.o $(ARCH_OUT)/aeabi_math.o \ - libc-nonshared-y += $(ARCH_OUT)/aeabi_lcsts.os $(ARCH_OUT)/aeabi_math.os \ - $(ARCH_OUT)/aeabi_sighandlers.os $(ARCH_OUT)/aeabi_unwind_cpp_pr1.o - endif -+ -+ifeq ($(UCLIBC_HAS_CONTEXT_FUNCS),y) -+CSRC += makecontext.c -+SSRC += getcontext.S setcontext.S swapcontext.S -+endif -diff --git a/libc/sysdeps/linux/arm/getcontext.S b/libc/sysdeps/linux/arm/getcontext.S -new file mode 100644 -index 0000000..a987c52 ---- /dev/null -+++ b/libc/sysdeps/linux/arm/getcontext.S -@@ -0,0 +1,80 @@ -+/* Copyright (C) 2012 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 <sysdep.h> -+ -+#include "ucontext_i.h" -+ -+ .syntax unified -+ .text -+ -+/* int getcontext (ucontext_t *ucp) */ -+ -+ENTRY(__getcontext) -+ /* No need to save r0-r3, d0-d7, or d16-d31. */ -+ add r1, r0, #MCONTEXT_ARM_R4 -+ stmia r1, {r4-r11} -+ -+ /* Save R13 separately as Thumb can't STM it. */ -+ str r13, [r0, #MCONTEXT_ARM_SP] -+ str r14, [r0, #MCONTEXT_ARM_LR] -+ /* Return to LR */ -+ str r14, [r0, #MCONTEXT_ARM_PC] -+ /* Return zero */ -+ mov r2, #0 -+ str r2, [r0, #MCONTEXT_ARM_R0] -+ -+ /* Save ucontext_t * across the next call. */ -+ mov r4, r0 -+ -+ /* __sigprocmask(SIG_BLOCK, NULL, &(ucontext->uc_sigmask)) */ -+ mov r0, #SIG_BLOCK -+ mov r1, #0 -+ add r2, r4, #UCONTEXT_SIGMASK -+ bl PLTJMP(sigprocmask) -+ -+#if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__ -+# ifdef __VFP_FP__ -+ /* Store the VFP registers. */ -+ /* Following instruction is fstmiax ip!, {d8-d15}. */ -+ stc p11, cr8, [r0], #64 -+ /* Store the floating-point status register. */ -+ /* Following instruction is fmrx r2, fpscr. */ -+ mrc p10, 7, r1, cr1, cr0, 0 -+ str r1, [r0], #4 -+# endif -+#endif -+#ifdef __IWMMXT__ -+ /* Save the call-preserved iWMMXt registers. */ -+ /* Following instructions are wstrd wr10, [r0], #8 (etc.) */ -+ stcl p1, cr10, [r0], #8 -+ stcl p1, cr11, [r0], #8 -+ stcl p1, cr12, [r0], #8 -+ stcl p1, cr13, [r0], #8 -+ stcl p1, cr14, [r0], #8 -+ stcl p1, cr15, [r0], #8 -+#endif -+ -+ /* Restore the clobbered R4 and LR. */ -+ ldr r14, [r4, #MCONTEXT_ARM_LR] -+ ldr r4, [r4, #MCONTEXT_ARM_R4] -+ -+ mov r0, #0 -+ DO_RET(r14) -+ -+END(__getcontext) -+weak_alias(__getcontext, getcontext) -diff --git a/libc/sysdeps/linux/arm/makecontext.c b/libc/sysdeps/linux/arm/makecontext.c -new file mode 100644 -index 0000000..d6ae6f0 ---- /dev/null -+++ b/libc/sysdeps/linux/arm/makecontext.c -@@ -0,0 +1,73 @@ -+/* Copyright (C) 2012 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 <stdarg.h> -+#include <ucontext.h> -+ -+/* Number of arguments that go in registers. */ -+#define NREG_ARGS 4 -+ -+/* Take a context previously prepared via getcontext() and set to -+ call func() with the given int only args. */ -+void -+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) -+{ -+ extern void __startcontext (void); -+ unsigned long *funcstack; -+ va_list vl; -+ unsigned long *regptr; -+ unsigned int reg; -+ int misaligned; -+ -+ /* Start at the top of stack. */ -+ funcstack = (unsigned long *) (ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); -+ -+ /* Ensure the stack stays eight byte aligned. */ -+ misaligned = ((unsigned long) funcstack & 4) != 0; -+ -+ if ((argc > NREG_ARGS) && (argc & 1) != 0) -+ misaligned = !misaligned; -+ -+ if (misaligned) -+ funcstack -= 1; -+ -+ va_start (vl, argc); -+ -+ /* Reserve space for the on-stack arguments. */ -+ if (argc > NREG_ARGS) -+ funcstack -= (argc - NREG_ARGS); -+ -+ ucp->uc_mcontext.arm_sp = (unsigned long) funcstack; -+ ucp->uc_mcontext.arm_pc = (unsigned long) func; -+ -+ /* Exit to startcontext() with the next context in R4 */ -+ ucp->uc_mcontext.arm_r4 = (unsigned long) ucp->uc_link; -+ ucp->uc_mcontext.arm_lr = (unsigned long) __startcontext; -+ -+ /* The first four arguments go into registers. */ -+ regptr = &(ucp->uc_mcontext.arm_r0); -+ -+ for (reg = 0; (reg < argc) && (reg < NREG_ARGS); reg++) -+ *regptr++ = va_arg (vl, unsigned long); -+ -+ /* And the remainder on the stack. */ -+ for (; reg < argc; reg++) -+ *funcstack++ = va_arg (vl, unsigned long); -+ -+ va_end (vl); -+} -+weak_alias (__makecontext, makecontext) -diff --git a/libc/sysdeps/linux/arm/setcontext.S b/libc/sysdeps/linux/arm/setcontext.S -new file mode 100644 -index 0000000..a5c33a0 ---- /dev/null -+++ b/libc/sysdeps/linux/arm/setcontext.S -@@ -0,0 +1,76 @@ -+/* Copyright (C) 2012 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 <sysdep.h> -+ -+#include "ucontext_i.h" -+ -+ .syntax unified -+ .text -+ -+/* int setcontext (const ucontext_t *ucp) */ -+ -+ENTRY(__setcontext) -+ mov r4, r0 -+ -+#if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__ -+# ifdef __VFP_FP__ -+ /* Following instruction is vldmia r0!, {d8-d15}. */ -+ ldc p11, cr8, [r0], #64 -+ /* Restore the floating-point status register. */ -+ ldr r1, [r0], #4 -+ /* Following instruction is fmxr fpscr, r1. */ -+ mcr p10, 7, r1, cr1, cr0, 0 -+# endif -+#endif -+ -+#ifdef __IWMMXT__ -+ /* Restore the call-preserved iWMMXt registers. */ -+ /* Following instructions are wldrd wr10, [r0], #8 (etc.) */ -+ ldcl p1, cr10, [r0], #8 -+ ldcl p1, cr11, [r0], #8 -+ ldcl p1, cr12, [r0], #8 -+ ldcl p1, cr13, [r0], #8 -+ ldcl p1, cr14, [r0], #8 -+ ldcl p1, cr15, [r0], #8 -+#endif -+ -+ /* Now bring back the signal status. */ -+ mov r0, #SIG_SETMASK -+ add r1, r4, #UCONTEXT_SIGMASK -+ mov r2, #0 -+ bl PLTJMP(sigprocmask) -+ -+ /* Loading r0-r3 makes makecontext easier. */ -+ add r14, r4, #MCONTEXT_ARM_R0 -+ ldmia r14, {r0-r11} -+ ldr r13, [r14, #(MCONTEXT_ARM_SP - MCONTEXT_ARM_R0)] -+ add r14, r14, #(MCONTEXT_ARM_LR - MCONTEXT_ARM_R0) -+ ldmia r14, {r14, pc} -+ -+END(setcontext) -+weak_alias(__setcontext, setcontext) -+ -+ /* Called when a makecontext() context returns. Start the -+ context in R4 or fall through to exit(). */ -+ENTRY(__startcontext) -+ movs r0, r4 -+ bne PLTJMP(__setcontext) -+ -+ @ New context was 0 - exit -+ b PLTJMP(_exit) -+END(__startcontext) -diff --git a/libc/sysdeps/linux/arm/swapcontext.S b/libc/sysdeps/linux/arm/swapcontext.S -new file mode 100644 -index 0000000..ba6e31c ---- /dev/null -+++ b/libc/sysdeps/linux/arm/swapcontext.S -@@ -0,0 +1,63 @@ -+/* Copyright (C) 2012 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 <sysdep.h> -+ -+#include "ucontext_i.h" -+ -+ .syntax unified -+ .text -+ -+/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */ -+ -+ENTRY(swapcontext) -+ -+ /* Have getcontext() do most of the work then fix up -+ LR afterwards. Save R3 to keep the stack aligned. */ -+ push {r0,r1,r3,r14} -+ cfi_adjust_cfa_offset (16) -+ cfi_rel_offset (r0,0) -+ cfi_rel_offset (r1,4) -+ cfi_rel_offset (r3,8) -+ cfi_rel_offset (r14,12) -+ -+ bl __getcontext -+ mov r4, r0 -+ -+ pop {r0,r1,r3,r14} -+ cfi_adjust_cfa_offset (-16) -+ cfi_restore (r0) -+ cfi_restore (r1) -+ cfi_restore (r3) -+ cfi_restore (r14) -+ -+ /* Exit if getcontext() failed. */ -+ cmp r4, #0 -+ itt ne -+ movne r0, r4 -+ RETINSTR(ne, r14) -+ -+ /* Fix up LR and the PC. */ -+ str r13,[r0, #MCONTEXT_ARM_SP] -+ str r14,[r0, #MCONTEXT_ARM_LR] -+ str r14,[r0, #MCONTEXT_ARM_PC] -+ -+ /* And swap using swapcontext(). */ -+ mov r0, r1 -+ b __setcontext -+ -+END(swapcontext) -diff --git a/libc/sysdeps/linux/arm/ucontext_i.sym b/libc/sysdeps/linux/arm/ucontext_i.sym -new file mode 100644 -index 0000000..9650322 ---- /dev/null -+++ b/libc/sysdeps/linux/arm/ucontext_i.sym -@@ -0,0 +1,30 @@ -+#include <inttypes.h> -+#include <signal.h> -+#include <stddef.h> -+#include <sys/ucontext.h> -+ -+SIG_BLOCK -+SIG_SETMASK -+ -+-- Offsets of the fields in the ucontext_t structure. -+#define ucontext(member) offsetof (ucontext_t, member) -+#define mcontext(member) ucontext (uc_mcontext.member) -+ -+UCONTEXT_FLAGS ucontext (uc_flags) -+UCONTEXT_LINK ucontext (uc_link) -+UCONTEXT_STACK ucontext (uc_stack) -+UCONTEXT_MCONTEXT ucontext (uc_mcontext) -+UCONTEXT_SIGMASK ucontext (uc_sigmask) -+ -+UCONTEXT_REGSPACE ucontext (uc_regspace) -+ -+MCONTEXT_TRAP_NO mcontext (trap_no) -+MCONTEXT_ERROR_CODE mcontext (error_code) -+MCONTEXT_OLDMASK mcontext (oldmask) -+MCONTEXT_ARM_R0 mcontext (arm_r0) -+MCONTEXT_ARM_R4 mcontext (arm_r4) -+MCONTEXT_ARM_SP mcontext (arm_sp) -+MCONTEXT_ARM_LR mcontext (arm_lr) -+MCONTEXT_ARM_PC mcontext (arm_pc) -+MCONTEXT_ARM_CPSR mcontext (arm_cpsr) -+MCONTEXT_FAULT_ADDRESS mcontext (fault_address) -diff --git a/libc/sysdeps/linux/i386/Makefile.arch b/libc/sysdeps/linux/i386/Makefile.arch -index a3bf32f..e7fd28e 100644 ---- a/libc/sysdeps/linux/i386/Makefile.arch -+++ b/libc/sysdeps/linux/i386/Makefile.arch -@@ -18,3 +18,7 @@ endif - ifneq ($(UCLIBC_HAS_THREADS_NATIVE),y) - SSRC += vfork.S clone.S - endif -+ -+ifeq ($(UCLIBC_HAS_CONTEXT_FUNCS),y) -+SSRC += makecontext.S setcontext.S getcontext.S swapcontext.S -+endif -diff --git a/libc/sysdeps/linux/i386/getcontext.S b/libc/sysdeps/linux/i386/getcontext.S -new file mode 100644 -index 0000000..3221b59 ---- /dev/null -+++ b/libc/sysdeps/linux/i386/getcontext.S -@@ -0,0 +1,84 @@ -+/* Save current context. -+ Copyright (C) 2001-2012 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2001. -+ -+ 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 <sysdep.h> -+ -+#include "ucontext_i.h" -+ -+ -+ENTRY(__getcontext) -+ /* Load address of the context data structure. */ -+ movl 4(%esp), %eax -+ -+ /* Return value of getcontext. EAX is the only register whose -+ value is not preserved. */ -+ movl $0, oEAX(%eax) -+ -+ /* Save the 32-bit register values and the return address. */ -+ movl %ecx, oECX(%eax) -+ movl %edx, oEDX(%eax) -+ movl %edi, oEDI(%eax) -+ movl %esi, oESI(%eax) -+ movl %ebp, oEBP(%eax) -+ movl (%esp), %ecx -+ movl %ecx, oEIP(%eax) -+ leal 4(%esp), %ecx /* Exclude the return address. */ -+ movl %ecx, oESP(%eax) -+ movl %ebx, oEBX(%eax) -+ -+ /* Save the FS segment register. We don't touch the GS register -+ since it is used for threads. */ -+ xorl %edx, %edx -+ movw %fs, %dx -+ movl %edx, oFS(%eax) -+ -+ /* We have separate floating-point register content memory on the -+ stack. We use the __fpregs_mem block in the context. Set the -+ links up correctly. */ -+ leal oFPREGSMEM(%eax), %ecx -+ movl %ecx, oFPREGS(%eax) -+ /* Save the floating-point context. */ -+ fnstenv (%ecx) -+ /* And load it right back since the processor changes the mask. -+ Intel thought this opcode to be used in interrupt handlers which -+ would block all exceptions. */ -+ fldenv (%ecx) -+ -+ /* Save the current signal mask. */ -+ pushl %ebx -+ cfi_adjust_cfa_offset (4) -+ cfi_rel_offset (ebx, 0) -+ leal oSIGMASK(%eax), %edx -+ xorl %ecx, %ecx -+ movl $SIG_BLOCK, %ebx -+ movl $__NR_sigprocmask, %eax -+ ENTER_KERNEL -+ popl %ebx -+ cfi_adjust_cfa_offset (-4) -+ cfi_restore (ebx) -+ cmpl $-4095, %eax /* Check %eax for error. */ -+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ -+ -+ /* All done, return 0 for success. */ -+ xorl %eax, %eax -+L(pseudo_end): -+ ret -+PSEUDO_END(__getcontext) -+ -+weak_alias (__getcontext, getcontext) -diff --git a/libc/sysdeps/linux/i386/makecontext.S b/libc/sysdeps/linux/i386/makecontext.S -new file mode 100644 -index 0000000..d12799d ---- /dev/null -+++ b/libc/sysdeps/linux/i386/makecontext.S -@@ -0,0 +1,123 @@ -+/* Create new context. -+ Copyright (C) 2001,2002,2005,2007,2008,2009 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2001. -+ -+ 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 <sysdep.h> -+ -+#include "ucontext_i.h" -+ -+ -+ENTRY(__makecontext) -+ movl 4(%esp), %eax -+ -+ /* Load the address of the function we are supposed to run. */ -+ movl 8(%esp), %ecx -+ -+ /* Compute the address of the stack. The information comes from -+ to us_stack element. */ -+ movl oSS_SP(%eax), %edx -+ movl %ecx, oEIP(%eax) -+ addl oSS_SIZE(%eax), %edx -+ -+ /* Remember the number of parameters for the exit handler since -+ it has to remove them. We store the number in the EBX register -+ which the function we will call must preserve. */ -+ movl 12(%esp), %ecx -+ movl %ecx, oEBX(%eax) -+ -+ /* Make room on the new stack for the parameters. -+ Room for the arguments, return address (== L(exitcode)) and -+ oLINK pointer is needed. One of the pointer sizes is subtracted -+ after aligning the stack. */ -+ negl %ecx -+ leal -4(%edx,%ecx,4), %edx -+ negl %ecx -+ -+ /* Align the stack. */ -+ andl $0xfffffff0, %edx -+ subl $4, %edx -+ -+ /* Store the future stack pointer. */ -+ movl %edx, oESP(%eax) -+ -+ /* Put the next context on the new stack (from the uc_link -+ element). */ -+ movl oLINK(%eax), %eax -+ movl %eax, 4(%edx,%ecx,4) -+ -+ /* Copy all the parameters. */ -+ jecxz 2f -+1: movl 12(%esp,%ecx,4), %eax -+ movl %eax, (%edx,%ecx,4) -+ decl %ecx -+ jnz 1b -+2: -+ -+ /* If the function we call returns we must continue with the -+ context which is given in the uc_link element. To do this -+ set the return address for the function the user provides -+ to a little bit of helper code which does the magic (see -+ below). */ -+#ifdef __PIC__ -+ call 1f -+ cfi_adjust_cfa_offset (4) -+1: popl %ecx -+ cfi_adjust_cfa_offset (-4) -+ addl $L(exitcode)-1b, %ecx -+ movl %ecx, (%edx) -+#else -+ movl $L(exitcode), (%edx) -+#endif -+ /* 'makecontext' returns no value. */ -+L(pseudo_end): -+ ret -+ -+ /* This is the helper code which gets called if a function which -+ is registered with 'makecontext' returns. In this case we -+ have to install the context listed in the uc_link element of -+ the context 'makecontext' manipulated at the time of the -+ 'makecontext' call. If the pointer is NULL the process must -+ terminate. */ -+ cfi_endproc -+L(exitcode): -+ /* This removes the parameters passed to the function given to -+ 'makecontext' from the stack. EBX contains the number of -+ parameters (see above). */ -+ leal (%esp,%ebx,4), %esp -+ -+#ifdef __PIC__ -+ call 1f -+1: popl %ebx -+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx -+#endif -+ cmpl $0, (%esp) /* Check the next context. */ -+ je 2f /* If it is zero exit. */ -+ -+ call JUMPTARGET(__setcontext) -+ /* If this returns (which can happen if the syscall fails) we'll -+ exit the program with the return error value (-1). */ -+ -+ movl %eax, (%esp) -+2: call HIDDEN_JUMPTARGET(exit) -+ /* The 'exit' call should never return. In case it does cause -+ the process to terminate. */ -+ hlt -+ cfi_startproc -+END(__makecontext) -+ -+weak_alias (__makecontext, makecontext) -diff --git a/libc/sysdeps/linux/i386/setcontext.S b/libc/sysdeps/linux/i386/setcontext.S -new file mode 100644 -index 0000000..ae953cc ---- /dev/null -+++ b/libc/sysdeps/linux/i386/setcontext.S -@@ -0,0 +1,96 @@ -+/* Install given context. -+ Copyright (C) 2001-2012 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2001. -+ -+ 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 <sysdep.h> -+ -+#include "ucontext_i.h" -+ -+ -+ENTRY(__setcontext) -+ /* Load address of the context data structure. */ -+ movl 4(%esp), %eax -+ -+ /* Get the current signal mask. Note that we preserve EBX in case -+ the system call fails and we return from the function with an -+ error. */ -+ pushl %ebx -+ cfi_adjust_cfa_offset (4) -+ xorl %edx, %edx -+ leal oSIGMASK(%eax), %ecx -+ movl $SIG_SETMASK, %ebx -+ cfi_rel_offset (ebx, 0) -+ movl $__NR_sigprocmask, %eax -+ ENTER_KERNEL -+ popl %ebx -+ cfi_adjust_cfa_offset (-4) -+ cfi_restore (ebx) -+ cmpl $-4095, %eax /* Check %eax for error. */ -+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ -+ -+ /* EAX was modified, reload it. */ -+ movl 4(%esp), %eax -+ -+ /* Restore the floating-point context. Not the registers, only the -+ rest. */ -+ movl oFPREGS(%eax), %ecx -+ fldenv (%ecx) -+ -+ /* Restore the FS segment register. We don't touch the GS register -+ since it is used for threads. */ -+ movl oFS(%eax), %ecx -+ movw %cx, %fs -+ -+ /* Fetch the address to return to. */ -+ movl oEIP(%eax), %ecx -+ -+ /* Load the new stack pointer. */ -+ cfi_def_cfa (eax, 0) -+ cfi_offset (edi, oEDI) -+ cfi_offset (esi, oESI) -+ cfi_offset (ebp, oEBP) -+ cfi_offset (ebx, oEBX) -+ cfi_offset (edx, oEDX) -+ cfi_offset (ecx, oECX) -+ movl oESP(%eax), %esp -+ -+ /* Push the return address on the new stack so we can return there. */ -+ pushl %ecx -+ -+ /* Load the values of all the 32-bit registers (except ESP). -+ Since we are loading from EAX, it must be last. */ -+ movl oEDI(%eax), %edi -+ movl oESI(%eax), %esi -+ movl oEBP(%eax), %ebp -+ movl oEBX(%eax), %ebx -+ movl oEDX(%eax), %edx -+ movl oECX(%eax), %ecx -+ movl oEAX(%eax), %eax -+ -+ /* End FDE here, we fall into another context. */ -+ cfi_endproc -+ cfi_startproc -+ -+ /* The following 'ret' will pop the address of the code and jump -+ to it. */ -+ -+L(pseudo_end): -+ ret -+PSEUDO_END(__setcontext) -+ -+weak_alias (__setcontext, setcontext) -diff --git a/libc/sysdeps/linux/i386/swapcontext.S b/libc/sysdeps/linux/i386/swapcontext.S -new file mode 100644 -index 0000000..ee5d0e4 ---- /dev/null -+++ b/libc/sysdeps/linux/i386/swapcontext.S -@@ -0,0 +1,110 @@ -+/* Save current context and install the given one. -+ Copyright (C) 2001-2012 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2001. -+ -+ 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 <sysdep.h> -+ -+#include "ucontext_i.h" -+ -+ -+ENTRY(__swapcontext) -+ /* Load address of the context data structure we save in. */ -+ movl 4(%esp), %eax -+ -+ /* Return value of swapcontext. EAX is the only register whose -+ value is not preserved. */ -+ movl $0, oEAX(%eax) -+ -+ /* Save the 32-bit register values and the return address. */ -+ movl %ecx, oECX(%eax) -+ movl %edx, oEDX(%eax) -+ movl %edi, oEDI(%eax) -+ movl %esi, oESI(%eax) -+ movl %ebp, oEBP(%eax) -+ movl (%esp), %ecx -+ movl %ecx, oEIP(%eax) -+ leal 4(%esp), %ecx -+ movl %ecx, oESP(%eax) -+ movl %ebx, oEBX(%eax) -+ -+ /* Save the FS segment register. */ -+ xorl %edx, %edx -+ movw %fs, %dx -+ movl %edx, oFS(%eax) -+ -+ /* We have separate floating-point register content memory on the -+ stack. We use the __fpregs_mem block in the context. Set the -+ links up correctly. */ -+ leal oFPREGSMEM(%eax), %ecx -+ movl %ecx, oFPREGS(%eax) -+ /* Save the floating-point context. */ -+ fnstenv (%ecx) -+ -+ /* Load address of the context data structure we have to load. */ -+ movl 8(%esp), %ecx -+ -+ /* Save the current signal mask and install the new one. */ -+ pushl %ebx -+ leal oSIGMASK(%eax), %edx -+ leal oSIGMASK(%ecx), %ecx -+ movl $SIG_SETMASK, %ebx -+ movl $__NR_sigprocmask, %eax -+ ENTER_KERNEL -+ popl %ebx -+ cmpl $-4095, %eax /* Check %eax for error. */ -+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ -+ -+ /* EAX was modified, reload it. */ -+ movl 8(%esp), %eax -+ -+ /* Restore the floating-point context. Not the registers, only the -+ rest. */ -+ movl oFPREGS(%eax), %ecx -+ fldenv (%ecx) -+ -+ /* Restore the FS segment register. We don't touch the GS register -+ since it is used for threads. */ -+ movl oFS(%eax), %edx -+ movw %dx, %fs -+ -+ /* Fetch the address to return to. */ -+ movl oEIP(%eax), %ecx -+ -+ /* Load the new stack pointer. */ -+ movl oESP(%eax), %esp -+ -+ /* Push the return address on the new stack so we can return there. */ -+ pushl %ecx -+ -+ /* Load the values of all the 32-bit registers (except ESP). -+ Since we are loading from EAX, it must be last. */ -+ movl oEDI(%eax), %edi -+ movl oESI(%eax), %esi -+ movl oEBP(%eax), %ebp -+ movl oEBX(%eax), %ebx -+ movl oEDX(%eax), %edx -+ movl oECX(%eax), %ecx -+ movl oEAX(%eax), %eax -+ -+ /* The following 'ret' will pop the address of the code and jump -+ to it. */ -+L(pseudo_end): -+ ret -+PSEUDO_END(__swapcontext) -+ -+weak_alias (__swapcontext, swapcontext) -diff --git a/libc/sysdeps/linux/i386/ucontext_i.sym b/libc/sysdeps/linux/i386/ucontext_i.sym -new file mode 100644 -index 0000000..b11a550 ---- /dev/null -+++ b/libc/sysdeps/linux/i386/ucontext_i.sym -@@ -0,0 +1,30 @@ -+#include <stddef.h> -+#include <signal.h> -+#include <sys/ucontext.h> -+ -+-- -+ -+SIG_BLOCK -+SIG_SETMASK -+ -+#define ucontext(member) offsetof (ucontext_t, member) -+#define mcontext(member) ucontext (uc_mcontext.member) -+#define mreg(reg) mcontext (gregs[REG_##reg]) -+ -+oLINK ucontext (uc_link) -+oSS_SP ucontext (uc_stack.ss_sp) -+oSS_SIZE ucontext (uc_stack.ss_size) -+oGS mreg (GS) -+oFS mreg (FS) -+oEDI mreg (EDI) -+oESI mreg (ESI) -+oEBP mreg (EBP) -+oESP mreg (ESP) -+oEBX mreg (EBX) -+oEDX mreg (EDX) -+oECX mreg (ECX) -+oEAX mreg (EAX) -+oEIP mreg (EIP) -+oFPREGS mcontext (fpregs) -+oSIGMASK ucontext (uc_sigmask) -+oFPREGSMEM ucontext (__fpregs_mem) -diff --git a/libc/sysdeps/linux/mips/Makefile.arch b/libc/sysdeps/linux/mips/Makefile.arch -index fce99f8..00b9331 100644 ---- a/libc/sysdeps/linux/mips/Makefile.arch -+++ b/libc/sysdeps/linux/mips/Makefile.arch -@@ -27,3 +27,7 @@ ASFLAGS-syscall_error.S += -D_LIBC_REENTRANT - - ARCH_HEADERS := sgidefs.h - # regdef.h -+ -+ifeq ($(UCLIBC_HAS_CONTEXT_FUNCS),y) -+SSRC += makecontext.S setcontext.S getcontext.S swapcontext.S -+endif -diff --git a/libc/sysdeps/linux/mips/getcontext.S b/libc/sysdeps/linux/mips/getcontext.S -new file mode 100644 -index 0000000..c4ad081 ---- /dev/null -+++ b/libc/sysdeps/linux/mips/getcontext.S -@@ -0,0 +1,148 @@ -+/* Save current context. -+ Copyright (C) 2009 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Maciej W. Rozycki <macro@codesourcery.com>. -+ -+ 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 <sysdep.h> -+#include <sys/asm.h> -+#include <sys/fpregdef.h> -+#include <sys/regdef.h> -+ -+#include "ucontext_i.h" -+ -+/* int getcontext (ucontext_t *ucp) */ -+ -+ .text -+LOCALSZ = 0 -+MASK = 0x00000000 -+#ifdef __PIC__ -+LOCALSZ = 1 /* save gp */ -+# if _MIPS_SIM != _ABIO32 -+MASK = 0x10000000 -+# endif -+#endif -+FRAMESZ = ((LOCALSZ * SZREG) + ALSZ) & ALMASK -+GPOFF = FRAMESZ - (1 * SZREG) -+ -+NESTED (__getcontext, FRAMESZ, ra) -+ .mask MASK, 0 -+ .fmask 0x00000000, 0 -+ -+#ifdef __PIC__ -+ SETUP_GP -+ -+ move a2, sp -+# define _SP a2 -+ -+# if _MIPS_SIM != _ABIO32 -+ move a3, gp -+# define _GP a3 -+# endif -+ -+ PTR_ADDIU sp, -FRAMESZ -+ SETUP_GP64 (GPOFF, __getcontext) -+ SAVE_GP (GPOFF) -+ -+#else /* ! __PIC__ */ -+# define _SP sp -+# define _GP gp -+ -+#endif /* ! __PIC__ */ -+ -+#ifdef PROF -+ .set noat -+ move AT, ra -+ jal _mcount -+ .set at -+#endif -+ -+ /* Store a magic flag. */ -+ li v1, 1 -+ REG_S v1, (0 * SZREG + MCONTEXT_GREGS)(a0) /* zero */ -+ -+ REG_S s0, (16 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S s1, (17 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S s2, (18 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S s3, (19 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S s4, (20 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S s5, (21 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S s6, (22 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S s7, (23 * SZREG + MCONTEXT_GREGS)(a0) -+#if ! defined (__PIC__) || _MIPS_SIM != _ABIO32 -+ REG_S _GP, (28 * SZREG + MCONTEXT_GREGS)(a0) -+#endif -+ REG_S _SP, (29 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S fp, (30 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S ra, (31 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S ra, MCONTEXT_PC(a0) -+ -+#ifdef __mips_hard_float -+# if _MIPS_SIM == _ABI64 -+ s.d fs0, (24 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs1, (25 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs2, (26 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs3, (27 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs4, (28 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs5, (29 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs6, (30 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs7, (31 * SZREG + MCONTEXT_FPREGS)(a0) -+ -+# else /* _MIPS_SIM != _ABI64 */ -+ s.d fs0, (20 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs1, (22 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs2, (24 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs3, (26 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs4, (28 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs5, (30 * SZREG + MCONTEXT_FPREGS)(a0) -+ -+# endif /* _MIPS_SIM != _ABI64 */ -+ -+ cfc1 v1, fcr31 -+ sw v1, MCONTEXT_FPC_CSR(a0) -+#endif /* __mips_hard_float */ -+ -+/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */ -+ li a3, _NSIG8 -+ PTR_ADDU a2, a0, UCONTEXT_SIGMASK -+ move a1, zero -+ li a0, SIG_BLOCK -+ -+ li v0, SYS_ify (rt_sigprocmask) -+ syscall -+ bnez a3, 99f -+ -+#ifdef __PIC__ -+ RESTORE_GP64 -+ PTR_ADDIU sp, FRAMESZ -+#endif -+ move v0, zero -+ jr ra -+ -+99: -+#ifdef __PIC__ -+ PTR_LA t9, JUMPTARGET (__syscall_error) -+ RESTORE_GP64 -+ PTR_ADDIU sp, FRAMESZ -+ jr t9 -+ -+#else /* ! __PIC__ */ -+ -+ j JUMPTARGET (__syscall_error) -+#endif /* ! __PIC__ */ -+PSEUDO_END (__getcontext) -+ -+weak_alias (__getcontext, getcontext) -diff --git a/libc/sysdeps/linux/mips/kernel_rt_sigframe.h b/libc/sysdeps/linux/mips/kernel_rt_sigframe.h -new file mode 100644 -index 0000000..77ffaf6 ---- /dev/null -+++ b/libc/sysdeps/linux/mips/kernel_rt_sigframe.h -@@ -0,0 +1,10 @@ -+/* Linux kernel RT signal frame. */ -+typedef struct kernel_rt_sigframe -+ { -+ uint32_t rs_ass[4]; -+ uint32_t rs_code[2]; -+ siginfo_t rs_info; -+ struct ucontext rs_uc; -+ uint32_t rs_altcode[8] __attribute__ ((__aligned__ (1 << 7))); -+ } -+kernel_rt_sigframe_t; -diff --git a/libc/sysdeps/linux/mips/makecontext.S b/libc/sysdeps/linux/mips/makecontext.S -new file mode 100644 -index 0000000..6427339 ---- /dev/null -+++ b/libc/sysdeps/linux/mips/makecontext.S -@@ -0,0 +1,188 @@ -+/* Modify saved context. -+ Copyright (C) 2009 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Maciej W. Rozycki <macro@codesourcery.com>. -+ -+ 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 <sysdep.h> -+#include <sys/asm.h> -+#include <sys/fpregdef.h> -+#include <sys/regdef.h> -+ -+#include "ucontext_i.h" -+ -+/* int makecontext (ucontext_t *ucp, (void *func) (), int argc, ...) */ -+ -+ .text -+LOCALSZ = 0 -+ARGSZ = 0 -+MASK = 0x00000000 -+#ifdef __PIC__ -+LOCALSZ = 1 /* save gp */ -+#endif -+#if _MIPS_SIM != _ABIO32 -+ARGSZ = 5 /* save a3-a7 */ -+# ifdef __PIC__ -+MASK = 0x10000000 -+# endif -+#endif -+FRAMESZ = (((ARGSZ + LOCALSZ) * SZREG) + ALSZ) & ALMASK -+GPOFF = FRAMESZ - ((ARGSZ + 1) * SZREG) -+#if _MIPS_SIM != _ABIO32 -+A3OFF = FRAMESZ - (5 * SZREG) /* callee-allocated */ -+A4OFF = FRAMESZ - (4 * SZREG) -+A5OFF = FRAMESZ - (3 * SZREG) -+A6OFF = FRAMESZ - (2 * SZREG) -+A7OFF = FRAMESZ - (1 * SZREG) -+NARGREGS = 8 -+#else -+A3OFF = FRAMESZ + (3 * SZREG) /* caller-allocated */ -+NARGREGS = 4 -+#endif -+ -+NESTED (__makecontext, FRAMESZ, ra) -+ .mask MASK, -(ARGSZ * SZREG) -+ .fmask 0x00000000, 0 -+ -+98: -+#ifdef __PIC__ -+ SETUP_GP -+#endif -+ -+ PTR_ADDIU sp, -FRAMESZ -+ -+#ifdef __PIC__ -+ SETUP_GP64 (GPOFF, __makecontext) -+ SAVE_GP (GPOFF) -+#endif -+ -+#ifdef PROF -+ .set noat -+ move AT, ra -+ jal _mcount -+ .set at -+#endif -+ -+ /* Store args to be passed. */ -+ REG_S a3, A3OFF(sp) -+#if _MIPS_SIM != _ABIO32 -+ REG_S a4, A4OFF(sp) -+ REG_S a5, A5OFF(sp) -+ REG_S a6, A6OFF(sp) -+ REG_S a7, A7OFF(sp) -+#endif -+ -+ /* Store a magic flag. */ -+ li v1, 1 -+ REG_S v1, (0 * SZREG + MCONTEXT_GREGS)(a0) /* zero */ -+ -+ /* Set up the stack. */ -+ PTR_L t0, STACK_SP(a0) -+ PTR_L t2, STACK_SIZE(a0) -+ PTR_ADDIU t1, sp, A3OFF -+ PTR_ADDU t0, t2 -+ and t0, ALMASK -+ blez a2, 2f /* no arguments */ -+ -+ /* Store register arguments. */ -+ PTR_ADDIU t2, a0, MCONTEXT_GREGS + 4 * SZREG -+ move t3, zero -+0: -+ addiu t3, 1 -+ REG_L v1, (t1) -+ PTR_ADDIU t1, SZREG -+ REG_S v1, (t2) -+ PTR_ADDIU t2, SZREG -+ bgeu t3, a2, 2f /* all done */ -+ bltu t3, NARGREGS, 0b /* next */ -+ -+ /* Make room for stack arguments. */ -+ PTR_SUBU t2, a2, t3 -+ PTR_SLL t2, 3 -+ PTR_SUBU t0, t2 -+ and t0, ALMASK -+ -+ /* Store stack arguments. */ -+ move t2, t0 -+1: -+ addiu t3, 1 -+ REG_L v1, (t1) -+ PTR_ADDIU t1, SZREG -+ REG_S v1, (t2) -+ PTR_ADDIU t2, SZREG -+ bltu t3, a2, 1b /* next */ -+ -+2: -+#if _MIPS_SIM == _ABIO32 -+ /* Make room for a0-a3 storage. */ -+ PTR_ADDIU t0, -(NARGSAVE * SZREG) -+#endif -+ PTR_L v1, UCONTEXT_LINK(a0) -+#ifdef __PIC__ -+ PTR_ADDIU t9, 99f - 98b -+#else -+ PTR_LA t9, 99f -+#endif -+ REG_S t0, (29 * SZREG + MCONTEXT_GREGS)(a0) /* sp */ -+ REG_S v1, (16 * SZREG + MCONTEXT_GREGS)(a0) /* s0 */ -+#ifdef __PIC__ -+ REG_S gp, (17 * SZREG + MCONTEXT_GREGS)(a0) /* s1 */ -+#endif -+ REG_S t9, (31 * SZREG + MCONTEXT_GREGS)(a0) /* ra */ -+ REG_S a1, MCONTEXT_PC(a0) -+ -+#ifdef __PIC__ -+ RESTORE_GP64 -+ PTR_ADDIU sp, FRAMESZ -+#endif -+ jr ra -+ -+99: -+#ifdef __PIC__ -+ move gp, s1 -+#endif -+ move a0, zero -+ beqz s0, 0f -+ -+ /* setcontext (ucp) */ -+ move a0, s0 -+#ifdef __PIC__ -+ PTR_LA t9, JUMPTARGET (__setcontext) -+ jalr t9 -+# if _MIPS_SIM == _ABIO32 -+ move gp, s1 -+# endif -+#else -+ jal JUMPTARGET (__setcontext) -+#endif -+ move a0, v0 -+ -+0: -+ /* exit (a0) */ -+#ifdef __PIC__ -+ PTR_LA t9, HIDDEN_JUMPTARGET (exit) -+ jalr t9 -+#else -+ jal HIDDEN_JUMPTARGET (exit) -+#endif -+ -+ /* You don't exist, you won't feel anything. */ -+1: -+ lb zero, (zero) -+ b 1b -+PSEUDO_END (__makecontext) -+ -+weak_alias (__makecontext, makecontext) -diff --git a/libc/sysdeps/linux/mips/setcontext.S b/libc/sysdeps/linux/mips/setcontext.S -new file mode 100644 -index 0000000..d3cde0e ---- /dev/null -+++ b/libc/sysdeps/linux/mips/setcontext.S -@@ -0,0 +1,191 @@ -+/* Set current context. -+ Copyright (C) 2009 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Maciej W. Rozycki <macro@codesourcery.com>. -+ -+ 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 <sysdep.h> -+#include <sys/asm.h> -+#include <sys/fpregdef.h> -+#include <sys/regdef.h> -+ -+#include "ucontext_i.h" -+ -+/* int setcontext (const ucontext_t *ucp) */ -+ -+ .text -+LOCALSZ = 0 -+ARGSZ = 0 -+MASK = 0x00000000 -+#ifdef __PIC__ -+LOCALSZ = 1 /* save gp */ -+#endif -+#if _MIPS_SIM != _ABIO32 -+ARGSZ = 1 /* save a0 */ -+# ifdef __PIC__ -+MASK = 0x10000000 -+# endif -+#endif -+FRAMESZ = (((ARGSZ + LOCALSZ) * SZREG) + ALSZ) & ALMASK -+GPOFF = FRAMESZ - ((ARGSZ + 1) * SZREG) -+#if _MIPS_SIM != _ABIO32 -+A0OFF = FRAMESZ - (1 * SZREG) /* callee-allocated */ -+#else -+A0OFF = FRAMESZ + (0 * SZREG) /* caller-allocated */ -+#endif -+ -+NESTED (__setcontext, FRAMESZ, ra) -+ .mask MASK, -(ARGSZ * SZREG) -+ .fmask 0x00000000, 0 -+ -+#ifdef __PIC__ -+ SETUP_GP -+#endif -+ -+ PTR_ADDIU sp, -FRAMESZ -+ -+#ifdef __PIC__ -+ SETUP_GP64 (GPOFF, __setcontext) -+ SAVE_GP (GPOFF) -+#endif -+ -+#ifdef PROF -+ .set noat -+ move AT, ra -+ jal _mcount -+ .set at -+#endif -+ -+ /* Check for the magic flag. */ -+ li v0, 1 -+ REG_L v1, (0 * SZREG + MCONTEXT_GREGS)(a0) /* zero */ -+ bne v0, v1, 98f -+ -+ REG_S a0, A0OFF(sp) -+ -+/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, NULL, _NSIG8) */ -+ li a3, _NSIG8 -+ move a2, zero -+ PTR_ADDU a1, a0, UCONTEXT_SIGMASK -+ li a0, SIG_SETMASK -+ -+ li v0, SYS_ify (rt_sigprocmask) -+ syscall -+ bnez a3, 99f -+ -+ REG_L v0, A0OFF(sp) -+ -+#ifdef __mips_hard_float -+# if _MIPS_SIM == _ABI64 -+ l.d fs0, (24 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs1, (25 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs2, (26 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs3, (27 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs4, (28 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs5, (29 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs6, (30 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs7, (31 * SZREG + MCONTEXT_FPREGS)(v0) -+ -+# else /* _MIPS_SIM != _ABI64 */ -+ l.d fs0, (20 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs1, (22 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs2, (24 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs3, (26 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs4, (28 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs5, (30 * SZREG + MCONTEXT_FPREGS)(v0) -+ -+# endif /* _MIPS_SIM != _ABI64 */ -+ -+ lw v1, MCONTEXT_FPC_CSR(v0) -+ ctc1 v1, fcr31 -+#endif /* __mips_hard_float */ -+ -+ /* Note the contents of argument registers will be random -+ unless makecontext() has been called. */ -+ REG_L a0, (4 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L a1, (5 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L a2, (6 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L a3, (7 * SZREG + MCONTEXT_GREGS)(v0) -+#if _MIPS_SIM != _ABIO32 -+ REG_L a4, (8 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L a5, (9 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L a6, (10 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L a7, (11 * SZREG + MCONTEXT_GREGS)(v0) -+#endif -+ -+ REG_L s0, (16 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L s1, (17 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L s2, (18 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L s3, (19 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L s4, (20 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L s5, (21 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L s6, (22 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L s7, (23 * SZREG + MCONTEXT_GREGS)(v0) -+#if ! defined (__PIC__) || _MIPS_SIM != _ABIO32 -+ REG_L gp, (28 * SZREG + MCONTEXT_GREGS)(v0) -+#endif -+ REG_L sp, (29 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L fp, (30 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L ra, (31 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L t9, MCONTEXT_PC(v0) -+ -+ move v0, zero -+ jr t9 -+ -+98: -+ /* This is a context obtained from a signal handler. -+ Perform a full restore by pushing the context -+ passed onto a simulated signal frame on the stack -+ and call the signal return syscall as if a signal -+ handler exited normally. */ -+ PTR_ADDIU sp, -((RT_SIGFRAME_SIZE + ALSZ) & ALMASK) -+ -+ /* Only ucontext is referred to from rt_sigreturn, -+ copy it. */ -+ PTR_ADDIU t1, sp, RT_SIGFRAME_UCONTEXT -+ li t3, ((UCONTEXT_SIZE + SZREG - 1) / SZREG) - 1 -+0: -+ REG_L t2, (a0) -+ PTR_ADDIU a0, SZREG -+ REG_S t2, (t1) -+ PTR_ADDIU t1, SZREG -+ .set noreorder -+ bgtz t3, 0b -+ addiu t3, -1 -+ .set reorder -+ -+/* rt_sigreturn () -- no arguments, sp points to struct rt_sigframe. */ -+ li v0, SYS_ify (rt_sigreturn) -+ syscall -+ -+ /* Restore the stack and fall through to the error -+ path. Successful rt_sigreturn never returns to -+ its calling place. */ -+ PTR_ADDIU sp, ((RT_SIGFRAME_SIZE + ALSZ) & ALMASK) -+99: -+#ifdef __PIC__ -+ PTR_LA t9, JUMPTARGET (__syscall_error) -+ RESTORE_GP64 -+ PTR_ADDIU sp, FRAMESZ -+ jr t9 -+ -+#else /* ! __PIC__ */ -+ -+ j JUMPTARGET (__syscall_error) -+#endif /* ! __PIC__ */ -+PSEUDO_END (__setcontext) -+ -+weak_alias (__setcontext, setcontext) -diff --git a/libc/sysdeps/linux/mips/swapcontext.S b/libc/sysdeps/linux/mips/swapcontext.S -new file mode 100644 -index 0000000..c7ac19b ---- /dev/null -+++ b/libc/sysdeps/linux/mips/swapcontext.S -@@ -0,0 +1,211 @@ -+/* Save and set current context. -+ Copyright (C) 2009 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Maciej W. Rozycki <macro@codesourcery.com>. -+ -+ 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 <sysdep.h> -+#include <sys/asm.h> -+#include <sys/fpregdef.h> -+#include <sys/regdef.h> -+ -+#include "ucontext_i.h" -+ -+/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */ -+ -+ .text -+LOCALSZ = 0 -+ARGSZ = 0 -+MASK = 0x00000000 -+#ifdef __PIC__ -+LOCALSZ = 1 /* save gp */ -+#endif -+#if _MIPS_SIM != _ABIO32 -+ARGSZ = 1 /* save a1 */ -+# ifdef __PIC__ -+MASK = 0x10000000 -+# endif -+#endif -+FRAMESZ = (((ARGSZ + LOCALSZ) * SZREG) + ALSZ) & ALMASK -+GPOFF = FRAMESZ - ((ARGSZ + 1) * SZREG) -+#if _MIPS_SIM != _ABIO32 -+A1OFF = FRAMESZ - (1 * SZREG) /* callee-allocated */ -+#else -+A1OFF = FRAMESZ + (1 * SZREG) /* caller-allocated */ -+#endif -+ -+NESTED (__swapcontext, FRAMESZ, ra) -+ .mask MASK, -(ARGSZ * SZREG) -+ .fmask 0x00000000, 0 -+ -+#ifdef __PIC__ -+ SETUP_GP -+ -+ move a2, sp -+# define _SP a2 -+ -+# if _MIPS_SIM != _ABIO32 -+ move a3, gp -+# define _GP a3 -+# endif -+ -+ PTR_ADDIU sp, -FRAMESZ -+ SETUP_GP64 (GPOFF, __swapcontext) -+ SAVE_GP (GPOFF) -+ -+#else /* ! __PIC__ */ -+# define _SP sp -+# define _GP gp -+ -+#endif /* ! __PIC__ */ -+ -+#ifdef PROF -+ .set noat -+ move AT, ra -+ jal _mcount -+ .set at -+#endif -+ -+ /* Store a magic flag. */ -+ li v1, 1 -+ REG_S v1, (0 * SZREG + MCONTEXT_GREGS)(a0) /* zero */ -+ -+ REG_S s0, (16 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S s1, (17 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S s2, (18 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S s3, (19 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S s4, (20 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S s5, (21 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S s6, (22 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S s7, (23 * SZREG + MCONTEXT_GREGS)(a0) -+#if ! defined (__PIC__) || _MIPS_SIM != _ABIO32 -+ REG_S _GP, (28 * SZREG + MCONTEXT_GREGS)(a0) -+#endif -+ REG_S _SP, (29 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S fp, (30 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S ra, (31 * SZREG + MCONTEXT_GREGS)(a0) -+ REG_S ra, MCONTEXT_PC(a0) -+ -+#ifdef __mips_hard_float -+# if _MIPS_SIM == _ABI64 -+ s.d fs0, (24 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs1, (25 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs2, (26 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs3, (27 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs4, (28 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs5, (29 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs6, (30 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs7, (31 * SZREG + MCONTEXT_FPREGS)(a0) -+ -+# else /* _MIPS_SIM != _ABI64 */ -+ s.d fs0, (20 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs1, (22 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs2, (24 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs3, (26 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs4, (28 * SZREG + MCONTEXT_FPREGS)(a0) -+ s.d fs5, (30 * SZREG + MCONTEXT_FPREGS)(a0) -+ -+# endif /* _MIPS_SIM != _ABI64 */ -+ -+ cfc1 v1, fcr31 -+ sw v1, MCONTEXT_FPC_CSR(a0) -+#endif /* __mips_hard_float */ -+ -+ REG_S a1, A1OFF(sp) -+ -+/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, _NSIG8) */ -+ li a3, _NSIG8 -+ PTR_ADDU a2, a0, UCONTEXT_SIGMASK -+ PTR_ADDU a1, a1, UCONTEXT_SIGMASK -+ li a0, SIG_SETMASK -+ -+ li v0, SYS_ify (rt_sigprocmask) -+ syscall -+ bnez a3, 99f -+ -+ REG_L v0, A1OFF(sp) -+ -+#ifdef __mips_hard_float -+# if _MIPS_SIM == _ABI64 -+ l.d fs0, (24 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs1, (25 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs2, (26 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs3, (27 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs4, (28 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs5, (29 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs6, (30 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs7, (31 * SZREG + MCONTEXT_FPREGS)(v0) -+ -+# else /* _MIPS_SIM != _ABI64 */ -+ l.d fs0, (20 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs1, (22 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs2, (24 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs3, (26 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs4, (28 * SZREG + MCONTEXT_FPREGS)(v0) -+ l.d fs5, (30 * SZREG + MCONTEXT_FPREGS)(v0) -+ -+# endif /* _MIPS_SIM != _ABI64 */ -+ -+ lw v1, MCONTEXT_FPC_CSR(v0) -+ ctc1 v1, fcr31 -+#endif /* __mips_hard_float */ -+ -+ /* Note the contents of argument registers will be random -+ unless makecontext() has been called. */ -+ REG_L a0, (4 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L a1, (5 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L a2, (6 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L a3, (7 * SZREG + MCONTEXT_GREGS)(v0) -+#if _MIPS_SIM != _ABIO32 -+ REG_L a4, (8 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L a5, (9 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L a6, (10 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L a7, (11 * SZREG + MCONTEXT_GREGS)(v0) -+#endif -+ -+ REG_L s0, (16 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L s1, (17 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L s2, (18 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L s3, (19 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L s4, (20 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L s5, (21 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L s6, (22 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L s7, (23 * SZREG + MCONTEXT_GREGS)(v0) -+#if ! defined (__PIC__) || _MIPS_SIM != _ABIO32 -+ REG_L gp, (28 * SZREG + MCONTEXT_GREGS)(v0) -+#endif -+ REG_L sp, (29 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L fp, (30 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L ra, (31 * SZREG + MCONTEXT_GREGS)(v0) -+ REG_L t9, MCONTEXT_PC(v0) -+ -+ move v0, zero -+ jr t9 -+ -+99: -+#ifdef __PIC__ -+ PTR_LA t9, JUMPTARGET (__syscall_error) -+ RESTORE_GP64 -+ PTR_ADDIU sp, FRAMESZ -+ jr t9 -+ -+#else /* ! __PIC__ */ -+ -+ j JUMPTARGET (__syscall_error) -+#endif /* ! __PIC__ */ -+PSEUDO_END (__swapcontext) -+ -+weak_alias (__swapcontext, swapcontext) -diff --git a/libc/sysdeps/linux/mips/ucontext_i.sym b/libc/sysdeps/linux/mips/ucontext_i.sym -new file mode 100644 -index 0000000..f14b886 ---- /dev/null -+++ b/libc/sysdeps/linux/mips/ucontext_i.sym -@@ -0,0 +1,52 @@ -+#include <inttypes.h> -+#include <signal.h> -+#include <stddef.h> -+#include <sys/ucontext.h> -+ -+#include <kernel_rt_sigframe.h> -+ -+-- Constants used by the rt_sigprocmask call. -+ -+SIG_BLOCK -+SIG_SETMASK -+ -+_NSIG8 (_NSIG / 8) -+ -+-- Offsets of the fields in the kernel rt_sigframe_t structure. -+#define rt_sigframe(member) offsetof (kernel_rt_sigframe_t, member) -+ -+RT_SIGFRAME_UCONTEXT rt_sigframe (rs_uc) -+ -+RT_SIGFRAME_SIZE sizeof (kernel_rt_sigframe_t) -+ -+-- Offsets of the fields in the ucontext_t structure. -+#define ucontext(member) offsetof (ucontext_t, member) -+#define stack(member) ucontext (uc_stack.member) -+#define mcontext(member) ucontext (uc_mcontext.member) -+ -+UCONTEXT_FLAGS ucontext (uc_flags) -+UCONTEXT_LINK ucontext (uc_link) -+UCONTEXT_STACK ucontext (uc_stack) -+UCONTEXT_MCONTEXT ucontext (uc_mcontext) -+UCONTEXT_SIGMASK ucontext (uc_sigmask) -+ -+STACK_SP stack (ss_sp) -+STACK_SIZE stack (ss_size) -+STACK_FLAGS stack (ss_flags) -+ -+MCONTEXT_GREGS mcontext (gregs) -+MCONTEXT_FPREGS mcontext (fpregs) -+MCONTEXT_MDHI mcontext (mdhi) -+MCONTEXT_HI1 mcontext (hi1) -+MCONTEXT_HI2 mcontext (hi2) -+MCONTEXT_HI3 mcontext (hi3) -+MCONTEXT_MDLO mcontext (mdlo) -+MCONTEXT_LO1 mcontext (lo1) -+MCONTEXT_LO2 mcontext (lo2) -+MCONTEXT_LO3 mcontext (lo3) -+MCONTEXT_PC mcontext (pc) -+MCONTEXT_FPC_CSR mcontext (fpc_csr) -+MCONTEXT_USED_MATH mcontext (used_math) -+MCONTEXT_DSP mcontext (dsp) -+ -+UCONTEXT_SIZE sizeof (ucontext_t) -diff --git a/libc/sysdeps/linux/x86_64/Makefile.arch b/libc/sysdeps/linux/x86_64/Makefile.arch -index 7491d92..93b8259 100644 ---- a/libc/sysdeps/linux/x86_64/Makefile.arch -+++ b/libc/sysdeps/linux/x86_64/Makefile.arch -@@ -20,3 +20,8 @@ ifeq ($(UCLIBC_HAS_TLS),y) - SSRC += sched_getcpu.S - endif - endif -+ -+ifeq ($(UCLIBC_HAS_CONTEXT_FUNCS),y) -+CSRC += makecontext.c -+SSRC += setcontext.S getcontext.S swapcontext.S __start_context.S -+endif -diff --git a/libc/sysdeps/linux/x86_64/__start_context.S b/libc/sysdeps/linux/x86_64/__start_context.S -new file mode 100644 -index 0000000..9f2ee23 ---- /dev/null -+++ b/libc/sysdeps/linux/x86_64/__start_context.S -@@ -0,0 +1,49 @@ -+/* Copyright (C) 2002-2012 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Andreas Jaeger <aj@suse.de>, 2002. -+ -+ 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 <sysdep.h> -+ -+/* This is the helper code which gets called if a function which is -+ registered with 'makecontext' returns. In this case we have to -+ install the context listed in the uc_link element of the context -+ 'makecontext' manipulated at the time of the 'makecontext' call. -+ If the pointer is NULL the process must terminate. */ -+ -+ -+ENTRY(__start_context) -+ /* This removes the parameters passed to the function given to -+ 'makecontext' from the stack. RBX contains the address -+ on the stack pointer for the next context. */ -+ movq %rbx, %rsp -+ -+ popq %rdi /* This is the next context. */ -+ cfi_adjust_cfa_offset(-8) -+ testq %rdi, %rdi -+ je 2f /* If it is zero exit. */ -+ -+ call JUMPTARGET(__setcontext) -+ /* If this returns (which can happen if the syscall fails) we'll -+ exit the program with the return error value (-1). */ -+ movq %rax,%rdi -+ -+2: -+ call HIDDEN_JUMPTARGET(exit) -+ /* The 'exit' call should never return. In case it does cause -+ the process to terminate. */ -+ hlt -+END(__start_context) -diff --git a/libc/sysdeps/linux/x86_64/getcontext.S b/libc/sysdeps/linux/x86_64/getcontext.S -new file mode 100644 -index 0000000..dcebc4f ---- /dev/null -+++ b/libc/sysdeps/linux/x86_64/getcontext.S -@@ -0,0 +1,88 @@ -+/* Save current context. -+ Copyright (C) 2002-2012 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Andreas Jaeger <aj@suse.de>, 2002. -+ -+ 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 <sysdep.h> -+ -+#include "ucontext_i.h" -+ -+/* int __getcontext (ucontext_t *ucp) -+ -+ Saves the machine context in UCP such that when it is activated, -+ it appears as if __getcontext() returned again. -+ -+ This implementation is intended to be used for *synchronous* context -+ switches only. Therefore, it does not have to save anything -+ other than the PRESERVED state. */ -+ -+ -+ENTRY(__getcontext) -+ /* Save the preserved registers, the registers used for passing -+ args, and the return address. */ -+ movq %rbx, oRBX(%rdi) -+ movq %rbp, oRBP(%rdi) -+ movq %r12, oR12(%rdi) -+ movq %r13, oR13(%rdi) -+ movq %r14, oR14(%rdi) -+ movq %r15, oR15(%rdi) -+ -+ movq %rdi, oRDI(%rdi) -+ movq %rsi, oRSI(%rdi) -+ movq %rdx, oRDX(%rdi) -+ movq %rcx, oRCX(%rdi) -+ movq %r8, oR8(%rdi) -+ movq %r9, oR9(%rdi) -+ -+ movq (%rsp), %rcx -+ movq %rcx, oRIP(%rdi) -+ leaq 8(%rsp), %rcx /* Exclude the return address. */ -+ movq %rcx, oRSP(%rdi) -+ -+ /* We have separate floating-point register content memory on the -+ stack. We use the __fpregs_mem block in the context. Set the -+ links up correctly. */ -+ -+ leaq oFPREGSMEM(%rdi), %rcx -+ movq %rcx, oFPREGS(%rdi) -+ /* Save the floating-point environment. */ -+ fnstenv (%rcx) -+ fldenv (%rcx) -+ stmxcsr oMXCSR(%rdi) -+ -+ /* Save the current signal mask with -+ rt_sigprocmask (SIG_BLOCK, NULL, set,_NSIG/8). */ -+ leaq oSIGMASK(%rdi), %rdx -+ xorl %esi,%esi -+#if SIG_BLOCK == 0 -+ xorl %edi, %edi -+#else -+ movl $SIG_BLOCK, %edi -+#endif -+ movl $_NSIG8,%r10d -+ movl $__NR_rt_sigprocmask, %eax -+ syscall -+ cmpq $-4095, %rax /* Check %rax for error. */ -+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ -+ -+ /* All done, return 0 for success. */ -+ xorl %eax, %eax -+L(pseudo_end): -+ ret -+PSEUDO_END(__getcontext) -+ -+weak_alias (__getcontext, getcontext) -diff --git a/libc/sysdeps/linux/x86_64/makecontext.c b/libc/sysdeps/linux/x86_64/makecontext.c -new file mode 100644 -index 0000000..5473031 ---- /dev/null -+++ b/libc/sysdeps/linux/x86_64/makecontext.c -@@ -0,0 +1,121 @@ -+/* Create new context. -+ Copyright (C) 2002, 2004, 2005, 2008 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Andreas Jaeger <aj@suse.de>, 2002. -+ -+ 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 <sysdep.h> -+#include <stdarg.h> -+#include <stdint.h> -+#include <ucontext.h> -+ -+#include "ucontext_i.h" -+ -+/* This implementation can handle any ARGC value but only -+ normal integer parameters. -+ makecontext sets up a stack and the registers for the -+ user context. The stack looks like this: -+ +-----------------------+ -+ | next context | -+ +-----------------------+ -+ | parameter 7-n | -+ +-----------------------+ -+ | trampoline address | -+ %rsp -> +-----------------------+ -+ -+ The registers are set up like this: -+ %rdi,%rsi,%rdx,%rcx,%r8,%r9: parameter 1 to 6 -+ %rbx : address of next context -+ %rsp : stack pointer. -+*/ -+ -+/* XXX: This implementation currently only handles integer arguments. -+ To handle long int and pointer arguments the va_arg arguments needs -+ to be changed to long and also the stdlib/tst-setcontext.c file needs -+ to be changed to pass long arguments to makecontext. */ -+ -+ -+void -+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) -+{ -+ extern void __start_context (void); -+ greg_t *sp; -+ unsigned int idx_uc_link; -+ va_list ap; -+ int i; -+ -+ /* Generate room on stack for parameter if needed and uc_link. */ -+ sp = (greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp -+ + ucp->uc_stack.ss_size); -+ sp -= (argc > 6 ? argc - 6 : 0) + 1; -+ /* Align stack and make space for trampoline address. */ -+ sp = (greg_t *) ((((uintptr_t) sp) & -16L) - 8); -+ -+ idx_uc_link = (argc > 6 ? argc - 6 : 0) + 1; -+ -+ /* Setup context ucp. */ -+ /* Address to jump to. */ -+ ucp->uc_mcontext.gregs[REG_RIP] = (uintptr_t) func; -+ /* Setup rbx.*/ -+ ucp->uc_mcontext.gregs[REG_RBX] = (uintptr_t) &sp[idx_uc_link]; -+ ucp->uc_mcontext.gregs[REG_RSP] = (uintptr_t) sp; -+ -+ /* Setup stack. */ -+ sp[0] = (uintptr_t) &__start_context; -+ sp[idx_uc_link] = (uintptr_t) ucp->uc_link; -+ -+ va_start (ap, argc); -+ /* Handle arguments. -+ -+ The standard says the parameters must all be int values. This is -+ an historic accident and would be done differently today. For -+ x86-64 all integer values are passed as 64-bit values and -+ therefore extending the API to copy 64-bit values instead of -+ 32-bit ints makes sense. It does not break existing -+ functionality and it does not violate the standard which says -+ that passing non-int values means undefined behavior. */ -+ for (i = 0; i < argc; ++i) -+ switch (i) -+ { -+ case 0: -+ ucp->uc_mcontext.gregs[REG_RDI] = va_arg (ap, greg_t); -+ break; -+ case 1: -+ ucp->uc_mcontext.gregs[REG_RSI] = va_arg (ap, greg_t); -+ break; -+ case 2: -+ ucp->uc_mcontext.gregs[REG_RDX] = va_arg (ap, greg_t); -+ break; -+ case 3: -+ ucp->uc_mcontext.gregs[REG_RCX] = va_arg (ap, greg_t); -+ break; -+ case 4: -+ ucp->uc_mcontext.gregs[REG_R8] = va_arg (ap, greg_t); -+ break; -+ case 5: -+ ucp->uc_mcontext.gregs[REG_R9] = va_arg (ap, greg_t); -+ break; -+ default: -+ /* Put value on stack. */ -+ sp[i - 5] = va_arg (ap, greg_t); -+ break; -+ } -+ va_end (ap); -+ -+} -+ -+ -+weak_alias (__makecontext, makecontext) -diff --git a/libc/sysdeps/linux/x86_64/setcontext.S b/libc/sysdeps/linux/x86_64/setcontext.S -new file mode 100644 -index 0000000..561ab9f ---- /dev/null -+++ b/libc/sysdeps/linux/x86_64/setcontext.S -@@ -0,0 +1,103 @@ -+/* Install given context. -+ Copyright (C) 2002-2012 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Andreas Jaeger <aj@suse.de>, 2002. -+ -+ 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 <sysdep.h> -+ -+#include "ucontext_i.h" -+ -+ -+/* int __setcontext (const ucontext_t *ucp) -+ -+ Restores the machine context in UCP and thereby resumes execution -+ in that context. -+ -+ This implementation is intended to be used for *synchronous* context -+ switches only. Therefore, it does not have to restore anything -+ other than the PRESERVED state. */ -+ -+ENTRY(__setcontext) -+ /* Save argument since syscall will destroy it. */ -+ pushq %rdi -+ cfi_adjust_cfa_offset(8) -+ -+ /* Set the signal mask with -+ rt_sigprocmask (SIG_SETMASK, mask, NULL, _NSIG/8). */ -+ leaq oSIGMASK(%rdi), %rsi -+ xorl %edx, %edx -+ movl $SIG_SETMASK, %edi -+ movl $_NSIG8,%r10d -+ movl $__NR_rt_sigprocmask, %eax -+ syscall -+ popq %rdi /* Reload %rdi, adjust stack. */ -+ cfi_adjust_cfa_offset(-8) -+ cmpq $-4095, %rax /* Check %rax for error. */ -+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ -+ -+ /* Restore the floating-point context. Not the registers, only the -+ rest. */ -+ movq oFPREGS(%rdi), %rcx -+ fldenv (%rcx) -+ ldmxcsr oMXCSR(%rdi) -+ -+ -+ /* Load the new stack pointer, the preserved registers and -+ registers used for passing args. */ -+ cfi_def_cfa(%rdi, 0) -+ cfi_offset(%rbx,oRBX) -+ cfi_offset(%rbp,oRBP) -+ cfi_offset(%r12,oR12) -+ cfi_offset(%r13,oR13) -+ cfi_offset(%r14,oR14) -+ cfi_offset(%r15,oR15) -+ cfi_offset(%rsp,oRSP) -+ cfi_offset(%rip,oRIP) -+ -+ movq oRSP(%rdi), %rsp -+ movq oRBX(%rdi), %rbx -+ movq oRBP(%rdi), %rbp -+ movq oR12(%rdi), %r12 -+ movq oR13(%rdi), %r13 -+ movq oR14(%rdi), %r14 -+ movq oR15(%rdi), %r15 -+ -+ /* The following ret should return to the address set with -+ getcontext. Therefore push the address on the stack. */ -+ movq oRIP(%rdi), %rcx -+ pushq %rcx -+ -+ movq oRSI(%rdi), %rsi -+ movq oRDX(%rdi), %rdx -+ movq oRCX(%rdi), %rcx -+ movq oR8(%rdi), %r8 -+ movq oR9(%rdi), %r9 -+ -+ /* Setup finally %rdi. */ -+ movq oRDI(%rdi), %rdi -+ -+ /* End FDE here, we fall into another context. */ -+ cfi_endproc -+ cfi_startproc -+ -+ /* Clear rax to indicate success. */ -+ xorl %eax, %eax -+L(pseudo_end): -+ ret -+PSEUDO_END(__setcontext) -+ -+weak_alias (__setcontext, setcontext) -diff --git a/libc/sysdeps/linux/x86_64/swapcontext.S b/libc/sysdeps/linux/x86_64/swapcontext.S -new file mode 100644 -index 0000000..6d2ebb8 ---- /dev/null -+++ b/libc/sysdeps/linux/x86_64/swapcontext.S -@@ -0,0 +1,121 @@ -+/* Save current context and install the given one. -+ Copyright (C) 2002-2012 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Andreas Jaeger <aj@suse.de>, 2002. -+ -+ 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 <sysdep.h> -+ -+#include "ucontext_i.h" -+ -+ -+/* int __swapcontext (ucontext_t *oucp, const ucontext_t *ucp); -+ -+ Saves the machine context in oucp such that when it is activated, -+ it appears as if __swapcontextt() returned again, restores the -+ machine context in ucp and thereby resumes execution in that -+ context. -+ -+ This implementation is intended to be used for *synchronous* context -+ switches only. Therefore, it does not have to save anything -+ other than the PRESERVED state. */ -+ -+ENTRY(__swapcontext) -+ /* Save the preserved registers, the registers used for passing args, -+ and the return address. */ -+ movq %rbx, oRBX(%rdi) -+ movq %rbp, oRBP(%rdi) -+ movq %r12, oR12(%rdi) -+ movq %r13, oR13(%rdi) -+ movq %r14, oR14(%rdi) -+ movq %r15, oR15(%rdi) -+ -+ movq %rdi, oRDI(%rdi) -+ movq %rsi, oRSI(%rdi) -+ movq %rdx, oRDX(%rdi) -+ movq %rcx, oRCX(%rdi) -+ movq %r8, oR8(%rdi) -+ movq %r9, oR9(%rdi) -+ -+ movq (%rsp), %rcx -+ movq %rcx, oRIP(%rdi) -+ leaq 8(%rsp), %rcx /* Exclude the return address. */ -+ movq %rcx, oRSP(%rdi) -+ -+ /* We have separate floating-point register content memory on the -+ stack. We use the __fpregs_mem block in the context. Set the -+ links up correctly. */ -+ leaq oFPREGSMEM(%rdi), %rcx -+ movq %rcx, oFPREGS(%rdi) -+ /* Save the floating-point environment. */ -+ fnstenv (%rcx) -+ stmxcsr oMXCSR(%rdi) -+ -+ -+ /* The syscall destroys some registers, save them. */ -+ movq %rsi, %r12 -+ -+ /* Save the current signal mask and install the new one with -+ rt_sigprocmask (SIG_BLOCK, newset, oldset,_NSIG/8). */ -+ leaq oSIGMASK(%rdi), %rdx -+ leaq oSIGMASK(%rsi), %rsi -+ movl $SIG_SETMASK, %edi -+ movl $_NSIG8,%r10d -+ movl $__NR_rt_sigprocmask, %eax -+ syscall -+ cmpq $-4095, %rax /* Check %rax for error. */ -+ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ -+ -+ /* Restore destroyed registers. */ -+ movq %r12, %rsi -+ -+ /* Restore the floating-point context. Not the registers, only the -+ rest. */ -+ movq oFPREGS(%rsi), %rcx -+ fldenv (%rcx) -+ ldmxcsr oMXCSR(%rsi) -+ -+ /* Load the new stack pointer and the preserved registers. */ -+ movq oRSP(%rsi), %rsp -+ movq oRBX(%rsi), %rbx -+ movq oRBP(%rsi), %rbp -+ movq oR12(%rsi), %r12 -+ movq oR13(%rsi), %r13 -+ movq oR14(%rsi), %r14 -+ movq oR15(%rsi), %r15 -+ -+ /* The following ret should return to the address set with -+ getcontext. Therefore push the address on the stack. */ -+ movq oRIP(%rsi), %rcx -+ pushq %rcx -+ -+ /* Setup registers used for passing args. */ -+ movq oRDI(%rsi), %rdi -+ movq oRDX(%rsi), %rdx -+ movq oRCX(%rsi), %rcx -+ movq oR8(%rsi), %r8 -+ movq oR9(%rsi), %r9 -+ -+ /* Setup finally %rsi. */ -+ movq oRSI(%rsi), %rsi -+ -+ /* Clear rax to indicate success. */ -+ xorl %eax, %eax -+L(pseudo_end): -+ ret -+PSEUDO_END(__swapcontext) -+ -+weak_alias (__swapcontext, swapcontext) -diff --git a/libc/sysdeps/linux/x86_64/ucontext_i.sym b/libc/sysdeps/linux/x86_64/ucontext_i.sym -new file mode 100644 -index 0000000..af3e0e5 ---- /dev/null -+++ b/libc/sysdeps/linux/x86_64/ucontext_i.sym -@@ -0,0 +1,37 @@ -+#include <stddef.h> -+#include <signal.h> -+#include <sys/ucontext.h> -+ -+-- -+ -+SIG_BLOCK -+SIG_SETMASK -+ -+_NSIG8 (_NSIG / 8) -+ -+#define ucontext(member) offsetof (ucontext_t, member) -+#define mcontext(member) ucontext (uc_mcontext.member) -+#define mreg(reg) mcontext (gregs[REG_##reg]) -+ -+oRBP mreg (RBP) -+oRSP mreg (RSP) -+oRBX mreg (RBX) -+oR8 mreg (R8) -+oR9 mreg (R9) -+oR10 mreg (R10) -+oR11 mreg (R11) -+oR12 mreg (R12) -+oR13 mreg (R13) -+oR14 mreg (R14) -+oR15 mreg (R15) -+oRDI mreg (RDI) -+oRSI mreg (RSI) -+oRDX mreg (RDX) -+oRAX mreg (RAX) -+oRCX mreg (RCX) -+oRIP mreg (RIP) -+oEFL mreg (EFL) -+oFPREGS mcontext (fpregs) -+oSIGMASK ucontext (uc_sigmask) -+oFPREGSMEM ucontext (__fpregs_mem) -+oMXCSR ucontext (__fpregs_mem.mxcsr) -diff --git a/libpthread/nptl/sysdeps/Makefile.commonarch b/libpthread/nptl/sysdeps/Makefile.commonarch -index 0c19216..8f5d61d 100644 ---- a/libpthread/nptl/sysdeps/Makefile.commonarch -+++ b/libpthread/nptl/sysdeps/Makefile.commonarch -@@ -47,9 +47,8 @@ $(libpthread_arch_OUT)/gen_tcb-offsets.c: $(libpthread_arch_DIR)/tcb-offsets.sym - $(libpthread_arch_OUT)/gen_tcb-offsets.s: $(libpthread_arch_OUT)/gen_tcb-offsets.c | headers - $(compile.c) - libpthread-generated-y += $(libpthread_arch_OUT)/gen_tcb-offsets.s --PTHREAD_TCB_OFFSET_MANGLE ?= -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*\$$/\#define \1 \2/p" - $(libpthread_arch_OUT)/tcb-offsets.h: $(libpthread_arch_OUT)/gen_tcb-offsets.s -- $(do_sed) $(PTHREAD_TCB_OFFSET_MANGLE) $< > $@ -+ $(do_sed) $(PTHREAD_GENERATE_MANGLE) $< > $@ - @if test ! -s $@ ; then rm -f $@ ; false ; fi - - pregen-headers-$(UCLIBC_HAS_THREADS_NATIVE) += $(libpthread_arch_OUT)/tcb-offsets.h -diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.commonarch b/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.commonarch -index 477fb1a..3372214 100644 ---- a/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.commonarch -+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/Makefile.commonarch -@@ -177,8 +177,6 @@ CFLAGS-gen_pthread-pi-defines.c = -S - CFLAGS-gen_structsem.c = -S - CFLAGS-gen_unwindbuf.c = -S - --PTHREAD_GENERATE_MANGLE ?= -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*\$$/\#define \1 \2/p" -- - PTHREAD_LINUX_SYM := $(notdir $(wildcard $(libpthread_linux_DIR)/*.sym)) - PTHREAD_LINUX_SYM_C := $(addprefix $(libpthread_linux_OUT)/gen_,$(PTHREAD_LINUX_SYM:.sym=.c)) - PTHREAD_LINUX_SYM_S := $(PTHREAD_LINUX_SYM_C:.c=.s) --- -1.8.4 - |