about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/x86_64
diff options
context:
space:
mode:
authorAndreas Jaeger <aj@suse.de>2002-08-31 08:06:48 +0000
committerAndreas Jaeger <aj@suse.de>2002-08-31 08:06:48 +0000
commitc816e074135d0de7dfd9e22e8e2bd4112736ae00 (patch)
tree652cb8d7611be3887b5b66e772e0e435a468650a /sysdeps/unix/sysv/linux/x86_64
parentba1e2fe668361bd6887f237f70f47def96fa7bef (diff)
downloadglibc-c816e074135d0de7dfd9e22e8e2bd4112736ae00.tar.gz
glibc-c816e074135d0de7dfd9e22e8e2bd4112736ae00.tar.xz
glibc-c816e074135d0de7dfd9e22e8e2bd4112736ae00.zip
Update.
2002-08-31  Andreas Jaeger  <aj@suse.de>

	* sysdeps/unix/sysv/linux/x86_64/Makefile (sysdep_routines): Add
	__start_context.

	* sysdeps/unix/sysv/linux/x86_64/__start_context.S: New file.

	* sysdeps/unix/sysv/linux/x86_64/makecontext.c: New file.

	* sysdeps/unix/sysv/linux/x86_64/ucontext_i.h: Add defines for
	registers used for passing args.

	* sysdeps/unix/sysv/linux/x86_64/swapcontext.S: Save and restore
	all needed registers.

	* sysdeps/unix/sysv/linux/x86_64/setcontext.S: Restore all
	registers.

	* sysdeps/unix/sysv/linux/x86_64/getcontext.S: Save all needed
	registers.
Diffstat (limited to 'sysdeps/unix/sysv/linux/x86_64')
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/Makefile4
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/__start_context.S48
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/getcontext.S10
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/setcontext.S12
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/swapcontext.S20
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/ucontext_i.h6
6 files changed, 97 insertions, 3 deletions
diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile
index e1b4a9561a..09745d82d4 100644
--- a/sysdeps/unix/sysv/linux/x86_64/Makefile
+++ b/sysdeps/unix/sysv/linux/x86_64/Makefile
@@ -44,3 +44,7 @@ $(objpfx)syscall-%.h $(objpfx)syscall-%.d: ../sysdeps/unix/sysv/linux/sys/syscal
 	mv -f $(@:.h=.d)-t2 $(@:.h=.d)
 
 endif
+
+ifeq ($(subdir),stdlib)
+sysdep_routines += __start_context
+endif
diff --git a/sysdeps/unix/sysv/linux/x86_64/__start_context.S b/sysdeps/unix/sysv/linux/x86_64/__start_context.S
new file mode 100644
index 0000000000..ad4502ca0a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/__start_context.S
@@ -0,0 +1,48 @@
+/* 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>
+
+/* 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.  */
+	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).  */
+
+2:	movq	%rax,%rdi
+	call	JUMPTARGET(exit)
+	/* The 'exit' call should never return.  In case it does cause
+	   the process to terminate.  */
+	hlt
+END(__start_context)
diff --git a/sysdeps/unix/sysv/linux/x86_64/getcontext.S b/sysdeps/unix/sysv/linux/x86_64/getcontext.S
index e941f5d5fd..2f2c710040 100644
--- a/sysdeps/unix/sysv/linux/x86_64/getcontext.S
+++ b/sysdeps/unix/sysv/linux/x86_64/getcontext.S
@@ -33,7 +33,8 @@
 
 
 ENTRY(__getcontext)
-	/* Save the preserved registers and the return address.  */
+	/* 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)
@@ -41,6 +42,13 @@ ENTRY(__getcontext)
 	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.  */
diff --git a/sysdeps/unix/sysv/linux/x86_64/setcontext.S b/sysdeps/unix/sysv/linux/x86_64/setcontext.S
index eb46034a50..e3d770bcc6 100644
--- a/sysdeps/unix/sysv/linux/x86_64/setcontext.S
+++ b/sysdeps/unix/sysv/linux/x86_64/setcontext.S
@@ -55,7 +55,8 @@ ENTRY(__setcontext)
 	ldmxcsr oMXCSR(%rdi)
 
 
-	/* Load the new stack pointer and the preserved registers.  */
+	/* Load the new stack pointer, the preserved registers and
+	   registers used for passing args.  */
 	movq	oRSP(%rdi), %rsp
 	movq	oRBX(%rdi), %rbx
 	movq	oRBP(%rdi), %rbp
@@ -69,6 +70,15 @@ ENTRY(__setcontext)
 	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
+
 	/* Clear rax to indicate success.  */
 	xorq	%rax, %rax
 
diff --git a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
index 3dddb3cec2..4394e2ae9f 100644
--- a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
+++ b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S
@@ -35,7 +35,8 @@
   other than the PRESERVED state.  */
 
 ENTRY(__swapcontext)
-	/* Save the preserved registers and the return address.  */
+	/* 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)
@@ -43,6 +44,13 @@ ENTRY(__swapcontext)
 	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.  */
@@ -95,6 +103,16 @@ ENTRY(__swapcontext)
 	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.  */
 	xorq	%rax, %rax
 
diff --git a/sysdeps/unix/sysv/linux/x86_64/ucontext_i.h b/sysdeps/unix/sysv/linux/x86_64/ucontext_i.h
index 0a2283b82c..5451a308ee 100644
--- a/sysdeps/unix/sysv/linux/x86_64/ucontext_i.h
+++ b/sysdeps/unix/sysv/linux/x86_64/ucontext_i.h
@@ -29,11 +29,17 @@
 #define oRBP		120
 #define oRSP		160
 #define oRBX		128
+#define oR8		40
+#define oR9		48
 #define oR12		72
 #define oR13		80
 #define oR14		88
 #define oR15		96
+#define oRDI		104
+#define oRSI		112
+#define oRDX		136
 #define oRAX		144
+#define oRCX		152
 #define oRIP		168
 #define oFPREGS		208
 #define oSIGMASK	280