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