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))
67void 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
75asm(
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
150extern
151ULong 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 * );
158asm(
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
220static 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 */
232static 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
383void VG_(cleanup_thread) ( ThreadArchState* arch )
384{
385}
386
387void 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
410DECL_TEMPLATE(ppc32_linux, sys_socketcall);
411DECL_TEMPLATE(ppc32_linux, sys_mmap);
412DECL_TEMPLATE(ppc32_linux, sys_mmap2);
413DECL_TEMPLATE(ppc32_linux, sys_stat64);
414DECL_TEMPLATE(ppc32_linux, sys_lstat64);
415DECL_TEMPLATE(ppc32_linux, sys_fstatat64);
416DECL_TEMPLATE(ppc32_linux, sys_fstat64);
417DECL_TEMPLATE(ppc32_linux, sys_ipc);
418DECL_TEMPLATE(ppc32_linux, sys_clone);
419DECL_TEMPLATE(ppc32_linux, sys_sigreturn);
420DECL_TEMPLATE(ppc32_linux, sys_rt_sigreturn);
421DECL_TEMPLATE(ppc32_linux, sys_spu_create);
422DECL_TEMPLATE(ppc32_linux, sys_spu_run);
423
424PRE(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
585POST(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
689PRE(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
705PRE(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
728PRE(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
736POST(sys_stat64)
737{
738   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
739}
740
741PRE(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
749POST(sys_lstat64)
750{
751   vg_assert(SUCCESS);
752   if (RES == 0) {
753      POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
754   }
755}
756
757PRE(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
766POST(sys_fstatat64)
767{
768   POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) );
769}
770
771PRE(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
778POST(sys_fstat64)
779{
780  POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
781}
782
783static 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
790PRE(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
870POST(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
972PRE(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
1057PRE(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
1092PRE(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
1392PRE(sys_spu_create)
1393{
1394   PRE_MEM_RASCIIZ("stat64(filename)", ARG1);
1395}
1396POST(sys_spu_create)
1397{
1398   vg_assert(SUCCESS);
1399}
1400
1401PRE(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}
1408POST(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
1433static 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
1812SyscallTableEntry* 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