Update.
authorAndreas Jaeger <aj@suse.de>
Thu, 28 Mar 2002 19:07:58 +0000 (19:07 +0000)
committerAndreas Jaeger <aj@suse.de>
Thu, 28 Mar 2002 19:07:58 +0000 (19:07 +0000)
2002-03-28  Andreas Jaeger  <aj@suse.de>

* sysdeps/unix/sysv/linux/x86_64/swapcontext.S: New.
* sysdeps/unix/sysv/linux/x86_64/getcontext.S: New.
* sysdeps/unix/sysv/linux/x86_64/setcontext.S: New.
* sysdeps/unix/sysv/linux/x86_64/ucontext_i.h: New.

ChangeLog
sysdeps/unix/sysv/linux/x86_64/getcontext.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/x86_64/setcontext.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/x86_64/swapcontext.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/x86_64/ucontext_i.h [new file with mode: 0644]

index 7269b6d..81f20a2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2002-03-28  Andreas Jaeger  <aj@suse.de>
+
+       * sysdeps/unix/sysv/linux/x86_64/swapcontext.S: New.
+       * sysdeps/unix/sysv/linux/x86_64/getcontext.S: New.
+       * sysdeps/unix/sysv/linux/x86_64/setcontext.S: New.
+       * sysdeps/unix/sysv/linux/x86_64/ucontext_i.h: New.
+
 2002-03-27  Andreas Jaeger  <aj@suse.de>
 
        * sysdeps/unix/sysv/linux/x86_64/bits/sigcontext.h (struct
diff --git a/sysdeps/unix/sysv/linux/x86_64/getcontext.S b/sysdeps/unix/sysv/linux/x86_64/getcontext.S
new file mode 100644 (file)
index 0000000..e941f5d
--- /dev/null
@@ -0,0 +1,76 @@
+/* Save current context.
+   Copyright (C) 2002 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#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 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    (%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)
+
+       /* Save the current signal mask with
+          rt_sigprocmask (SIG_BLOCK, NULL, set,_NSIG/8).  */
+       leaq    oSIGMASK(%rdi), %rdx
+       xorq    %rsi,%rsi
+       movq    $SIG_BLOCK, %rdi
+       movq    $_NSIG8,%r10
+       movq    $__NR_rt_sigprocmask, %rax
+       syscall
+       cmpq    $-4095, %rax            /* Check %rax for error.  */
+       jae     SYSCALL_ERROR_LABEL     /* Jump to error handler if error.  */
+
+       /* All done, return 0 for success.  */
+       xorq    %rax, %rax
+L(pseudo_end):
+       ret
+PSEUDO_END(__getcontext)
+
+weak_alias(__getcontext, getcontext)
diff --git a/sysdeps/unix/sysv/linux/x86_64/setcontext.S b/sysdeps/unix/sysv/linux/x86_64/setcontext.S
new file mode 100644 (file)
index 0000000..eb46034
--- /dev/null
@@ -0,0 +1,79 @@
+/* Install given context.
+   Copyright (C) 2002 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#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
+
+       /* Set the signal mask with
+          rt_sigprocmask (SIG_SETMASK, mask, NULL, _NSIG/8).  */
+       leaq    oSIGMASK(%rdi), %rsi
+       xorq    %rdx, %rdx
+       movq    $SIG_SETMASK, %rdi
+       movq    $_NSIG8,%r10
+       movq    $__NR_rt_sigprocmask, %rax
+       syscall
+       popq    %rdi                    /* Reload %rdi, adjust stack.  */
+       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 and the preserved registers.  */
+       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
+
+       /* Clear rax to indicate success.  */
+       xorq    %rax, %rax
+
+L(pseudo_end):
+       ret
+PSEUDO_END(__setcontext)
+
+weak_alias(__setcontext, setcontext)
diff --git a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
new file mode 100644 (file)
index 0000000..3dddb3c
--- /dev/null
@@ -0,0 +1,105 @@
+/* Save current context and install the given one.
+   Copyright (C) 2002 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#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 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    (%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
+       movq    $SIG_SETMASK, %rdi
+       movq    $_NSIG8,%r10
+       movq    $__NR_rt_sigprocmask, %rax
+       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
+
+       /* Clear rax to indicate success.  */
+       xorq    %rax, %rax
+
+L(pseudo_end):
+       ret
+PSEUDO_END(__swapcontext)
+
+weak_alias(__swapcontext, swapcontext)
diff --git a/sysdeps/unix/sysv/linux/x86_64/ucontext_i.h b/sysdeps/unix/sysv/linux/x86_64/ucontext_i.h
new file mode 100644 (file)
index 0000000..0a2283b
--- /dev/null
@@ -0,0 +1,41 @@
+/* Offsets and other constants needed in the *context() function
+   implementation for Linux/x86-64.
+   Copyright (C) 2002 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#define SIG_BLOCK      0
+#define SIG_SETMASK    2
+
+/* Since we cannot include a header to define _NSIG/8, we define it
+   here.  */
+#define _NSIG8         8
+
+/* Offsets of the fields in the ucontext_t structure.  */
+#define oRBP           120
+#define oRSP           160
+#define oRBX           128
+#define oR12           72
+#define oR13           80
+#define oR14           88
+#define oR15           96
+#define oRAX           144
+#define oRIP           168
+#define oFPREGS                208
+#define oSIGMASK       280
+#define oFPREGSMEM     408
+#define oMXCSR         432