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