From 3cf01adb3940f23808bcbf04d964bb15bed1ed5a Mon Sep 17 00:00:00 2001 From: Andreas Jaeger Date: Thu, 28 Mar 2002 19:07:58 +0000 Subject: [PATCH] Update. 2002-03-28 Andreas Jaeger * 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 | 7 ++ sysdeps/unix/sysv/linux/x86_64/getcontext.S | 76 ++++++++++++++ sysdeps/unix/sysv/linux/x86_64/setcontext.S | 79 ++++++++++++++ sysdeps/unix/sysv/linux/x86_64/swapcontext.S | 105 +++++++++++++++++++ sysdeps/unix/sysv/linux/x86_64/ucontext_i.h | 41 ++++++++ 5 files changed, 308 insertions(+) create mode 100644 sysdeps/unix/sysv/linux/x86_64/getcontext.S create mode 100644 sysdeps/unix/sysv/linux/x86_64/setcontext.S create mode 100644 sysdeps/unix/sysv/linux/x86_64/swapcontext.S create mode 100644 sysdeps/unix/sysv/linux/x86_64/ucontext_i.h diff --git a/ChangeLog b/ChangeLog index 7269b6d730..81f20a20cd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2002-03-28 Andreas Jaeger + + * 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 * 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 index 0000000000..e941f5d5fd --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86_64/getcontext.S @@ -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 , 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 + +#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 index 0000000000..eb46034a50 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86_64/setcontext.S @@ -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 , 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 + +#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 index 0000000000..3dddb3cec2 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S @@ -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 , 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 + +#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 index 0000000000..0a2283b82c --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86_64/ucontext_i.h @@ -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