diff options
Diffstat (limited to 'main/libc0.9.32/0001-libc-sysdeps-get-make-set-swap-context-for-i386.patch')
-rw-r--r-- | main/libc0.9.32/0001-libc-sysdeps-get-make-set-swap-context-for-i386.patch | 560 |
1 files changed, 560 insertions, 0 deletions
diff --git a/main/libc0.9.32/0001-libc-sysdeps-get-make-set-swap-context-for-i386.patch b/main/libc0.9.32/0001-libc-sysdeps-get-make-set-swap-context-for-i386.patch new file mode 100644 index 0000000000..1292fce91f --- /dev/null +++ b/main/libc0.9.32/0001-libc-sysdeps-get-make-set-swap-context-for-i386.patch @@ -0,0 +1,560 @@ +From 647868c7ccfbe766445fc74ff7bcb1f9b76fdb0f Mon Sep 17 00:00:00 2001 +From: Natanael Copa <ncopa@alpinelinux.org> +Date: Mon, 29 Oct 2012 13:24:05 +0000 +Subject: [PATCH 1/2] libc/sysdeps: {get,make,set,swap}context for i386 + +crudely imported from glibc + +Conflicts: + libc/sysdeps/linux/i386/Makefile.arch +--- + .gitignore | 1 + + libc/sysdeps/linux/i386/Makefile.arch | 36 ++++++++++ + 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 ++++++++ + 7 files changed, 480 insertions(+) + 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 + +diff --git a/.gitignore b/.gitignore +index c2603a0..a980db6 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -18,6 +18,7 @@ install_dir/ + .*.dep + /*.log + cscope.* ++ucontext_i.[chs] + + # + # Debugging files +diff --git a/libc/sysdeps/linux/i386/Makefile.arch b/libc/sysdeps/linux/i386/Makefile.arch +index 966f8b5..64f8110 100644 +--- a/libc/sysdeps/linux/i386/Makefile.arch ++++ b/libc/sysdeps/linux/i386/Makefile.arch +@@ -11,7 +11,43 @@ SSRC := \ + __longjmp.S setjmp.S bsd-setjmp.S bsd-_setjmp.S \ + sync_file_range.S syscall.S mmap.S mmap64.S posix_fadvise64.S + ++LIBC_ARCH_DIR := $(top_srcdir)/libc/sysdeps/linux/$(TARGET_ARCH) ++LIBC_ARCH_OUT := $(top_builddir)/libc/sysdeps/linux/$(TARGET_ARCH) + + ifneq ($(UCLIBC_HAS_THREADS_NATIVE),y) + SSRC += vfork.S clone.S + endif ++ ++ifeq ($(UCLIBC_SUSV4_LEGACY),y) ++SSRC += makecontext.S setcontext.S getcontext.S swapcontext.S ++ ++ASFLAGS-setcontext.S := -D_LIBC_REENTRANT ++ASFLAGS-getcontext.S := -D_LIBC_REENTRANT ++ASFLAGS-swapcontext.S := -D_LIBC_REENTRANT ++ ++ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y) ++#Needed to use the correct SYSCALL_ERROR_HANDLER ++ASFLAGS-setcontext.S += -DUSE___THREAD ++ASFLAGS-getcontext.S += -DUSE___THREAD ++ASFLAGS-swapcontext.S += -DUSE___THREAD ++endif ++ ++pregen-headers-$(UCLIBC_SUSV4_LEGACY) += $(LIBC_ARCH_OUT)/ucontext_i.h ++ ++headers_clean-y += libc_arch_headers_clean ++ ++CFLAGS-ucontext_i.c = -S ++ ++$(LIBC_ARCH_OUT)/ucontext_i.c: $(LIBC_ARCH_DIR)/ucontext_i.sym ++ $(do_awk) $(top_srcdir)extra/scripts/gen-as-const.awk $< > $@ ++ ++$(LIBC_ARCH_OUT)/ucontext_i.s: $(LIBC_ARCH_OUT)/ucontext_i.c ++ $(compile.c) ++ ++$(LIBC_ARCH_OUT)/ucontext_i.h: $(LIBC_ARCH_OUT)/ucontext_i.s ++ $(do_sed) -n "s/^.*@@@name@@@\([^@]*\)@@@value@@@[^0-9Xxa-fA-F-]*\([0-9Xxa-fA-F-][0-9Xxa-fA-F-]*\).*@@@end@@@.*$\/#define \1 \2/p" $< > $@ ++ ++libc_arch_headers_clean: ++ $(do_rm) $(addprefix $(LIBC_ARCH_OUT)/ucontext_i., c h 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..0f68b57 +--- /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) +-- +1.8.0 + |