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-2013 Nicholas Nethercote <njn@valgrind.org>
11   Copyright (C) 2005-2013 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_libcsetjmp.h"    // to keep _threadstate.h happy
37#include "pub_core_threadstate.h"
38#include "pub_core_aspacemgr.h"
39#include "pub_core_debuglog.h"
40#include "pub_core_libcbase.h"
41#include "pub_core_libcassert.h"
42#include "pub_core_libcprint.h"
43#include "pub_core_libcproc.h"
44#include "pub_core_libcsignal.h"
45#include "pub_core_options.h"
46#include "pub_core_scheduler.h"
47#include "pub_core_sigframe.h"      // For VG_(sigframe_destroy)()
48#include "pub_core_signals.h"
49#include "pub_core_syscall.h"
50#include "pub_core_syswrap.h"
51#include "pub_core_tooliface.h"
52#include "pub_core_stacks.h"        // VG_(register_stack)
53
54#include "priv_types_n_macros.h"
55#include "priv_syswrap-generic.h"   /* for decls of generic wrappers */
56#include "priv_syswrap-linux.h"     /* for decls of linux-ish wrappers */
57#include "priv_syswrap-main.h"
58
59
60/* ---------------------------------------------------------------------
61   clone() handling
62   ------------------------------------------------------------------ */
63
64/* Call f(arg1), but first switch stacks, using 'stack' as the new
65   stack, and use 'retaddr' as f's return-to address.  Also, clear all
66   the integer registers before entering f.*/
67__attribute__((noreturn))
68void ML_(call_on_new_stack_0_1) ( Addr stack,
69                                  Addr retaddr,
70                                  void (*f)(Word),
71                                  Word arg1 );
72//    r3 = stack
73//    r4 = retaddr
74//    r5 = f
75//    r6 = arg1
76asm(
77".text\n"
78".globl vgModuleLocal_call_on_new_stack_0_1\n"
79"vgModuleLocal_call_on_new_stack_0_1:\n"
80"   mr    %r1,%r3\n\t"     // stack to %sp
81"   mtlr  %r4\n\t"         // retaddr to %lr
82"   mtctr %r5\n\t"         // f to count reg
83"   mr %r3,%r6\n\t"        // arg1 to %r3
84"   li 0,0\n\t"            // zero all GP regs
85"   li 4,0\n\t"
86"   li 5,0\n\t"
87"   li 6,0\n\t"
88"   li 7,0\n\t"
89"   li 8,0\n\t"
90"   li 9,0\n\t"
91"   li 10,0\n\t"
92"   li 11,0\n\t"
93"   li 12,0\n\t"
94"   li 13,0\n\t"
95"   li 14,0\n\t"
96"   li 15,0\n\t"
97"   li 16,0\n\t"
98"   li 17,0\n\t"
99"   li 18,0\n\t"
100"   li 19,0\n\t"
101"   li 20,0\n\t"
102"   li 21,0\n\t"
103"   li 22,0\n\t"
104"   li 23,0\n\t"
105"   li 24,0\n\t"
106"   li 25,0\n\t"
107"   li 26,0\n\t"
108"   li 27,0\n\t"
109"   li 28,0\n\t"
110"   li 29,0\n\t"
111"   li 30,0\n\t"
112"   li 31,0\n\t"
113"   mtxer 0\n\t"           // CAB: Need this?
114"   mtcr 0\n\t"            // CAB: Need this?
115"   bctr\n\t"              // jump to dst
116"   trap\n"                // should never get here
117".previous\n"
118);
119
120
121/*
122        Perform a clone system call.  clone is strange because it has
123        fork()-like return-twice semantics, so it needs special
124        handling here.
125
126        Upon entry, we have:
127
128            int (fn)(void*)     in r3
129            void* child_stack   in r4
130            int flags           in r5
131            void* arg           in r6
132            pid_t* child_tid    in r7
133            pid_t* parent_tid   in r8
134            void* ???           in r9
135
136        System call requires:
137
138            int    $__NR_clone  in r0  (sc number)
139            int    flags        in r3  (sc arg1)
140            void*  child_stack  in r4  (sc arg2)
141            pid_t* parent_tid   in r5  (sc arg3)
142            ??     child_tls    in r6  (sc arg4)
143            pid_t* child_tid    in r7  (sc arg5)
144            void*  ???          in r8  (sc arg6)
145
146        Returns an Int encoded in the linux-ppc32 way, not a SysRes.
147 */
148#define __NR_CLONE        VG_STRINGIFY(__NR_clone)
149#define __NR_EXIT         VG_STRINGIFY(__NR_exit)
150
151extern
152ULong do_syscall_clone_ppc32_linux ( Word (*fn)(void *),
153                                     void* stack,
154                                     Int   flags,
155                                     void* arg,
156                                     Int*  child_tid,
157                                     Int*  parent_tid,
158                                     vki_modify_ldt_t * );
159asm(
160".text\n"
161".globl do_syscall_clone_ppc32_linux\n"
162"do_syscall_clone_ppc32_linux:\n"
163"       stwu    1,-32(1)\n"
164"       stw     29,20(1)\n"
165"       stw     30,24(1)\n"
166"       stw     31,28(1)\n"
167"       mr      30,3\n"              // preserve fn
168"       mr      31,6\n"              // preserve arg
169
170        // setup child stack
171"       rlwinm  4,4,0,~0xf\n"        // trim sp to multiple of 16 bytes
172"       li      0,0\n"
173"       stwu    0,-16(4)\n"          // make initial stack frame
174"       mr      29,4\n"              // preserve sp
175
176        // setup syscall
177"       li      0,"__NR_CLONE"\n"    // syscall number
178"       mr      3,5\n"               // syscall arg1: flags
179        // r4 already setup          // syscall arg2: child_stack
180"       mr      5,8\n"               // syscall arg3: parent_tid
181"       mr      6,2\n"               // syscall arg4: REAL THREAD tls
182"       mr      7,7\n"               // syscall arg5: child_tid
183"       mr      8,8\n"               // syscall arg6: ????
184"       mr      9,9\n"               // syscall arg7: ????
185
186"       sc\n"                        // clone()
187
188"       mfcr    4\n"                 // return CR in r4 (low word of ULong)
189"       cmpwi   3,0\n"               // child if retval == 0
190"       bne     1f\n"                // jump if !child
191
192        /* CHILD - call thread function */
193        /* Note: 2.4 kernel doesn't set the child stack pointer,
194           so we do it here.
195           That does leave a small window for a signal to be delivered
196           on the wrong stack, unfortunately. */
197"       mr      1,29\n"
198"       mtctr   30\n"                // ctr reg = fn
199"       mr      3,31\n"              // r3 = arg
200"       bctrl\n"                     // call fn()
201
202        // exit with result
203"       li      0,"__NR_EXIT"\n"
204"       sc\n"
205
206        // Exit returned?!
207"       .long   0\n"
208
209        // PARENT or ERROR - return
210"1:     lwz     29,20(1)\n"
211"       lwz     30,24(1)\n"
212"       lwz     31,28(1)\n"
213"       addi    1,1,32\n"
214"       blr\n"
215".previous\n"
216);
217
218#undef __NR_CLONE
219#undef __NR_EXIT
220
221// forward declarations
222static void setup_child ( ThreadArchState*, ThreadArchState* );
223
224/*
225   When a client clones, we need to keep track of the new thread.  This means:
226   1. allocate a ThreadId+ThreadState+stack for the the thread
227
228   2. initialize the thread's new VCPU state
229
230   3. create the thread using the same args as the client requested,
231   but using the scheduler entrypoint for IP, and a separate stack
232   for SP.
233 */
234static SysRes do_clone ( ThreadId ptid,
235                         UInt flags, Addr sp,
236                         Int *parent_tidptr,
237                         Int *child_tidptr,
238                         Addr child_tls)
239{
240   const Bool debug = False;
241
242   ThreadId     ctid = VG_(alloc_ThreadState)();
243   ThreadState* ptst = VG_(get_ThreadState)(ptid);
244   ThreadState* ctst = VG_(get_ThreadState)(ctid);
245   ULong        word64;
246   UWord*       stack;
247   NSegment const* seg;
248   SysRes       res;
249   vki_sigset_t blockall, savedmask;
250
251   VG_(sigfillset)(&blockall);
252
253   vg_assert(VG_(is_running_thread)(ptid));
254   vg_assert(VG_(is_valid_tid)(ctid));
255
256   stack = (UWord*)ML_(allocstack)(ctid);
257   if (stack == NULL) {
258      res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
259      goto out;
260   }
261
262//?   /* make a stack frame */
263//?   stack -= 16;
264//?   *(UWord *)stack = 0;
265
266
267   /* Copy register state
268
269      Both parent and child return to the same place, and the code
270      following the clone syscall works out which is which, so we
271      don't need to worry about it.
272
273      The parent gets the child's new tid returned from clone, but the
274      child gets 0.
275
276      If the clone call specifies a NULL SP for the new thread, then
277      it actually gets a copy of the parent's SP.
278
279      The child's TLS register (r2) gets set to the tlsaddr argument
280      if the CLONE_SETTLS flag is set.
281   */
282   setup_child( &ctst->arch, &ptst->arch );
283
284   /* Make sys_clone appear to have returned Success(0) in the
285      child. */
286   { UInt old_cr = LibVEX_GuestPPC32_get_CR( &ctst->arch.vex );
287     /* %r3 = 0 */
288     ctst->arch.vex.guest_GPR3 = 0;
289     /* %cr0.so = 0 */
290     LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
291   }
292
293   if (sp != 0)
294      ctst->arch.vex.guest_GPR1 = sp;
295
296   ctst->os_state.parent = ptid;
297
298   /* inherit signal mask */
299   ctst->sig_mask = ptst->sig_mask;
300   ctst->tmp_sig_mask = ptst->sig_mask;
301
302   /* Start the child with its threadgroup being the same as the
303      parent's.  This is so that any exit_group calls that happen
304      after the child is created but before it sets its
305      os_state.threadgroup field for real (in thread_wrapper in
306      syswrap-linux.c), really kill the new thread.  a.k.a this avoids
307      a race condition in which the thread is unkillable (via
308      exit_group) because its threadgroup is not set.  The race window
309      is probably only a few hundred or a few thousand cycles long.
310      See #226116. */
311   ctst->os_state.threadgroup = ptst->os_state.threadgroup;
312
313   /* We don't really know where the client stack is, because its
314      allocated by the client.  The best we can do is look at the
315      memory mappings and try to derive some useful information.  We
316      assume that esp starts near its highest possible value, and can
317      only go down to the start of the mmaped segment. */
318   seg = VG_(am_find_nsegment)(sp);
319   if (seg && seg->kind != SkResvn) {
320      ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(sp);
321      ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
322
323      VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
324
325      if (debug)
326	 VG_(printf)("\ntid %d: guessed client stack range %#lx-%#lx\n",
327		     ctid, seg->start, VG_PGROUNDUP(sp));
328   } else {
329      VG_(message)(Vg_UserMsg,
330                   "!? New thread %d starts with R1(%#lx) unmapped\n",
331		   ctid, sp);
332      ctst->client_stack_szB  = 0;
333   }
334
335   /* Assume the clone will succeed, and tell any tool that wants to
336      know that this thread has come into existence.  If the clone
337      fails, we'll send out a ll_exit notification for it at the out:
338      label below, to clean up. */
339   vg_assert(VG_(owns_BigLock_LL)(ptid));
340   VG_TRACK ( pre_thread_ll_create, ptid, ctid );
341
342   if (flags & VKI_CLONE_SETTLS) {
343      if (debug)
344         VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls);
345      ctst->arch.vex.guest_GPR2 = child_tls;
346   }
347
348   flags &= ~VKI_CLONE_SETTLS;
349
350   /* start the thread with everything blocked */
351   VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
352
353   /* Create the new thread */
354   word64 = do_syscall_clone_ppc32_linux(
355               ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid],
356               child_tidptr, parent_tidptr, NULL
357            );
358   /* High half word64 is syscall return value.  Low half is
359      the entire CR, from which we need to extract CR0.SO. */
360   /* VG_(printf)("word64 = 0x%llx\n", word64); */
361   res = VG_(mk_SysRes_ppc32_linux)(
362            /*val*/(UInt)(word64 >> 32),
363            /*errflag*/ (((UInt)word64) >> 28) & 1
364         );
365
366   VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
367
368  out:
369   if (sr_isError(res)) {
370      /* clone failed */
371      VG_(cleanup_thread)(&ctst->arch);
372      ctst->status = VgTs_Empty;
373      /* oops.  Better tell the tool the thread exited in a hurry :-) */
374      VG_TRACK( pre_thread_ll_exit, ctid );
375   }
376
377   return res;
378}
379
380
381
382/* ---------------------------------------------------------------------
383   More thread stuff
384   ------------------------------------------------------------------ */
385
386void VG_(cleanup_thread) ( ThreadArchState* arch )
387{
388}
389
390void setup_child ( /*OUT*/ ThreadArchState *child,
391                   /*IN*/  ThreadArchState *parent )
392{
393   /* We inherit our parent's guest state. */
394   child->vex = parent->vex;
395   child->vex_shadow1 = parent->vex_shadow1;
396   child->vex_shadow2 = parent->vex_shadow2;
397}
398
399
400/* ---------------------------------------------------------------------
401   PRE/POST wrappers for ppc32/Linux-specific syscalls
402   ------------------------------------------------------------------ */
403
404#define PRE(name)       DEFN_PRE_TEMPLATE(ppc32_linux, name)
405#define POST(name)      DEFN_POST_TEMPLATE(ppc32_linux, name)
406
407/* Add prototypes for the wrappers declared here, so that gcc doesn't
408   harass us for not having prototypes.  Really this is a kludge --
409   the right thing to do is to make these wrappers 'static' since they
410   aren't visible outside this file, but that requires even more macro
411   magic. */
412
413DECL_TEMPLATE(ppc32_linux, sys_mmap);
414DECL_TEMPLATE(ppc32_linux, sys_mmap2);
415DECL_TEMPLATE(ppc32_linux, sys_stat64);
416DECL_TEMPLATE(ppc32_linux, sys_lstat64);
417DECL_TEMPLATE(ppc32_linux, sys_fstatat64);
418DECL_TEMPLATE(ppc32_linux, sys_fstat64);
419DECL_TEMPLATE(ppc32_linux, sys_clone);
420DECL_TEMPLATE(ppc32_linux, sys_sigreturn);
421DECL_TEMPLATE(ppc32_linux, sys_rt_sigreturn);
422DECL_TEMPLATE(ppc32_linux, sys_sigsuspend);
423DECL_TEMPLATE(ppc32_linux, sys_spu_create);
424DECL_TEMPLATE(ppc32_linux, sys_spu_run);
425
426PRE(sys_mmap)
427{
428   SysRes r;
429
430   PRINT("sys_mmap ( %#lx, %llu, %ld, %ld, %ld, %ld )",
431         ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
432   PRE_REG_READ6(long, "mmap",
433                 unsigned long, start, unsigned long, length,
434                 unsigned long, prot,  unsigned long, flags,
435                 unsigned long, fd,    unsigned long, offset);
436
437   r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
438                                       (Off64T)ARG6 );
439   SET_STATUS_from_SysRes(r);
440}
441
442PRE(sys_mmap2)
443{
444   SysRes r;
445
446   // Exactly like old_mmap() except:
447   //  - the file offset is specified in 4K units rather than bytes,
448   //    so that it can be used for files bigger than 2^32 bytes.
449   PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )",
450         ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
451   PRE_REG_READ6(long, "mmap2",
452                 unsigned long, start, unsigned long, length,
453                 unsigned long, prot,  unsigned long, flags,
454                 unsigned long, fd,    unsigned long, offset);
455
456   r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
457                                       4096 * (Off64T)ARG6 );
458   SET_STATUS_from_SysRes(r);
459}
460
461// XXX: lstat64/fstat64/stat64 are generic, but not necessarily
462// applicable to every architecture -- I think only to 32-bit archs.
463// We're going to need something like linux/core_os32.h for such
464// things, eventually, I think.  --njn
465PRE(sys_stat64)
466{
467   PRINT("sys_stat64 ( %#lx, %#lx )",ARG1,ARG2);
468   PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
469   PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
470   PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
471}
472
473POST(sys_stat64)
474{
475   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
476}
477
478PRE(sys_lstat64)
479{
480   PRINT("sys_lstat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
481   PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
482   PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
483   PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
484}
485
486POST(sys_lstat64)
487{
488   vg_assert(SUCCESS);
489   if (RES == 0) {
490      POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
491   }
492}
493
494PRE(sys_fstatat64)
495{
496  PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )",ARG1,ARG2,(char*)ARG2,ARG3);
497   PRE_REG_READ3(long, "fstatat64",
498                 int, dfd, char *, file_name, struct stat64 *, buf);
499   PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 );
500   PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) );
501}
502
503POST(sys_fstatat64)
504{
505   POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) );
506}
507
508PRE(sys_fstat64)
509{
510  PRINT("sys_fstat64 ( %ld, %#lx )",ARG1,ARG2);
511  PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
512  PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
513}
514
515POST(sys_fstat64)
516{
517  POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
518}
519
520
521
522//.. PRE(old_select, MayBlock)
523//.. {
524//..    /* struct sel_arg_struct {
525//..       unsigned long n;
526//..       fd_set *inp, *outp, *exp;
527//..       struct timeval *tvp;
528//..       };
529//..    */
530//..    PRE_REG_READ1(long, "old_select", struct sel_arg_struct *, args);
531//..    PRE_MEM_READ( "old_select(args)", ARG1, 5*sizeof(UWord) );
532//..
533//..    {
534//..       UInt* arg_struct = (UInt*)ARG1;
535//..       UInt a1, a2, a3, a4, a5;
536//..
537//..       a1 = arg_struct[0];
538//..       a2 = arg_struct[1];
539//..       a3 = arg_struct[2];
540//..       a4 = arg_struct[3];
541//..       a5 = arg_struct[4];
542//..
543//..       PRINT("old_select ( %d, %p, %p, %p, %p )", a1,a2,a3,a4,a5);
544//..       if (a2 != (Addr)NULL)
545//.. 	 PRE_MEM_READ( "old_select(readfds)",   a2, a1/8 /* __FD_SETSIZE/8 */ );
546//..       if (a3 != (Addr)NULL)
547//.. 	 PRE_MEM_READ( "old_select(writefds)",  a3, a1/8 /* __FD_SETSIZE/8 */ );
548//..       if (a4 != (Addr)NULL)
549//.. 	 PRE_MEM_READ( "old_select(exceptfds)", a4, a1/8 /* __FD_SETSIZE/8 */ );
550//..       if (a5 != (Addr)NULL)
551//.. 	 PRE_MEM_READ( "old_select(timeout)", a5, sizeof(struct vki_timeval) );
552//..    }
553//.. }
554
555PRE(sys_clone)
556{
557   UInt cloneflags;
558
559   PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
560   PRE_REG_READ5(int, "clone",
561                 unsigned long, flags,
562                 void *,        child_stack,
563                 int *,         parent_tidptr,
564                 void *,        child_tls,
565                 int *,         child_tidptr);
566
567   if (ARG1 & VKI_CLONE_PARENT_SETTID) {
568      PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
569      if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
570                                             VKI_PROT_WRITE)) {
571         SET_STATUS_Failure( VKI_EFAULT );
572         return;
573      }
574   }
575   if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
576      PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
577      if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int),
578                                             VKI_PROT_WRITE)) {
579         SET_STATUS_Failure( VKI_EFAULT );
580         return;
581      }
582   }
583
584   cloneflags = ARG1;
585
586   if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
587      SET_STATUS_Failure( VKI_EINVAL );
588      return;
589   }
590
591   /* Only look at the flags we really care about */
592   switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
593                         | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
594   case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
595      /* thread creation */
596      SET_STATUS_from_SysRes(
597         do_clone(tid,
598                  ARG1,         /* flags */
599                  (Addr)ARG2,   /* child SP */
600                  (Int *)ARG3,  /* parent_tidptr */
601                  (Int *)ARG5,  /* child_tidptr */
602                  (Addr)ARG4)); /* child_tls */
603      break;
604
605   case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
606      /* FALLTHROUGH - assume vfork == fork */
607      cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
608
609   case 0: /* plain fork */
610      SET_STATUS_from_SysRes(
611         ML_(do_fork_clone)(tid,
612                       cloneflags,      /* flags */
613                       (Int *)ARG3,     /* parent_tidptr */
614                       (Int *)ARG5));   /* child_tidptr */
615      break;
616
617   default:
618      /* should we just ENOSYS? */
619      VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
620      VG_(message)(Vg_UserMsg, "\n");
621      VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
622      VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
623      VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
624      VG_(unimplemented)
625         ("Valgrind does not support general clone().");
626   }
627
628   if (SUCCESS) {
629      if (ARG1 & VKI_CLONE_PARENT_SETTID)
630         POST_MEM_WRITE(ARG3, sizeof(Int));
631      if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
632         POST_MEM_WRITE(ARG5, sizeof(Int));
633
634      /* Thread creation was successful; let the child have the chance
635         to run */
636      *flags |= SfYieldAfter;
637   }
638}
639
640PRE(sys_sigreturn)
641{
642   /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
643      an explanation of what follows. */
644
645   //ThreadState* tst;
646   PRINT("sys_sigreturn ( )");
647
648   vg_assert(VG_(is_valid_tid)(tid));
649   vg_assert(tid >= 1 && tid < VG_N_THREADS);
650   vg_assert(VG_(is_running_thread)(tid));
651
652   ///* Adjust esp to point to start of frame; skip back up over
653   //   sigreturn sequence's "popl %eax" and handler ret addr */
654   //tst = VG_(get_ThreadState)(tid);
655   //tst->arch.vex.guest_ESP -= sizeof(Addr)+sizeof(Word);
656   // Should we do something equivalent on ppc32?  Who knows.
657
658   ///* This is only so that the EIP is (might be) useful to report if
659   //   something goes wrong in the sigreturn */
660   //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
661   // Should we do something equivalent on ppc32?  Who knows.
662
663   /* Restore register state from frame and remove it */
664   VG_(sigframe_destroy)(tid, False);
665
666   /* Tell the driver not to update the guest state with the "result",
667      and set a bogus result to keep it happy. */
668   *flags |= SfNoWriteResult;
669   SET_STATUS_Success(0);
670
671   /* Check to see if any signals arose as a result of this. */
672   *flags |= SfPollAfter;
673}
674
675PRE(sys_rt_sigreturn)
676{
677   /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
678      an explanation of what follows. */
679
680   //ThreadState* tst;
681   PRINT("rt_sigreturn ( )");
682
683   vg_assert(VG_(is_valid_tid)(tid));
684   vg_assert(tid >= 1 && tid < VG_N_THREADS);
685   vg_assert(VG_(is_running_thread)(tid));
686
687   ///* Adjust esp to point to start of frame; skip back up over handler
688   //   ret addr */
689   //tst = VG_(get_ThreadState)(tid);
690   //tst->arch.vex.guest_ESP -= sizeof(Addr);
691   // Should we do something equivalent on ppc32?  Who knows.
692
693   ///* This is only so that the EIP is (might be) useful to report if
694   //   something goes wrong in the sigreturn */
695   //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
696   // Should we do something equivalent on ppc32?  Who knows.
697
698   /* Restore register state from frame and remove it */
699   VG_(sigframe_destroy)(tid, True);
700
701   /* Tell the driver not to update the guest state with the "result",
702      and set a bogus result to keep it happy. */
703   *flags |= SfNoWriteResult;
704   SET_STATUS_Success(0);
705
706   /* Check to see if any signals arose as a result of this. */
707   *flags |= SfPollAfter;
708}
709
710
711//.. PRE(sys_modify_ldt, Special)
712//.. {
713//..    PRINT("sys_modify_ldt ( %d, %p, %d )", ARG1,ARG2,ARG3);
714//..    PRE_REG_READ3(int, "modify_ldt", int, func, void *, ptr,
715//..                  unsigned long, bytecount);
716//..
717//..    if (ARG1 == 0) {
718//..       /* read the LDT into ptr */
719//..       PRE_MEM_WRITE( "modify_ldt(ptr)", ARG2, ARG3 );
720//..    }
721//..    if (ARG1 == 1 || ARG1 == 0x11) {
722//..       /* write the LDT with the entry pointed at by ptr */
723//..       PRE_MEM_READ( "modify_ldt(ptr)", ARG2, sizeof(vki_modify_ldt_t) );
724//..    }
725//..    /* "do" the syscall ourselves; the kernel never sees it */
726//..    SET_RESULT( VG_(sys_modify_ldt)( tid, ARG1, (void*)ARG2, ARG3 ) );
727//..
728//..    if (ARG1 == 0 && !VG_(is_kerror)(RES) && RES > 0) {
729//..       POST_MEM_WRITE( ARG2, RES );
730//..    }
731//.. }
732
733//.. PRE(sys_set_thread_area, Special)
734//.. {
735//..    PRINT("sys_set_thread_area ( %p )", ARG1);
736//..    PRE_REG_READ1(int, "set_thread_area", struct user_desc *, u_info)
737//..    PRE_MEM_READ( "set_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
738//..
739//..    /* "do" the syscall ourselves; the kernel never sees it */
740//..    SET_RESULT( VG_(sys_set_thread_area)( tid, (void *)ARG1 ) );
741//.. }
742
743//.. PRE(sys_get_thread_area, Special)
744//.. {
745//..    PRINT("sys_get_thread_area ( %p )", ARG1);
746//..    PRE_REG_READ1(int, "get_thread_area", struct user_desc *, u_info)
747//..    PRE_MEM_WRITE( "get_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
748//..
749//..    /* "do" the syscall ourselves; the kernel never sees it */
750//..    SET_RESULT( VG_(sys_get_thread_area)( tid, (void *)ARG1 ) );
751//..
752//..    if (!VG_(is_kerror)(RES)) {
753//..       POST_MEM_WRITE( ARG1, sizeof(vki_modify_ldt_t) );
754//..    }
755//.. }
756
757//.. // Parts of this are ppc32-specific, but the *PEEK* cases are generic.
758//.. // XXX: Why is the memory pointed to by ARG3 never checked?
759//.. PRE(sys_ptrace, 0)
760//.. {
761//..    PRINT("sys_ptrace ( %d, %d, %p, %p )", ARG1,ARG2,ARG3,ARG4);
762//..    PRE_REG_READ4(int, "ptrace",
763//..                  long, request, long, pid, long, addr, long, data);
764//..    switch (ARG1) {
765//..    case VKI_PTRACE_PEEKTEXT:
766//..    case VKI_PTRACE_PEEKDATA:
767//..    case VKI_PTRACE_PEEKUSR:
768//..       PRE_MEM_WRITE( "ptrace(peek)", ARG4,
769//.. 		     sizeof (long));
770//..       break;
771//..    case VKI_PTRACE_GETREGS:
772//..       PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
773//.. 		     sizeof (struct vki_user_regs_struct));
774//..       break;
775//..    case VKI_PTRACE_GETFPREGS:
776//..       PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
777//.. 		     sizeof (struct vki_user_i387_struct));
778//..       break;
779//..    case VKI_PTRACE_GETFPXREGS:
780//..       PRE_MEM_WRITE( "ptrace(getfpxregs)", ARG4,
781//..                      sizeof(struct vki_user_fxsr_struct) );
782//..       break;
783//..    case VKI_PTRACE_SETREGS:
784//..       PRE_MEM_READ( "ptrace(setregs)", ARG4,
785//.. 		     sizeof (struct vki_user_regs_struct));
786//..       break;
787//..    case VKI_PTRACE_SETFPREGS:
788//..       PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
789//.. 		     sizeof (struct vki_user_i387_struct));
790//..       break;
791//..    case VKI_PTRACE_SETFPXREGS:
792//..       PRE_MEM_READ( "ptrace(setfpxregs)", ARG4,
793//..                      sizeof(struct vki_user_fxsr_struct) );
794//..       break;
795//..    default:
796//..       break;
797//..    }
798//.. }
799
800//.. POST(sys_ptrace)
801//.. {
802//..    switch (ARG1) {
803//..    case VKI_PTRACE_PEEKTEXT:
804//..    case VKI_PTRACE_PEEKDATA:
805//..    case VKI_PTRACE_PEEKUSR:
806//..       POST_MEM_WRITE( ARG4, sizeof (long));
807//..       break;
808//..    case VKI_PTRACE_GETREGS:
809//..       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
810//..       break;
811//..    case VKI_PTRACE_GETFPREGS:
812//..       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
813//..       break;
814//..    case VKI_PTRACE_GETFPXREGS:
815//..       POST_MEM_WRITE( ARG4, sizeof(struct vki_user_fxsr_struct) );
816//..       break;
817//..    default:
818//..       break;
819//..    }
820//.. }
821
822/* NB: This is an almost identical clone of versions for x86-linux and
823   arm-linux, which are themselves literally identical. */
824PRE(sys_sigsuspend)
825{
826   /* The C library interface to sigsuspend just takes a pointer to
827      a signal mask but this system call only takes the first word of
828      the signal mask as an argument so only 32 signals are supported.
829
830      In fact glibc normally uses rt_sigsuspend if it is available as
831      that takes a pointer to the signal mask so supports more signals.
832    */
833   *flags |= SfMayBlock;
834   PRINT("sys_sigsuspend ( %ld )", ARG1 );
835   PRE_REG_READ1(int, "sigsuspend", vki_old_sigset_t, mask);
836}
837
838PRE(sys_spu_create)
839{
840   PRE_MEM_RASCIIZ("stat64(filename)", ARG1);
841}
842POST(sys_spu_create)
843{
844   vg_assert(SUCCESS);
845}
846
847PRE(sys_spu_run)
848{
849   *flags |= SfMayBlock;
850   if (ARG2 != 0)
851      PRE_MEM_WRITE("npc", ARG2, sizeof(unsigned int));
852   PRE_MEM_READ("event", ARG3, sizeof(unsigned int));
853}
854POST(sys_spu_run)
855{
856   if (ARG2 != 0)
857      POST_MEM_WRITE(ARG2, sizeof(unsigned int));
858}
859
860#undef PRE
861#undef POST
862
863/* ---------------------------------------------------------------------
864   The ppc32/Linux syscall table
865   ------------------------------------------------------------------ */
866
867/* Add an ppc32-linux specific wrapper to a syscall table. */
868#define PLAX_(sysno, name)    WRAPPER_ENTRY_X_(ppc32_linux, sysno, name)
869#define PLAXY(sysno, name)    WRAPPER_ENTRY_XY(ppc32_linux, sysno, name)
870
871// This table maps from __NR_xxx syscall numbers (from
872// linux/include/asm-ppc/unistd.h) to the appropriate PRE/POST sys_foo()
873// wrappers on ppc32 (as per sys_call_table in linux/arch/ppc/kernel/entry.S).
874//
875// For those syscalls not handled by Valgrind, the annotation indicate its
876// arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
877// (unknown).
878
879static SyscallTableEntry syscall_table[] = {
880//..   (restart_syscall)                                      // 0
881   GENX_(__NR_exit,              sys_exit),              // 1
882   GENX_(__NR_fork,              sys_fork),              // 2
883   GENXY(__NR_read,              sys_read),              // 3
884   GENX_(__NR_write,             sys_write),             // 4
885
886   GENXY(__NR_open,              sys_open),              // 5
887   GENXY(__NR_close,             sys_close),             // 6
888   GENXY(__NR_waitpid,           sys_waitpid),           // 7
889   GENXY(__NR_creat,             sys_creat),             // 8
890   GENX_(__NR_link,              sys_link),              // 9
891
892   GENX_(__NR_unlink,            sys_unlink),            // 10
893   GENX_(__NR_execve,            sys_execve),            // 11
894   GENX_(__NR_chdir,             sys_chdir),             // 12
895   GENXY(__NR_time,              sys_time),              // 13
896   GENX_(__NR_mknod,             sys_mknod),             // 14
897//..
898   GENX_(__NR_chmod,             sys_chmod),             // 15
899   GENX_(__NR_lchown,            sys_lchown),          // 16 ## P
900//..    GENX_(__NR_break,             sys_ni_syscall),        // 17
901//..    //   (__NR_oldstat,           sys_stat),              // 18 (obsolete)
902   LINX_(__NR_lseek,             sys_lseek),             // 19
903//..
904   GENX_(__NR_getpid,            sys_getpid),            // 20
905   LINX_(__NR_mount,             sys_mount),             // 21
906   LINX_(__NR_umount,            sys_oldumount),         // 22
907   GENX_(__NR_setuid,            sys_setuid),            // 23 ## P
908   GENX_(__NR_getuid,            sys_getuid),            // 24 ## P
909//..
910//..    //   (__NR_stime,             sys_stime),             // 25 * (SVr4,SVID,X/OPEN)
911//..    PLAXY(__NR_ptrace,            sys_ptrace),            // 26
912   GENX_(__NR_alarm,             sys_alarm),             // 27
913//..    //   (__NR_oldfstat,          sys_fstat),             // 28 * L -- obsolete
914   GENX_(__NR_pause,             sys_pause),             // 29
915//..
916   LINX_(__NR_utime,             sys_utime),                  // 30
917//..    GENX_(__NR_stty,              sys_ni_syscall),        // 31
918//..    GENX_(__NR_gtty,              sys_ni_syscall),        // 32
919   GENX_(__NR_access,            sys_access),            // 33
920//..    GENX_(__NR_nice,              sys_nice),              // 34
921//..
922//..    GENX_(__NR_ftime,             sys_ni_syscall),        // 35
923//..    GENX_(__NR_sync,              sys_sync),              // 36
924   GENX_(__NR_kill,              sys_kill),              // 37
925   GENX_(__NR_rename,            sys_rename),            // 38
926   GENX_(__NR_mkdir,             sys_mkdir),             // 39
927
928   GENX_(__NR_rmdir,             sys_rmdir),             // 40
929   GENXY(__NR_dup,               sys_dup),               // 41
930   LINXY(__NR_pipe,              sys_pipe),              // 42
931   GENXY(__NR_times,             sys_times),             // 43
932//..    GENX_(__NR_prof,              sys_ni_syscall),        // 44
933//..
934   GENX_(__NR_brk,               sys_brk),               // 45
935   GENX_(__NR_setgid,            sys_setgid),            // 46
936   GENX_(__NR_getgid,            sys_getgid),            // 47
937//..    //   (__NR_signal,            sys_signal),            // 48 */* (ANSI C)
938   GENX_(__NR_geteuid,           sys_geteuid),           // 49
939
940   GENX_(__NR_getegid,           sys_getegid),           // 50
941//..    GENX_(__NR_acct,              sys_acct),              // 51
942   LINX_(__NR_umount2,           sys_umount),            // 52
943//..    GENX_(__NR_lock,              sys_ni_syscall),        // 53
944   LINXY(__NR_ioctl,             sys_ioctl),             // 54
945//..
946   LINXY(__NR_fcntl,             sys_fcntl),             // 55
947//..    GENX_(__NR_mpx,               sys_ni_syscall),        // 56
948   GENX_(__NR_setpgid,           sys_setpgid),           // 57
949//..    GENX_(__NR_ulimit,            sys_ni_syscall),        // 58
950//..    //   (__NR_oldolduname,       sys_olduname),          // 59 Linux -- obsolete
951
952   GENX_(__NR_umask,             sys_umask),             // 60
953   GENX_(__NR_chroot,            sys_chroot),            // 61
954//..    //   (__NR_ustat,             sys_ustat)              // 62 SVr4 -- deprecated
955   GENXY(__NR_dup2,              sys_dup2),              // 63
956   GENX_(__NR_getppid,           sys_getppid),           // 64
957
958   GENX_(__NR_getpgrp,           sys_getpgrp),           // 65
959   GENX_(__NR_setsid,            sys_setsid),            // 66
960   LINXY(__NR_sigaction,         sys_sigaction),         // 67
961//..    //   (__NR_sgetmask,          sys_sgetmask),          // 68 */* (ANSI C)
962//..    //   (__NR_ssetmask,          sys_ssetmask),          // 69 */* (ANSI C)
963//..
964   GENX_(__NR_setreuid,          sys_setreuid),          // 70
965   GENX_(__NR_setregid,          sys_setregid),          // 71
966   PLAX_(__NR_sigsuspend,        sys_sigsuspend),        // 72
967   LINXY(__NR_sigpending,        sys_sigpending),        // 73
968//..    //   (__NR_sethostname,       sys_sethostname),       // 74 */*
969//..
970   GENX_(__NR_setrlimit,         sys_setrlimit),              // 75
971//..    GENXY(__NR_getrlimit,         sys_old_getrlimit),     // 76
972   GENXY(__NR_getrusage,         sys_getrusage),         // 77
973   GENXY(__NR_gettimeofday,      sys_gettimeofday),           // 78
974//..    GENX_(__NR_settimeofday,      sys_settimeofday),      // 79
975//..
976   GENXY(__NR_getgroups,         sys_getgroups),         // 80
977   GENX_(__NR_setgroups,         sys_setgroups),         // 81
978//..    PLAX_(__NR_select,            old_select),            // 82
979   GENX_(__NR_symlink,           sys_symlink),           // 83
980//..    //   (__NR_oldlstat,          sys_lstat),             // 84 -- obsolete
981//..
982   GENX_(__NR_readlink,          sys_readlink),          // 85
983//..    //   (__NR_uselib,            sys_uselib),            // 86 */Linux
984//..    //   (__NR_swapon,            sys_swapon),            // 87 */Linux
985//..    //   (__NR_reboot,            sys_reboot),            // 88 */Linux
986//..    //   (__NR_readdir,           old_readdir),           // 89 -- superseded
987
988   PLAX_(__NR_mmap,              sys_mmap),                   // 90
989   GENXY(__NR_munmap,            sys_munmap),                 // 91
990   GENX_(__NR_truncate,          sys_truncate),          // 92
991   GENX_(__NR_ftruncate,         sys_ftruncate),         // 93
992   GENX_(__NR_fchmod,            sys_fchmod),            // 94
993
994   GENX_(__NR_fchown,            sys_fchown),            // 95
995   GENX_(__NR_getpriority,       sys_getpriority),       // 96
996   GENX_(__NR_setpriority,       sys_setpriority),       // 97
997//..    GENX_(__NR_profil,            sys_ni_syscall),        // 98
998   GENXY(__NR_statfs,            sys_statfs),            // 99
999//..
1000   GENXY(__NR_fstatfs,           sys_fstatfs),           // 100
1001//..    LINX_(__NR_ioperm,            sys_ioperm),            // 101
1002   LINXY(__NR_socketcall,        sys_socketcall),        // 102
1003   LINXY(__NR_syslog,            sys_syslog),            // 103
1004   GENXY(__NR_setitimer,         sys_setitimer),         // 104
1005
1006   GENXY(__NR_getitimer,         sys_getitimer),         // 105
1007   GENXY(__NR_stat,              sys_newstat),           // 106
1008   GENXY(__NR_lstat,             sys_newlstat),          // 107
1009   GENXY(__NR_fstat,             sys_newfstat),          // 108
1010//..    //   (__NR_olduname,          sys_uname),             // 109 -- obsolete
1011//..
1012//..    GENX_(__NR_iopl,              sys_iopl),              // 110
1013   LINX_(__NR_vhangup,           sys_vhangup),           // 111
1014//..    GENX_(__NR_idle,              sys_ni_syscall),        // 112
1015//..    //   (__NR_vm86old,           sys_vm86old),           // 113 x86/Linux-only
1016   GENXY(__NR_wait4,             sys_wait4),             // 114
1017//..
1018//..    //   (__NR_swapoff,           sys_swapoff),           // 115 */Linux
1019   LINXY(__NR_sysinfo,           sys_sysinfo),           // 116
1020   LINXY(__NR_ipc,               sys_ipc),               // 117
1021   GENX_(__NR_fsync,             sys_fsync),             // 118
1022   PLAX_(__NR_sigreturn,         sys_sigreturn),         // 119 ?/Linux
1023//..
1024   PLAX_(__NR_clone,             sys_clone),             // 120
1025//..    //   (__NR_setdomainname,     sys_setdomainname),     // 121 */*(?)
1026   GENXY(__NR_uname,             sys_newuname),          // 122
1027//..    PLAX_(__NR_modify_ldt,        sys_modify_ldt),        // 123
1028   LINXY(__NR_adjtimex,          sys_adjtimex),          // 124
1029
1030   GENXY(__NR_mprotect,          sys_mprotect),          // 125
1031   LINXY(__NR_sigprocmask,       sys_sigprocmask),       // 126
1032   GENX_(__NR_create_module,     sys_ni_syscall),        // 127
1033   LINX_(__NR_init_module,       sys_init_module),       // 128
1034   LINX_(__NR_delete_module,     sys_delete_module),     // 129
1035//..
1036//..    // Nb: get_kernel_syms() was removed 2.4-->2.6
1037//..    GENX_(__NR_get_kernel_syms,   sys_ni_syscall),        // 130
1038//..    LINX_(__NR_quotactl,          sys_quotactl),          // 131
1039   GENX_(__NR_getpgid,           sys_getpgid),           // 132
1040   GENX_(__NR_fchdir,            sys_fchdir),            // 133
1041//..    //   (__NR_bdflush,           sys_bdflush),           // 134 */Linux
1042//..
1043//..    //   (__NR_sysfs,             sys_sysfs),             // 135 SVr4
1044   LINX_(__NR_personality,       sys_personality),       // 136
1045//..    GENX_(__NR_afs_syscall,       sys_ni_syscall),        // 137
1046   LINX_(__NR_setfsuid,          sys_setfsuid),          // 138
1047   LINX_(__NR_setfsgid,          sys_setfsgid),          // 139
1048
1049   LINXY(__NR__llseek,           sys_llseek),            // 140
1050   GENXY(__NR_getdents,          sys_getdents),          // 141
1051   GENX_(__NR__newselect,        sys_select),            // 142
1052   GENX_(__NR_flock,             sys_flock),             // 143
1053   GENX_(__NR_msync,             sys_msync),             // 144
1054//..
1055   GENXY(__NR_readv,             sys_readv),             // 145
1056   GENX_(__NR_writev,            sys_writev),            // 146
1057   GENX_(__NR_getsid,            sys_getsid),            // 147
1058   GENX_(__NR_fdatasync,         sys_fdatasync),         // 148
1059   LINXY(__NR__sysctl,           sys_sysctl),            // 149
1060//..
1061   GENX_(__NR_mlock,             sys_mlock),             // 150
1062   GENX_(__NR_munlock,           sys_munlock),           // 151
1063   GENX_(__NR_mlockall,          sys_mlockall),          // 152
1064   LINX_(__NR_munlockall,        sys_munlockall),        // 153
1065   LINXY(__NR_sched_setparam,    sys_sched_setparam),    // 154
1066//..
1067   LINXY(__NR_sched_getparam,         sys_sched_getparam),        // 155
1068   LINX_(__NR_sched_setscheduler,     sys_sched_setscheduler),    // 156
1069   LINX_(__NR_sched_getscheduler,     sys_sched_getscheduler),    // 157
1070   LINX_(__NR_sched_yield,            sys_sched_yield),           // 158
1071   LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
1072
1073   LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
1074   LINXY(__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 161
1075   GENXY(__NR_nanosleep,         sys_nanosleep),         // 162
1076   GENX_(__NR_mremap,            sys_mremap),            // 163
1077   LINX_(__NR_setresuid,         sys_setresuid),         // 164
1078
1079   LINXY(__NR_getresuid,         sys_getresuid),         // 165
1080
1081//..    GENX_(__NR_query_module,      sys_ni_syscall),        // 166
1082   GENXY(__NR_poll,              sys_poll),              // 167
1083//..    //   (__NR_nfsservctl,        sys_nfsservctl),        // 168 */Linux
1084//..
1085   LINX_(__NR_setresgid,         sys_setresgid),         // 169
1086   LINXY(__NR_getresgid,         sys_getresgid),         // 170
1087   LINXY(__NR_prctl,             sys_prctl),             // 171
1088   PLAX_(__NR_rt_sigreturn,      sys_rt_sigreturn),      // 172
1089   LINXY(__NR_rt_sigaction,      sys_rt_sigaction),      // 173
1090
1091   LINXY(__NR_rt_sigprocmask,    sys_rt_sigprocmask),    // 174
1092   LINXY(__NR_rt_sigpending,     sys_rt_sigpending),     // 175
1093   LINXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),   // 176
1094   LINXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),   // 177
1095   LINX_(__NR_rt_sigsuspend,     sys_rt_sigsuspend),     // 178
1096
1097   GENXY(__NR_pread64,           sys_pread64),           // 179
1098   GENX_(__NR_pwrite64,          sys_pwrite64),          // 180
1099   GENX_(__NR_chown,             sys_chown),             // 181
1100   GENXY(__NR_getcwd,            sys_getcwd),            // 182
1101   LINXY(__NR_capget,            sys_capget),            // 183
1102   LINX_(__NR_capset,            sys_capset),            // 184
1103   GENXY(__NR_sigaltstack,       sys_sigaltstack),       // 185
1104   LINXY(__NR_sendfile,          sys_sendfile),          // 186
1105//..    GENXY(__NR_getpmsg,           sys_getpmsg),           // 187
1106//..    GENX_(__NR_putpmsg,           sys_putpmsg),           // 188
1107
1108   // Nb: we treat vfork as fork
1109   GENX_(__NR_vfork,             sys_fork),              // 189
1110   GENXY(__NR_ugetrlimit,        sys_getrlimit),         // 190
1111   LINX_(__NR_readahead,         sys_readahead),         // 191 */Linux
1112   PLAX_(__NR_mmap2,             sys_mmap2),             // 192
1113   GENX_(__NR_truncate64,        sys_truncate64),        // 193
1114   GENX_(__NR_ftruncate64,       sys_ftruncate64),       // 194
1115//..
1116
1117   PLAXY(__NR_stat64,            sys_stat64),            // 195
1118   PLAXY(__NR_lstat64,           sys_lstat64),           // 196
1119   PLAXY(__NR_fstat64,           sys_fstat64),           // 197
1120
1121// __NR_pciconfig_read                                        // 198
1122// __NR_pciconfig_write                                       // 199
1123// __NR_pciconfig_iobase                                      // 200
1124// __NR_multiplexer                                           // 201
1125
1126   GENXY(__NR_getdents64,        sys_getdents64),        // 202
1127//..    //   (__NR_pivot_root,        sys_pivot_root),        // 203 */Linux
1128   LINXY(__NR_fcntl64,           sys_fcntl64),           // 204
1129   GENX_(__NR_madvise,           sys_madvise),           // 205
1130   GENXY(__NR_mincore,           sys_mincore),           // 206
1131   LINX_(__NR_gettid,            sys_gettid),            // 207
1132//..    LINX_(__NR_tkill,             sys_tkill),             // 208 */Linux
1133   LINX_(__NR_setxattr,          sys_setxattr),          // 209
1134   LINX_(__NR_lsetxattr,         sys_lsetxattr),         // 210
1135   LINX_(__NR_fsetxattr,         sys_fsetxattr),         // 211
1136   LINXY(__NR_getxattr,          sys_getxattr),          // 212
1137   LINXY(__NR_lgetxattr,         sys_lgetxattr),         // 213
1138   LINXY(__NR_fgetxattr,         sys_fgetxattr),         // 214
1139   LINXY(__NR_listxattr,         sys_listxattr),         // 215
1140   LINXY(__NR_llistxattr,        sys_llistxattr),        // 216
1141   LINXY(__NR_flistxattr,        sys_flistxattr),        // 217
1142   LINX_(__NR_removexattr,       sys_removexattr),       // 218
1143   LINX_(__NR_lremovexattr,      sys_lremovexattr),      // 219
1144   LINX_(__NR_fremovexattr,      sys_fremovexattr),      // 220
1145
1146   LINXY(__NR_futex,             sys_futex),                  // 221
1147   LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 222
1148   LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 223
1149/* 224 currently unused */
1150
1151// __NR_tuxcall                                               // 225
1152
1153   LINXY(__NR_sendfile64,        sys_sendfile64),        // 226
1154//..
1155   LINX_(__NR_io_setup,          sys_io_setup),          // 227
1156   LINX_(__NR_io_destroy,        sys_io_destroy),        // 228
1157   LINXY(__NR_io_getevents,      sys_io_getevents),      // 229
1158   LINX_(__NR_io_submit,         sys_io_submit),         // 230
1159   LINXY(__NR_io_cancel,         sys_io_cancel),         // 231
1160//..
1161   LINX_(__NR_set_tid_address,   sys_set_tid_address),   // 232
1162
1163   LINX_(__NR_fadvise64,         sys_fadvise64),         // 233 */(Linux?)
1164   LINX_(__NR_exit_group,        sys_exit_group),        // 234
1165//..    GENXY(__NR_lookup_dcookie,    sys_lookup_dcookie),    // 235
1166   LINXY(__NR_epoll_create,      sys_epoll_create),      // 236
1167   LINX_(__NR_epoll_ctl,         sys_epoll_ctl),         // 237
1168   LINXY(__NR_epoll_wait,        sys_epoll_wait),        // 238
1169
1170//..    //   (__NR_remap_file_pages,  sys_remap_file_pages),  // 239 */Linux
1171   LINXY(__NR_timer_create,      sys_timer_create),      // 240
1172   LINXY(__NR_timer_settime,     sys_timer_settime),     // 241
1173   LINXY(__NR_timer_gettime,     sys_timer_gettime),     // 242
1174   LINX_(__NR_timer_getoverrun,  sys_timer_getoverrun),  // 243
1175   LINX_(__NR_timer_delete,      sys_timer_delete),      // 244
1176   LINX_(__NR_clock_settime,     sys_clock_settime),     // 245
1177   LINXY(__NR_clock_gettime,     sys_clock_gettime),     // 246
1178   LINXY(__NR_clock_getres,      sys_clock_getres),      // 247
1179   LINXY(__NR_clock_nanosleep,   sys_clock_nanosleep),   // 248
1180
1181// __NR_swapcontext                                           // 249
1182
1183   LINXY(__NR_tgkill,            sys_tgkill),            // 250 */Linux
1184//..    GENX_(__NR_utimes,            sys_utimes),            // 251
1185   GENXY(__NR_statfs64,          sys_statfs64),          // 252
1186   GENXY(__NR_fstatfs64,         sys_fstatfs64),         // 253
1187   LINX_(__NR_fadvise64_64,      sys_fadvise64_64),      // 254 */(Linux?)
1188
1189// __NR_rtas                                                  // 255
1190
1191/* Number 256 is reserved for sys_debug_setcontext */
1192/* Number 257 is reserved for vserver */
1193/* Number 258 is reserved for new sys_remap_file_pages */
1194   LINX_(__NR_mbind,             sys_mbind),             // 259
1195   LINXY(__NR_get_mempolicy,     sys_get_mempolicy),          // 260
1196   LINX_(__NR_set_mempolicy,     sys_set_mempolicy),          // 261
1197
1198   LINXY(__NR_mq_open,           sys_mq_open),           // 262
1199   LINX_(__NR_mq_unlink,         sys_mq_unlink),         // 263
1200   LINX_(__NR_mq_timedsend,      sys_mq_timedsend),      // 264
1201   LINXY(__NR_mq_timedreceive,   sys_mq_timedreceive),   // 265
1202   LINX_(__NR_mq_notify,         sys_mq_notify),         // 266
1203   LINXY(__NR_mq_getsetattr,     sys_mq_getsetattr),     // 267
1204// __NR_kexec_load                                            // 268
1205
1206/* Number 269 is reserved for sys_add_key */
1207/* Number 270 is reserved for sys_request_key */
1208/* Number 271 is reserved for sys_keyctl */
1209/* Number 272 is reserved for sys_waitid */
1210   LINX_(__NR_ioprio_set,        sys_ioprio_set),         // 273
1211   LINX_(__NR_ioprio_get,        sys_ioprio_get),         // 274
1212
1213   LINX_(__NR_inotify_init,  sys_inotify_init),               // 275
1214   LINX_(__NR_inotify_add_watch,  sys_inotify_add_watch),     // 276
1215   LINX_(__NR_inotify_rm_watch,   sys_inotify_rm_watch),      // 277
1216   PLAXY(__NR_spu_run,            sys_spu_run),               // 278
1217   PLAX_(__NR_spu_create,         sys_spu_create),            // 279
1218
1219   LINX_(__NR_pselect6,          sys_pselect6),          // 280
1220   LINXY(__NR_ppoll,             sys_ppoll),             // 281
1221
1222   LINXY(__NR_openat,            sys_openat),            // 286
1223   LINX_(__NR_mkdirat,           sys_mkdirat),           // 287
1224   LINX_(__NR_mknodat,           sys_mknodat),           // 288
1225   LINX_(__NR_fchownat,          sys_fchownat),          // 289
1226   LINX_(__NR_futimesat,         sys_futimesat),         // 290
1227   PLAXY(__NR_fstatat64,         sys_fstatat64),         // 291
1228   LINX_(__NR_unlinkat,          sys_unlinkat),          // 292
1229   LINX_(__NR_renameat,          sys_renameat),          // 293
1230   LINX_(__NR_linkat,            sys_linkat),            // 294
1231   LINX_(__NR_symlinkat,         sys_symlinkat),         // 295
1232   LINX_(__NR_readlinkat,        sys_readlinkat),        // 296
1233   LINX_(__NR_fchmodat,          sys_fchmodat),          // 297
1234   LINX_(__NR_faccessat,         sys_faccessat),         // 298
1235   LINX_(__NR_set_robust_list,   sys_set_robust_list),   // 299
1236   LINXY(__NR_get_robust_list,   sys_get_robust_list),   // 300
1237   LINXY(__NR_move_pages,        sys_move_pages),        // 301
1238   LINXY(__NR_getcpu,            sys_getcpu),            // 302
1239   LINXY(__NR_epoll_pwait,       sys_epoll_pwait),       // 303
1240   LINX_(__NR_utimensat,         sys_utimensat),         // 304
1241   LINXY(__NR_signalfd,          sys_signalfd),          // 305
1242   LINXY(__NR_timerfd_create,    sys_timerfd_create),    // 306
1243   LINXY(__NR_eventfd,           sys_eventfd),           // 307
1244   LINX_(__NR_sync_file_range2,  sys_sync_file_range2),  // 308
1245   LINX_(__NR_fallocate,         sys_fallocate),         // 309
1246//   LINXY(__NR_subpage_prot,       sys_ni_syscall),       // 310
1247   LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 311
1248   LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),  // 312
1249   LINXY(__NR_signalfd4,         sys_signalfd4),        // 313
1250   LINXY(__NR_eventfd2,          sys_eventfd2),         // 314
1251   LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 315
1252   LINXY(__NR_dup3,              sys_dup3),             // 316
1253   LINXY(__NR_pipe2,             sys_pipe2),            // 317
1254   LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 318
1255   LINXY(__NR_perf_event_open,   sys_perf_event_open),  // 319
1256   LINXY(__NR_preadv,            sys_preadv),           // 320
1257   LINX_(__NR_pwritev,           sys_pwritev),          // 321
1258   LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 322
1259
1260   LINX_(__NR_clock_adjtime,     sys_clock_adjtime),    // 347
1261
1262   LINXY(__NR_process_vm_readv,  sys_process_vm_readv), // 351
1263   LINX_(__NR_process_vm_writev, sys_process_vm_writev) // 352
1264};
1265
1266SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1267{
1268   const UInt syscall_table_size
1269      = sizeof(syscall_table) / sizeof(syscall_table[0]);
1270
1271   /* Is it in the contiguous initial section of the table? */
1272   if (sysno < syscall_table_size) {
1273      SyscallTableEntry* sys = &syscall_table[sysno];
1274      if (sys->before == NULL)
1275         return NULL; /* no entry */
1276      else
1277         return sys;
1278   }
1279
1280   /* Can't find a wrapper */
1281   return NULL;
1282}
1283
1284#endif // defined(VGP_ppc32_linux)
1285
1286/*--------------------------------------------------------------------*/
1287/*--- end                                                          ---*/
1288/*--------------------------------------------------------------------*/
1289