1f0c1250e324f6684757c6a15545366447ef1d64fsewardj
2f0c1250e324f6684757c6a15545366447ef1d64fsewardj/*--------------------------------------------------------------------*/
3f0c1250e324f6684757c6a15545366447ef1d64fsewardj/*--- Support for doing system calls.        syscall-arm64-linux.S ---*/
4f0c1250e324f6684757c6a15545366447ef1d64fsewardj/*--------------------------------------------------------------------*/
5f0c1250e324f6684757c6a15545366447ef1d64fsewardj
6f0c1250e324f6684757c6a15545366447ef1d64fsewardj/*
7f0c1250e324f6684757c6a15545366447ef1d64fsewardj  This file is part of Valgrind, a dynamic binary instrumentation
8f0c1250e324f6684757c6a15545366447ef1d64fsewardj  framework.
9f0c1250e324f6684757c6a15545366447ef1d64fsewardj
10f0c1250e324f6684757c6a15545366447ef1d64fsewardj  Copyright (C) 2013-2013 OpenWorks
11f0c1250e324f6684757c6a15545366447ef1d64fsewardj     info@open-works.net
12f0c1250e324f6684757c6a15545366447ef1d64fsewardj
13f0c1250e324f6684757c6a15545366447ef1d64fsewardj  This program is free software; you can redistribute it and/or
14f0c1250e324f6684757c6a15545366447ef1d64fsewardj  modify it under the terms of the GNU General Public License as
15f0c1250e324f6684757c6a15545366447ef1d64fsewardj  published by the Free Software Foundation; either version 2 of the
16f0c1250e324f6684757c6a15545366447ef1d64fsewardj  License, or (at your option) any later version.
17f0c1250e324f6684757c6a15545366447ef1d64fsewardj
18f0c1250e324f6684757c6a15545366447ef1d64fsewardj  This program is distributed in the hope that it will be useful, but
19f0c1250e324f6684757c6a15545366447ef1d64fsewardj  WITHOUT ANY WARRANTY; without even the implied warranty of
20f0c1250e324f6684757c6a15545366447ef1d64fsewardj  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21f0c1250e324f6684757c6a15545366447ef1d64fsewardj  General Public License for more details.
22f0c1250e324f6684757c6a15545366447ef1d64fsewardj
23f0c1250e324f6684757c6a15545366447ef1d64fsewardj  You should have received a copy of the GNU General Public License
24f0c1250e324f6684757c6a15545366447ef1d64fsewardj  along with this program; if not, write to the Free Software
25f0c1250e324f6684757c6a15545366447ef1d64fsewardj  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26f0c1250e324f6684757c6a15545366447ef1d64fsewardj  02111-1307, USA.
27f0c1250e324f6684757c6a15545366447ef1d64fsewardj
28f0c1250e324f6684757c6a15545366447ef1d64fsewardj  The GNU General Public License is contained in the file COPYING.
29f0c1250e324f6684757c6a15545366447ef1d64fsewardj*/
30f0c1250e324f6684757c6a15545366447ef1d64fsewardj
31f0c1250e324f6684757c6a15545366447ef1d64fsewardj#if defined(VGP_arm64_linux)
32f0c1250e324f6684757c6a15545366447ef1d64fsewardj
33f0c1250e324f6684757c6a15545366447ef1d64fsewardj#include "pub_core_basics_asm.h"
34f0c1250e324f6684757c6a15545366447ef1d64fsewardj#include "pub_core_vkiscnums_asm.h"
35f0c1250e324f6684757c6a15545366447ef1d64fsewardj#include "libvex_guest_offsets.h"
36f0c1250e324f6684757c6a15545366447ef1d64fsewardj
37f0c1250e324f6684757c6a15545366447ef1d64fsewardj
38f0c1250e324f6684757c6a15545366447ef1d64fsewardj/*----------------------------------------------------------------*/
39f0c1250e324f6684757c6a15545366447ef1d64fsewardj/*
40f0c1250e324f6684757c6a15545366447ef1d64fsewardj        Perform a syscall for the client.  This will run a syscall
41f0c1250e324f6684757c6a15545366447ef1d64fsewardj        with the client's specific per-thread signal mask.
42f0c1250e324f6684757c6a15545366447ef1d64fsewardj
43f0c1250e324f6684757c6a15545366447ef1d64fsewardj        The structure of this function is such that, if the syscall is
44f0c1250e324f6684757c6a15545366447ef1d64fsewardj        interrupted by a signal, we can determine exactly what
45f0c1250e324f6684757c6a15545366447ef1d64fsewardj        execution state we were in with respect to the execution of
46f0c1250e324f6684757c6a15545366447ef1d64fsewardj        the syscall by examining the value of IP in the signal
47f0c1250e324f6684757c6a15545366447ef1d64fsewardj        handler.  This means that we can always do the appropriate
48f0c1250e324f6684757c6a15545366447ef1d64fsewardj        thing to precisely emulate the kernel's signal/syscall
49f0c1250e324f6684757c6a15545366447ef1d64fsewardj        interactions.
50f0c1250e324f6684757c6a15545366447ef1d64fsewardj
51f0c1250e324f6684757c6a15545366447ef1d64fsewardj        The syscall number is taken from the argument, even though it
52f0c1250e324f6684757c6a15545366447ef1d64fsewardj        should also be in guest_state->guest_X8.  The syscall result
53f0c1250e324f6684757c6a15545366447ef1d64fsewardj	is written back to guest_state->guest_X0 on completion.
54f0c1250e324f6684757c6a15545366447ef1d64fsewardj
55f0c1250e324f6684757c6a15545366447ef1d64fsewardj        Returns 0 if the syscall was successfully called (even if the
56f0c1250e324f6684757c6a15545366447ef1d64fsewardj        syscall itself failed), or a nonzero error code in the lowest
57f0c1250e324f6684757c6a15545366447ef1d64fsewardj        8 bits if one of the sigprocmasks failed (there's no way to
58f0c1250e324f6684757c6a15545366447ef1d64fsewardj        determine which one failed).  And there's no obvious way to
59f0c1250e324f6684757c6a15545366447ef1d64fsewardj        recover from that either, but nevertheless we want to know.
60f0c1250e324f6684757c6a15545366447ef1d64fsewardj
61f0c1250e324f6684757c6a15545366447ef1d64fsewardj        VG_(fixup_guest_state_after_syscall_interrupted) does the
62f0c1250e324f6684757c6a15545366447ef1d64fsewardj        thread state fixup in the case where we were interrupted by a
63f0c1250e324f6684757c6a15545366447ef1d64fsewardj        signal.
64f0c1250e324f6684757c6a15545366447ef1d64fsewardj
65f0c1250e324f6684757c6a15545366447ef1d64fsewardj        Prototype:
66f0c1250e324f6684757c6a15545366447ef1d64fsewardj
67f0c1250e324f6684757c6a15545366447ef1d64fsewardj   UWord ML_(do_syscall_for_client_WRK)(
68f0c1250e324f6684757c6a15545366447ef1d64fsewardj              Int syscallno,                 // x0
69f0c1250e324f6684757c6a15545366447ef1d64fsewardj              void* guest_state,             // x1
70f0c1250e324f6684757c6a15545366447ef1d64fsewardj              const vki_sigset_t *sysmask,   // x2
71f0c1250e324f6684757c6a15545366447ef1d64fsewardj              const vki_sigset_t *postmask,  // x3
72f0c1250e324f6684757c6a15545366447ef1d64fsewardj              Int nsigwords)                 // x4
73f0c1250e324f6684757c6a15545366447ef1d64fsewardj*/
74f0c1250e324f6684757c6a15545366447ef1d64fsewardj/* from vki-arm64-linux.h */
75f0c1250e324f6684757c6a15545366447ef1d64fsewardj#define VKI_SIG_SETMASK 2
76f0c1250e324f6684757c6a15545366447ef1d64fsewardj
77f0c1250e324f6684757c6a15545366447ef1d64fsewardj.globl ML_(do_syscall_for_client_WRK)
78f0c1250e324f6684757c6a15545366447ef1d64fsewardjML_(do_syscall_for_client_WRK):
79f0c1250e324f6684757c6a15545366447ef1d64fsewardj
80f0c1250e324f6684757c6a15545366447ef1d64fsewardj   /* Stash callee-saves and our args on the stack */
81f0c1250e324f6684757c6a15545366447ef1d64fsewardj   stp  x29, x30, [sp, #-16]!
82f0c1250e324f6684757c6a15545366447ef1d64fsewardj   stp  x27, x28, [sp, #-16]!
83f0c1250e324f6684757c6a15545366447ef1d64fsewardj   stp  x25, x26, [sp, #-16]!
84f0c1250e324f6684757c6a15545366447ef1d64fsewardj   stp  x23, x24, [sp, #-16]!
85f0c1250e324f6684757c6a15545366447ef1d64fsewardj   stp  x21, x22, [sp, #-16]!
86f0c1250e324f6684757c6a15545366447ef1d64fsewardj   stp  x19, x20, [sp, #-16]!
87f0c1250e324f6684757c6a15545366447ef1d64fsewardj   stp  x4,  x5,  [sp, #-16]!
88f0c1250e324f6684757c6a15545366447ef1d64fsewardj   stp  x2,  x3,  [sp, #-16]!
89f0c1250e324f6684757c6a15545366447ef1d64fsewardj   stp  x0,  x1,  [sp, #-16]!
90f0c1250e324f6684757c6a15545366447ef1d64fsewardj
91f0c1250e324f6684757c6a15545366447ef1d64fsewardj1:
92f0c1250e324f6684757c6a15545366447ef1d64fsewardj
93f0c1250e324f6684757c6a15545366447ef1d64fsewardj   mov x8, #__NR_rt_sigprocmask
94f0c1250e324f6684757c6a15545366447ef1d64fsewardj   mov x0, #VKI_SIG_SETMASK
95f0c1250e324f6684757c6a15545366447ef1d64fsewardj   mov x1, x2 /* sysmask */
96f0c1250e324f6684757c6a15545366447ef1d64fsewardj   mov x2, x3 /* postmask */
97f0c1250e324f6684757c6a15545366447ef1d64fsewardj   mov x3, x4 /* nsigwords */
98f0c1250e324f6684757c6a15545366447ef1d64fsewardj   svc 0x00000000
99f0c1250e324f6684757c6a15545366447ef1d64fsewardj
100f0c1250e324f6684757c6a15545366447ef1d64fsewardj
101f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldr x5, [sp, #8] /* saved x1 == guest_state */
102f0c1250e324f6684757c6a15545366447ef1d64fsewardj
103f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldr x8, [sp, #0] /* saved x0 == syscall# */
104f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldr x0, [x5, #OFFSET_arm64_X0]
105f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldr x1, [x5, #OFFSET_arm64_X1]
106f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldr x2, [x5, #OFFSET_arm64_X2]
107f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldr x3, [x5, #OFFSET_arm64_X3]
108f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldr x4, [x5, #OFFSET_arm64_X4]
109f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldr x5, [x5, #OFFSET_arm64_X5]
110f0c1250e324f6684757c6a15545366447ef1d64fsewardj
111f0c1250e324f6684757c6a15545366447ef1d64fsewardj2: svc 0x00000000
112f0c1250e324f6684757c6a15545366447ef1d64fsewardj3:
113f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldr x5, [sp, #8] /* saved x1 == guest_state */
114f0c1250e324f6684757c6a15545366447ef1d64fsewardj   str x0, [x5, #OFFSET_arm64_X0]
115f0c1250e324f6684757c6a15545366447ef1d64fsewardj
116f0c1250e324f6684757c6a15545366447ef1d64fsewardj4:
117f0c1250e324f6684757c6a15545366447ef1d64fsewardj   mov x8, #__NR_rt_sigprocmask
118f0c1250e324f6684757c6a15545366447ef1d64fsewardj   mov x0, #VKI_SIG_SETMASK
119f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldr x1, [sp, #24] /* saved x3 == postmask */
120f0c1250e324f6684757c6a15545366447ef1d64fsewardj   mov x2, #0
121f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldr x3, [sp, #32] /* saved x4 == nsigwords */
122f0c1250e324f6684757c6a15545366447ef1d64fsewardj   svc 0x00000000
123f0c1250e324f6684757c6a15545366447ef1d64fsewardj
124f0c1250e324f6684757c6a15545366447ef1d64fsewardj   cmp x0, #0
125f0c1250e324f6684757c6a15545366447ef1d64fsewardj   blt 7f
126f0c1250e324f6684757c6a15545366447ef1d64fsewardj
127f0c1250e324f6684757c6a15545366447ef1d64fsewardj5: /* Success: return zero */
128f0c1250e324f6684757c6a15545366447ef1d64fsewardj   mov  x0, #0
129f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  xzr, x1,  [sp], #16
130f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  x2,  x3,  [sp], #16
131f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  x4,  x5,  [sp], #16
132f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  x19, x20, [sp], #16
133f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  x21, x22, [sp], #16
134f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  x23, x24, [sp], #16
135f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  x25, x26, [sp], #16
136f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  x27, x28, [sp], #16
137f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  x29, x30, [sp], #16
138f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ret
139f0c1250e324f6684757c6a15545366447ef1d64fsewardj
140f0c1250e324f6684757c6a15545366447ef1d64fsewardj7: /* Failure: return 0x8000 | error code */
141f0c1250e324f6684757c6a15545366447ef1d64fsewardj   orr  x0, x0, #0x8000
142f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  xzr, x1,  [sp], #16
143f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  x2,  x3,  [sp], #16
144f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  x4,  x5,  [sp], #16
145f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  x19, x20, [sp], #16
146f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  x21, x22, [sp], #16
147f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  x23, x24, [sp], #16
148f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  x25, x26, [sp], #16
149f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  x27, x28, [sp], #16
150f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ldp  x29, x30, [sp], #16
151f0c1250e324f6684757c6a15545366447ef1d64fsewardj   ret
152f0c1250e324f6684757c6a15545366447ef1d64fsewardj
153f0c1250e324f6684757c6a15545366447ef1d64fsewardj
154f0c1250e324f6684757c6a15545366447ef1d64fsewardj
155f0c1250e324f6684757c6a15545366447ef1d64fsewardj.section .rodata
156f0c1250e324f6684757c6a15545366447ef1d64fsewardj/* export the ranges so that
157f0c1250e324f6684757c6a15545366447ef1d64fsewardj   VG_(fixup_guest_state_after_syscall_interrupted) can do the
158f0c1250e324f6684757c6a15545366447ef1d64fsewardj   right thing */
159f0c1250e324f6684757c6a15545366447ef1d64fsewardj
1600910203449e7fddb1dea4f040cdcf997b7d3ad5asewardj.align 3
161f0c1250e324f6684757c6a15545366447ef1d64fsewardj.globl ML_(blksys_setup)
162f0c1250e324f6684757c6a15545366447ef1d64fsewardj.globl ML_(blksys_restart)
163f0c1250e324f6684757c6a15545366447ef1d64fsewardj.globl ML_(blksys_complete)
164f0c1250e324f6684757c6a15545366447ef1d64fsewardj.globl ML_(blksys_committed)
165f0c1250e324f6684757c6a15545366447ef1d64fsewardj.globl ML_(blksys_finished)
166f0c1250e324f6684757c6a15545366447ef1d64fsewardjML_(blksys_setup):      .quad 1b
167f0c1250e324f6684757c6a15545366447ef1d64fsewardjML_(blksys_restart):    .quad 2b
168f0c1250e324f6684757c6a15545366447ef1d64fsewardjML_(blksys_complete):   .quad 3b
169f0c1250e324f6684757c6a15545366447ef1d64fsewardjML_(blksys_committed):  .quad 4b
170f0c1250e324f6684757c6a15545366447ef1d64fsewardjML_(blksys_finished):   .quad 5b
171f0c1250e324f6684757c6a15545366447ef1d64fsewardj
172f0c1250e324f6684757c6a15545366447ef1d64fsewardj/* Let the linker know we don't need an executable stack */
173f0c1250e324f6684757c6a15545366447ef1d64fsewardj.section .note.GNU-stack,"",%progbits
174f0c1250e324f6684757c6a15545366447ef1d64fsewardj
175f0c1250e324f6684757c6a15545366447ef1d64fsewardj.previous
176f0c1250e324f6684757c6a15545366447ef1d64fsewardj
177f0c1250e324f6684757c6a15545366447ef1d64fsewardj#endif // defined(VGP_arm_linux)
178f0c1250e324f6684757c6a15545366447ef1d64fsewardj
179f0c1250e324f6684757c6a15545366447ef1d64fsewardj/*--------------------------------------------------------------------*/
180f0c1250e324f6684757c6a15545366447ef1d64fsewardj/*--- end                                                          ---*/
181f0c1250e324f6684757c6a15545366447ef1d64fsewardj/*--------------------------------------------------------------------*/
182