Blame sysdeps/unix/sysv/linux/hppa/pt-vfork.S

Packit Service 93dc7a
/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
Packit Service 93dc7a
   This file is part of the GNU C Library.
Packit Service 93dc7a
Packit Service 93dc7a
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 93dc7a
   modify it under the terms of the GNU Lesser General Public
Packit Service 93dc7a
   License as published by the Free Software Foundation; either
Packit Service 93dc7a
   version 2.1 of the License, or (at your option) any later version.
Packit Service 93dc7a
Packit Service 93dc7a
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 93dc7a
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 93dc7a
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
Packit Service 93dc7a
   Lesser General Public License for more details.
Packit Service 93dc7a
Packit Service 93dc7a
   You should have received a copy of the GNU Lesser General Public
Packit Service 93dc7a
   License along with the GNU C Library.  If not, see
Packit Service 93dc7a
   <http://www.gnu.org/licenses/>.  */
Packit Service 93dc7a
Packit Service 93dc7a
#include <sysdep.h>
Packit Service 93dc7a
#define _ERRNO_H        1
Packit Service 93dc7a
#include <bits/errno.h>
Packit Service 93dc7a
#include <tcb-offsets.h>
Packit Service 93dc7a
Packit Service 93dc7a
/* Clone the calling process, but without copying the whole address space.
Packit Service 93dc7a
   The calling process is suspended until the new process exits or is
Packit Service 93dc7a
   replaced by a call to `execve'.  Return -1 for errors, 0 to the new process,
Packit Service 93dc7a
   and the process ID of the new process to the old process.  */
Packit Service 93dc7a
Packit Service 93dc7a
.Lthread_start:						ASM_LINE_SEP
Packit Service 93dc7a
Packit Service 93dc7a
	/* r26, r25, r24, r23 are free since vfork has no arguments */
Packit Service 93dc7a
ENTRY(__vfork)
Packit Service 93dc7a
	/* We must not create a frame. When the child unwinds to call
Packit Service 93dc7a
	   exec it will clobber the same frame that the parent
Packit Service 93dc7a
	   needs to unwind.  */
Packit Service 93dc7a
Packit Service 93dc7a
	/* Save the PIC register. */
Packit Service 93dc7a
#ifdef PIC
Packit Service 93dc7a
	copy	%r19, %r25	/* parent */
Packit Service 93dc7a
#endif
Packit Service 93dc7a
Packit Service 93dc7a
	/* Syscall saves and restores all register states */
Packit Service 93dc7a
	ble	0x100(%sr2,%r0)
Packit Service 93dc7a
	ldi	__NR_vfork,%r20
Packit Service 93dc7a
Packit Service 93dc7a
	/* Check for error */
Packit Service 93dc7a
	ldi	-4096,%r1
Packit Service 93dc7a
	comclr,>>= %r1,%ret0,%r0        /* Note: unsigned compare. */
Packit Service 93dc7a
	b,n	.Lerror
Packit Service 93dc7a
Packit Service 93dc7a
	/* Return, and DO NOT restore rp. The child may have called
Packit Service 93dc7a
	   functions that updated the frame's rp. This works because
Packit Service 93dc7a
	   the kernel ensures rp is preserved across the vfork
Packit Service 93dc7a
	   syscall.  */
Packit Service 93dc7a
	bv,n	%r0(%rp)
Packit Service 93dc7a
Packit Service 93dc7a
.Lerror:
Packit Service 93dc7a
	/* Now we need a stack to call a function. We are assured
Packit Service 93dc7a
	   that there is no child now, so it's safe to create
Packit Service 93dc7a
	   a frame.  */
Packit Service 93dc7a
	stw	%rp, -20(%sp)
Packit Service 93dc7a
	.cfi_offset 2, -20
Packit Service 93dc7a
	stwm	%r3, 64(%sp)
Packit Service 93dc7a
	.cfi_def_cfa_offset -64
Packit Service 93dc7a
	.cfi_offset 3, 0
Packit Service 93dc7a
	stw	%sp, -4(%sp)
Packit Service 93dc7a
Packit Service 93dc7a
	sub	%r0,%ret0,%r3
Packit Service 93dc7a
	SYSCALL_ERROR_HANDLER
Packit Service 93dc7a
	/* Restore the PIC register (in delay slot) on error */
Packit Service 93dc7a
#ifdef PIC
Packit Service 93dc7a
	copy	%r25, %r19    /* parent */
Packit Service 93dc7a
#else
Packit Service 93dc7a
	nop
Packit Service 93dc7a
#endif
Packit Service 93dc7a
	/* Write syscall return into errno location */
Packit Service 93dc7a
	stw	%r3, 0(%ret0)
Packit Service 93dc7a
	ldw	-84(%sp), %rp
Packit Service 93dc7a
	bv	%r0(%rp)
Packit Service 93dc7a
	ldwm	-64(%sp), %r3
Packit Service 93dc7a
PSEUDO_END (__vfork)
Packit Service 93dc7a
libc_hidden_def (__vfork)
Packit Service 93dc7a
weak_alias (__vfork, vfork)