blob: cdcc860ceafcc6341a5a9242e5366f722c686c7e [file] [log] [blame]
sewardj2c48c7b2005-11-29 13:05:56 +00001
sewardj331dc982005-12-22 20:14:57 +00002/*--------------------------------------------------------------------*/
3/*--- Support for doing system calls. syscall-ppc64-linux.S ---*/
4/*--------------------------------------------------------------------*/
sewardj2c48c7b2005-11-29 13:05:56 +00005
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
sewardj4d474d02008-02-11 11:34:59 +000010 Copyright (C) 2005-2008 Paul Mackerras <paulus@samba.org>
sewardj2c48c7b2005-11-29 13:05:56 +000011
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25 02111-1307, USA.
26
27 The GNU General Public License is contained in the file COPYING.
28*/
29
30#include "pub_core_basics_asm.h"
sewardjc95257a2006-10-14 19:51:19 +000031#include "pub_core_vkiscnums.h"
sewardj2c48c7b2005-11-29 13:05:56 +000032#include "libvex_guest_offsets.h"
33
34
35/*----------------------------------------------------------------*/
36/*
37 Perform a syscall for the client. This will run a syscall
38 with the client's specific per-thread signal mask.
39
40 The structure of this function is such that, if the syscall is
41 interrupted by a signal, we can determine exactly what
42 execution state we were in with respect to the execution of
43 the syscall by examining the value of NIP in the signal
44 handler. This means that we can always do the appropriate
45 thing to precisely emulate the kernel's signal/syscall
46 interactions.
47
48 The syscall number is taken from the argument, even though it
49 should also be in regs->m_gpr[0]. The syscall result is written
50 back to regs->m_gpr[3]/m_xer/m_result on completion.
51
52 Returns 0 if the syscall was successfully called (even if the
sewardj331dc982005-12-22 20:14:57 +000053 syscall itself failed), or a nonzero error code in the lowest
sewardj25376162005-12-22 19:28:37 +000054 8 bits if one of the sigprocmasks failed (there's no way to
55 determine which one failed). And there's no obvious way to
56 recover from that either, but nevertheless we want to know.
sewardj2c48c7b2005-11-29 13:05:56 +000057
58 VG_(fixup_guest_state_after_syscall_interrupted) does the
59 thread state fixup in the case where we were interrupted by a
60 signal.
61
62 Prototype:
63
sewardj25376162005-12-22 19:28:37 +000064 UWord ML_(do_syscall_for_client_WRK)(
sewardj2c48c7b2005-11-29 13:05:56 +000065 Int syscallno, // r3
66 void* guest_state, // r4
67 const vki_sigset_t *sysmask, // r5
68 const vki_sigset_t *postmask, // r6
69 Int nsigwords) // r7
70*/
71/* from vki_arch.h */
72#define VKI_SIG_SETMASK 2
73
cerion297c88f2005-12-22 15:53:12 +000074.align 2
75.globl ML_(do_syscall_for_client_WRK)
76.section ".opd","aw"
77.align 3
78ML_(do_syscall_for_client_WRK):
79.quad .ML_(do_syscall_for_client_WRK),.TOC.@tocbase,0
80.previous
81.type .ML_(do_syscall_for_client_WRK),@function
sewardj2c48c7b2005-11-29 13:05:56 +000082.globl .ML_(do_syscall_for_client_WRK)
83.ML_(do_syscall_for_client_WRK):
84 /* make a stack frame */
cerion297c88f2005-12-22 15:53:12 +000085 stdu 1,-80(1)
86 std 31,72(1)
87 std 30,64(1)
88 std 29,56(1)
89 std 28,48(1)
sewardj2c48c7b2005-11-29 13:05:56 +000090 mr 31,3 /* syscall number */
91 mr 30,4 /* guest_state */
92 mr 29,6 /* postmask */
93 mr 28,7 /* nsigwords */
94
95 /* set the signal mask for doing the system call */
96 /* set up for sigprocmask(SIG_SETMASK, sysmask, postmask) */
sewardj25376162005-12-22 19:28:37 +0000971: li 0,__NR_rt_sigprocmask
sewardj2c48c7b2005-11-29 13:05:56 +000098 li 3,VKI_SIG_SETMASK
99 mr 4,5
100 mr 5,6
sewardj25376162005-12-22 19:28:37 +0000101 mr 6,7
sewardj2c48c7b2005-11-29 13:05:56 +0000102 sc /* set the mask */
103 bso 7f /* if the sigprocmask fails */
104
105 /* load up syscall args from the threadstate */
106 ld 3,OFFSET_ppc64_GPR3(30)
107 ld 4,OFFSET_ppc64_GPR4(30)
108 ld 5,OFFSET_ppc64_GPR5(30)
109 ld 6,OFFSET_ppc64_GPR6(30)
110 ld 7,OFFSET_ppc64_GPR7(30)
111 ld 8,OFFSET_ppc64_GPR8(30)
112 mr 0,31 /* syscall number */
1132: sc /* do the syscall */
114
115 /* put the result back in the threadstate */
1163: std 3,OFFSET_ppc64_GPR3(30) /* gst->GPR3 = sc result */
117 /* copy cr0.so back to simulated state */
118 mfcr 5 /* r5 = CR */
119 rlwinm 5,5,4,31,31 /* r5 = (CR >> 28) & 1 */
120 stb 5,OFFSET_ppc64_CR0_0(30) /* gst->CR0.SO = cr0.so */
121
122 /* block signals again */
123 /* set up for sigprocmask(SIG_SETMASK, postmask, NULL) */
sewardj25376162005-12-22 19:28:37 +00001244: li 0,__NR_rt_sigprocmask
sewardj2c48c7b2005-11-29 13:05:56 +0000125 li 3,VKI_SIG_SETMASK
126 mr 4,29
127 li 5,0
128 mr 6,28
129 sc /* set the mask */
130 bso 7f /* if the sigprocmask fails */
sewardj2c48c7b2005-11-29 13:05:56 +0000131 /* now safe from signals */
sewardj25376162005-12-22 19:28:37 +0000132 li 3,0 /* SUCCESS */
sewardj2c48c7b2005-11-29 13:05:56 +0000133
134 /* pop off stack frame */
cerion297c88f2005-12-22 15:53:12 +00001355: ld 28,48(1)
136 ld 29,56(1)
137 ld 30,64(1)
138 ld 31,72(1)
139 addi 1,1,80
sewardj2c48c7b2005-11-29 13:05:56 +0000140 blr
141
sewardj331dc982005-12-22 20:14:57 +0000142 /* failure: return 0x8000 | error code */
sewardj25376162005-12-22 19:28:37 +00001437: ori 3,3,0x8000 /* FAILURE -- ensure return value is nonzero */
sewardj2c48c7b2005-11-29 13:05:56 +0000144 b 5b
145
146.section .rodata
147/* export the ranges so that
148 VG_(fixup_guest_state_after_syscall_interrupted) can do the
149 right thing */
150
151.globl ML_(blksys_setup)
152.globl ML_(blksys_restart)
153.globl ML_(blksys_complete)
154.globl ML_(blksys_committed)
155.globl ML_(blksys_finished)
sewardj4246fc62006-01-02 19:06:08 +0000156ML_(blksys_setup): .quad 1b
157ML_(blksys_restart): .quad 2b
158ML_(blksys_complete): .quad 3b
159ML_(blksys_committed): .quad 4b
160ML_(blksys_finished): .quad 5b
sewardj2c48c7b2005-11-29 13:05:56 +0000161
cerion297c88f2005-12-22 15:53:12 +0000162
sewardj2c48c7b2005-11-29 13:05:56 +0000163/* Let the linker know we don't need an executable stack */
164.section .note.GNU-stack,"",@progbits
165
sewardj331dc982005-12-22 20:14:57 +0000166/*--------------------------------------------------------------------*/
167/*--- end ---*/
168/*--------------------------------------------------------------------*/