blob: 7be2f6a9acf8fe881b15bca1e26fd55f49004cce [file] [log] [blame]
sewardj112711a2015-04-10 12:30:09 +00001/*--------------------------------------------------------------------*/
2/*--- Support for doing system calls. syscall-tilegx-linux.S ---*/
3/*--------------------------------------------------------------------*/
4
5/*
6 This file is part of Valgrind, a dynamic binary instrumentation
7 framework.
8
9 Copyright (C) 2010-2012 Tilera Corp.
10
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2 of the
14 License, or (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 02111-1307, USA.
25
26 The GNU General Public License is contained in the file COPYING.
27*/
28
29/* Contributed by Zhi-Gang Liu <zliu at tilera dot com> */
30
florian3f1d6132015-09-30 20:30:48 +000031#include "pub_core_basics_asm.h"
32
sewardj112711a2015-04-10 12:30:09 +000033#if defined(VGP_tilegx_linux)
34
sewardj112711a2015-04-10 12:30:09 +000035#include "pub_core_vkiscnums_asm.h"
36#include "libvex_guest_offsets.h"
37
38
39/*----------------------------------------------------------------*/
40/*
41 Perform a syscall for the client. This will run a syscall
42 with the client's specific per-thread signal mask.
43
44 The structure of this function is such that, if the syscall is
45 interrupted by a signal, we can determine exactly what
46 execution state we were in with respect to the execution of
47 the syscall by examining the value of IP in the signal
48 handler. This means that we can always do the appropriate
49 thing to precisely emulate the kernel's signal/syscall
50 interactions.
51
52 The syscall number is taken from the argument, even though it
53 should also be in regs->v0. The syscall result is written
54 back to regs->v0 on completion.
55
56 Returns 0 if the syscall was successfully called (even if the
57 syscall itself failed), or a nonzero error code in the lowest
58 8 bits if one of the sigprocmasks failed (there's no way to
59 determine which one failed). And there's no obvious way to
60 recover from that either, but nevertheless we want to know.
61
62 VG_(fixup_guest_state_after_syscall_interrupted) does the
63 thread state fixup in the case where we were interrupted by a
64 signal.
65
66 Prototype:
67
68 UWord ML_(do_syscall_for_client_WRK)(
69 Int syscallno, // r0
70 void* guest_state, // r1
71 const vki_sigset_t *sysmask, // r2
72 const vki_sigset_t *postmask, // r3
73 Int nsigwords) // r4
74*/
75/* from vki_arch.h */
76#define VKI_SIG_SETMASK 2
77
78.globl ML_(do_syscall_for_client_WRK)
79ML_(do_syscall_for_client_WRK):
80
81 addli sp, sp, -64 // alloc 64B new stack space
82 addli r29, sp, 56 // r29 points to offset 56 above sp
83 st_add r29, r0, -8 // save r0
84 // offset 48
85 st_add r29, r1, -8 // save r1
86 // offset 40
87 st_add r29, r2, -8 // save r2
88 // offset 32
89 st_add r29, r3, -8 // save r3
90 // offset 24
91 st_add r29, r4, -8 // save r4
92 // offset 16
93 st r29, lr // save lr
941:
95 {
96 moveli r10, __NR_rt_sigprocmask
97 moveli r0, VKI_SIG_SETMASK
98 }
99 {
100 move r1, r2
101 move r2, r3
102 }
103 move r3, r4
104 swint1
105
106 // error, go 7f
107 bnez r1, 7f
108
109 /* Get registers from guest_state. */
110 addli r29, sp, 56 // get syscallno
111 ld r10, r29
112 addli r29, sp, 48
113 ld r29, r29 // r29 points to guest_state
114 ld_add r0, r29, 8 // read r0
115 ld_add r1, r29, 8 // read r1
116 ld_add r2, r29, 8 // read r2
117 ld_add r3, r29, 8 // read r3
118 ld_add r4, r29, 8 // read r4
119 ld_add r5, r29, 8 // read r5
120
1212: swint1 // syscall
1223:
123 // Write register into guest_state
124 addli r29, sp, 48
125 ld r29, r29
126 st_add r29, r0, 8
127 st_add r29, r1, 8
128 st_add r29, r2, 8
129 st_add r29, r3, 8
130 st_add r29, r4, 8
131 st_add r29, r5, 8
132 nop
1334:
134 {
135 moveli r10, __NR_rt_sigprocmask
136 moveli r0, VKI_SIG_SETMASK
137 }
138 addli r29, sp, 32
139 {
140 ld r1, r29
141 movei r2, 0
142 }
143 addli r29, sp, 24
144 ld r3, r29
145
146 swint1
147 // error, go 7f
148 bnez r1, 7f
149 nop
1505: addli r29, sp, 16
151 {
152 ld lr, r29 // restore lr
153 addli sp, sp, 64
154 }
155 jr lr
156
1577: addi r29, sp, 16
158 {
159 ld lr, r29 // restore lr
160 addi sp, sp, 64
161 }
162 {
163 // r0 = 0x8000
164 shl16insli r0, zero, -0x8000
165 jr lr
166 }
167
168 .section .rodata
169 /* export the ranges so that
170 VG_(fixup_guest_state_after_syscall_interrupted) can do the
171 right thing */
172
173 .globl ML_(blksys_setup)
174 .globl ML_(blksys_restart)
175 .globl ML_(blksys_complete)
176 .globl ML_(blksys_committed)
177 .globl ML_(blksys_finished)
178 ML_(blksys_setup): .quad 1b
179 ML_(blksys_restart): .quad 2b
180 ML_(blksys_complete): .quad 3b
181 ML_(blksys_committed): .quad 4b
182 ML_(blksys_finished): .quad 5b
183 .previous
sewardj112711a2015-04-10 12:30:09 +0000184
185#endif /* defined(VGP_tilegx_linux) */
186
florian3f1d6132015-09-30 20:30:48 +0000187/* Let the linker know we don't need an executable stack */
188MARK_STACK_NO_EXEC
189
sewardj112711a2015-04-10 12:30:09 +0000190/*--------------------------------------------------------------------*/
191/*--- end ---*/
192/*--------------------------------------------------------------------*/
193