1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--------------------------------------------------------------------*/
3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- Support for doing system calls.        syscall-s390x-linux.S ---*/
4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--------------------------------------------------------------------*/
5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*
7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   This file is part of Valgrind, a dynamic binary instrumentation
8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   framework.
9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Copyright IBM Corp. 2010-2011
11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   This program is free software; you can redistribute it and/or
13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   modify it under the terms of the GNU General Public License as
14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   published by the Free Software Foundation; either version 2 of the
15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   License, or (at your option) any later version.
16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   This program is distributed in the hope that it will be useful, but
18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   WITHOUT ANY WARRANTY; without even the implied warranty of
19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   General Public License for more details.
21b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
22b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   You should have received a copy of the GNU General Public License
23b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   along with this program; if not, write to the Free Software
24b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   02111-1307, USA.
26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   The GNU General Public License is contained in the file COPYING.
28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
30b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Contributed by Christian Borntraeger */
31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_basics_asm.h"
33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_vkiscnums_asm.h"
34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "libvex_guest_offsets.h"
35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGA_s390x)
37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*----------------------------------------------------------------*/
39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*
40b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        Perform a syscall for the client.  This will run a syscall
41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        with the client's specific per-thread signal mask.
42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
43b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        The structure of this function is such that, if the syscall is
44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        interrupted by a signal, we can determine exactly what
45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        execution state we were in with respect to the execution of
46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        the syscall by examining the value of NIP in the signal
47b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        handler.  This means that we can always do the appropriate
48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        thing to precisely emulate the kernel's signal/syscall
49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        interactions.
50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        The syscall number is taken from the argument, since the syscall
52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        number can be encoded in the svc instruction itself.
53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        The syscall result is written back to guest register r2.
54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        Returns 0 if the syscall was successfully called (even if the
56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        syscall itself failed), or a nonzero error code in the lowest
57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	8 bits if one of the sigprocmasks failed (there's no way to
58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	determine which one failed).  And there's no obvious way to
59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	recover from that either, but nevertheless we want to know.
60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        VG_(fixup_guest_state_after_syscall_interrupted) does the
62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	thread state fixup in the case where we were interrupted by a
63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	signal.
64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        Prototype:
66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	UWord ML_(do_syscall_for_client_WRK)(
68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov				  Int syscallno,		// r2
69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov				  void* guest_state,		// r3
70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov				  const vki_sigset_t *sysmask,	// r4
71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov				  const vki_sigset_t *postmask,	// r5
72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov				  Int nsigwords)		// r6
73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* from vki_arch.h */
75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VKI_SIG_SETMASK 2
76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define SP_SAVE 16
78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define SP_R2	SP_SAVE + 0*8
79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define SP_R3	SP_SAVE + 1*8
80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define SP_R4	SP_SAVE + 2*8
81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define SP_R5	SP_SAVE + 3*8
82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define SP_R6	SP_SAVE + 4*8
83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define SP_R7	SP_SAVE + 5*8
84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define SP_R8	SP_SAVE + 6*8
85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define SP_R9	SP_SAVE + 7*8
86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.align 4
88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.globl ML_(do_syscall_for_client_WRK)
89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovML_(do_syscall_for_client_WRK):
90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov1:	/* Even though we can't take a signal until the sigprocmask completes,
91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	start the range early.
92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	If IA is in the range [1,2), the syscall hasn't been started yet */
93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	/* Set the signal mask which should be current during the syscall. */
95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	/* Save and restore all the parameters and all the registers that
96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	   we clobber (r6-r9) */
97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	stmg	%r2,%r9, SP_R2(%r15)
98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lghi	%r2, VKI_SIG_SETMASK		/* how */
100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lgr	%r3, %r4			/* sysmask */
101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lgr	%r4, %r5			/* postmask */
102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lgr	%r5, %r6			/* nsigwords */
103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	svc	__NR_rt_sigprocmask
104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	cghi	%r2, 0x0
105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	jne	7f				/* sigprocmask failed */
106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	/* OK, that worked.  Now do the syscall proper. */
108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lg	%r9, SP_R3(%r15)		/* guest state --> r9 */
109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lg	%r2, OFFSET_s390x_r2(%r9)	/* guest r2 --> real r2 */
110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lg	%r3, OFFSET_s390x_r3(%r9)	/* guest r3 --> real r3 */
111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lg	%r4, OFFSET_s390x_r4(%r9)	/* guest r4 --> real r4 */
112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lg	%r5, OFFSET_s390x_r5(%r9)	/* guest r5 --> real r5 */
113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lg	%r6, OFFSET_s390x_r6(%r9)	/* guest r6 --> real r6 */
114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lg	%r7, OFFSET_s390x_r7(%r9)	/* guest r7 --> real r7 */
115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lg	%r1, SP_R2(%r15)		/* syscallno -> r1 */
116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov2:	svc	0
118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov3:
120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	stg	%r2, OFFSET_s390x_r2(%r9)
121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov4:	/* Re-block signals.  If IA is in [4,5), then the syscall
123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	   is complete and we needn't worry about it. */
124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lghi	%r2, VKI_SIG_SETMASK		/* how */
125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lg	%r3, SP_R5(%r15)		/* postmask */
126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lghi	%r4, 0x0			/* NULL */
127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lg	%r5, SP_R6(%r15)		/* nsigwords */
128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	svc	__NR_rt_sigprocmask
129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	cghi	%r2, 0x0
130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	jne	7f				/* sigprocmask failed */
131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov5:	/* Everyting ok. Return 0 and restore the call-saved
133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	   registers, that we have clobbered */
134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lghi	%r2, 0x0
135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lmg	%r6,%r9, SP_R6(%r15)
136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	br	%r14
137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov7:	/* Some problem. Return 0x8000 | error and restore the call-saved
139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	   registers we have clobbered. */
140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	nill	%r2, 0x7fff
141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	oill	%r2, 0x8000
142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	lmg	%r6,%r9, SP_R6(%r15)
143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	br	%r14
144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.section .rodata
146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Export the ranges so that
147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_(fixup_guest_state_after_syscall_interrupted) can do the
148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   right thing */
149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.globl ML_(blksys_setup)
151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.globl ML_(blksys_restart)
152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.globl ML_(blksys_complete)
153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.globl ML_(blksys_committed)
154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.globl ML_(blksys_finished)
155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* The compiler can assume that 8 byte data elements are aligned on 8 byte */
157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.align 8
158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovML_(blksys_setup):     .quad 1b
159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovML_(blksys_restart):   .quad 2b
160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovML_(blksys_complete):  .quad 3b
161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovML_(blksys_committed): .quad 4b
162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovML_(blksys_finished):  .quad 5b
163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.previous
164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Let the linker know we don't need an executable stack */
166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov.section .note.GNU-stack,"",@progbits
167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif /* VGA_s390x */
169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--------------------------------------------------------------------*/
171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- end                                                          ---*/
172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--------------------------------------------------------------------*/
173