1
2/*--------------------------------------------------------------------*/
3/*--- Platform-specific syscalls stuff.    syswrap-mips32-linux.c ----*/
4/*--------------------------------------------------------------------*/
5
6/*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
9
10   Copyright (C) 2010-2013 RT-RK
11      mips-valgrind@rt-rk.com
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_mips32_linux)
32#include "pub_core_basics.h"
33#include "pub_core_vki.h"
34#include "pub_core_vkiscnums.h"
35#include "pub_core_libcsetjmp.h"    // to keep _threadstate.h happy
36#include "pub_core_threadstate.h"
37#include "pub_core_aspacemgr.h"
38#include "pub_core_debuglog.h"
39#include "pub_core_libcbase.h"
40#include "pub_core_libcassert.h"
41#include "pub_core_libcprint.h"
42#include "pub_core_libcproc.h"
43#include "pub_core_libcsignal.h"
44#include "pub_core_options.h"
45#include "pub_core_scheduler.h"
46#include "pub_core_sigframe.h"     // For VG_(sigframe_destroy)()
47#include "pub_core_signals.h"
48#include "pub_core_syscall.h"
49#include "pub_core_syswrap.h"
50#include "pub_core_tooliface.h"
51#include "pub_core_stacks.h"        // VG_(register_stack)
52#include "pub_core_transtab.h"      // VG_(discard_translations)
53#include "priv_types_n_macros.h"
54#include "priv_syswrap-generic.h"   /* for decls of generic wrappers */
55#include "priv_syswrap-linux.h"     /* for decls of linux-ish wrappers */
56#include "priv_syswrap-main.h"
57
58#include "pub_core_debuginfo.h"     // VG_(di_notify_*)
59#include "pub_core_xarray.h"
60#include "pub_core_clientstate.h"   // VG_(brk_base), VG_(brk_limit)
61#include "pub_core_errormgr.h"
62#include "pub_core_gdbserver.h"     // VG_(gdbserver)
63#include "pub_core_libcfile.h"
64#include "pub_core_machine.h"       // VG_(get_SP)
65#include "pub_core_mallocfree.h"
66#include "pub_core_stacktrace.h"    // For VG_(get_and_pp_StackTrace)()
67#include "pub_core_ume.h"
68
69#include "priv_syswrap-generic.h"
70
71#include "config.h"
72
73#include <errno.h>
74
75/* ---------------------------------------------------------------------
76                             clone() handling
77   ------------------------------------------------------------------ */
78/* Call f(arg1), but first switch stacks, using 'stack' as the new
79   stack, and use 'retaddr' as f's return-to address.  Also, clear all
80   the integer registers before entering f.*/
81
82__attribute__ ((noreturn))
83void ML_ (call_on_new_stack_0_1) (Addr stack, Addr retaddr,
84                                  void (*f) (Word), Word arg1);
85//    a0 = stack
86//    a1 = retaddr
87//    a2 = f
88//    a3 = arg1
89asm (
90".text\n"
91".globl vgModuleLocal_call_on_new_stack_0_1\n"
92"vgModuleLocal_call_on_new_stack_0_1:\n"
93"   move	$29, $4\n\t"	// stack to %sp
94"   move	$25, $6\n\t"	// f to t9/$25
95"   move 	$4, $7\n\t"	// arg1 to $a0
96"   li 		$2, 0\n\t"	// zero all GP regs
97"   li 		$3, 0\n\t"
98"   li 		$5, 0\n\t"
99"   li 		$6, 0\n\t"
100"   li 		$7, 0\n\t"
101
102"   li 		$12, 0\n\t"
103"   li 		$13, 0\n\t"
104"   li 		$14, 0\n\t"
105"   li 		$15, 0\n\t"
106"   li 		$16, 0\n\t"
107"   li 		$17, 0\n\t"
108"   li 		$18, 0\n\t"
109"   li 		$19, 0\n\t"
110"   li 		$20, 0\n\t"
111"   li 		$21, 0\n\t"
112"   li 		$22, 0\n\t"
113"   li 		$23, 0\n\t"
114"   li 		$24, 0\n\t"
115"   jr 		$25\n\t"	// jump to dst
116"   break	0x7\n"	// should never get here
117".previous\n"
118);
119
120/*
121        Perform a clone system call.  clone is strange because it has
122        fork()-like return-twice semantics, so it needs special
123        handling here.
124        Upon entry, we have:
125            int (fn)(void*)     in  $a0       0
126            void* child_stack   in  $a1       4
127            int flags           in  $a2       8
128            void* arg           in  $a3       12
129            pid_t* child_tid    in  stack     16
130            pid_t* parent_tid   in  stack     20
131            void* tls_ptr       in  stack     24
132
133        System call requires:
134            int    $__NR_clone  in $v0
135            int    flags        in $a0   0
136            void*  child_stack  in $a1   4
137            pid_t* parent_tid   in $a2   8
138            void*  tls_ptr      in $a3   12
139            pid_t* child_tid    in stack 16
140
141   int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
142             void *parent_tidptr, void *tls, void *child_tidptr)
143
144   Returns an Int encoded in the linux-mips way, not a SysRes.
145 */
146#define __NR_CLONE        VG_STRINGIFY(__NR_clone)
147#define __NR_EXIT         VG_STRINGIFY(__NR_exit)
148
149//extern
150UInt do_syscall_clone_mips_linux (Word (*fn) (void *), //a0      0     32
151                                   void *stack,         //a1      4     36
152                                   Int flags,           //a2      8     40
153                                   void *arg,           //a3      12    44
154                                   Int * child_tid,     //stack   16    48
155                                   Int * parent_tid,    //stack   20    52
156                                   Int tls);          //stack   24    56
157asm (
158".text\n"
159"   .globl   do_syscall_clone_mips_linux\n"
160"   do_syscall_clone_mips_linux:\n"
161"   subu    $29,$29,32\n\t"
162"   sw $31, 0($29)\n\t"
163"   sw $2, 4($29)\n\t"
164"   sw $3, 8($29)\n\t"
165"   sw $30, 12($29)\n\t"
166"   sw $28, 28($29)\n\t"
167    /* set up child stack with function and arg */
168    /* syscall arg 2 child_stack is already in a1 */
169"   subu $5, $5, 32\n\t" /* make space on stack */
170"   sw $4, 0($5)\n\t" /* fn  */
171"   sw $7, 4($5)\n\t" /* fn arg */
172"   sw $6, 8($5)\n\t"
173    /* get other args to clone */
174
175"   move $4, $a2\n\t" /* a0 = flags */
176"   lw $6,  52($29)\n\t" /* a2 = parent_tid */
177"   lw $7,  48($29)\n\t" /* a3 = child_tid */
178"   sw $7,  16($29)\n\t" /* 16(sp) = child_tid */
179"   lw $7,  56($29)\n\t" /* a3 = tls_ptr */
180    /* do the system call */
181
182"   li $2, " __NR_CLONE "\n\t" /* __NR_clone */
183"   syscall\n\t"
184"   nop\n\t"
185
186"   bnez    $7, .Lerror\n\t"
187"   nop\n\t"
188"   beqz    $2, .Lstart\n\t"
189"   nop\n\t"
190
191"   lw      $31, 0($sp)\n\t"
192"   nop\n\t"
193"   lw      $30, 12($sp)\n\t"
194"   nop\n\t"
195"   addu    $29,$29,32\n\t" /* free stack */
196"   nop\n\t"
197"   jr      $31\n\t"
198"   nop\n\t"
199
200".Lerror:\n\t"
201"   li      $31, 5\n\t"
202"   jr      $31\n\t"
203"   nop\n\t"
204
205".Lstart:\n\t"
206"   lw      $4,  4($29)\n\t"
207"   nop\n\t"
208"   lw      $25, 0($29)\n\t"
209"   nop\n\t"
210"   jalr    $25\n\t"
211"   nop\n\t"
212
213"   move $4, $2\n\t" /* retval from fn is in $v0 */
214"   li $2, " __NR_EXIT "\n\t" /* NR_exit */
215"   syscall\n\t"
216"   nop\n\t"
217"   .previous\n"
218);
219
220#undef __NR_CLONE
221#undef __NR_EXIT
222
223// forward declarations
224
225static void setup_child (ThreadArchState *, ThreadArchState *);
226static SysRes sys_set_tls (ThreadId tid, Addr tlsptr);
227static SysRes mips_PRE_sys_mmap (ThreadId tid,
228                                 UWord arg1, UWord arg2, UWord arg3,
229                                 UWord arg4, UWord arg5, Off64T arg6);
230/*
231   When a client clones, we need to keep track of the new thread.  This means:
232   1. allocate a ThreadId+ThreadState+stack for the the thread
233   2. initialize the thread's new VCPU state
234   3. create the thread using the same args as the client requested,
235   but using the scheduler entrypoint for IP, and a separate stack
236   for SP.
237 */
238
239static SysRes do_clone (ThreadId ptid,
240                        UInt flags, Addr sp,
241                        Int * parent_tidptr,
242                        Int * child_tidptr,
243                        Addr child_tls)
244{
245   const Bool debug = False;
246   ThreadId ctid = VG_ (alloc_ThreadState) ();
247   ThreadState * ptst = VG_ (get_ThreadState) (ptid);
248   ThreadState * ctst = VG_ (get_ThreadState) (ctid);
249   UInt ret = 0;
250   UWord * stack;
251   NSegment const *seg;
252   SysRes res;
253   vki_sigset_t blockall, savedmask;
254
255   VG_ (sigfillset) (&blockall);
256   vg_assert (VG_ (is_running_thread) (ptid));
257   vg_assert (VG_ (is_valid_tid) (ctid));
258   stack = (UWord *) ML_ (allocstack) (ctid);
259   if (stack == NULL) {
260      res = VG_ (mk_SysRes_Error) (VKI_ENOMEM);
261      goto out;
262   }
263   setup_child (&ctst->arch, &ptst->arch);
264
265   /* on MIPS we need to set V0 and A3 to zero */
266   ctst->arch.vex.guest_r2 = 0;
267   ctst->arch.vex.guest_r7 = 0;
268   if (sp != 0)
269      ctst->arch.vex.guest_r29 = sp;
270
271   ctst->os_state.parent = ptid;
272   ctst->sig_mask = ptst->sig_mask;
273   ctst->tmp_sig_mask = ptst->sig_mask;
274
275   /* Start the child with its threadgroup being the same as the
276      parent's.  This is so that any exit_group calls that happen
277      after the child is created but before it sets its
278      os_state.threadgroup field for real (in thread_wrapper in
279      syswrap-linux.c), really kill the new thread.  a.k.a this avoids
280      a race condition in which the thread is unkillable (via
281      exit_group) because its threadgroup is not set.  The race window
282      is probably only a few hundred or a few thousand cycles long.
283      See #226116. */
284
285   ctst->os_state.threadgroup = ptst->os_state.threadgroup;
286   seg = VG_ (am_find_nsegment) ((Addr) sp);
287
288   if (seg && seg->kind != SkResvn) {
289      ctst->client_stack_highest_word = (Addr) VG_PGROUNDUP (sp);
290      ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
291      VG_ (register_stack) (seg->start, ctst->client_stack_highest_word);
292      if (debug)
293         VG_ (printf) ("tid %d: guessed client stack range %#lx-%#lx\n",
294
295      ctid, seg->start, VG_PGROUNDUP (sp));
296   } else {
297      VG_ (message) (Vg_UserMsg,
298                     "!? New thread %d starts with sp+%#lx) unmapped\n",
299                     ctid, sp);
300      ctst->client_stack_szB = 0;
301   }
302
303   VG_TRACK (pre_thread_ll_create, ptid, ctid);
304   if (flags & VKI_CLONE_SETTLS) {
305      if (debug)
306        VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls);
307      ctst->arch.vex.guest_r27 = child_tls;
308      res = sys_set_tls(ctid, child_tls);
309      if (sr_isError(res))
310         goto out;
311      ctst->arch.vex.guest_r27 = child_tls;
312  }
313
314   flags &= ~VKI_CLONE_SETTLS;
315   VG_ (sigprocmask) (VKI_SIG_SETMASK, &blockall, &savedmask);
316   /* Create the new thread */
317   ret = do_syscall_clone_mips_linux (ML_ (start_thread_NORETURN),
318                                    stack, flags, &VG_ (threads)[ctid],
319                                    child_tidptr, parent_tidptr,
320                                    0 /*child_tls*/);
321
322   /* High half word64 is syscall return value.  Low half is
323      the entire CR, from which we need to extract CR0.SO. */
324   if (debug)
325      VG_(printf)("ret: 0x%x\n", ret);
326
327   res = VG_ (mk_SysRes_mips32_linux) (/*val */ ret, 0, /*errflag */ 0);
328
329   VG_ (sigprocmask) (VKI_SIG_SETMASK, &savedmask, NULL);
330
331   out:
332   if (sr_isError (res)) {
333      VG_(cleanup_thread) (&ctst->arch);
334      ctst->status = VgTs_Empty;
335      VG_TRACK (pre_thread_ll_exit, ctid);
336   }
337   ptst->arch.vex.guest_r2 = 0;
338
339   return res;
340}
341
342/* ---------------------------------------------------------------------
343   More thread stuff
344   ------------------------------------------------------------------ */
345
346// MIPS doesn't have any architecture specific thread stuff that
347// needs to be cleaned up da li ????!!!!???
348void
349VG_ (cleanup_thread) (ThreadArchState * arch) { }
350
351void
352setup_child ( /*OUT*/ ThreadArchState * child,
353              /*IN*/ ThreadArchState * parent)
354{
355   /* We inherit our parent's guest state. */
356   child->vex = parent->vex;
357   child->vex_shadow1 = parent->vex_shadow1;
358   child->vex_shadow2 = parent->vex_shadow2;
359}
360
361SysRes sys_set_tls ( ThreadId tid, Addr tlsptr )
362{
363   VG_(threads)[tid].arch.vex.guest_ULR = tlsptr;
364   return VG_(mk_SysRes_Success)( 0 );
365}
366
367/* ---------------------------------------------------------------------
368   mips handler for mmap and mmap2
369   ------------------------------------------------------------------ */
370static void notify_core_of_mmap(Addr a, SizeT len, UInt prot,
371                                UInt flags, Int fd, Off64T offset)
372{
373   Bool d;
374
375   /* 'a' is the return value from a real kernel mmap, hence: */
376   vg_assert(VG_IS_PAGE_ALIGNED(a));
377   /* whereas len is whatever the syscall supplied.  So: */
378   len = VG_PGROUNDUP(len);
379
380   d = VG_(am_notify_client_mmap)( a, len, prot, flags, fd, offset );
381
382   if (d)
383      VG_(discard_translations)( (Addr64)a, (ULong)len,
384                                 "notify_core_of_mmap" );
385}
386
387static void notify_tool_of_mmap(Addr a, SizeT len, UInt prot, ULong di_handle)
388{
389   Bool rr, ww, xx;
390
391   /* 'a' is the return value from a real kernel mmap, hence: */
392   vg_assert(VG_IS_PAGE_ALIGNED(a));
393   /* whereas len is whatever the syscall supplied.  So: */
394   len = VG_PGROUNDUP(len);
395
396   rr = toBool(prot & VKI_PROT_READ);
397   ww = toBool(prot & VKI_PROT_WRITE);
398   xx = toBool(prot & VKI_PROT_EXEC);
399
400   VG_TRACK( new_mem_mmap, a, len, rr, ww, xx, di_handle );
401}
402
403/* Based on ML_(generic_PRE_sys_mmap) from syswrap-generic.c.
404   If we are trying to do mmap with VKI_MAP_SHARED flag we need to align the
405   start address on VKI_SHMLBA like we did in
406   VG_(am_mmap_file_float_valgrind_flags)
407 */
408static SysRes mips_PRE_sys_mmap(ThreadId tid,
409                                UWord arg1, UWord arg2, UWord arg3,
410                                UWord arg4, UWord arg5, Off64T arg6)
411{
412   Addr       advised;
413   SysRes     sres;
414   MapRequest mreq;
415   Bool       mreq_ok;
416
417   if (arg2 == 0) {
418      /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
419         shall be established. */
420      return VG_(mk_SysRes_Error)( VKI_EINVAL );
421   }
422
423   if (!VG_IS_PAGE_ALIGNED(arg1)) {
424      /* zap any misaligned addresses. */
425      /* SuSV3 says misaligned addresses only cause the MAP_FIXED case
426         to fail.   Here, we catch them all. */
427      return VG_(mk_SysRes_Error)( VKI_EINVAL );
428   }
429
430   if (!VG_IS_PAGE_ALIGNED(arg6)) {
431      /* zap any misaligned offsets. */
432      /* SuSV3 says: The off argument is constrained to be aligned and
433         sized according to the value returned by sysconf() when
434         passed _SC_PAGESIZE or _SC_PAGE_SIZE. */
435      return VG_(mk_SysRes_Error)( VKI_EINVAL );
436   }
437
438   /* Figure out what kind of allocation constraints there are
439      (fixed/hint/any), and ask aspacem what we should do. */
440   mreq.start = arg1;
441   mreq.len   = arg2;
442   if (arg4 & VKI_MAP_FIXED) {
443      mreq.rkind = MFixed;
444   } else
445   if (arg1 != 0) {
446      mreq.rkind = MHint;
447   } else {
448      mreq.rkind = MAny;
449   }
450
451   if ((VKI_SHMLBA > VKI_PAGE_SIZE) && (VKI_MAP_SHARED & arg4)
452       && !(VKI_MAP_FIXED & arg4))
453      mreq.len = arg2 + VKI_SHMLBA - VKI_PAGE_SIZE;
454
455   /* Enquire ... */
456   advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok );
457
458   if ((VKI_SHMLBA > VKI_PAGE_SIZE) && (VKI_MAP_SHARED & arg4)
459       && !(VKI_MAP_FIXED & arg4))
460      advised = VG_ROUNDUP(advised, VKI_SHMLBA);
461
462   if (!mreq_ok) {
463      /* Our request was bounced, so we'd better fail. */
464      return VG_(mk_SysRes_Error)( VKI_EINVAL );
465   }
466
467   /* Otherwise we're OK (so far).  Install aspacem's choice of
468      address, and let the mmap go through.  */
469   sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
470                                    arg4 | VKI_MAP_FIXED,
471                                    arg5, arg6);
472
473   /* A refinement: it may be that the kernel refused aspacem's choice
474      of address.  If we were originally asked for a hinted mapping,
475      there is still a last chance: try again at any address.
476      Hence: */
477   if (mreq.rkind == MHint && sr_isError(sres)) {
478      mreq.start = 0;
479      mreq.len   = arg2;
480      mreq.rkind = MAny;
481      advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok );
482      if (!mreq_ok) {
483         /* Our request was bounced, so we'd better fail. */
484         return VG_(mk_SysRes_Error)( VKI_EINVAL );
485      }
486      /* and try again with the kernel */
487      sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
488                                       arg4 | VKI_MAP_FIXED,
489                                       arg5, arg6);
490   }
491
492   if (!sr_isError(sres)) {
493      ULong di_handle;
494      /* Notify aspacem. */
495      notify_core_of_mmap(
496         (Addr)sr_Res(sres), /* addr kernel actually assigned */
497         arg2, /* length */
498         arg3, /* prot */
499         arg4, /* the original flags value */
500         arg5, /* fd */
501         arg6  /* offset */
502      );
503      /* Load symbols? */
504      di_handle = VG_(di_notify_mmap)( (Addr)sr_Res(sres),
505                                       False/*allow_SkFileV*/, (Int)arg5 );
506      /* Notify the tool. */
507      notify_tool_of_mmap(
508         (Addr)sr_Res(sres), /* addr kernel actually assigned */
509         arg2, /* length */
510         arg3, /* prot */
511         di_handle /* so the tool can refer to the read debuginfo later,
512                      if it wants. */
513      );
514   }
515
516   /* Stay sane */
517   if (!sr_isError(sres) && (arg4 & VKI_MAP_FIXED))
518      vg_assert(sr_Res(sres) == arg1);
519
520   return sres;
521}
522/* ---------------------------------------------------------------------
523   PRE/POST wrappers for mips/Linux-specific syscalls
524   ------------------------------------------------------------------ */
525#define PRE(name)       DEFN_PRE_TEMPLATE(mips_linux, name)
526#define POST(name)      DEFN_POST_TEMPLATE(mips_linux, name)
527
528/* Add prototypes for the wrappers declared here, so that gcc doesn't
529   harass us for not having prototypes.  Really this is a kludge --
530   the right thing to do is to make these wrappers 'static' since they
531   aren't visible outside this file, but that requires even more macro
532   magic. */
533//DECL_TEMPLATE (mips_linux, sys_syscall);
534DECL_TEMPLATE (mips_linux, sys_mmap);
535DECL_TEMPLATE (mips_linux, sys_mmap2);
536DECL_TEMPLATE (mips_linux, sys_stat64);
537DECL_TEMPLATE (mips_linux, sys_lstat64);
538DECL_TEMPLATE (mips_linux, sys_fstatat64);
539DECL_TEMPLATE (mips_linux, sys_fstat64);
540DECL_TEMPLATE (mips_linux, sys_clone);
541DECL_TEMPLATE (mips_linux, sys_sigreturn);
542DECL_TEMPLATE (mips_linux, sys_rt_sigreturn);
543DECL_TEMPLATE (mips_linux, sys_cacheflush);
544DECL_TEMPLATE (mips_linux, sys_set_thread_area);
545DECL_TEMPLATE (mips_linux, sys_pipe);
546
547PRE(sys_mmap2)
548{
549  /* Exactly like sys_mmap() except the file offset is specified in pagesize
550     units rather than bytes, so that it can be used for files bigger than
551     2^32 bytes. */
552  SysRes r;
553  PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )", ARG1, (ULong) ARG2,
554                                                        ARG3, ARG4, ARG5, ARG6);
555  PRE_REG_READ6(long, "mmap2", unsigned long, start, unsigned long, length,
556                unsigned long, prot, unsigned long, flags,
557                unsigned long, fd, unsigned long, offset);
558  r = mips_PRE_sys_mmap(tid, ARG1, ARG2, ARG3, ARG4, ARG5,
559                        VKI_PAGE_SIZE * (Off64T) ARG6);
560  SET_STATUS_from_SysRes(r);
561}
562
563PRE(sys_mmap)
564{
565  SysRes r;
566  PRINT("sys_mmap ( %#lx, %llu, %lu, %lu, %lu, %ld )", ARG1, (ULong) ARG2,
567                                                       ARG3, ARG4, ARG5, ARG6);
568  PRE_REG_READ6(long, "mmap", unsigned long, start, vki_size_t, length,
569                int, prot, int, flags, int, fd, unsigned long, offset);
570  r = mips_PRE_sys_mmap(tid, ARG1, ARG2, ARG3, ARG4, ARG5, (Off64T) ARG6);
571  SET_STATUS_from_SysRes(r);
572}
573
574// XXX: lstat64/fstat64/stat64 are generic, but not necessarily
575// applicable to every architecture -- I think only to 32-bit archs.
576// We're going to need something like linux/core_os32.h for such
577// things, eventually, I think.  --njn
578
579PRE (sys_lstat64)
580{
581  PRINT ("sys_lstat64 ( %#lx(%s), %#lx )", ARG1, (char *) ARG1, ARG2);
582  PRE_REG_READ2 (long, "lstat64", char *, file_name, struct stat64 *, buf);
583  PRE_MEM_RASCIIZ ("lstat64(file_name)", ARG1);
584  PRE_MEM_WRITE ("lstat64(buf)", ARG2, sizeof (struct vki_stat64));
585}
586
587POST (sys_lstat64)
588{
589  vg_assert (SUCCESS);
590  if (RES == 0)
591    {
592      POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64));
593    }
594}
595
596PRE (sys_stat64)
597{
598  PRINT ("sys_stat64 ( %#lx(%s), %#lx )", ARG1, (char *) ARG1, ARG2);
599  PRE_REG_READ2 (long, "stat64", char *, file_name, struct stat64 *, buf);
600  PRE_MEM_RASCIIZ ("stat64(file_name)", ARG1);
601  PRE_MEM_WRITE ("stat64(buf)", ARG2, sizeof (struct vki_stat64));
602}
603
604POST (sys_stat64)
605{
606  POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64));
607}
608
609PRE (sys_fstatat64)
610{
611  PRINT ("sys_fstatat64 ( %ld, %#lx(%s), %#lx )", ARG1, ARG2, (char *) ARG2,
612                                                  ARG3);
613  PRE_REG_READ3 (long, "fstatat64", int, dfd, char *, file_name,
614                 struct stat64 *, buf);
615  PRE_MEM_RASCIIZ ("fstatat64(file_name)", ARG2);
616  PRE_MEM_WRITE ("fstatat64(buf)", ARG3, sizeof (struct vki_stat64));
617}
618
619POST (sys_fstatat64)
620{
621  POST_MEM_WRITE (ARG3, sizeof (struct vki_stat64));
622}
623
624PRE (sys_fstat64)
625{
626  PRINT ("sys_fstat64 ( %ld, %#lx )", ARG1, ARG2);
627  PRE_REG_READ2 (long, "fstat64", unsigned long, fd, struct stat64 *, buf);
628  PRE_MEM_WRITE ("fstat64(buf)", ARG2, sizeof (struct vki_stat64));
629}
630
631POST (sys_fstat64)
632{
633  POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64));
634}
635
636PRE (sys_clone)
637  {
638    Bool badarg = False;
639    UInt cloneflags;
640    PRINT ("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )", ARG1, ARG2, ARG3,
641                                                        ARG4, ARG5);
642    PRE_REG_READ2 (int, "clone", unsigned long, flags,  void *, child_stack);
643    if (ARG1 & VKI_CLONE_PARENT_SETTID)
644      {
645        if (VG_ (tdict).track_pre_reg_read)
646          {
647            PRA3 ("clone", int *, parent_tidptr);
648          }
649        PRE_MEM_WRITE ("clone(parent_tidptr)", ARG3, sizeof (Int));
650        if (!VG_ (am_is_valid_for_client)(ARG3, sizeof (Int), VKI_PROT_WRITE))
651        {
652          badarg = True;
653        }
654      }
655    if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
656      {
657        if (VG_ (tdict).track_pre_reg_read)
658          {
659            PRA5 ("clone", int *, child_tidptr);
660          }
661        PRE_MEM_WRITE ("clone(child_tidptr)", ARG5, sizeof (Int));
662        if (!VG_ (am_is_valid_for_client)(ARG5, sizeof (Int), VKI_PROT_WRITE))
663          {
664            badarg = True;
665          }
666      }
667    if (badarg)
668      {
669        SET_STATUS_Failure (VKI_EFAULT);
670        return;
671      }
672    cloneflags = ARG1;
673    if (!ML_ (client_signal_OK) (ARG1 & VKI_CSIGNAL))
674      {
675        SET_STATUS_Failure (VKI_EINVAL);
676        return;
677      }
678    /* Only look at the flags we really care about */
679    switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
680           |VKI_CLONE_FILES | VKI_CLONE_VFORK))
681      {
682        case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
683        /* thread creation */
684        PRINT ("sys_clone1 ( %#lx, %#lx, %#lx, %#lx, %#lx )",
685               ARG1, ARG2, ARG3, ARG4, ARG5);
686        SET_STATUS_from_SysRes (do_clone (tid,
687                                          ARG1, /* flags */
688                                          (Addr) ARG2, /* child SP */
689                                          (Int *) ARG3, /* parent_tidptr */
690                                          (Int *) ARG5, /* child_tidptr */
691                                          (Addr) ARG4));	/* child_tls */
692
693        break;
694        case VKI_CLONE_VFORK | VKI_CLONE_VM:	/* vfork */
695          /* FALLTHROUGH - assume vfork == fork */
696          cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
697        case 0:  /* plain fork */
698          SET_STATUS_from_SysRes (ML_ (do_fork_clone) (tid,
699                                  cloneflags, /* flags */
700                                  (Int *) ARG3, /* parent_tidptr */
701                                  (Int *) ARG5));	/* child_tidptr */
702        break;
703        default:
704          /* should we just ENOSYS? */
705          VG_ (message) (Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
706          VG_ (message) (Vg_UserMsg, "\n");
707          VG_ (message) (Vg_UserMsg, "The only supported clone() uses are:\n");
708          VG_ (message) (Vg_UserMsg,
709                          " - via a threads library (LinuxThreads or NPTL)\n");
710          VG_ (message) (Vg_UserMsg,
711                          " - via the implementation of fork or vfork\n");
712          VG_ (unimplemented)("Valgrind does not support general clone().");
713    }
714    if (SUCCESS)
715      {
716        if (ARG1 & VKI_CLONE_PARENT_SETTID)
717          POST_MEM_WRITE (ARG3, sizeof (Int));
718        if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
719          POST_MEM_WRITE (ARG5, sizeof (Int));
720        /* Thread creation was successful; let the child have the chance
721         * to run */
722        *flags |= SfYieldAfter;
723      }
724}
725
726PRE (sys_sigreturn)
727{
728  PRINT ("sys_sigreturn ( )");
729  vg_assert (VG_ (is_valid_tid) (tid));
730  vg_assert (tid >= 1 && tid < VG_N_THREADS);
731  vg_assert (VG_ (is_running_thread) (tid));
732  VG_ (sigframe_destroy) (tid, False);
733  /* Tell the driver not to update the guest state with the "result",
734     and set a bogus result to keep it happy. */
735  *flags |= SfNoWriteResult;
736  SET_STATUS_Success (0);
737   /* Check to see if any signals arose as a result of this. */
738  *flags |= SfPollAfter;
739}
740
741PRE (sys_rt_sigreturn)
742{
743  PRINT ("rt_sigreturn ( )");
744  vg_assert (VG_ (is_valid_tid) (tid));
745  vg_assert (tid >= 1 && tid < VG_N_THREADS);
746  vg_assert (VG_ (is_running_thread) (tid));
747  /* Restore register state from frame and remove it */
748  VG_ (sigframe_destroy) (tid, True);
749  /* Tell the driver not to update the guest state with the "result",
750     and set a bogus result to keep it happy. */
751  *flags |= SfNoWriteResult;
752  SET_STATUS_Success (0);
753  /* Check to see if any signals arose as a result of this. */
754  *flags |= SfPollAfter;
755}
756
757PRE (sys_set_thread_area)
758{
759   PRINT ("set_thread_area (%lx)", ARG1);
760   PRE_REG_READ1(long, "set_thread_area", unsigned long, addr);
761   SET_STATUS_from_SysRes( sys_set_tls( tid, ARG1 ) );
762}
763
764/* Very much MIPS specific */
765PRE (sys_cacheflush)
766{
767  PRINT ("cacheflush (%lx, %lx, %lx)", ARG1, ARG2, ARG3);
768  PRE_REG_READ3(long, "cacheflush", unsigned long, addr,
769                int, nbytes, int, cache);
770  VG_ (discard_translations) ((Addr64) ARG1, ((ULong) ARG2),
771                              "PRE(sys_cacheflush)");
772  SET_STATUS_Success (0);
773}
774
775PRE(sys_pipe)
776{
777   PRINT("sys_pipe ( %#lx )", ARG1);
778   PRE_REG_READ1(int, "pipe", int *, filedes);
779   PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
780}
781
782POST(sys_pipe)
783{
784   Int p0, p1;
785   vg_assert(SUCCESS);
786   p0 = RES;
787   p1 = sr_ResEx(status->sres);
788
789   if (!ML_(fd_allowed)(p0, "pipe", tid, True) ||
790       !ML_(fd_allowed)(p1, "pipe", tid, True)) {
791      VG_(close)(p0);
792      VG_(close)(p1);
793      SET_STATUS_Failure( VKI_EMFILE );
794   } else {
795      if (VG_(clo_track_fds)) {
796         ML_(record_fd_open_nameless)(tid, p0);
797         ML_(record_fd_open_nameless)(tid, p1);
798      }
799   }
800}
801
802#undef PRE
803#undef POST
804
805/* ---------------------------------------------------------------------
806   The mips/Linux syscall table
807   ------------------------------------------------------------------ */
808#define PLAX_(sysno, name)    WRAPPER_ENTRY_X_(mips_linux, sysno, name)
809#define PLAXY(sysno, name)    WRAPPER_ENTRY_XY(mips_linux, sysno, name)
810
811// This table maps from __NR_xxx syscall numbers (from
812// linux/include/asm-mips/unistd.h) to the appropriate PRE/POST sys_foo()
813// wrappers on mips (as per sys_call_table in linux/arch/mips/kernel/entry.S).
814//
815
816// For those syscalls not handled by Valgrind, the annotation indicate its
817// arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
818// (unknown).
819
820static SyscallTableEntry syscall_main_table[] = {
821   //..    PLAXY (__NR_syscall,                sys_syscall),            // 0
822   GENX_ (__NR_exit,                   sys_exit),                    // 1
823   GENX_ (__NR_fork,                   sys_fork),                    // 2
824   GENXY (__NR_read,                   sys_read),                    // 3
825   GENX_ (__NR_write,                  sys_write),                   // 4
826   GENXY (__NR_open,                   sys_open),                    // 5
827   GENXY (__NR_close,                  sys_close),                   // 6
828   GENXY (__NR_waitpid,                sys_waitpid),                 // 7
829   GENXY (__NR_creat,                  sys_creat),                   // 8
830   GENX_ (__NR_link,                   sys_link),                    // 9
831   GENX_ (__NR_unlink,                 sys_unlink),                  // 10
832   GENX_ (__NR_execve,                 sys_execve),                  // 11
833   GENX_ (__NR_chdir,                  sys_chdir),                   // 12
834   GENXY (__NR_time,                   sys_time),                    // 13
835   GENX_ (__NR_mknod,                  sys_mknod),                   // 14
836   GENX_ (__NR_chmod,                  sys_chmod),                   // 15
837   GENX_ (__NR_lchown,                 sys_lchown),                  // 16
838   //..
839   LINX_ (__NR_lseek,                  sys_lseek),                   // 19
840   GENX_ (__NR_getpid,                 sys_getpid),                  // 20
841   LINX_ (__NR_mount,                  sys_mount),                   // 21
842   LINX_ (__NR_umount,                 sys_oldumount),               // 22
843   GENX_ (__NR_setuid,                 sys_setuid),                  // 23
844   GENX_ (__NR_getuid,                 sys_getuid),                  // 24
845   LINX_ (__NR_stime,                  sys_stime),                   // 25
846   //..    PLAXY(__NR_ptrace,            sys_ptrace),            // 26
847   GENX_ (__NR_alarm,                  sys_alarm),                   // 27
848   //..    //   (__NR_oldfstat,          sys_fstat),  // 28
849   GENX_ (__NR_pause,                  sys_pause),                   // 29
850   LINX_ (__NR_utime,                  sys_utime),                   // 30
851   //..    GENX_(__NR_stty,              sys_ni_syscall),        // 31
852   //..    GENX_(__NR_gtty,              sys_ni_syscall),        // 32
853   GENX_ (__NR_access,                 sys_access),                  // 33
854   //..    GENX_(__NR_nice,              sys_nice),              // 34
855   //..    GENX_(__NR_ftime,             sys_ni_syscall),        // 35
856   //..    GENX_(__NR_sync,              sys_sync),              // 36
857   GENX_ (__NR_kill,                   sys_kill),                    // 37
858   GENX_ (__NR_rename,                 sys_rename),                  // 38
859   GENX_ (__NR_mkdir,                  sys_mkdir),                   // 39
860   GENX_ (__NR_rmdir,                  sys_rmdir),                   // 40
861   GENXY (__NR_dup,                    sys_dup),                     // 41
862   PLAXY (__NR_pipe,                   sys_pipe),                    // 42
863   GENXY (__NR_times,                  sys_times),                   // 43
864   //..    GENX_(__NR_prof,              sys_ni_syscall),   // 44
865   GENX_ (__NR_brk,                    sys_brk),                     // 45
866   GENX_ (__NR_setgid,                 sys_setgid),                  // 46
867   GENX_ (__NR_getgid,                 sys_getgid),                  // 47
868   //..    //   (__NR_signal,            sys_signal),       // 48
869   GENX_ (__NR_geteuid,                sys_geteuid),                 // 49
870   GENX_ (__NR_getegid,                sys_getegid),                 // 50
871   //..    GENX_(__NR_acct,              sys_acct),         // 51
872   LINX_ (__NR_umount2,                sys_umount),                  // 52
873   //..    GENX_(__NR_lock,              sys_ni_syscall),   // 53
874   LINXY (__NR_ioctl,                  sys_ioctl),                   // 54
875   LINXY (__NR_fcntl,                  sys_fcntl),                   // 55
876   //..    GENX_(__NR_mpx,               sys_ni_syscall),   // 56
877   GENX_ (__NR_setpgid,                sys_setpgid),                 // 57
878   //..    GENX_(__NR_ulimit,            sys_ni_syscall),        // 58
879   //..    //   (__NR_oldolduname,       sys_olduname),          // 59
880   GENX_ (__NR_umask,                  sys_umask),                   // 60
881   GENX_ (__NR_chroot,                 sys_chroot),                  // 61
882   //..    //   (__NR_ustat,             sys_ustat)              // 62
883   GENXY (__NR_dup2,                   sys_dup2),                    // 63
884   GENX_ (__NR_getppid,                sys_getppid),                 // 64
885   GENX_ (__NR_getpgrp,                sys_getpgrp),                 // 65
886   GENX_ (__NR_setsid,                 sys_setsid),                  // 66
887   LINXY (__NR_sigaction,              sys_sigaction),               // 67
888   //..    //   (__NR_sgetmask,          sys_sgetmask),          // 68
889   //..    //   (__NR_ssetmask,          sys_ssetmask),          // 69
890   GENX_ (__NR_setreuid,               sys_setreuid),                // 70
891   GENX_ (__NR_setregid,               sys_setregid),                // 71
892   //   PLAX_(__NR_sigsuspend,        sys_sigsuspend),        // 72
893   LINXY (__NR_sigpending,             sys_sigpending),              // 73
894   //..    //   (__NR_sethostname,       sys_sethostname),       // 74
895   GENX_ (__NR_setrlimit,              sys_setrlimit),               // 75
896   GENXY (__NR_getrlimit,              sys_getrlimit),               // 76
897   GENXY (__NR_getrusage,              sys_getrusage),               // 77
898   GENXY (__NR_gettimeofday,           sys_gettimeofday),            // 78
899   GENX_ (__NR_settimeofday,           sys_settimeofday),            // 79
900   GENXY (__NR_getgroups,              sys_getgroups),               // 80
901   GENX_ (__NR_setgroups,              sys_setgroups),               // 81
902   //..    PLAX_(__NR_select,            old_select),            // 82
903   GENX_ (__NR_symlink,                sys_symlink),                 // 83
904   //..    //   (__NR_oldlstat,          sys_lstat),             // 84
905   GENX_ (__NR_readlink,               sys_readlink),                // 85
906   //..    //   (__NR_uselib,            sys_uselib),            // 86
907   //..    //   (__NR_swapon,            sys_swapon),            // 87
908   //..    //   (__NR_reboot,            sys_reboot),            // 88
909   //..    //   (__NR_readdir,           old_readdir),           // 89
910   PLAX_ (__NR_mmap,                   sys_mmap),                    // 90
911   GENXY (__NR_munmap,                 sys_munmap),                  // 91
912   GENX_ (__NR_truncate,               sys_truncate),                // 92
913   GENX_ (__NR_ftruncate,              sys_ftruncate),               // 93
914   GENX_ (__NR_fchmod,                 sys_fchmod),                  // 94
915   GENX_ (__NR_fchown,                 sys_fchown),                  // 95
916   GENX_ (__NR_getpriority,            sys_getpriority),             // 96
917   GENX_ (__NR_setpriority,            sys_setpriority),             // 97
918   //..    GENX_(__NR_profil,            sys_ni_syscall),        // 98
919   GENXY (__NR_statfs,                 sys_statfs),                  // 99
920   GENXY (__NR_fstatfs,                sys_fstatfs),                 // 100
921   //..    LINX_(__NR_ioperm,            sys_ioperm),            // 101
922   LINXY (__NR_socketcall,             sys_socketcall),              // 102
923   LINXY (__NR_syslog,                 sys_syslog),                  // 103
924   GENXY (__NR_setitimer,              sys_setitimer),               // 104
925   //..    GENXY(__NR_getitimer,         sys_getitimer),         // 105
926   GENXY (__NR_stat,                   sys_newstat),                 // 106
927   GENXY (__NR_lstat,                  sys_newlstat),                // 107
928   GENXY (__NR_fstat,                  sys_newfstat),                // 108
929   //..    //   (__NR_olduname,          sys_uname),             // 109
930   //..    GENX_(__NR_iopl,              sys_iopl),              // 110
931   //..    LINX_(__NR_vhangup,           sys_vhangup),           // 111
932   //..    GENX_(__NR_idle,              sys_ni_syscall),        // 112
933   //..    //   (__NR_vm86old,           sys_vm86old),           // 113
934   GENXY (__NR_wait4,                  sys_wait4),                   // 114
935   //..    //   (__NR_swapoff,           sys_swapoff),           // 115
936   LINXY (__NR_sysinfo,                sys_sysinfo),                 // 116
937   LINXY (__NR_ipc,                    sys_ipc),                     // 117
938   GENX_ (__NR_fsync,                  sys_fsync),                   // 118
939   PLAX_ (__NR_sigreturn,              sys_sigreturn),               // 119
940   PLAX_ (__NR_clone,                  sys_clone),                   // 120
941   //..    //   (__NR_setdomainname,     sys_setdomainname),     // 121
942   GENXY (__NR_uname,                  sys_newuname),                // 122
943   //..    PLAX_(__NR_modify_ldt,        sys_modify_ldt),        // 123
944   //..    LINXY(__NR_adjtimex,          sys_adjtimex),          // 124
945   GENXY (__NR_mprotect,               sys_mprotect),                // 125
946   LINXY (__NR_sigprocmask,            sys_sigprocmask),             // 126
947   //..    GENX_(__NR_create_module,     sys_ni_syscall),        // 127
948   //..    GENX_(__NR_init_module,       sys_init_module),       // 128
949   //..    //   (__NR_delete_module,     sys_delete_module),     // 129
950   //..    GENX_(__NR_get_kernel_syms,   sys_ni_syscall),        // 130
951   //..    LINX_(__NR_quotactl,          sys_quotactl),          // 131
952   GENX_ (__NR_getpgid,                sys_getpgid),                 // 132
953   GENX_ (__NR_fchdir,                 sys_fchdir),                  // 133
954   //..    //   (__NR_bdflush,           sys_bdflush),           // 134
955   //..    //   (__NR_sysfs,             sys_sysfs),             // 135
956   LINX_ (__NR_personality,            sys_personality),            // 136
957   //..    GENX_(__NR_afs_syscall,       sys_ni_syscall),        // 137
958   LINX_ (__NR_setfsuid,               sys_setfsuid),                // 138
959   LINX_ (__NR_setfsgid,               sys_setfsgid),                // 139
960   LINXY (__NR__llseek,                sys_llseek),                  // 140
961   GENXY (__NR_getdents,               sys_getdents),                // 141
962   GENX_ (__NR__newselect,             sys_select),                  // 142
963   GENX_ (__NR_flock,                  sys_flock),                   // 143
964   GENX_ (__NR_msync,                  sys_msync),                   // 144
965   GENXY (__NR_readv,                  sys_readv),                   // 145
966   GENX_ (__NR_writev,                 sys_writev),                  // 146
967   PLAX_ (__NR_cacheflush,             sys_cacheflush),              // 147
968   GENX_ (__NR_getsid,                 sys_getsid),                  // 151
969   GENX_ (__NR_fdatasync,              sys_fdatasync),               // 152
970   LINXY (__NR__sysctl,                sys_sysctl),                  // 153
971   GENX_ (__NR_mlock,                  sys_mlock),                   // 154
972   GENX_ (__NR_munlock,                sys_munlock),                 // 155
973   GENX_ (__NR_mlockall,               sys_mlockall),                // 156
974   LINX_ (__NR_munlockall,             sys_munlockall),              // 157
975   //..    LINXY(__NR_sched_setparam,    sys_sched_setparam),    // 158
976   LINXY (__NR_sched_getparam,         sys_sched_getparam),          // 159
977   LINX_ (__NR_sched_setscheduler,     sys_sched_setscheduler),      // 160
978   LINX_ (__NR_sched_getscheduler,     sys_sched_getscheduler),      // 161
979   LINX_ (__NR_sched_yield,            sys_sched_yield),             // 162
980   LINX_ (__NR_sched_get_priority_max, sys_sched_get_priority_max),  // 163
981   LINX_ (__NR_sched_get_priority_min, sys_sched_get_priority_min),  // 164
982   //.. //LINX?(__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 165
983   GENXY (__NR_nanosleep,              sys_nanosleep),               // 166
984   GENX_ (__NR_mremap,                 sys_mremap),                  // 167
985   LINXY (__NR_accept,                 sys_accept),                  // 168
986   LINX_ (__NR_bind,                   sys_bind),                    // 169
987   LINX_ (__NR_connect,                sys_connect),                 // 170
988   LINXY (__NR_getpeername,            sys_getpeername),             // 171
989   LINXY (__NR_getsockname,            sys_getsockname),             // 172
990   LINXY (__NR_getsockopt,             sys_getsockopt),              // 173
991   LINX_ (__NR_listen,                 sys_listen),                  // 174
992   LINXY (__NR_recv,                   sys_recv),                    // 175
993   LINXY (__NR_recvfrom,               sys_recvfrom),                // 176
994   LINXY (__NR_recvmsg,                sys_recvmsg),                 // 177
995   LINX_ (__NR_send,                   sys_send),                    // 178
996   LINX_ (__NR_sendmsg,                sys_sendmsg),                 // 179
997   LINX_ (__NR_sendto,                 sys_sendto),                  // 180
998   LINX_ (__NR_setsockopt,             sys_setsockopt),              // 181
999   LINX_ (__NR_shutdown,               sys_shutdown),                // 182
1000   LINXY (__NR_socket,                 sys_socket),                  // 183
1001   LINXY (__NR_socketpair,             sys_socketpair),              // 184
1002   LINX_ (__NR_setresuid,              sys_setresuid),               // 185
1003   LINXY (__NR_getresuid,              sys_getresuid),               // 186
1004   //..    GENX_(__NR_query_module,      sys_ni_syscall),        // 187
1005   GENXY (__NR_poll,                   sys_poll),                    // 188
1006   //..
1007   LINX_ (__NR_setresgid,              sys_setresgid),               // 190
1008   LINXY (__NR_getresgid,              sys_getresgid),               // 191
1009   LINXY (__NR_prctl,                  sys_prctl),                   // 192
1010   PLAX_ (__NR_rt_sigreturn,           sys_rt_sigreturn),            // 193
1011   LINXY (__NR_rt_sigaction,           sys_rt_sigaction),            // 194
1012   LINXY (__NR_rt_sigprocmask,         sys_rt_sigprocmask),          // 195
1013   LINXY (__NR_rt_sigpending,          sys_rt_sigpending),           // 196
1014   LINXY (__NR_rt_sigtimedwait,        sys_rt_sigtimedwait),         // 197
1015   LINXY (__NR_rt_sigqueueinfo,        sys_rt_sigqueueinfo),         // 198
1016   LINX_ (__NR_rt_sigsuspend,          sys_rt_sigsuspend),           // 199
1017   GENXY (__NR_pread64,                sys_pread64),                 // 200
1018   GENX_ (__NR_pwrite64,               sys_pwrite64),                // 201
1019   GENX_ (__NR_chown,                  sys_chown),                   // 202
1020   GENXY (__NR_getcwd,                 sys_getcwd),                  // 203
1021   LINXY (__NR_capget,                 sys_capget),                  // 204
1022   //..    LINX_(__NR_capset,            sys_capset),            // 205
1023   GENXY (__NR_sigaltstack,            sys_sigaltstack),             // 206
1024   LINXY (__NR_sendfile,               sys_sendfile),                // 207
1025   //..    GENXY(__NR_getpmsg,           sys_getpmsg),           // 208
1026   //..    GENX_(__NR_putpmsg,           sys_putpmsg),           // 209
1027   PLAX_ (__NR_mmap2,                  sys_mmap2),                   // 210
1028   //   GENX_(__NR_truncate64,        sys_truncate64),        // 211
1029   GENX_ (__NR_ftruncate64,            sys_ftruncate64),             // 212
1030   PLAXY (__NR_stat64,                 sys_stat64),                  // 213
1031   PLAXY (__NR_lstat64,                sys_lstat64),                 // 214
1032   PLAXY (__NR_fstat64,                sys_fstat64),                 // 215
1033   //..
1034   GENXY (__NR_mincore,                sys_mincore),                 // 217
1035   GENX_ (__NR_madvise,                sys_madvise),                 // 218
1036   GENXY (__NR_getdents64,             sys_getdents64),              // 219
1037   LINXY (__NR_fcntl64,                sys_fcntl64),                 // 220
1038   //..
1039   LINX_ (__NR_gettid,                 sys_gettid),                  // 222
1040   //..
1041   LINXY (__NR_getxattr,               sys_getxattr),                // 227
1042   LINXY (__NR_lgetxattr,              sys_lgetxattr),               // 228
1043   LINXY (__NR_fgetxattr,              sys_fgetxattr),               // 229
1044   LINXY (__NR_listxattr,              sys_listxattr),               // 230
1045   LINXY (__NR_llistxattr,             sys_llistxattr),              // 231
1046   LINXY (__NR_flistxattr,             sys_flistxattr),              // 232
1047   LINX_ (__NR_removexattr,            sys_removexattr),             // 233
1048   LINX_ (__NR_lremovexattr,           sys_lremovexattr),            // 234
1049   LINX_ (__NR_fremovexattr,           sys_fremovexattr),            // 235
1050   //..
1051   LINXY (__NR_sendfile64,             sys_sendfile64),              // 237
1052   LINXY (__NR_futex,                  sys_futex),                   // 238
1053   LINX_ (__NR_sched_setaffinity,      sys_sched_setaffinity),       // 239
1054   LINXY (__NR_sched_getaffinity,      sys_sched_getaffinity),       // 240
1055   LINX_ (__NR_io_setup,               sys_io_setup),                // 241
1056   LINX_ (__NR_io_destroy,             sys_io_destroy),              // 242
1057   LINXY (__NR_io_getevents,           sys_io_getevents),            // 243
1058   LINX_ (__NR_io_submit,              sys_io_submit),               // 244
1059   LINXY (__NR_io_cancel,              sys_io_cancel),               // 245
1060   LINX_ (__NR_exit_group,             sys_exit_group),              // 246
1061   //..
1062   LINXY (__NR_epoll_create,           sys_epoll_create),            // 248
1063   LINX_ (__NR_epoll_ctl,              sys_epoll_ctl),               // 249
1064   LINXY (__NR_epoll_wait,             sys_epoll_wait),              // 250
1065   //..
1066   LINX_ (__NR_set_tid_address,        sys_set_tid_address),         // 252
1067   LINX_ (__NR_fadvise64,              sys_fadvise64),               // 254
1068   GENXY (__NR_statfs64,               sys_statfs64),                // 255
1069   GENXY (__NR_fstatfs64,              sys_fstatfs64),               // 256
1070   //..
1071   LINXY (__NR_timer_create,           sys_timer_create),            // 257
1072   LINXY (__NR_timer_settime,          sys_timer_settime),           // 258
1073   LINXY (__NR_timer_gettime,          sys_timer_gettime),           // 259
1074   LINX_ (__NR_timer_getoverrun,       sys_timer_getoverrun),        // 260
1075   LINX_ (__NR_timer_delete,           sys_timer_delete),            // 261
1076   LINX_ (__NR_clock_settime,          sys_clock_settime),           // 262
1077   LINXY (__NR_clock_gettime,          sys_clock_gettime),           // 263
1078   LINXY (__NR_clock_getres,           sys_clock_getres),            // 264
1079   LINXY (__NR_clock_nanosleep,        sys_clock_nanosleep),         // 265
1080   LINXY (__NR_tgkill,                 sys_tgkill),                  // 266
1081   //..    GENX_(__NR_utimes,            sys_utimes),            // 267
1082   LINXY (__NR_get_mempolicy,          sys_get_mempolicy),           // 269
1083   LINX_ (__NR_set_mempolicy,          sys_set_mempolicy),           // 270
1084   LINXY (__NR_mq_open,                sys_mq_open),                 // 271
1085   LINX_ (__NR_mq_unlink,              sys_mq_unlink),               // 272
1086   LINX_ (__NR_mq_timedsend,           sys_mq_timedsend),            // 273
1087   LINXY (__NR_mq_timedreceive,        sys_mq_timedreceive),         // 274
1088   LINX_ (__NR_mq_notify,              sys_mq_notify),               // 275
1089   LINXY (__NR_mq_getsetattr,          sys_mq_getsetattr),           // 276
1090   LINX_ (__NR_inotify_init,           sys_inotify_init),            // 275
1091   LINX_ (__NR_inotify_add_watch,      sys_inotify_add_watch),       // 276
1092   LINX_ (__NR_inotify_rm_watch,       sys_inotify_rm_watch),        // 277
1093   //..
1094   PLAX_ (__NR_set_thread_area,        sys_set_thread_area),         // 283
1095   //..
1096   LINXY (__NR_openat,                 sys_openat),                  // 288
1097   LINX_ (__NR_mkdirat,                sys_mkdirat),                 // 289
1098   LINX_ (__NR_mknodat,                sys_mknodat),                 // 290
1099   LINX_ (__NR_fchownat,               sys_fchownat),                // 291
1100   LINX_ (__NR_futimesat,              sys_futimesat),               // 292
1101   PLAXY (__NR_fstatat64,              sys_fstatat64),               // 293
1102   LINX_ (__NR_unlinkat,               sys_unlinkat),                // 294
1103   LINX_ (__NR_renameat,               sys_renameat),                // 295
1104   LINX_ (__NR_linkat,                 sys_linkat),                  // 296
1105   LINX_ (__NR_symlinkat,              sys_symlinkat),               // 297
1106   LINX_ (__NR_readlinkat,             sys_readlinkat),              // 298
1107   LINX_ (__NR_fchmodat,               sys_fchmodat),                // 299
1108   LINX_ (__NR_faccessat,              sys_faccessat),               // 300
1109   //..
1110   LINXY (__NR_ppoll,                  sys_ppoll),                   // 302
1111   //..
1112   LINX_ (__NR_set_robust_list,        sys_set_robust_list),         // 309
1113   LINXY (__NR_get_robust_list,        sys_get_robust_list),         // 310
1114   //..
1115   LINXY (__NR_epoll_pwait,            sys_epoll_pwait),             // 313
1116   //..
1117   LINX_ (__NR_utimensat,              sys_utimensat),               // 316
1118   //..
1119   LINX_ (__NR_fallocate,              sys_fallocate),               // 320
1120   LINXY (__NR_timerfd_create,         sys_timerfd_create),          // 321
1121   LINXY (__NR_timerfd_gettime,        sys_timerfd_gettime),         // 322
1122   LINXY (__NR_timerfd_settime,        sys_timerfd_settime),         // 323
1123   LINXY (__NR_signalfd4,              sys_signalfd4),               // 324
1124   LINXY (__NR_eventfd2,               sys_eventfd2),                // 325
1125   //..
1126   LINXY (__NR_pipe2,                  sys_pipe2),                   // 328
1127   LINXY (__NR_inotify_init1,          sys_inotify_init1),           // 329
1128   //..
1129   LINXY (__NR_prlimit64,              sys_prlimit64),               // 338
1130   //..
1131   LINXY (__NR_clock_adjtime,          sys_clock_adjtime),           // 341
1132   //..
1133   LINXY (__NR_process_vm_readv,       sys_process_vm_readv),        // 345
1134   LINX_ (__NR_process_vm_writev,      sys_process_vm_writev)        // 346
1135};
1136
1137SyscallTableEntry* ML_(get_linux_syscall_entry) (UInt sysno)
1138{
1139   const UInt syscall_main_table_size
1140               = sizeof (syscall_main_table) / sizeof (syscall_main_table[0]);
1141   /* Is it in the contiguous initial section of the table? */
1142   if (sysno < syscall_main_table_size) {
1143      SyscallTableEntry * sys = &syscall_main_table[sysno];
1144      if (sys->before == NULL)
1145         return NULL;  /* No entry. */
1146      else
1147         return sys;
1148   }
1149   /* Can't find a wrapper. */
1150   return NULL;
1151}
1152
1153#endif // defined(VGP_mips32_linux)
1154
1155/*--------------------------------------------------------------------*/
1156/*--- end                                     syswrap-mips-linux.c ---*/
1157/*--------------------------------------------------------------------*/
1158