1/*--------------------------------------------------------------------*/
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
31#include "pub_core_basics_asm.h"
32
33#if defined(VGP_tilegx_linux)
34
35#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
184
185#endif /* defined(VGP_tilegx_linux) */
186
187/* Let the linker know we don't need an executable stack */
188MARK_STACK_NO_EXEC
189
190/*--------------------------------------------------------------------*/
191/*--- end                                                          ---*/
192/*--------------------------------------------------------------------*/
193
194