Blame sysdeps/unix/sysv/linux/aarch64/getcontext.S

Packit 6c4009
/* Save current context.
Packit 6c4009
Packit 6c4009
   Copyright (C) 2009-2018 Free Software Foundation, Inc.
Packit 6c4009
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public License as
Packit 6c4009
   published by the Free Software Foundation; either version 2.1 of the
Packit 6c4009
   License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <sysdep.h>
Packit 6c4009
#include "ucontext_i.h"
Packit 6c4009
#include "ucontext-internal.h"
Packit 6c4009
Packit 6c4009
/* int getcontext (ucontext_t *ucp)
Packit 6c4009
Packit 6c4009
   Returns 0 on success -1 and errno on failure.
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
	.text
Packit 6c4009
Packit 6c4009
ENTRY(__getcontext)
Packit 6c4009
	DELOUSE (0)
Packit 6c4009
	/* The saved context will return to the getcontext() call point
Packit 6c4009
	   with a return value of 0 */
Packit 6c4009
	str	xzr,	  [x0, oX0 +  0 * SZREG]
Packit 6c4009
Packit 6c4009
	stp	x18, x19, [x0, oX0 + 18 * SZREG]
Packit 6c4009
	stp	x20, x21, [x0, oX0 + 20 * SZREG]
Packit 6c4009
	stp	x22, x23, [x0, oX0 + 22 * SZREG]
Packit 6c4009
	stp	x24, x25, [x0, oX0 + 24 * SZREG]
Packit 6c4009
	stp	x26, x27, [x0, oX0 + 26 * SZREG]
Packit 6c4009
	stp	x28, x29, [x0, oX0 + 28 * SZREG]
Packit 6c4009
	str     x30,      [x0, oX0 + 30 * SZREG]
Packit 6c4009
Packit 6c4009
	/* Place LR into the saved PC, this will ensure that when
Packit 6c4009
	   switching to this saved context with setcontext() control
Packit 6c4009
	   will pass back to the caller of getcontext(), we have
Packit 6c4009
	   already arrange to return the appropriate return value in x0
Packit 6c4009
	   above.  */
Packit 6c4009
	str	x30, [x0, oPC]
Packit 6c4009
Packit 6c4009
	/* Save the current SP */
Packit 6c4009
	mov	x2, sp
Packit 6c4009
	str     x2, [x0, oSP]
Packit 6c4009
Packit 6c4009
	/* Initialize the pstate.  */
Packit 6c4009
	str	xzr, [x0, oPSTATE]
Packit 6c4009
Packit 6c4009
	/* Figure out where to place the first context extension
Packit 6c4009
	   block.  */
Packit 6c4009
	add     x2, x0, #oEXTENSION
Packit 6c4009
Packit 6c4009
	/* Write the context extension fpsimd header.  */
Packit 6c4009
	mov	w3, #(FPSIMD_MAGIC & 0xffff)
Packit 6c4009
	movk	w3, #(FPSIMD_MAGIC >> 16), lsl #16
Packit 6c4009
	str	w3, [x2, #oHEAD + oMAGIC]
Packit 6c4009
	mov	w3, #FPSIMD_CONTEXT_SIZE
Packit 6c4009
	str	w3, [x2, #oHEAD + oSIZE]
Packit 6c4009
Packit 6c4009
	/* Fill in the FP SIMD context.  */
Packit 6c4009
	add	x3, x2, #oV0 + 8 * SZVREG
Packit 6c4009
	stp	 q8,  q9, [x3], # 2 * SZVREG
Packit 6c4009
	stp	q10, q11, [x3], # 2 * SZVREG
Packit 6c4009
	stp	q12, q13, [x3], # 2 * SZVREG
Packit 6c4009
	stp	q14, q15, [x3], # 2 * SZVREG
Packit 6c4009
Packit 6c4009
	add	x3, x2, oFPSR
Packit 6c4009
Packit 6c4009
	mrs	x4, fpsr
Packit 6c4009
	str	w4, [x3]
Packit 6c4009
Packit 6c4009
	mrs	x4, fpcr
Packit 6c4009
	str	w4, [x3, oFPCR - oFPSR]
Packit 6c4009
Packit 6c4009
	/* Write the termination context extension header.  */
Packit 6c4009
	add	x2, x2, #FPSIMD_CONTEXT_SIZE
Packit 6c4009
Packit 6c4009
	str	xzr, [x2, #oHEAD + oMAGIC]
Packit 6c4009
	str	xzr, [x2, #oHEAD + oSIZE]
Packit 6c4009
Packit 6c4009
	/* Grab the signal mask */
Packit 6c4009
	/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
Packit 6c4009
	add	PTR_REG (2), PTR_REG (0), #UCONTEXT_SIGMASK
Packit 6c4009
	mov	x0, SIG_BLOCK
Packit 6c4009
	mov	x1, 0
Packit 6c4009
	mov	x3, _NSIG8
Packit 6c4009
	mov	x8, SYS_ify (rt_sigprocmask)
Packit 6c4009
	svc	0
Packit 6c4009
	cbnz	x0, 1f
Packit 6c4009
Packit 6c4009
	/* Return 0 for success */
Packit 6c4009
	mov	x0, 0
Packit 6c4009
	RET
Packit 6c4009
1:
Packit 6c4009
	b	C_SYMBOL_NAME(__syscall_error)
Packit 6c4009
Packit 6c4009
	PSEUDO_END (__getcontext)
Packit 6c4009
weak_alias (__getcontext, getcontext)