1/* Save current context.
2   Copyright (C) 2001-2022 Free Software Foundation, Inc.
3   This file is part of the GNU C Library.
4
5   The GNU C Library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9
10   The GNU C Library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14
15   You should have received a copy of the GNU Lesser General Public
16   License along with the GNU C Library; if not, see
17   <https://www.gnu.org/licenses/>.  */
18
19#include <sysdep.h>
20
21#include "ucontext_i.h"
22
23
24ENTRY(__getcontext)
25	/* Load address of the context data structure.  */
26	movl	4(%esp), %eax
27
28	/* Return value of getcontext.  EAX is the only register whose
29	   value is not preserved.  */
30	movl	$0, oEAX(%eax)
31
32	/* Save the 32-bit register values and the return address.  */
33	movl	%ecx, oECX(%eax)
34	movl	%edx, oEDX(%eax)
35	movl	%edi, oEDI(%eax)
36	movl	%esi, oESI(%eax)
37	movl	%ebp, oEBP(%eax)
38	movl	(%esp), %ecx
39	movl	%ecx, oEIP(%eax)
40	leal	4(%esp), %ecx		/* Exclude the return address.  */
41	movl	%ecx, oESP(%eax)
42	movl	%ebx, oEBX(%eax)
43
44	/* Save the FS segment register.  We don't touch the GS register
45	   since it is used for threads.  */
46	xorl	%edx, %edx
47	movw	%fs, %dx
48	movl	%edx, oFS(%eax)
49
50	leal	oFPREGS(%eax), %ecx
51	/* Save the floating-point context.  */
52	fnstenv	(%ecx)
53	/* And load it right back since the processor changes the mask.
54	   Intel thought this opcode to be used in interrupt handlers which
55	   would block all exceptions.  */
56	fldenv	(%ecx)
57
58	/* Save the current signal mask.  */
59	subl	$12, %esp
60	cfi_adjust_cfa_offset (12)
61	leal	oSIGMASK(%eax), %eax
62	movl	%eax, 8(%esp)
63	movl	$0, 4(%esp)
64	movl	$SIG_BLOCK, (%esp)
65	call	HIDDEN_JUMPTARGET (__sigprocmask)
66	addl	$12, %esp
67	cfi_adjust_cfa_offset (-12)
68	/* Propagate %eax (and errno, in case).  */
69
70	ret
71PSEUDO_END(__getcontext)
72
73weak_alias (__getcontext, getcontext)
74