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