1112711afefcfcd43680c7c4aa8d38ef180e8811esewardj/*--------------------------------------------------------------------*/ 2112711afefcfcd43680c7c4aa8d38ef180e8811esewardj/*--- Support for doing system calls. syscall-tilegx-linux.S ---*/ 3112711afefcfcd43680c7c4aa8d38ef180e8811esewardj/*--------------------------------------------------------------------*/ 4112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 5112711afefcfcd43680c7c4aa8d38ef180e8811esewardj/* 6112711afefcfcd43680c7c4aa8d38ef180e8811esewardj This file is part of Valgrind, a dynamic binary instrumentation 7112711afefcfcd43680c7c4aa8d38ef180e8811esewardj framework. 8112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 9112711afefcfcd43680c7c4aa8d38ef180e8811esewardj Copyright (C) 2010-2012 Tilera Corp. 10112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 11112711afefcfcd43680c7c4aa8d38ef180e8811esewardj This program is free software; you can redistribute it and/or 12112711afefcfcd43680c7c4aa8d38ef180e8811esewardj modify it under the terms of the GNU General Public License as 13112711afefcfcd43680c7c4aa8d38ef180e8811esewardj published by the Free Software Foundation; either version 2 of the 14112711afefcfcd43680c7c4aa8d38ef180e8811esewardj License, or (at your option) any later version. 15112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 16112711afefcfcd43680c7c4aa8d38ef180e8811esewardj This program is distributed in the hope that it will be useful, but 17112711afefcfcd43680c7c4aa8d38ef180e8811esewardj WITHOUT ANY WARRANTY; without even the implied warranty of 18112711afefcfcd43680c7c4aa8d38ef180e8811esewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19112711afefcfcd43680c7c4aa8d38ef180e8811esewardj General Public License for more details. 20112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 21112711afefcfcd43680c7c4aa8d38ef180e8811esewardj You should have received a copy of the GNU General Public License 22112711afefcfcd43680c7c4aa8d38ef180e8811esewardj along with this program; if not, write to the Free Software 23112711afefcfcd43680c7c4aa8d38ef180e8811esewardj Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 24112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 02111-1307, USA. 25112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 26112711afefcfcd43680c7c4aa8d38ef180e8811esewardj The GNU General Public License is contained in the file COPYING. 27112711afefcfcd43680c7c4aa8d38ef180e8811esewardj*/ 28112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 29112711afefcfcd43680c7c4aa8d38ef180e8811esewardj/* Contributed by Zhi-Gang Liu <zliu at tilera dot com> */ 30112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 31112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#if defined(VGP_tilegx_linux) 32112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 33112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#include "pub_core_basics_asm.h" 34112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#include "pub_core_vkiscnums_asm.h" 35112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#include "libvex_guest_offsets.h" 36112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 37112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 38112711afefcfcd43680c7c4aa8d38ef180e8811esewardj/*----------------------------------------------------------------*/ 39112711afefcfcd43680c7c4aa8d38ef180e8811esewardj/* 40112711afefcfcd43680c7c4aa8d38ef180e8811esewardj Perform a syscall for the client. This will run a syscall 41112711afefcfcd43680c7c4aa8d38ef180e8811esewardj with the client's specific per-thread signal mask. 42112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 43112711afefcfcd43680c7c4aa8d38ef180e8811esewardj The structure of this function is such that, if the syscall is 44112711afefcfcd43680c7c4aa8d38ef180e8811esewardj interrupted by a signal, we can determine exactly what 45112711afefcfcd43680c7c4aa8d38ef180e8811esewardj execution state we were in with respect to the execution of 46112711afefcfcd43680c7c4aa8d38ef180e8811esewardj the syscall by examining the value of IP in the signal 47112711afefcfcd43680c7c4aa8d38ef180e8811esewardj handler. This means that we can always do the appropriate 48112711afefcfcd43680c7c4aa8d38ef180e8811esewardj thing to precisely emulate the kernel's signal/syscall 49112711afefcfcd43680c7c4aa8d38ef180e8811esewardj interactions. 50112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 51112711afefcfcd43680c7c4aa8d38ef180e8811esewardj The syscall number is taken from the argument, even though it 52112711afefcfcd43680c7c4aa8d38ef180e8811esewardj should also be in regs->v0. The syscall result is written 53112711afefcfcd43680c7c4aa8d38ef180e8811esewardj back to regs->v0 on completion. 54112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 55112711afefcfcd43680c7c4aa8d38ef180e8811esewardj Returns 0 if the syscall was successfully called (even if the 56112711afefcfcd43680c7c4aa8d38ef180e8811esewardj syscall itself failed), or a nonzero error code in the lowest 57112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 8 bits if one of the sigprocmasks failed (there's no way to 58112711afefcfcd43680c7c4aa8d38ef180e8811esewardj determine which one failed). And there's no obvious way to 59112711afefcfcd43680c7c4aa8d38ef180e8811esewardj recover from that either, but nevertheless we want to know. 60112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 61112711afefcfcd43680c7c4aa8d38ef180e8811esewardj VG_(fixup_guest_state_after_syscall_interrupted) does the 62112711afefcfcd43680c7c4aa8d38ef180e8811esewardj thread state fixup in the case where we were interrupted by a 63112711afefcfcd43680c7c4aa8d38ef180e8811esewardj signal. 64112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 65112711afefcfcd43680c7c4aa8d38ef180e8811esewardj Prototype: 66112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 67112711afefcfcd43680c7c4aa8d38ef180e8811esewardj UWord ML_(do_syscall_for_client_WRK)( 68112711afefcfcd43680c7c4aa8d38ef180e8811esewardj Int syscallno, // r0 69112711afefcfcd43680c7c4aa8d38ef180e8811esewardj void* guest_state, // r1 70112711afefcfcd43680c7c4aa8d38ef180e8811esewardj const vki_sigset_t *sysmask, // r2 71112711afefcfcd43680c7c4aa8d38ef180e8811esewardj const vki_sigset_t *postmask, // r3 72112711afefcfcd43680c7c4aa8d38ef180e8811esewardj Int nsigwords) // r4 73112711afefcfcd43680c7c4aa8d38ef180e8811esewardj*/ 74112711afefcfcd43680c7c4aa8d38ef180e8811esewardj/* from vki_arch.h */ 75112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#define VKI_SIG_SETMASK 2 76112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 77112711afefcfcd43680c7c4aa8d38ef180e8811esewardj.globl ML_(do_syscall_for_client_WRK) 78112711afefcfcd43680c7c4aa8d38ef180e8811esewardjML_(do_syscall_for_client_WRK): 79112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 80112711afefcfcd43680c7c4aa8d38ef180e8811esewardj addli sp, sp, -64 // alloc 64B new stack space 81112711afefcfcd43680c7c4aa8d38ef180e8811esewardj addli r29, sp, 56 // r29 points to offset 56 above sp 82112711afefcfcd43680c7c4aa8d38ef180e8811esewardj st_add r29, r0, -8 // save r0 83112711afefcfcd43680c7c4aa8d38ef180e8811esewardj // offset 48 84112711afefcfcd43680c7c4aa8d38ef180e8811esewardj st_add r29, r1, -8 // save r1 85112711afefcfcd43680c7c4aa8d38ef180e8811esewardj // offset 40 86112711afefcfcd43680c7c4aa8d38ef180e8811esewardj st_add r29, r2, -8 // save r2 87112711afefcfcd43680c7c4aa8d38ef180e8811esewardj // offset 32 88112711afefcfcd43680c7c4aa8d38ef180e8811esewardj st_add r29, r3, -8 // save r3 89112711afefcfcd43680c7c4aa8d38ef180e8811esewardj // offset 24 90112711afefcfcd43680c7c4aa8d38ef180e8811esewardj st_add r29, r4, -8 // save r4 91112711afefcfcd43680c7c4aa8d38ef180e8811esewardj // offset 16 92112711afefcfcd43680c7c4aa8d38ef180e8811esewardj st r29, lr // save lr 93112711afefcfcd43680c7c4aa8d38ef180e8811esewardj1: 94112711afefcfcd43680c7c4aa8d38ef180e8811esewardj { 95112711afefcfcd43680c7c4aa8d38ef180e8811esewardj moveli r10, __NR_rt_sigprocmask 96112711afefcfcd43680c7c4aa8d38ef180e8811esewardj moveli r0, VKI_SIG_SETMASK 97112711afefcfcd43680c7c4aa8d38ef180e8811esewardj } 98112711afefcfcd43680c7c4aa8d38ef180e8811esewardj { 99112711afefcfcd43680c7c4aa8d38ef180e8811esewardj move r1, r2 100112711afefcfcd43680c7c4aa8d38ef180e8811esewardj move r2, r3 101112711afefcfcd43680c7c4aa8d38ef180e8811esewardj } 102112711afefcfcd43680c7c4aa8d38ef180e8811esewardj move r3, r4 103112711afefcfcd43680c7c4aa8d38ef180e8811esewardj swint1 104112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 105112711afefcfcd43680c7c4aa8d38ef180e8811esewardj // error, go 7f 106112711afefcfcd43680c7c4aa8d38ef180e8811esewardj bnez r1, 7f 107112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 108112711afefcfcd43680c7c4aa8d38ef180e8811esewardj /* Get registers from guest_state. */ 109112711afefcfcd43680c7c4aa8d38ef180e8811esewardj addli r29, sp, 56 // get syscallno 110112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ld r10, r29 111112711afefcfcd43680c7c4aa8d38ef180e8811esewardj addli r29, sp, 48 112112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ld r29, r29 // r29 points to guest_state 113112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ld_add r0, r29, 8 // read r0 114112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ld_add r1, r29, 8 // read r1 115112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ld_add r2, r29, 8 // read r2 116112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ld_add r3, r29, 8 // read r3 117112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ld_add r4, r29, 8 // read r4 118112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ld_add r5, r29, 8 // read r5 119112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 120112711afefcfcd43680c7c4aa8d38ef180e8811esewardj2: swint1 // syscall 121112711afefcfcd43680c7c4aa8d38ef180e8811esewardj3: 122112711afefcfcd43680c7c4aa8d38ef180e8811esewardj // Write register into guest_state 123112711afefcfcd43680c7c4aa8d38ef180e8811esewardj addli r29, sp, 48 124112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ld r29, r29 125112711afefcfcd43680c7c4aa8d38ef180e8811esewardj st_add r29, r0, 8 126112711afefcfcd43680c7c4aa8d38ef180e8811esewardj st_add r29, r1, 8 127112711afefcfcd43680c7c4aa8d38ef180e8811esewardj st_add r29, r2, 8 128112711afefcfcd43680c7c4aa8d38ef180e8811esewardj st_add r29, r3, 8 129112711afefcfcd43680c7c4aa8d38ef180e8811esewardj st_add r29, r4, 8 130112711afefcfcd43680c7c4aa8d38ef180e8811esewardj st_add r29, r5, 8 131112711afefcfcd43680c7c4aa8d38ef180e8811esewardj nop 132112711afefcfcd43680c7c4aa8d38ef180e8811esewardj4: 133112711afefcfcd43680c7c4aa8d38ef180e8811esewardj { 134112711afefcfcd43680c7c4aa8d38ef180e8811esewardj moveli r10, __NR_rt_sigprocmask 135112711afefcfcd43680c7c4aa8d38ef180e8811esewardj moveli r0, VKI_SIG_SETMASK 136112711afefcfcd43680c7c4aa8d38ef180e8811esewardj } 137112711afefcfcd43680c7c4aa8d38ef180e8811esewardj addli r29, sp, 32 138112711afefcfcd43680c7c4aa8d38ef180e8811esewardj { 139112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ld r1, r29 140112711afefcfcd43680c7c4aa8d38ef180e8811esewardj movei r2, 0 141112711afefcfcd43680c7c4aa8d38ef180e8811esewardj } 142112711afefcfcd43680c7c4aa8d38ef180e8811esewardj addli r29, sp, 24 143112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ld r3, r29 144112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 145112711afefcfcd43680c7c4aa8d38ef180e8811esewardj swint1 146112711afefcfcd43680c7c4aa8d38ef180e8811esewardj // error, go 7f 147112711afefcfcd43680c7c4aa8d38ef180e8811esewardj bnez r1, 7f 148112711afefcfcd43680c7c4aa8d38ef180e8811esewardj nop 149112711afefcfcd43680c7c4aa8d38ef180e8811esewardj5: addli r29, sp, 16 150112711afefcfcd43680c7c4aa8d38ef180e8811esewardj { 151112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ld lr, r29 // restore lr 152112711afefcfcd43680c7c4aa8d38ef180e8811esewardj addli sp, sp, 64 153112711afefcfcd43680c7c4aa8d38ef180e8811esewardj } 154112711afefcfcd43680c7c4aa8d38ef180e8811esewardj jr lr 155112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 156112711afefcfcd43680c7c4aa8d38ef180e8811esewardj7: addi r29, sp, 16 157112711afefcfcd43680c7c4aa8d38ef180e8811esewardj { 158112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ld lr, r29 // restore lr 159112711afefcfcd43680c7c4aa8d38ef180e8811esewardj addi sp, sp, 64 160112711afefcfcd43680c7c4aa8d38ef180e8811esewardj } 161112711afefcfcd43680c7c4aa8d38ef180e8811esewardj { 162112711afefcfcd43680c7c4aa8d38ef180e8811esewardj // r0 = 0x8000 163112711afefcfcd43680c7c4aa8d38ef180e8811esewardj shl16insli r0, zero, -0x8000 164112711afefcfcd43680c7c4aa8d38ef180e8811esewardj jr lr 165112711afefcfcd43680c7c4aa8d38ef180e8811esewardj } 166112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 167112711afefcfcd43680c7c4aa8d38ef180e8811esewardj .section .rodata 168112711afefcfcd43680c7c4aa8d38ef180e8811esewardj /* export the ranges so that 169112711afefcfcd43680c7c4aa8d38ef180e8811esewardj VG_(fixup_guest_state_after_syscall_interrupted) can do the 170112711afefcfcd43680c7c4aa8d38ef180e8811esewardj right thing */ 171112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 172112711afefcfcd43680c7c4aa8d38ef180e8811esewardj .globl ML_(blksys_setup) 173112711afefcfcd43680c7c4aa8d38ef180e8811esewardj .globl ML_(blksys_restart) 174112711afefcfcd43680c7c4aa8d38ef180e8811esewardj .globl ML_(blksys_complete) 175112711afefcfcd43680c7c4aa8d38ef180e8811esewardj .globl ML_(blksys_committed) 176112711afefcfcd43680c7c4aa8d38ef180e8811esewardj .globl ML_(blksys_finished) 177112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ML_(blksys_setup): .quad 1b 178112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ML_(blksys_restart): .quad 2b 179112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ML_(blksys_complete): .quad 3b 180112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ML_(blksys_committed): .quad 4b 181112711afefcfcd43680c7c4aa8d38ef180e8811esewardj ML_(blksys_finished): .quad 5b 182112711afefcfcd43680c7c4aa8d38ef180e8811esewardj .previous 183112711afefcfcd43680c7c4aa8d38ef180e8811esewardj /* Let the linker know we don't need an executable stack */ 184112711afefcfcd43680c7c4aa8d38ef180e8811esewardj .section .note.GNU-stack,"",%progbits 185112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 186112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#endif /* defined(VGP_tilegx_linux) */ 187112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 188112711afefcfcd43680c7c4aa8d38ef180e8811esewardj/*--------------------------------------------------------------------*/ 189112711afefcfcd43680c7c4aa8d38ef180e8811esewardj/*--- end ---*/ 190112711afefcfcd43680c7c4aa8d38ef180e8811esewardj/*--------------------------------------------------------------------*/ 191112711afefcfcd43680c7c4aa8d38ef180e8811esewardj 192