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