1
2 /*--------------------------------------------------------------------*/
3 /*--- Platform-specific syscalls stuff. syswrap-ppc32-linux.c ---*/
4 /*--------------------------------------------------------------------*/
5
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2005-2010 Nicholas Nethercote <njn@valgrind.org>
11 Copyright (C) 2005-2010 Cerion Armour-Brown <cerion@open-works.co.uk>
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29 */
30
31 #if defined(VGP_ppc32_linux)
32
33 #include "pub_core_basics.h"
34 #include "pub_core_vki.h"
35 #include "pub_core_vkiscnums.h"
36 #include "pub_core_threadstate.h"
37 #include "pub_core_aspacemgr.h"
38 #include "pub_core_debuglog.h"
39 #include "pub_core_libcbase.h"
40 #include "pub_core_libcassert.h"
41 #include "pub_core_libcprint.h"
42 #include "pub_core_libcproc.h"
43 #include "pub_core_libcsignal.h"
44 #include "pub_core_options.h"
45 #include "pub_core_scheduler.h"
46 #include "pub_core_sigframe.h" // For VG_(sigframe_destroy)()
47 #include "pub_core_signals.h"
48 #include "pub_core_syscall.h"
49 #include "pub_core_syswrap.h"
50 #include "pub_core_tooliface.h"
51 #include "pub_core_stacks.h" // VG_(register_stack)
52
53 #include "priv_types_n_macros.h"
54 #include "priv_syswrap-generic.h" /* for decls of generic wrappers */
55 #include "priv_syswrap-linux.h" /* for decls of linux-ish wrappers */
56 #include "priv_syswrap-main.h"
57
58
59 /* ---------------------------------------------------------------------
60 clone() handling
61 ------------------------------------------------------------------ */
62
63 /* Call f(arg1), but first switch stacks, using 'stack' as the new
64 stack, and use 'retaddr' as f's return-to address. Also, clear all
65 the integer registers before entering f.*/
66 __attribute__((noreturn))
67 void ML_(call_on_new_stack_0_1) ( Addr stack,
68 Addr retaddr,
69 void (*f)(Word),
70 Word arg1 );
71 // r3 = stack
72 // r4 = retaddr
73 // r5 = f
74 // r6 = arg1
75 asm(
76 ".text\n"
77 ".globl vgModuleLocal_call_on_new_stack_0_1\n"
78 "vgModuleLocal_call_on_new_stack_0_1:\n"
79 " mr %r1,%r3\n\t" // stack to %sp
80 " mtlr %r4\n\t" // retaddr to %lr
81 " mtctr %r5\n\t" // f to count reg
82 " mr %r3,%r6\n\t" // arg1 to %r3
83 " li 0,0\n\t" // zero all GP regs
84 " li 4,0\n\t"
85 " li 5,0\n\t"
86 " li 6,0\n\t"
87 " li 7,0\n\t"
88 " li 8,0\n\t"
89 " li 9,0\n\t"
90 " li 10,0\n\t"
91 " li 11,0\n\t"
92 " li 12,0\n\t"
93 " li 13,0\n\t"
94 " li 14,0\n\t"
95 " li 15,0\n\t"
96 " li 16,0\n\t"
97 " li 17,0\n\t"
98 " li 18,0\n\t"
99 " li 19,0\n\t"
100 " li 20,0\n\t"
101 " li 21,0\n\t"
102 " li 22,0\n\t"
103 " li 23,0\n\t"
104 " li 24,0\n\t"
105 " li 25,0\n\t"
106 " li 26,0\n\t"
107 " li 27,0\n\t"
108 " li 28,0\n\t"
109 " li 29,0\n\t"
110 " li 30,0\n\t"
111 " li 31,0\n\t"
112 " mtxer 0\n\t" // CAB: Need this?
113 " mtcr 0\n\t" // CAB: Need this?
114 " bctr\n\t" // jump to dst
115 " trap\n" // should never get here
116 ".previous\n"
117 );
118
119
120 /*
121 Perform a clone system call. clone is strange because it has
122 fork()-like return-twice semantics, so it needs special
123 handling here.
124
125 Upon entry, we have:
126
127 int (fn)(void*) in r3
128 void* child_stack in r4
129 int flags in r5
130 void* arg in r6
131 pid_t* child_tid in r7
132 pid_t* parent_tid in r8
133 void* ??? in r9
134
135 System call requires:
136
137 int $__NR_clone in r0 (sc number)
138 int flags in r3 (sc arg1)
139 void* child_stack in r4 (sc arg2)
140 pid_t* parent_tid in r5 (sc arg3)
141 ?? child_tls in r6 (sc arg4)
142 pid_t* child_tid in r7 (sc arg5)
143 void* ??? in r8 (sc arg6)
144
145 Returns an Int encoded in the linux-ppc32 way, not a SysRes.
146 */
147 #define __NR_CLONE VG_STRINGIFY(__NR_clone)
148 #define __NR_EXIT VG_STRINGIFY(__NR_exit)
149
150 extern
151 ULong do_syscall_clone_ppc32_linux ( Word (*fn)(void *),
152 void* stack,
153 Int flags,
154 void* arg,
155 Int* child_tid,
156 Int* parent_tid,
157 vki_modify_ldt_t * );
158 asm(
159 ".text\n"
160 "do_syscall_clone_ppc32_linux:\n"
161 " stwu 1,-32(1)\n"
162 " stw 29,20(1)\n"
163 " stw 30,24(1)\n"
164 " stw 31,28(1)\n"
165 " mr 30,3\n" // preserve fn
166 " mr 31,6\n" // preserve arg
167
168 // setup child stack
169 " rlwinm 4,4,0,~0xf\n" // trim sp to multiple of 16 bytes
170 " li 0,0\n"
171 " stwu 0,-16(4)\n" // make initial stack frame
172 " mr 29,4\n" // preserve sp
173
174 // setup syscall
175 " li 0,"__NR_CLONE"\n" // syscall number
176 " mr 3,5\n" // syscall arg1: flags
177 // r4 already setup // syscall arg2: child_stack
178 " mr 5,8\n" // syscall arg3: parent_tid
179 " mr 6,2\n" // syscall arg4: REAL THREAD tls
180 " mr 7,7\n" // syscall arg5: child_tid
181 " mr 8,8\n" // syscall arg6: ????
182 " mr 9,9\n" // syscall arg7: ????
183
184 " sc\n" // clone()
185
186 " mfcr 4\n" // return CR in r4 (low word of ULong)
187 " cmpwi 3,0\n" // child if retval == 0
188 " bne 1f\n" // jump if !child
189
190 /* CHILD - call thread function */
191 /* Note: 2.4 kernel doesn't set the child stack pointer,
192 so we do it here.
193 That does leave a small window for a signal to be delivered
194 on the wrong stack, unfortunately. */
195 " mr 1,29\n"
196 " mtctr 30\n" // ctr reg = fn
197 " mr 3,31\n" // r3 = arg
198 " bctrl\n" // call fn()
199
200 // exit with result
201 " li 0,"__NR_EXIT"\n"
202 " sc\n"
203
204 // Exit returned?!
205 " .long 0\n"
206
207 // PARENT or ERROR - return
208 "1: lwz 29,20(1)\n"
209 " lwz 30,24(1)\n"
210 " lwz 31,28(1)\n"
211 " addi 1,1,32\n"
212 " blr\n"
213 ".previous\n"
214 );
215
216 #undef __NR_CLONE
217 #undef __NR_EXIT
218
219 // forward declarations
220 static void setup_child ( ThreadArchState*, ThreadArchState* );
221
222 /*
223 When a client clones, we need to keep track of the new thread. This means:
224 1. allocate a ThreadId+ThreadState+stack for the the thread
225
226 2. initialize the thread's new VCPU state
227
228 3. create the thread using the same args as the client requested,
229 but using the scheduler entrypoint for IP, and a separate stack
230 for SP.
231 */
do_clone(ThreadId ptid,UInt flags,Addr sp,Int * parent_tidptr,Int * child_tidptr,Addr child_tls)232 static SysRes do_clone ( ThreadId ptid,
233 UInt flags, Addr sp,
234 Int *parent_tidptr,
235 Int *child_tidptr,
236 Addr child_tls)
237 {
238 const Bool debug = False;
239
240 ThreadId ctid = VG_(alloc_ThreadState)();
241 ThreadState* ptst = VG_(get_ThreadState)(ptid);
242 ThreadState* ctst = VG_(get_ThreadState)(ctid);
243 ULong word64;
244 UWord* stack;
245 NSegment const* seg;
246 SysRes res;
247 vki_sigset_t blockall, savedmask;
248
249 VG_(sigfillset)(&blockall);
250
251 vg_assert(VG_(is_running_thread)(ptid));
252 vg_assert(VG_(is_valid_tid)(ctid));
253
254 stack = (UWord*)ML_(allocstack)(ctid);
255 if (stack == NULL) {
256 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
257 goto out;
258 }
259
260 //? /* make a stack frame */
261 //? stack -= 16;
262 //? *(UWord *)stack = 0;
263
264
265 /* Copy register state
266
267 Both parent and child return to the same place, and the code
268 following the clone syscall works out which is which, so we
269 don't need to worry about it.
270
271 The parent gets the child's new tid returned from clone, but the
272 child gets 0.
273
274 If the clone call specifies a NULL SP for the new thread, then
275 it actually gets a copy of the parent's SP.
276
277 The child's TLS register (r2) gets set to the tlsaddr argument
278 if the CLONE_SETTLS flag is set.
279 */
280 setup_child( &ctst->arch, &ptst->arch );
281
282 /* Make sys_clone appear to have returned Success(0) in the
283 child. */
284 { UInt old_cr = LibVEX_GuestPPC32_get_CR( &ctst->arch.vex );
285 /* %r3 = 0 */
286 ctst->arch.vex.guest_GPR3 = 0;
287 /* %cr0.so = 0 */
288 LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
289 }
290
291 if (sp != 0)
292 ctst->arch.vex.guest_GPR1 = sp;
293
294 ctst->os_state.parent = ptid;
295
296 /* inherit signal mask */
297 ctst->sig_mask = ptst->sig_mask;
298 ctst->tmp_sig_mask = ptst->sig_mask;
299
300 /* Start the child with its threadgroup being the same as the
301 parent's. This is so that any exit_group calls that happen
302 after the child is created but before it sets its
303 os_state.threadgroup field for real (in thread_wrapper in
304 syswrap-linux.c), really kill the new thread. a.k.a this avoids
305 a race condition in which the thread is unkillable (via
306 exit_group) because its threadgroup is not set. The race window
307 is probably only a few hundred or a few thousand cycles long.
308 See #226116. */
309 ctst->os_state.threadgroup = ptst->os_state.threadgroup;
310
311 /* We don't really know where the client stack is, because its
312 allocated by the client. The best we can do is look at the
313 memory mappings and try to derive some useful information. We
314 assume that esp starts near its highest possible value, and can
315 only go down to the start of the mmaped segment. */
316 seg = VG_(am_find_nsegment)(sp);
317 if (seg && seg->kind != SkResvn) {
318 ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(sp);
319 ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
320
321 VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
322
323 if (debug)
324 VG_(printf)("\ntid %d: guessed client stack range %#lx-%#lx\n",
325 ctid, seg->start, VG_PGROUNDUP(sp));
326 } else {
327 VG_(message)(Vg_UserMsg,
328 "!? New thread %d starts with R1(%#lx) unmapped\n",
329 ctid, sp);
330 ctst->client_stack_szB = 0;
331 }
332
333 /* Assume the clone will succeed, and tell any tool that wants to
334 know that this thread has come into existence. If the clone
335 fails, we'll send out a ll_exit notification for it at the out:
336 label below, to clean up. */
337 VG_TRACK ( pre_thread_ll_create, ptid, ctid );
338
339 if (flags & VKI_CLONE_SETTLS) {
340 if (debug)
341 VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls);
342 ctst->arch.vex.guest_GPR2 = child_tls;
343 }
344
345 flags &= ~VKI_CLONE_SETTLS;
346
347 /* start the thread with everything blocked */
348 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
349
350 /* Create the new thread */
351 word64 = do_syscall_clone_ppc32_linux(
352 ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid],
353 child_tidptr, parent_tidptr, NULL
354 );
355 /* High half word64 is syscall return value. Low half is
356 the entire CR, from which we need to extract CR0.SO. */
357 /* VG_(printf)("word64 = 0x%llx\n", word64); */
358 res = VG_(mk_SysRes_ppc32_linux)(
359 /*val*/(UInt)(word64 >> 32),
360 /*errflag*/ (((UInt)word64) >> 28) & 1
361 );
362
363 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
364
365 out:
366 if (sr_isError(res)) {
367 /* clone failed */
368 VG_(cleanup_thread)(&ctst->arch);
369 ctst->status = VgTs_Empty;
370 /* oops. Better tell the tool the thread exited in a hurry :-) */
371 VG_TRACK( pre_thread_ll_exit, ctid );
372 }
373
374 return res;
375 }
376
377
378
379 /* ---------------------------------------------------------------------
380 More thread stuff
381 ------------------------------------------------------------------ */
382
VG_(cleanup_thread)383 void VG_(cleanup_thread) ( ThreadArchState* arch )
384 {
385 }
386
setup_child(ThreadArchState * child,ThreadArchState * parent)387 void setup_child ( /*OUT*/ ThreadArchState *child,
388 /*IN*/ ThreadArchState *parent )
389 {
390 /* We inherit our parent's guest state. */
391 child->vex = parent->vex;
392 child->vex_shadow1 = parent->vex_shadow1;
393 child->vex_shadow2 = parent->vex_shadow2;
394 }
395
396
397 /* ---------------------------------------------------------------------
398 PRE/POST wrappers for ppc32/Linux-specific syscalls
399 ------------------------------------------------------------------ */
400
401 #define PRE(name) DEFN_PRE_TEMPLATE(ppc32_linux, name)
402 #define POST(name) DEFN_POST_TEMPLATE(ppc32_linux, name)
403
404 /* Add prototypes for the wrappers declared here, so that gcc doesn't
405 harass us for not having prototypes. Really this is a kludge --
406 the right thing to do is to make these wrappers 'static' since they
407 aren't visible outside this file, but that requires even more macro
408 magic. */
409
410 DECL_TEMPLATE(ppc32_linux, sys_socketcall);
411 DECL_TEMPLATE(ppc32_linux, sys_mmap);
412 DECL_TEMPLATE(ppc32_linux, sys_mmap2);
413 DECL_TEMPLATE(ppc32_linux, sys_stat64);
414 DECL_TEMPLATE(ppc32_linux, sys_lstat64);
415 DECL_TEMPLATE(ppc32_linux, sys_fstatat64);
416 DECL_TEMPLATE(ppc32_linux, sys_fstat64);
417 DECL_TEMPLATE(ppc32_linux, sys_ipc);
418 DECL_TEMPLATE(ppc32_linux, sys_clone);
419 DECL_TEMPLATE(ppc32_linux, sys_sigreturn);
420 DECL_TEMPLATE(ppc32_linux, sys_rt_sigreturn);
421 DECL_TEMPLATE(ppc32_linux, sys_spu_create);
422 DECL_TEMPLATE(ppc32_linux, sys_spu_run);
423
PRE(sys_socketcall)424 PRE(sys_socketcall)
425 {
426 # define ARG2_0 (((UWord*)ARG2)[0])
427 # define ARG2_1 (((UWord*)ARG2)[1])
428 # define ARG2_2 (((UWord*)ARG2)[2])
429 # define ARG2_3 (((UWord*)ARG2)[3])
430 # define ARG2_4 (((UWord*)ARG2)[4])
431 # define ARG2_5 (((UWord*)ARG2)[5])
432
433 *flags |= SfMayBlock;
434 PRINT("sys_socketcall ( %ld, %#lx )",ARG1,ARG2);
435 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
436
437 switch (ARG1 /* request */) {
438
439 case VKI_SYS_SOCKETPAIR:
440 /* int socketpair(int d, int type, int protocol, int sv[2]); */
441 PRE_MEM_READ( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
442 ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
443 break;
444
445 case VKI_SYS_SOCKET:
446 /* int socket(int domain, int type, int protocol); */
447 PRE_MEM_READ( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
448 break;
449
450 case VKI_SYS_BIND:
451 /* int bind(int sockfd, struct sockaddr *my_addr,
452 int addrlen); */
453 PRE_MEM_READ( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
454 ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
455 break;
456
457 case VKI_SYS_LISTEN:
458 /* int listen(int s, int backlog); */
459 PRE_MEM_READ( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
460 break;
461
462 case VKI_SYS_ACCEPT: {
463 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
464 PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
465 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
466 break;
467 }
468
469 case VKI_SYS_ACCEPT4: {
470 /* int accept(int s, struct sockaddr *addr, int *addrlen, int args); */
471 PRE_MEM_READ( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
472 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
473 break;
474 }
475
476 case VKI_SYS_SENDTO:
477 /* int sendto(int s, const void *msg, int len,
478 unsigned int flags,
479 const struct sockaddr *to, int tolen); */
480 PRE_MEM_READ( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
481 ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
482 ARG2_3, ARG2_4, ARG2_5 );
483 break;
484
485 case VKI_SYS_SEND:
486 /* int send(int s, const void *msg, size_t len, int flags); */
487 PRE_MEM_READ( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
488 ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
489 break;
490
491 case VKI_SYS_RECVFROM:
492 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
493 struct sockaddr *from, int *fromlen); */
494 PRE_MEM_READ( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
495 ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
496 ARG2_3, ARG2_4, ARG2_5 );
497 break;
498
499 case VKI_SYS_RECV:
500 /* int recv(int s, void *buf, int len, unsigned int flags); */
501 /* man 2 recv says:
502 The recv call is normally used only on a connected socket
503 (see connect(2)) and is identical to recvfrom with a NULL
504 from parameter.
505 */
506 PRE_MEM_READ( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
507 ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
508 break;
509
510 case VKI_SYS_CONNECT:
511 /* int connect(int sockfd,
512 struct sockaddr *serv_addr, int addrlen ); */
513 PRE_MEM_READ( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
514 ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
515 break;
516
517 case VKI_SYS_SETSOCKOPT:
518 /* int setsockopt(int s, int level, int optname,
519 const void *optval, int optlen); */
520 PRE_MEM_READ( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
521 ML_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
522 ARG2_3, ARG2_4 );
523 break;
524
525 case VKI_SYS_GETSOCKOPT:
526 /* int getsockopt(int s, int level, int optname,
527 void *optval, socklen_t *optlen); */
528 PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
529 ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
530 ARG2_3, ARG2_4 );
531 break;
532
533 case VKI_SYS_GETSOCKNAME:
534 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
535 PRE_MEM_READ( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
536 ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
537 break;
538
539 case VKI_SYS_GETPEERNAME:
540 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
541 PRE_MEM_READ( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
542 ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
543 break;
544
545 case VKI_SYS_SHUTDOWN:
546 /* int shutdown(int s, int how); */
547 PRE_MEM_READ( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
548 break;
549
550 case VKI_SYS_SENDMSG: {
551 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
552
553 /* this causes warnings, and I don't get why. glibc bug?
554 * (after all it's glibc providing the arguments array)
555 PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
556 */
557 ML_(generic_PRE_sys_sendmsg)( tid, ARG2_0, ARG2_1 );
558 break;
559 }
560
561 case VKI_SYS_RECVMSG: {
562 /* int recvmsg(int s, struct msghdr *msg, int flags); */
563
564 /* this causes warnings, and I don't get why. glibc bug?
565 * (after all it's glibc providing the arguments array)
566 PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
567 */
568 ML_(generic_PRE_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
569 break;
570 }
571
572 default:
573 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
574 SET_STATUS_Failure( VKI_EINVAL );
575 break;
576 }
577 # undef ARG2_0
578 # undef ARG2_1
579 # undef ARG2_2
580 # undef ARG2_3
581 # undef ARG2_4
582 # undef ARG2_5
583 }
584
POST(sys_socketcall)585 POST(sys_socketcall)
586 {
587 # define ARG2_0 (((UWord*)ARG2)[0])
588 # define ARG2_1 (((UWord*)ARG2)[1])
589 # define ARG2_2 (((UWord*)ARG2)[2])
590 # define ARG2_3 (((UWord*)ARG2)[3])
591 # define ARG2_4 (((UWord*)ARG2)[4])
592 # define ARG2_5 (((UWord*)ARG2)[5])
593
594 SysRes r;
595 vg_assert(SUCCESS);
596 switch (ARG1 /* request */) {
597
598 case VKI_SYS_SOCKETPAIR:
599 r = ML_(generic_POST_sys_socketpair)(
600 tid, VG_(mk_SysRes_Success)(RES),
601 ARG2_0, ARG2_1, ARG2_2, ARG2_3
602 );
603 SET_STATUS_from_SysRes(r);
604 break;
605
606 case VKI_SYS_SOCKET:
607 r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
608 SET_STATUS_from_SysRes(r);
609 break;
610
611 case VKI_SYS_BIND:
612 /* int bind(int sockfd, struct sockaddr *my_addr,
613 int addrlen); */
614 break;
615
616 case VKI_SYS_LISTEN:
617 /* int listen(int s, int backlog); */
618 break;
619
620 case VKI_SYS_ACCEPT:
621 case VKI_SYS_ACCEPT4:
622 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
623 r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
624 ARG2_0, ARG2_1, ARG2_2 );
625 SET_STATUS_from_SysRes(r);
626 break;
627
628 case VKI_SYS_SENDTO:
629 break;
630
631 case VKI_SYS_SEND:
632 break;
633
634 case VKI_SYS_RECVFROM:
635 ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
636 ARG2_0, ARG2_1, ARG2_2,
637 ARG2_3, ARG2_4, ARG2_5 );
638 break;
639
640 case VKI_SYS_RECV:
641 ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
642 break;
643
644 case VKI_SYS_CONNECT:
645 break;
646
647 case VKI_SYS_SETSOCKOPT:
648 break;
649
650 case VKI_SYS_GETSOCKOPT:
651 ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
652 ARG2_0, ARG2_1,
653 ARG2_2, ARG2_3, ARG2_4 );
654 break;
655
656 case VKI_SYS_GETSOCKNAME:
657 ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
658 ARG2_0, ARG2_1, ARG2_2 );
659 break;
660
661 case VKI_SYS_GETPEERNAME:
662 ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
663 ARG2_0, ARG2_1, ARG2_2 );
664 break;
665
666 case VKI_SYS_SHUTDOWN:
667 break;
668
669 case VKI_SYS_SENDMSG:
670 break;
671
672 case VKI_SYS_RECVMSG:
673 ML_(generic_POST_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
674 break;
675
676 default:
677 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
678 VG_(core_panic)("... bye!\n");
679 break; /*NOTREACHED*/
680 }
681 # undef ARG2_0
682 # undef ARG2_1
683 # undef ARG2_2
684 # undef ARG2_3
685 # undef ARG2_4
686 # undef ARG2_5
687 }
688
PRE(sys_mmap)689 PRE(sys_mmap)
690 {
691 SysRes r;
692
693 PRINT("sys_mmap ( %#lx, %llu, %ld, %ld, %ld, %ld )",
694 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
695 PRE_REG_READ6(long, "mmap",
696 unsigned long, start, unsigned long, length,
697 unsigned long, prot, unsigned long, flags,
698 unsigned long, fd, unsigned long, offset);
699
700 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
701 (Off64T)ARG6 );
702 SET_STATUS_from_SysRes(r);
703 }
704
PRE(sys_mmap2)705 PRE(sys_mmap2)
706 {
707 SysRes r;
708
709 // Exactly like old_mmap() except:
710 // - the file offset is specified in 4K units rather than bytes,
711 // so that it can be used for files bigger than 2^32 bytes.
712 PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )",
713 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
714 PRE_REG_READ6(long, "mmap2",
715 unsigned long, start, unsigned long, length,
716 unsigned long, prot, unsigned long, flags,
717 unsigned long, fd, unsigned long, offset);
718
719 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
720 4096 * (Off64T)ARG6 );
721 SET_STATUS_from_SysRes(r);
722 }
723
724 // XXX: lstat64/fstat64/stat64 are generic, but not necessarily
725 // applicable to every architecture -- I think only to 32-bit archs.
726 // We're going to need something like linux/core_os32.h for such
727 // things, eventually, I think. --njn
PRE(sys_stat64)728 PRE(sys_stat64)
729 {
730 PRINT("sys_stat64 ( %#lx, %#lx )",ARG1,ARG2);
731 PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
732 PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
733 PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
734 }
735
POST(sys_stat64)736 POST(sys_stat64)
737 {
738 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
739 }
740
PRE(sys_lstat64)741 PRE(sys_lstat64)
742 {
743 PRINT("sys_lstat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
744 PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
745 PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
746 PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
747 }
748
POST(sys_lstat64)749 POST(sys_lstat64)
750 {
751 vg_assert(SUCCESS);
752 if (RES == 0) {
753 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
754 }
755 }
756
PRE(sys_fstatat64)757 PRE(sys_fstatat64)
758 {
759 PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )",ARG1,ARG2,(char*)ARG2,ARG3);
760 PRE_REG_READ3(long, "fstatat64",
761 int, dfd, char *, file_name, struct stat64 *, buf);
762 PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 );
763 PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) );
764 }
765
POST(sys_fstatat64)766 POST(sys_fstatat64)
767 {
768 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) );
769 }
770
PRE(sys_fstat64)771 PRE(sys_fstat64)
772 {
773 PRINT("sys_fstat64 ( %ld, %#lx )",ARG1,ARG2);
774 PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
775 PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
776 }
777
POST(sys_fstat64)778 POST(sys_fstat64)
779 {
780 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
781 }
782
deref_Addr(ThreadId tid,Addr a,Char * s)783 static Addr deref_Addr ( ThreadId tid, Addr a, Char* s )
784 {
785 Addr* a_p = (Addr*)a;
786 PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
787 return *a_p;
788 }
789
PRE(sys_ipc)790 PRE(sys_ipc)
791 {
792 PRINT("sys_ipc ( %ld, %ld, %ld, %ld, %#lx, %ld )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
793 // XXX: this is simplistic -- some args are not used in all circumstances.
794 PRE_REG_READ6(int, "ipc",
795 vki_uint, call, int, first, int, second, int, third,
796 void *, ptr, long, fifth)
797
798 switch (ARG1 /* call */) {
799 case VKI_SEMOP:
800 ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
801 *flags |= SfMayBlock;
802 break;
803 case VKI_SEMGET:
804 break;
805 case VKI_SEMCTL:
806 {
807 UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
808 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
809 break;
810 }
811 case VKI_SEMTIMEDOP:
812 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
813 *flags |= SfMayBlock;
814 break;
815 case VKI_MSGSND:
816 ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
817 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
818 *flags |= SfMayBlock;
819 break;
820 case VKI_MSGRCV:
821 {
822 Addr msgp;
823 Word msgtyp;
824
825 msgp = deref_Addr( tid,
826 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
827 "msgrcv(msgp)" );
828 msgtyp = deref_Addr( tid,
829 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
830 "msgrcv(msgp)" );
831
832 ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
833
834 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
835 *flags |= SfMayBlock;
836 break;
837 }
838 case VKI_MSGGET:
839 break;
840 case VKI_MSGCTL:
841 ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
842 break;
843 case VKI_SHMAT:
844 {
845 UWord w;
846 PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
847 w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
848 if (w == 0)
849 SET_STATUS_Failure( VKI_EINVAL );
850 else
851 ARG5 = w;
852 break;
853 }
854 case VKI_SHMDT:
855 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
856 SET_STATUS_Failure( VKI_EINVAL );
857 break;
858 case VKI_SHMGET:
859 break;
860 case VKI_SHMCTL: /* IPCOP_shmctl */
861 ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
862 break;
863 default:
864 VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %ld\n", ARG1 );
865 VG_(core_panic)("... bye!\n");
866 break; /*NOTREACHED*/
867 }
868 }
869
POST(sys_ipc)870 POST(sys_ipc)
871 {
872 vg_assert(SUCCESS);
873 switch (ARG1 /* call */) {
874 case VKI_SEMOP:
875 case VKI_SEMGET:
876 break;
877 case VKI_SEMCTL:
878 {
879 UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
880 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
881 break;
882 }
883 case VKI_SEMTIMEDOP:
884 case VKI_MSGSND:
885 break;
886 case VKI_MSGRCV:
887 {
888 Addr msgp;
889 Word msgtyp;
890
891 msgp = deref_Addr( tid,
892 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
893 "msgrcv(msgp)" );
894 msgtyp = deref_Addr( tid,
895 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
896 "msgrcv(msgp)" );
897
898 ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
899 break;
900 }
901 case VKI_MSGGET:
902 break;
903 case VKI_MSGCTL:
904 ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
905 break;
906 case VKI_SHMAT:
907 {
908 Addr addr;
909
910 /* force readability. before the syscall it is
911 * indeed uninitialized, as can be seen in
912 * glibc/sysdeps/unix/sysv/linux/shmat.c */
913 POST_MEM_WRITE( ARG4, sizeof( Addr ) );
914
915 addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
916 ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
917 break;
918 }
919 case VKI_SHMDT:
920 ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
921 break;
922 case VKI_SHMGET:
923 break;
924 case VKI_SHMCTL:
925 ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
926 break;
927 default:
928 VG_(message)(Vg_DebugMsg,
929 "FATAL: unhandled syscall(ipc) %ld\n",
930 ARG1 );
931 VG_(core_panic)("... bye!\n");
932 break; /*NOTREACHED*/
933 }
934 }
935
936
937
938
939 //.. PRE(old_select, MayBlock)
940 //.. {
941 //.. /* struct sel_arg_struct {
942 //.. unsigned long n;
943 //.. fd_set *inp, *outp, *exp;
944 //.. struct timeval *tvp;
945 //.. };
946 //.. */
947 //.. PRE_REG_READ1(long, "old_select", struct sel_arg_struct *, args);
948 //.. PRE_MEM_READ( "old_select(args)", ARG1, 5*sizeof(UWord) );
949 //..
950 //.. {
951 //.. UInt* arg_struct = (UInt*)ARG1;
952 //.. UInt a1, a2, a3, a4, a5;
953 //..
954 //.. a1 = arg_struct[0];
955 //.. a2 = arg_struct[1];
956 //.. a3 = arg_struct[2];
957 //.. a4 = arg_struct[3];
958 //.. a5 = arg_struct[4];
959 //..
960 //.. PRINT("old_select ( %d, %p, %p, %p, %p )", a1,a2,a3,a4,a5);
961 //.. if (a2 != (Addr)NULL)
962 //.. PRE_MEM_READ( "old_select(readfds)", a2, a1/8 /* __FD_SETSIZE/8 */ );
963 //.. if (a3 != (Addr)NULL)
964 //.. PRE_MEM_READ( "old_select(writefds)", a3, a1/8 /* __FD_SETSIZE/8 */ );
965 //.. if (a4 != (Addr)NULL)
966 //.. PRE_MEM_READ( "old_select(exceptfds)", a4, a1/8 /* __FD_SETSIZE/8 */ );
967 //.. if (a5 != (Addr)NULL)
968 //.. PRE_MEM_READ( "old_select(timeout)", a5, sizeof(struct vki_timeval) );
969 //.. }
970 //.. }
971
PRE(sys_clone)972 PRE(sys_clone)
973 {
974 UInt cloneflags;
975
976 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
977 PRE_REG_READ5(int, "clone",
978 unsigned long, flags,
979 void *, child_stack,
980 int *, parent_tidptr,
981 void *, child_tls,
982 int *, child_tidptr);
983
984 if (ARG1 & VKI_CLONE_PARENT_SETTID) {
985 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
986 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
987 VKI_PROT_WRITE)) {
988 SET_STATUS_Failure( VKI_EFAULT );
989 return;
990 }
991 }
992 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
993 PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
994 if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int),
995 VKI_PROT_WRITE)) {
996 SET_STATUS_Failure( VKI_EFAULT );
997 return;
998 }
999 }
1000
1001 cloneflags = ARG1;
1002
1003 if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
1004 SET_STATUS_Failure( VKI_EINVAL );
1005 return;
1006 }
1007
1008 /* Only look at the flags we really care about */
1009 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
1010 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
1011 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
1012 /* thread creation */
1013 SET_STATUS_from_SysRes(
1014 do_clone(tid,
1015 ARG1, /* flags */
1016 (Addr)ARG2, /* child SP */
1017 (Int *)ARG3, /* parent_tidptr */
1018 (Int *)ARG5, /* child_tidptr */
1019 (Addr)ARG4)); /* child_tls */
1020 break;
1021
1022 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
1023 /* FALLTHROUGH - assume vfork == fork */
1024 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
1025
1026 case 0: /* plain fork */
1027 SET_STATUS_from_SysRes(
1028 ML_(do_fork_clone)(tid,
1029 cloneflags, /* flags */
1030 (Int *)ARG3, /* parent_tidptr */
1031 (Int *)ARG5)); /* child_tidptr */
1032 break;
1033
1034 default:
1035 /* should we just ENOSYS? */
1036 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
1037 VG_(message)(Vg_UserMsg, "\n");
1038 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
1039 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
1040 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
1041 VG_(unimplemented)
1042 ("Valgrind does not support general clone().");
1043 }
1044
1045 if (SUCCESS) {
1046 if (ARG1 & VKI_CLONE_PARENT_SETTID)
1047 POST_MEM_WRITE(ARG3, sizeof(Int));
1048 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
1049 POST_MEM_WRITE(ARG5, sizeof(Int));
1050
1051 /* Thread creation was successful; let the child have the chance
1052 to run */
1053 *flags |= SfYieldAfter;
1054 }
1055 }
1056
PRE(sys_sigreturn)1057 PRE(sys_sigreturn)
1058 {
1059 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
1060 an explanation of what follows. */
1061
1062 ThreadState* tst;
1063 PRINT("sys_sigreturn ( )");
1064
1065 vg_assert(VG_(is_valid_tid)(tid));
1066 vg_assert(tid >= 1 && tid < VG_N_THREADS);
1067 vg_assert(VG_(is_running_thread)(tid));
1068
1069 ///* Adjust esp to point to start of frame; skip back up over
1070 // sigreturn sequence's "popl %eax" and handler ret addr */
1071 tst = VG_(get_ThreadState)(tid);
1072 //tst->arch.vex.guest_ESP -= sizeof(Addr)+sizeof(Word);
1073 // Should we do something equivalent on ppc32? Who knows.
1074
1075 ///* This is only so that the EIP is (might be) useful to report if
1076 // something goes wrong in the sigreturn */
1077 //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
1078 // Should we do something equivalent on ppc32? Who knows.
1079
1080 /* Restore register state from frame and remove it */
1081 VG_(sigframe_destroy)(tid, False);
1082
1083 /* Tell the driver not to update the guest state with the "result",
1084 and set a bogus result to keep it happy. */
1085 *flags |= SfNoWriteResult;
1086 SET_STATUS_Success(0);
1087
1088 /* Check to see if any signals arose as a result of this. */
1089 *flags |= SfPollAfter;
1090 }
1091
PRE(sys_rt_sigreturn)1092 PRE(sys_rt_sigreturn)
1093 {
1094 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
1095 an explanation of what follows. */
1096
1097 ThreadState* tst;
1098 PRINT("rt_sigreturn ( )");
1099
1100 vg_assert(VG_(is_valid_tid)(tid));
1101 vg_assert(tid >= 1 && tid < VG_N_THREADS);
1102 vg_assert(VG_(is_running_thread)(tid));
1103
1104 ///* Adjust esp to point to start of frame; skip back up over handler
1105 // ret addr */
1106 tst = VG_(get_ThreadState)(tid);
1107 //tst->arch.vex.guest_ESP -= sizeof(Addr);
1108 // Should we do something equivalent on ppc32? Who knows.
1109
1110 ///* This is only so that the EIP is (might be) useful to report if
1111 // something goes wrong in the sigreturn */
1112 //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
1113 // Should we do something equivalent on ppc32? Who knows.
1114
1115 /* Restore register state from frame and remove it */
1116 VG_(sigframe_destroy)(tid, True);
1117
1118 /* Tell the driver not to update the guest state with the "result",
1119 and set a bogus result to keep it happy. */
1120 *flags |= SfNoWriteResult;
1121 SET_STATUS_Success(0);
1122
1123 /* Check to see if any signals arose as a result of this. */
1124 *flags |= SfPollAfter;
1125 }
1126
1127
1128 //.. PRE(sys_modify_ldt, Special)
1129 //.. {
1130 //.. PRINT("sys_modify_ldt ( %d, %p, %d )", ARG1,ARG2,ARG3);
1131 //.. PRE_REG_READ3(int, "modify_ldt", int, func, void *, ptr,
1132 //.. unsigned long, bytecount);
1133 //..
1134 //.. if (ARG1 == 0) {
1135 //.. /* read the LDT into ptr */
1136 //.. PRE_MEM_WRITE( "modify_ldt(ptr)", ARG2, ARG3 );
1137 //.. }
1138 //.. if (ARG1 == 1 || ARG1 == 0x11) {
1139 //.. /* write the LDT with the entry pointed at by ptr */
1140 //.. PRE_MEM_READ( "modify_ldt(ptr)", ARG2, sizeof(vki_modify_ldt_t) );
1141 //.. }
1142 //.. /* "do" the syscall ourselves; the kernel never sees it */
1143 //.. SET_RESULT( VG_(sys_modify_ldt)( tid, ARG1, (void*)ARG2, ARG3 ) );
1144 //..
1145 //.. if (ARG1 == 0 && !VG_(is_kerror)(RES) && RES > 0) {
1146 //.. POST_MEM_WRITE( ARG2, RES );
1147 //.. }
1148 //.. }
1149
1150 //.. PRE(sys_set_thread_area, Special)
1151 //.. {
1152 //.. PRINT("sys_set_thread_area ( %p )", ARG1);
1153 //.. PRE_REG_READ1(int, "set_thread_area", struct user_desc *, u_info)
1154 //.. PRE_MEM_READ( "set_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
1155 //..
1156 //.. /* "do" the syscall ourselves; the kernel never sees it */
1157 //.. SET_RESULT( VG_(sys_set_thread_area)( tid, (void *)ARG1 ) );
1158 //.. }
1159
1160 //.. PRE(sys_get_thread_area, Special)
1161 //.. {
1162 //.. PRINT("sys_get_thread_area ( %p )", ARG1);
1163 //.. PRE_REG_READ1(int, "get_thread_area", struct user_desc *, u_info)
1164 //.. PRE_MEM_WRITE( "get_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
1165 //..
1166 //.. /* "do" the syscall ourselves; the kernel never sees it */
1167 //.. SET_RESULT( VG_(sys_get_thread_area)( tid, (void *)ARG1 ) );
1168 //..
1169 //.. if (!VG_(is_kerror)(RES)) {
1170 //.. POST_MEM_WRITE( ARG1, sizeof(vki_modify_ldt_t) );
1171 //.. }
1172 //.. }
1173
1174 //.. // Parts of this are ppc32-specific, but the *PEEK* cases are generic.
1175 //.. // XXX: Why is the memory pointed to by ARG3 never checked?
1176 //.. PRE(sys_ptrace, 0)
1177 //.. {
1178 //.. PRINT("sys_ptrace ( %d, %d, %p, %p )", ARG1,ARG2,ARG3,ARG4);
1179 //.. PRE_REG_READ4(int, "ptrace",
1180 //.. long, request, long, pid, long, addr, long, data);
1181 //.. switch (ARG1) {
1182 //.. case VKI_PTRACE_PEEKTEXT:
1183 //.. case VKI_PTRACE_PEEKDATA:
1184 //.. case VKI_PTRACE_PEEKUSR:
1185 //.. PRE_MEM_WRITE( "ptrace(peek)", ARG4,
1186 //.. sizeof (long));
1187 //.. break;
1188 //.. case VKI_PTRACE_GETREGS:
1189 //.. PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
1190 //.. sizeof (struct vki_user_regs_struct));
1191 //.. break;
1192 //.. case VKI_PTRACE_GETFPREGS:
1193 //.. PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
1194 //.. sizeof (struct vki_user_i387_struct));
1195 //.. break;
1196 //.. case VKI_PTRACE_GETFPXREGS:
1197 //.. PRE_MEM_WRITE( "ptrace(getfpxregs)", ARG4,
1198 //.. sizeof(struct vki_user_fxsr_struct) );
1199 //.. break;
1200 //.. case VKI_PTRACE_SETREGS:
1201 //.. PRE_MEM_READ( "ptrace(setregs)", ARG4,
1202 //.. sizeof (struct vki_user_regs_struct));
1203 //.. break;
1204 //.. case VKI_PTRACE_SETFPREGS:
1205 //.. PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
1206 //.. sizeof (struct vki_user_i387_struct));
1207 //.. break;
1208 //.. case VKI_PTRACE_SETFPXREGS:
1209 //.. PRE_MEM_READ( "ptrace(setfpxregs)", ARG4,
1210 //.. sizeof(struct vki_user_fxsr_struct) );
1211 //.. break;
1212 //.. default:
1213 //.. break;
1214 //.. }
1215 //.. }
1216
1217 //.. POST(sys_ptrace)
1218 //.. {
1219 //.. switch (ARG1) {
1220 //.. case VKI_PTRACE_PEEKTEXT:
1221 //.. case VKI_PTRACE_PEEKDATA:
1222 //.. case VKI_PTRACE_PEEKUSR:
1223 //.. POST_MEM_WRITE( ARG4, sizeof (long));
1224 //.. break;
1225 //.. case VKI_PTRACE_GETREGS:
1226 //.. POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
1227 //.. break;
1228 //.. case VKI_PTRACE_GETFPREGS:
1229 //.. POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
1230 //.. break;
1231 //.. case VKI_PTRACE_GETFPXREGS:
1232 //.. POST_MEM_WRITE( ARG4, sizeof(struct vki_user_fxsr_struct) );
1233 //.. break;
1234 //.. default:
1235 //.. break;
1236 //.. }
1237 //.. }
1238
1239 //.. // XXX: this duplicates a function in coregrind/vg_syscalls.c, yuk
1240 //.. static Addr deref_Addr ( ThreadId tid, Addr a, Char* s )
1241 //.. {
1242 //.. Addr* a_p = (Addr*)a;
1243 //.. PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
1244 //.. return *a_p;
1245 //.. }
1246
1247 //.. // XXX: should use the constants here (eg. SHMAT), not the numbers directly!
1248 //.. PRE(sys_ipc, 0)
1249 //.. {
1250 //.. PRINT("sys_ipc ( %d, %d, %d, %d, %p, %d )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
1251 //.. // XXX: this is simplistic -- some args are not used in all circumstances.
1252 //.. PRE_REG_READ6(int, "ipc",
1253 //.. vki_uint, call, int, first, int, second, int, third,
1254 //.. void *, ptr, long, fifth)
1255 //..
1256 //.. switch (ARG1 /* call */) {
1257 //.. case VKI_SEMOP:
1258 //.. ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
1259 //.. /* tst->sys_flags |= MayBlock; */
1260 //.. break;
1261 //.. case VKI_SEMGET:
1262 //.. break;
1263 //.. case VKI_SEMCTL:
1264 //.. {
1265 //.. UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
1266 //.. ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
1267 //.. break;
1268 //.. }
1269 //.. case VKI_SEMTIMEDOP:
1270 //.. ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
1271 //.. /* tst->sys_flags |= MayBlock; */
1272 //.. break;
1273 //.. case VKI_MSGSND:
1274 //.. ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
1275 //.. /* if ((ARG4 & VKI_IPC_NOWAIT) == 0)
1276 //.. tst->sys_flags |= MayBlock;
1277 //.. */
1278 //.. break;
1279 //.. case VKI_MSGRCV:
1280 //.. {
1281 //.. Addr msgp;
1282 //.. Word msgtyp;
1283 //..
1284 //.. msgp = deref_Addr( tid,
1285 //.. (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
1286 //.. "msgrcv(msgp)" );
1287 //.. msgtyp = deref_Addr( tid,
1288 //.. (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
1289 //.. "msgrcv(msgp)" );
1290 //..
1291 //.. ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
1292 //..
1293 //.. /* if ((ARG4 & VKI_IPC_NOWAIT) == 0)
1294 //.. tst->sys_flags |= MayBlock;
1295 //.. */
1296 //.. break;
1297 //.. }
1298 //.. case VKI_MSGGET:
1299 //.. break;
1300 //.. case VKI_MSGCTL:
1301 //.. ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
1302 //.. break;
1303 //.. case VKI_SHMAT:
1304 //.. PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
1305 //.. ARG5 = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
1306 //.. if (ARG5 == 0)
1307 //.. SET_RESULT( -VKI_EINVAL );
1308 //.. break;
1309 //.. case VKI_SHMDT:
1310 //.. if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
1311 //.. SET_RESULT( -VKI_EINVAL );
1312 //.. break;
1313 //.. case VKI_SHMGET:
1314 //.. break;
1315 //.. case VKI_SHMCTL: /* IPCOP_shmctl */
1316 //.. ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
1317 //.. break;
1318 //.. default:
1319 //.. VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %d", ARG1 );
1320 //.. VG_(core_panic)("... bye!\n");
1321 //.. break; /*NOTREACHED*/
1322 //.. }
1323 //.. }
1324
1325 //.. POST(sys_ipc)
1326 //.. {
1327 //.. switch (ARG1 /* call */) {
1328 //.. case VKI_SEMOP:
1329 //.. case VKI_SEMGET:
1330 //.. break;
1331 //.. case VKI_SEMCTL:
1332 //.. {
1333 //.. UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
1334 //.. ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
1335 //.. break;
1336 //.. }
1337 //.. case VKI_SEMTIMEDOP:
1338 //.. case VKI_MSGSND:
1339 //.. break;
1340 //.. case VKI_MSGRCV:
1341 //.. {
1342 //.. Addr msgp;
1343 //.. Word msgtyp;
1344 //..
1345 //.. msgp = deref_Addr( tid,
1346 //.. (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
1347 //.. "msgrcv(msgp)" );
1348 //.. msgtyp = deref_Addr( tid,
1349 //.. (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
1350 //.. "msgrcv(msgp)" );
1351 //..
1352 //.. ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
1353 //.. break;
1354 //.. }
1355 //.. case VKI_MSGGET:
1356 //.. break;
1357 //.. case VKI_MSGCTL:
1358 //.. ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
1359 //.. break;
1360 //.. case VKI_SHMAT:
1361 //.. {
1362 //.. Addr addr;
1363 //..
1364 //.. /* force readability. before the syscall it is
1365 //.. * indeed uninitialized, as can be seen in
1366 //.. * glibc/sysdeps/unix/sysv/linux/shmat.c */
1367 //.. POST_MEM_WRITE( ARG4, sizeof( Addr ) );
1368 //..
1369 //.. addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
1370 //.. if ( addr > 0 ) {
1371 //.. ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
1372 //.. }
1373 //.. break;
1374 //.. }
1375 //.. case VKI_SHMDT:
1376 //.. ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
1377 //.. break;
1378 //.. case VKI_SHMGET:
1379 //.. break;
1380 //.. case VKI_SHMCTL:
1381 //.. ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
1382 //.. break;
1383 //.. default:
1384 //.. VG_(message)(Vg_DebugMsg,
1385 //.. "FATAL: unhandled syscall(ipc) %d",
1386 //.. ARG1 );
1387 //.. VG_(core_panic)("... bye!\n");
1388 //.. break; /*NOTREACHED*/
1389 //.. }
1390 //.. }
1391
PRE(sys_spu_create)1392 PRE(sys_spu_create)
1393 {
1394 PRE_MEM_RASCIIZ("stat64(filename)", ARG1);
1395 }
POST(sys_spu_create)1396 POST(sys_spu_create)
1397 {
1398 vg_assert(SUCCESS);
1399 }
1400
PRE(sys_spu_run)1401 PRE(sys_spu_run)
1402 {
1403 *flags |= SfMayBlock;
1404 if (ARG2 != 0)
1405 PRE_MEM_WRITE("npc", ARG2, sizeof(unsigned int));
1406 PRE_MEM_READ("event", ARG3, sizeof(unsigned int));
1407 }
POST(sys_spu_run)1408 POST(sys_spu_run)
1409 {
1410 if (ARG2 != 0)
1411 POST_MEM_WRITE(ARG2, sizeof(unsigned int));
1412 }
1413
1414 #undef PRE
1415 #undef POST
1416
1417 /* ---------------------------------------------------------------------
1418 The ppc32/Linux syscall table
1419 ------------------------------------------------------------------ */
1420
1421 /* Add an ppc32-linux specific wrapper to a syscall table. */
1422 #define PLAX_(sysno, name) WRAPPER_ENTRY_X_(ppc32_linux, sysno, name)
1423 #define PLAXY(sysno, name) WRAPPER_ENTRY_XY(ppc32_linux, sysno, name)
1424
1425 // This table maps from __NR_xxx syscall numbers (from
1426 // linux/include/asm-ppc/unistd.h) to the appropriate PRE/POST sys_foo()
1427 // wrappers on ppc32 (as per sys_call_table in linux/arch/ppc/kernel/entry.S).
1428 //
1429 // For those syscalls not handled by Valgrind, the annotation indicate its
1430 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
1431 // (unknown).
1432
1433 static SyscallTableEntry syscall_table[] = {
1434 //.. (restart_syscall) // 0
1435 GENX_(__NR_exit, sys_exit), // 1
1436 GENX_(__NR_fork, sys_fork), // 2
1437 GENXY(__NR_read, sys_read), // 3
1438 GENX_(__NR_write, sys_write), // 4
1439
1440 GENXY(__NR_open, sys_open), // 5
1441 GENXY(__NR_close, sys_close), // 6
1442 GENXY(__NR_waitpid, sys_waitpid), // 7
1443 GENXY(__NR_creat, sys_creat), // 8
1444 GENX_(__NR_link, sys_link), // 9
1445
1446 GENX_(__NR_unlink, sys_unlink), // 10
1447 GENX_(__NR_execve, sys_execve), // 11
1448 GENX_(__NR_chdir, sys_chdir), // 12
1449 GENXY(__NR_time, sys_time), // 13
1450 GENX_(__NR_mknod, sys_mknod), // 14
1451 //..
1452 GENX_(__NR_chmod, sys_chmod), // 15
1453 GENX_(__NR_lchown, sys_lchown), // 16 ## P
1454 //.. GENX_(__NR_break, sys_ni_syscall), // 17
1455 //.. // (__NR_oldstat, sys_stat), // 18 (obsolete)
1456 LINX_(__NR_lseek, sys_lseek), // 19
1457 //..
1458 GENX_(__NR_getpid, sys_getpid), // 20
1459 LINX_(__NR_mount, sys_mount), // 21
1460 LINX_(__NR_umount, sys_oldumount), // 22
1461 GENX_(__NR_setuid, sys_setuid), // 23 ## P
1462 GENX_(__NR_getuid, sys_getuid), // 24 ## P
1463 //..
1464 //.. // (__NR_stime, sys_stime), // 25 * (SVr4,SVID,X/OPEN)
1465 //.. PLAXY(__NR_ptrace, sys_ptrace), // 26
1466 GENX_(__NR_alarm, sys_alarm), // 27
1467 //.. // (__NR_oldfstat, sys_fstat), // 28 * L -- obsolete
1468 GENX_(__NR_pause, sys_pause), // 29
1469 //..
1470 LINX_(__NR_utime, sys_utime), // 30
1471 //.. GENX_(__NR_stty, sys_ni_syscall), // 31
1472 //.. GENX_(__NR_gtty, sys_ni_syscall), // 32
1473 GENX_(__NR_access, sys_access), // 33
1474 //.. GENX_(__NR_nice, sys_nice), // 34
1475 //..
1476 //.. GENX_(__NR_ftime, sys_ni_syscall), // 35
1477 //.. GENX_(__NR_sync, sys_sync), // 36
1478 GENX_(__NR_kill, sys_kill), // 37
1479 GENX_(__NR_rename, sys_rename), // 38
1480 GENX_(__NR_mkdir, sys_mkdir), // 39
1481
1482 GENX_(__NR_rmdir, sys_rmdir), // 40
1483 GENXY(__NR_dup, sys_dup), // 41
1484 LINXY(__NR_pipe, sys_pipe), // 42
1485 GENXY(__NR_times, sys_times), // 43
1486 //.. GENX_(__NR_prof, sys_ni_syscall), // 44
1487 //..
1488 GENX_(__NR_brk, sys_brk), // 45
1489 GENX_(__NR_setgid, sys_setgid), // 46
1490 GENX_(__NR_getgid, sys_getgid), // 47
1491 //.. // (__NR_signal, sys_signal), // 48 */* (ANSI C)
1492 GENX_(__NR_geteuid, sys_geteuid), // 49
1493
1494 GENX_(__NR_getegid, sys_getegid), // 50
1495 //.. GENX_(__NR_acct, sys_acct), // 51
1496 LINX_(__NR_umount2, sys_umount), // 52
1497 //.. GENX_(__NR_lock, sys_ni_syscall), // 53
1498 LINXY(__NR_ioctl, sys_ioctl), // 54
1499 //..
1500 LINXY(__NR_fcntl, sys_fcntl), // 55
1501 //.. GENX_(__NR_mpx, sys_ni_syscall), // 56
1502 GENX_(__NR_setpgid, sys_setpgid), // 57
1503 //.. GENX_(__NR_ulimit, sys_ni_syscall), // 58
1504 //.. // (__NR_oldolduname, sys_olduname), // 59 Linux -- obsolete
1505
1506 GENX_(__NR_umask, sys_umask), // 60
1507 GENX_(__NR_chroot, sys_chroot), // 61
1508 //.. // (__NR_ustat, sys_ustat) // 62 SVr4 -- deprecated
1509 GENXY(__NR_dup2, sys_dup2), // 63
1510 GENX_(__NR_getppid, sys_getppid), // 64
1511
1512 GENX_(__NR_getpgrp, sys_getpgrp), // 65
1513 GENX_(__NR_setsid, sys_setsid), // 66
1514 LINXY(__NR_sigaction, sys_sigaction), // 67
1515 //.. // (__NR_sgetmask, sys_sgetmask), // 68 */* (ANSI C)
1516 //.. // (__NR_ssetmask, sys_ssetmask), // 69 */* (ANSI C)
1517 //..
1518 GENX_(__NR_setreuid, sys_setreuid), // 70
1519 GENX_(__NR_setregid, sys_setregid), // 71
1520 LINX_(__NR_sigsuspend, sys_sigsuspend), // 72
1521 LINXY(__NR_sigpending, sys_sigpending), // 73
1522 //.. // (__NR_sethostname, sys_sethostname), // 74 */*
1523 //..
1524 GENX_(__NR_setrlimit, sys_setrlimit), // 75
1525 //.. GENXY(__NR_getrlimit, sys_old_getrlimit), // 76
1526 GENXY(__NR_getrusage, sys_getrusage), // 77
1527 GENXY(__NR_gettimeofday, sys_gettimeofday), // 78
1528 //.. GENX_(__NR_settimeofday, sys_settimeofday), // 79
1529 //..
1530 GENXY(__NR_getgroups, sys_getgroups), // 80
1531 GENX_(__NR_setgroups, sys_setgroups), // 81
1532 //.. PLAX_(__NR_select, old_select), // 82
1533 GENX_(__NR_symlink, sys_symlink), // 83
1534 //.. // (__NR_oldlstat, sys_lstat), // 84 -- obsolete
1535 //..
1536 GENX_(__NR_readlink, sys_readlink), // 85
1537 //.. // (__NR_uselib, sys_uselib), // 86 */Linux
1538 //.. // (__NR_swapon, sys_swapon), // 87 */Linux
1539 //.. // (__NR_reboot, sys_reboot), // 88 */Linux
1540 //.. // (__NR_readdir, old_readdir), // 89 -- superseded
1541
1542 PLAX_(__NR_mmap, sys_mmap), // 90
1543 GENXY(__NR_munmap, sys_munmap), // 91
1544 GENX_(__NR_truncate, sys_truncate), // 92
1545 GENX_(__NR_ftruncate, sys_ftruncate), // 93
1546 GENX_(__NR_fchmod, sys_fchmod), // 94
1547
1548 GENX_(__NR_fchown, sys_fchown), // 95
1549 GENX_(__NR_getpriority, sys_getpriority), // 96
1550 GENX_(__NR_setpriority, sys_setpriority), // 97
1551 //.. GENX_(__NR_profil, sys_ni_syscall), // 98
1552 GENXY(__NR_statfs, sys_statfs), // 99
1553 //..
1554 GENXY(__NR_fstatfs, sys_fstatfs), // 100
1555 //.. LINX_(__NR_ioperm, sys_ioperm), // 101
1556 PLAXY(__NR_socketcall, sys_socketcall), // 102
1557 LINXY(__NR_syslog, sys_syslog), // 103
1558 GENXY(__NR_setitimer, sys_setitimer), // 104
1559
1560 GENXY(__NR_getitimer, sys_getitimer), // 105
1561 GENXY(__NR_stat, sys_newstat), // 106
1562 GENXY(__NR_lstat, sys_newlstat), // 107
1563 GENXY(__NR_fstat, sys_newfstat), // 108
1564 //.. // (__NR_olduname, sys_uname), // 109 -- obsolete
1565 //..
1566 //.. GENX_(__NR_iopl, sys_iopl), // 110
1567 LINX_(__NR_vhangup, sys_vhangup), // 111
1568 //.. GENX_(__NR_idle, sys_ni_syscall), // 112
1569 //.. // (__NR_vm86old, sys_vm86old), // 113 x86/Linux-only
1570 GENXY(__NR_wait4, sys_wait4), // 114
1571 //..
1572 //.. // (__NR_swapoff, sys_swapoff), // 115 */Linux
1573 LINXY(__NR_sysinfo, sys_sysinfo), // 116
1574 PLAXY(__NR_ipc, sys_ipc), // 117
1575 GENX_(__NR_fsync, sys_fsync), // 118
1576 PLAX_(__NR_sigreturn, sys_sigreturn), // 119 ?/Linux
1577 //..
1578 PLAX_(__NR_clone, sys_clone), // 120
1579 //.. // (__NR_setdomainname, sys_setdomainname), // 121 */*(?)
1580 GENXY(__NR_uname, sys_newuname), // 122
1581 //.. PLAX_(__NR_modify_ldt, sys_modify_ldt), // 123
1582 LINXY(__NR_adjtimex, sys_adjtimex), // 124
1583
1584 GENXY(__NR_mprotect, sys_mprotect), // 125
1585 LINXY(__NR_sigprocmask, sys_sigprocmask), // 126
1586 GENX_(__NR_create_module, sys_ni_syscall), // 127
1587 LINX_(__NR_init_module, sys_init_module), // 128
1588 LINX_(__NR_delete_module, sys_delete_module), // 129
1589 //..
1590 //.. // Nb: get_kernel_syms() was removed 2.4-->2.6
1591 //.. GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130
1592 //.. LINX_(__NR_quotactl, sys_quotactl), // 131
1593 GENX_(__NR_getpgid, sys_getpgid), // 132
1594 GENX_(__NR_fchdir, sys_fchdir), // 133
1595 //.. // (__NR_bdflush, sys_bdflush), // 134 */Linux
1596 //..
1597 //.. // (__NR_sysfs, sys_sysfs), // 135 SVr4
1598 LINX_(__NR_personality, sys_personality), // 136
1599 //.. GENX_(__NR_afs_syscall, sys_ni_syscall), // 137
1600 LINX_(__NR_setfsuid, sys_setfsuid), // 138
1601 LINX_(__NR_setfsgid, sys_setfsgid), // 139
1602
1603 LINXY(__NR__llseek, sys_llseek), // 140
1604 GENXY(__NR_getdents, sys_getdents), // 141
1605 GENX_(__NR__newselect, sys_select), // 142
1606 GENX_(__NR_flock, sys_flock), // 143
1607 GENX_(__NR_msync, sys_msync), // 144
1608 //..
1609 GENXY(__NR_readv, sys_readv), // 145
1610 GENX_(__NR_writev, sys_writev), // 146
1611 GENX_(__NR_getsid, sys_getsid), // 147
1612 GENX_(__NR_fdatasync, sys_fdatasync), // 148
1613 LINXY(__NR__sysctl, sys_sysctl), // 149
1614 //..
1615 GENX_(__NR_mlock, sys_mlock), // 150
1616 GENX_(__NR_munlock, sys_munlock), // 151
1617 GENX_(__NR_mlockall, sys_mlockall), // 152
1618 LINX_(__NR_munlockall, sys_munlockall), // 153
1619 LINXY(__NR_sched_setparam, sys_sched_setparam), // 154
1620 //..
1621 LINXY(__NR_sched_getparam, sys_sched_getparam), // 155
1622 LINX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 156
1623 LINX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 157
1624 LINX_(__NR_sched_yield, sys_sched_yield), // 158
1625 LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
1626
1627 LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
1628 LINXY(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 161
1629 GENXY(__NR_nanosleep, sys_nanosleep), // 162
1630 GENX_(__NR_mremap, sys_mremap), // 163
1631 LINX_(__NR_setresuid, sys_setresuid), // 164
1632
1633 LINXY(__NR_getresuid, sys_getresuid), // 165
1634
1635 //.. GENX_(__NR_query_module, sys_ni_syscall), // 166
1636 GENXY(__NR_poll, sys_poll), // 167
1637 //.. // (__NR_nfsservctl, sys_nfsservctl), // 168 */Linux
1638 //..
1639 LINX_(__NR_setresgid, sys_setresgid), // 169
1640 LINXY(__NR_getresgid, sys_getresgid), // 170
1641 LINXY(__NR_prctl, sys_prctl), // 171
1642 PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 172
1643 LINXY(__NR_rt_sigaction, sys_rt_sigaction), // 173
1644
1645 LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 174
1646 LINXY(__NR_rt_sigpending, sys_rt_sigpending), // 175
1647 LINXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait), // 176
1648 LINXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo), // 177
1649 LINX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 178
1650
1651 GENXY(__NR_pread64, sys_pread64), // 179
1652 GENX_(__NR_pwrite64, sys_pwrite64), // 180
1653 GENX_(__NR_chown, sys_chown), // 181
1654 GENXY(__NR_getcwd, sys_getcwd), // 182
1655 LINXY(__NR_capget, sys_capget), // 183
1656 LINX_(__NR_capset, sys_capset), // 184
1657 GENXY(__NR_sigaltstack, sys_sigaltstack), // 185
1658 LINXY(__NR_sendfile, sys_sendfile), // 186
1659 //.. GENXY(__NR_getpmsg, sys_getpmsg), // 187
1660 //.. GENX_(__NR_putpmsg, sys_putpmsg), // 188
1661
1662 // Nb: we treat vfork as fork
1663 GENX_(__NR_vfork, sys_fork), // 189
1664 GENXY(__NR_ugetrlimit, sys_getrlimit), // 190
1665 LINX_(__NR_readahead, sys_readahead), // 191 */Linux
1666 PLAX_(__NR_mmap2, sys_mmap2), // 192
1667 GENX_(__NR_truncate64, sys_truncate64), // 193
1668 GENX_(__NR_ftruncate64, sys_ftruncate64), // 194
1669 //..
1670
1671 PLAXY(__NR_stat64, sys_stat64), // 195
1672 PLAXY(__NR_lstat64, sys_lstat64), // 196
1673 PLAXY(__NR_fstat64, sys_fstat64), // 197
1674
1675 // __NR_pciconfig_read // 198
1676 // __NR_pciconfig_write // 199
1677 // __NR_pciconfig_iobase // 200
1678 // __NR_multiplexer // 201
1679
1680 GENXY(__NR_getdents64, sys_getdents64), // 202
1681 //.. // (__NR_pivot_root, sys_pivot_root), // 203 */Linux
1682 LINXY(__NR_fcntl64, sys_fcntl64), // 204
1683 GENX_(__NR_madvise, sys_madvise), // 205
1684 GENXY(__NR_mincore, sys_mincore), // 206
1685 LINX_(__NR_gettid, sys_gettid), // 207
1686 //.. LINX_(__NR_tkill, sys_tkill), // 208 */Linux
1687 //.. LINX_(__NR_setxattr, sys_setxattr), // 209
1688 //.. LINX_(__NR_lsetxattr, sys_lsetxattr), // 210
1689 //.. LINX_(__NR_fsetxattr, sys_fsetxattr), // 211
1690 LINXY(__NR_getxattr, sys_getxattr), // 212
1691 LINXY(__NR_lgetxattr, sys_lgetxattr), // 213
1692 LINXY(__NR_fgetxattr, sys_fgetxattr), // 214
1693 LINXY(__NR_listxattr, sys_listxattr), // 215
1694 LINXY(__NR_llistxattr, sys_llistxattr), // 216
1695 LINXY(__NR_flistxattr, sys_flistxattr), // 217
1696 LINX_(__NR_removexattr, sys_removexattr), // 218
1697 LINX_(__NR_lremovexattr, sys_lremovexattr), // 219
1698 LINX_(__NR_fremovexattr, sys_fremovexattr), // 220
1699
1700 LINXY(__NR_futex, sys_futex), // 221
1701 LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 222
1702 LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 223
1703 /* 224 currently unused */
1704
1705 // __NR_tuxcall // 225
1706
1707 LINXY(__NR_sendfile64, sys_sendfile64), // 226
1708 //..
1709 LINX_(__NR_io_setup, sys_io_setup), // 227
1710 LINX_(__NR_io_destroy, sys_io_destroy), // 228
1711 LINXY(__NR_io_getevents, sys_io_getevents), // 229
1712 LINX_(__NR_io_submit, sys_io_submit), // 230
1713 LINXY(__NR_io_cancel, sys_io_cancel), // 231
1714 //..
1715 LINX_(__NR_set_tid_address, sys_set_tid_address), // 232
1716
1717 LINX_(__NR_fadvise64, sys_fadvise64), // 233 */(Linux?)
1718 LINX_(__NR_exit_group, sys_exit_group), // 234
1719 //.. GENXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 235
1720 LINXY(__NR_epoll_create, sys_epoll_create), // 236
1721 LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 237
1722 LINXY(__NR_epoll_wait, sys_epoll_wait), // 238
1723
1724 //.. // (__NR_remap_file_pages, sys_remap_file_pages), // 239 */Linux
1725 LINXY(__NR_timer_create, sys_timer_create), // 240
1726 LINXY(__NR_timer_settime, sys_timer_settime), // 241
1727 LINXY(__NR_timer_gettime, sys_timer_gettime), // 242
1728 LINX_(__NR_timer_getoverrun, sys_timer_getoverrun), // 243
1729 LINX_(__NR_timer_delete, sys_timer_delete), // 244
1730 LINX_(__NR_clock_settime, sys_clock_settime), // 245
1731 LINXY(__NR_clock_gettime, sys_clock_gettime), // 246
1732 LINXY(__NR_clock_getres, sys_clock_getres), // 247
1733 LINXY(__NR_clock_nanosleep, sys_clock_nanosleep), // 248
1734
1735 // __NR_swapcontext // 249
1736
1737 LINXY(__NR_tgkill, sys_tgkill), // 250 */Linux
1738 //.. GENX_(__NR_utimes, sys_utimes), // 251
1739 GENXY(__NR_statfs64, sys_statfs64), // 252
1740 GENXY(__NR_fstatfs64, sys_fstatfs64), // 253
1741 LINX_(__NR_fadvise64_64, sys_fadvise64_64), // 254 */(Linux?)
1742
1743 // __NR_rtas // 255
1744
1745 /* Number 256 is reserved for sys_debug_setcontext */
1746 /* Number 257 is reserved for vserver */
1747 /* Number 258 is reserved for new sys_remap_file_pages */
1748 /* Number 259 is reserved for new sys_mbind */
1749 LINXY(__NR_get_mempolicy, sys_get_mempolicy), // 260
1750 LINX_(__NR_set_mempolicy, sys_set_mempolicy), // 261
1751
1752 LINXY(__NR_mq_open, sys_mq_open), // 262
1753 LINX_(__NR_mq_unlink, sys_mq_unlink), // 263
1754 LINX_(__NR_mq_timedsend, sys_mq_timedsend), // 264
1755 LINXY(__NR_mq_timedreceive, sys_mq_timedreceive), // 265
1756 LINX_(__NR_mq_notify, sys_mq_notify), // 266
1757 LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // 267
1758 // __NR_kexec_load // 268
1759
1760 /* Number 269 is reserved for sys_add_key */
1761 /* Number 270 is reserved for sys_request_key */
1762 /* Number 271 is reserved for sys_keyctl */
1763 /* Number 272 is reserved for sys_waitid */
1764 LINX_(__NR_ioprio_set, sys_ioprio_set), // 273
1765 LINX_(__NR_ioprio_get, sys_ioprio_get), // 274
1766
1767 LINX_(__NR_inotify_init, sys_inotify_init), // 275
1768 LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 276
1769 LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 277
1770 PLAXY(__NR_spu_run, sys_spu_run), // 278
1771 PLAX_(__NR_spu_create, sys_spu_create), // 279
1772
1773 LINXY(__NR_openat, sys_openat), // 286
1774 LINX_(__NR_mkdirat, sys_mkdirat), // 287
1775 LINX_(__NR_mknodat, sys_mknodat), // 288
1776 LINX_(__NR_fchownat, sys_fchownat), // 289
1777 LINX_(__NR_futimesat, sys_futimesat), // 290
1778 PLAXY(__NR_fstatat64, sys_fstatat64), // 291
1779 LINX_(__NR_unlinkat, sys_unlinkat), // 292
1780 LINX_(__NR_renameat, sys_renameat), // 293
1781 LINX_(__NR_linkat, sys_linkat), // 294
1782 LINX_(__NR_symlinkat, sys_symlinkat), // 295
1783 LINX_(__NR_readlinkat, sys_readlinkat), // 296
1784 LINX_(__NR_fchmodat, sys_fchmodat), // 297
1785 LINX_(__NR_faccessat, sys_faccessat), // 298
1786 LINX_(__NR_set_robust_list, sys_set_robust_list), // 299
1787 LINXY(__NR_get_robust_list, sys_get_robust_list), // 300
1788 // LINX_(__NR_move_pages, sys_ni_syscall), // 301
1789 LINXY(__NR_getcpu, sys_getcpu), // 302
1790 LINXY(__NR_epoll_pwait, sys_epoll_pwait), // 303
1791 LINX_(__NR_utimensat, sys_utimensat), // 304
1792 LINXY(__NR_signalfd, sys_signalfd), // 305
1793 LINXY(__NR_timerfd_create, sys_timerfd_create), // 306
1794 LINX_(__NR_eventfd, sys_eventfd), // 307
1795 LINX_(__NR_sync_file_range2, sys_sync_file_range2), // 308
1796 LINX_(__NR_fallocate, sys_fallocate), // 309
1797 // LINXY(__NR_subpage_prot, sys_ni_syscall), // 310
1798 LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 311
1799 LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 312
1800 LINXY(__NR_signalfd4, sys_signalfd4), // 313
1801 LINX_(__NR_eventfd2, sys_eventfd2), // 314
1802 LINXY(__NR_epoll_create1, sys_epoll_create1), // 315
1803 LINXY(__NR_dup3, sys_dup3), // 316
1804 LINXY(__NR_pipe2, sys_pipe2), // 317
1805 LINXY(__NR_inotify_init1, sys_inotify_init1), // 318
1806 LINXY(__NR_perf_counter_open, sys_perf_counter_open),// 319
1807 LINXY(__NR_preadv, sys_preadv), // 320
1808 LINX_(__NR_pwritev, sys_pwritev), // 321
1809 LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo) // 322
1810 };
1811
ML_(get_linux_syscall_entry)1812 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1813 {
1814 const UInt syscall_table_size
1815 = sizeof(syscall_table) / sizeof(syscall_table[0]);
1816
1817 /* Is it in the contiguous initial section of the table? */
1818 if (sysno < syscall_table_size) {
1819 SyscallTableEntry* sys = &syscall_table[sysno];
1820 if (sys->before == NULL)
1821 return NULL; /* no entry */
1822 else
1823 return sys;
1824 }
1825
1826 /* Can't find a wrapper */
1827 return NULL;
1828 }
1829
1830 #endif // defined(VGP_ppc32_linux)
1831
1832 /*--------------------------------------------------------------------*/
1833 /*--- end ---*/
1834 /*--------------------------------------------------------------------*/
1835