syswrap-mips32-linux.c revision f2a7bbe64a8a2e3bd91c8b9f344d8a343453b52a
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-2012 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_tool_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);
227/*
228   When a client clones, we need to keep track of the new thread.  This means:
229   1. allocate a ThreadId+ThreadState+stack for the the thread
230   2. initialize the thread's new VCPU state
231   3. create the thread using the same args as the client requested,
232   but using the scheduler entrypoint for IP, and a separate stack
233   for SP.
234 */
235
236static SysRes do_clone (ThreadId ptid,
237                        UInt flags, Addr sp,
238                        Int * parent_tidptr,
239                        Int * child_tidptr,
240                        Addr child_tls)
241{
242   const Bool debug = False;
243   ThreadId ctid = VG_ (alloc_ThreadState) ();
244   ThreadState * ptst = VG_ (get_ThreadState) (ptid);
245   ThreadState * ctst = VG_ (get_ThreadState) (ctid);
246   UInt ret = 0;
247   UWord * stack;
248   NSegment const *seg;
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   seg = VG_ (am_find_nsegment) ((Addr) sp);
284
285   if (seg && seg->kind != SkResvn) {
286      ctst->client_stack_highest_word = (Addr) VG_PGROUNDUP (sp);
287      ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
288      VG_ (register_stack) (seg->start, ctst->client_stack_highest_word);
289      if (debug)
290         VG_ (printf) ("tid %d: guessed client stack range %#lx-%#lx\n",
291
292      ctid, seg->start, VG_PGROUNDUP (sp));
293   } else {
294      VG_ (message) (Vg_UserMsg,
295                     "!? New thread %d starts with sp+%#lx) unmapped\n",
296                     ctid, sp);
297      ctst->client_stack_szB = 0;
298   }
299
300   VG_TRACK (pre_thread_ll_create, ptid, ctid);
301   if (flags & VKI_CLONE_SETTLS) {
302      if (debug)
303        VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls);
304      ctst->arch.vex.guest_r27 = child_tls;
305      res = sys_set_tls(ctid, child_tls);
306      if (sr_isError(res))
307         goto out;
308      ctst->arch.vex.guest_r27 = child_tls;
309  }
310
311   flags &= ~VKI_CLONE_SETTLS;
312   VG_ (sigprocmask) (VKI_SIG_SETMASK, &blockall, &savedmask);
313   /* Create the new thread */
314   ret = do_syscall_clone_mips_linux (ML_ (start_thread_NORETURN),
315                                    stack, flags, &VG_ (threads)[ctid],
316                                    child_tidptr, parent_tidptr,
317                                    0 /*child_tls*/);
318
319   /* High half word64 is syscall return value.  Low half is
320      the entire CR, from which we need to extract CR0.SO. */
321   if (debug)
322      VG_(printf)("ret: 0x%x\n", ret);
323
324   res = VG_ (mk_SysRes_mips32_linux) (/*val */ ret, 0, /*errflag */ 0);
325
326   VG_ (sigprocmask) (VKI_SIG_SETMASK, &savedmask, NULL);
327
328   out:
329   if (sr_isError (res)) {
330      VG_(cleanup_thread) (&ctst->arch);
331      ctst->status = VgTs_Empty;
332      VG_TRACK (pre_thread_ll_exit, ctid);
333   }
334   ptst->arch.vex.guest_r2 = 0;
335
336   return res;
337}
338
339/* ---------------------------------------------------------------------
340   More thread stuff
341   ------------------------------------------------------------------ */
342
343// MIPS doesn't have any architecture specific thread stuff that
344// needs to be cleaned up da li ????!!!!???
345void
346VG_ (cleanup_thread) (ThreadArchState * arch) { }
347
348void
349setup_child ( /*OUT*/ ThreadArchState * child,
350              /*IN*/ ThreadArchState * parent)
351{
352   /* We inherit our parent's guest state. */
353   child->vex = parent->vex;
354   child->vex_shadow1 = parent->vex_shadow1;
355   child->vex_shadow2 = parent->vex_shadow2;
356}
357
358SysRes sys_set_tls ( ThreadId tid, Addr tlsptr )
359{
360   VG_(threads)[tid].arch.vex.guest_ULR = tlsptr;
361   return VG_(mk_SysRes_Success)( 0 );
362}
363
364/* ---------------------------------------------------------------------
365   PRE/POST wrappers for mips/Linux-specific syscalls
366   ------------------------------------------------------------------ */
367#define PRE(name)       DEFN_PRE_TEMPLATE(mips_linux, name)
368#define POST(name)      DEFN_POST_TEMPLATE(mips_linux, name)
369
370/* Add prototypes for the wrappers declared here, so that gcc doesn't
371   harass us for not having prototypes.  Really this is a kludge --
372   the right thing to do is to make these wrappers 'static' since they
373   aren't visible outside this file, but that requires even more macro
374   magic. */
375//DECL_TEMPLATE (mips_linux, sys_syscall);
376DECL_TEMPLATE (mips_linux, sys_socket);
377DECL_TEMPLATE (mips_linux, sys_setsockopt);
378DECL_TEMPLATE (mips_linux, sys_getsockopt);
379DECL_TEMPLATE (mips_linux, sys_connect);
380DECL_TEMPLATE (mips_linux, sys_accept);
381DECL_TEMPLATE (mips_linux, sys_sendto);
382DECL_TEMPLATE (mips_linux, sys_recvfrom);
383DECL_TEMPLATE (mips_linux, sys_semget);
384DECL_TEMPLATE (mips_linux, sys_semop);
385DECL_TEMPLATE (mips_linux, sys_semctl);
386DECL_TEMPLATE (mips_linux, sys_semtimedop);
387DECL_TEMPLATE (mips_linux, sys_shmget);
388DECL_TEMPLATE (mips_linux, sys_shmdt);
389DECL_TEMPLATE (mips_linux, sys_shmctl);
390DECL_TEMPLATE (mips_linux, sys_sendmsg);
391DECL_TEMPLATE (mips_linux, sys_recvmsg);
392DECL_TEMPLATE (mips_linux, sys_msgget);
393DECL_TEMPLATE (mips_linux, sys_msgrcv);
394DECL_TEMPLATE (mips_linux, sys_msgsnd);
395DECL_TEMPLATE (mips_linux, sys_msgctl);
396DECL_TEMPLATE (mips_linux, sys_shutdown);
397DECL_TEMPLATE (mips_linux, sys_bind);
398DECL_TEMPLATE (mips_linux, sys_listen);
399DECL_TEMPLATE (mips_linux, sys_getsockname);
400DECL_TEMPLATE (mips_linux, sys_getpeername);
401DECL_TEMPLATE (mips_linux, sys_socketpair);
402DECL_TEMPLATE (mips_linux, sys_send);
403DECL_TEMPLATE (mips_linux, sys_recv);
404DECL_TEMPLATE (mips_linux, sys_mmap);
405DECL_TEMPLATE (mips_linux, sys_mmap2);
406DECL_TEMPLATE (mips_linux, sys_stat64);
407DECL_TEMPLATE (mips_linux, sys_lstat64);
408DECL_TEMPLATE (mips_linux, sys_fstatat64);
409DECL_TEMPLATE (mips_linux, sys_fstat64);
410DECL_TEMPLATE (mips_linux, sys_clone);
411DECL_TEMPLATE (mips_linux, sys_sigreturn);
412DECL_TEMPLATE (mips_linux, sys_rt_sigreturn);
413DECL_TEMPLATE (mips_linux, sys_cacheflush);
414DECL_TEMPLATE (mips_linux, sys_set_thread_area);
415DECL_TEMPLATE (mips_linux, sys_pipe);
416
417PRE (sys_socket)
418{
419  PRINT ("sys_socket ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
420  PRE_REG_READ3 (long, "socket", int, domain, int, type, int, protocol);
421}
422
423POST (sys_socket)
424{
425  SysRes r;
426  vg_assert (SUCCESS);
427  r = ML_ (generic_POST_sys_socket) (tid, VG_ (mk_SysRes_Success) (RES));
428  SET_STATUS_from_SysRes (r);
429}
430
431PRE (sys_setsockopt)
432{
433  PRINT ("sys_setsockopt ( %ld, %ld, %ld, %#lx, %ld )", ARG1, ARG2, ARG3,
434                                                        ARG4, ARG5);
435  PRE_REG_READ5 (long, "setsockopt", int, s, int, level, int, optname,
436                 const void *, optval, int, optlen);
437  ML_ (generic_PRE_sys_setsockopt) (tid, ARG1, ARG2, ARG3, ARG4, ARG5);
438}
439
440PRE (sys_getsockopt)
441{
442  PRINT ("sys_getsockopt ( %ld, %ld, %ld, %#lx, %#lx )", ARG1, ARG2, ARG3,
443                                                         ARG4, ARG5);
444  PRE_REG_READ5 (long, "getsockopt", int, s, int, level, int, optname,
445                 void *, optval, int, *optlen);
446  ML_ (linux_PRE_sys_getsockopt) (tid, ARG1, ARG2, ARG3, ARG4, ARG5);
447}
448
449POST (sys_getsockopt)
450{
451  vg_assert (SUCCESS);
452  ML_ (linux_POST_sys_getsockopt) (tid, VG_ (mk_SysRes_Success) (RES),
453                                   ARG1, ARG2, ARG3, ARG4, ARG5);
454}
455
456PRE(sys_connect)
457{
458   *flags |= SfMayBlock;
459   PRINT("sys_connect ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
460   PRE_REG_READ3(long, "connect",
461                 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
462   ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
463}
464
465PRE (sys_accept)
466{
467  *flags |= SfMayBlock;
468  PRINT ("sys_accept ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
469  PRE_REG_READ3 (long, "accept",  int, s, struct sockaddr *, addr, int,
470                 *addrlen);
471  ML_ (generic_PRE_sys_accept) (tid, ARG1, ARG2, ARG3);
472}
473
474POST (sys_accept)
475{
476  SysRes r;
477  vg_assert (SUCCESS);
478  r =
479    ML_ (generic_POST_sys_accept) (tid, VG_ (mk_SysRes_Success) (RES),
480                                   ARG1, ARG2, ARG3);
481  SET_STATUS_from_SysRes (r);
482}
483
484PRE (sys_sendto)
485{
486  *flags |= SfMayBlock;
487  PRINT ("sys_sendto ( %ld, %#lx, %ld, %lu, %#lx, %ld )", ARG1, ARG2, ARG3,
488                                                          ARG4, ARG5, ARG6);
489  PRE_REG_READ6 (long, "sendto", int, s, const void *, msg, int, len,
490                 unsigned int, flags, const struct sockaddr *, to, int,
491                 tolen);
492  ML_ (generic_PRE_sys_sendto) (tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
493}
494
495PRE (sys_recvfrom)
496{
497  *flags |= SfMayBlock;
498  PRINT ("sys_recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )", ARG1, ARG2,
499                                                ARG3, ARG4, ARG5, ARG6);
500  PRE_REG_READ6 (long, "recvfrom", int, s, void *, buf, int, len,
501                 unsigned int, flags,
502  struct sockaddr *, from, int *, fromlen);
503  ML_ (generic_PRE_sys_recvfrom) (tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
504}
505
506POST (sys_recvfrom)
507{
508  vg_assert (SUCCESS);
509  ML_ (generic_POST_sys_recvfrom) (tid, VG_ (mk_SysRes_Success) (RES),
510                                   ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
511}
512
513PRE(sys_sendmsg)
514{
515   *flags |= SfMayBlock;
516   PRINT("sys_sendmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
517   PRE_REG_READ3(long, "sendmsg",
518                 int, s, const struct msghdr *, msg, int, flags);
519   ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)ARG2);
520}
521
522PRE(sys_recvmsg)
523{
524   *flags |= SfMayBlock;
525   PRINT("sys_recvmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
526   PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg, int, flags);
527   ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2);
528}
529POST(sys_recvmsg)
530{
531   ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2, RES);
532}
533
534PRE (sys_semget)
535{
536  PRINT ("sys_semget ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
537  PRE_REG_READ3 (long, "semget", vki_key_t, key, int, nsems, int, semflg);
538}
539
540PRE (sys_semop)
541{
542  *flags |= SfMayBlock;
543  PRINT ("sys_semop ( %ld, %#lx, %lu )", ARG1, ARG2, ARG3);
544  PRE_REG_READ3 (long, "semop", int, semid, struct sembuf *, sops,
545                 unsigned, nsoops);
546  ML_ (generic_PRE_sys_semop) (tid, ARG1, ARG2, ARG3);
547}
548
549PRE (sys_semctl)
550{
551  switch (ARG3 & ~VKI_IPC_64)
552    {
553      case VKI_IPC_INFO:
554      case VKI_SEM_INFO:
555        PRINT ("sys_semctl ( %ld, %ld, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4);
556                                             PRE_REG_READ4 (long, "semctl",
557                                        int, semid, int, semnum, int, cmd,
558                                                struct seminfo *, arg);
559      break;
560      case VKI_IPC_STAT:
561      case VKI_SEM_STAT:
562      case VKI_IPC_SET:
563        PRINT ("sys_semctl ( %ld, %ld, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4);
564        PRE_REG_READ4 (long, "semctl", int, semid, int, semnum, int, cmd,
565                       struct semid_ds *, arg);
566      break;
567      case VKI_GETALL:
568      case VKI_SETALL:
569        PRINT ("sys_semctl ( %ld, %ld, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4);
570        PRE_REG_READ4 (long, "semctl", int, semid, int, semnum, int, cmd,
571                       unsigned short *, arg);
572      break;
573      default:
574        PRINT ("sys_semctl ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
575        PRE_REG_READ3 (long, "semctl", int, semid, int, semnum, int, cmd);
576        break;
577    }
578  ML_ (generic_PRE_sys_semctl) (tid, ARG1, ARG2, ARG3, ARG4);
579}
580
581POST (sys_semctl)
582{
583  ML_ (generic_POST_sys_semctl) (tid, RES, ARG1, ARG2, ARG3, ARG4);
584}
585
586PRE (sys_semtimedop)
587{
588  *flags |= SfMayBlock;
589  PRINT ("sys_semtimedop ( %ld, %#lx, %lu, %#lx )", ARG1, ARG2, ARG3, ARG4);
590  PRE_REG_READ4 (long, "semtimedop", int, semid, struct sembuf *, sops,
591                 unsigned, nsoops,
592  struct timespec *, timeout);
593  ML_ (generic_PRE_sys_semtimedop) (tid, ARG1, ARG2, ARG3, ARG4);
594}
595
596PRE (sys_msgget)
597{
598  PRINT ("sys_msgget ( %ld, %ld )", ARG1, ARG2);
599  PRE_REG_READ2 (long, "msgget", vki_key_t, key, int, msgflg);
600}
601
602PRE (sys_msgsnd)
603{
604  PRINT ("sys_msgsnd ( %ld, %#lx, %ld, %ld )", ARG1, ARG2, ARG3, ARG4);
605  PRE_REG_READ4 (long, "msgsnd", int, msqid, struct msgbuf *, msgp,
606                 vki_size_t, msgsz, int, msgflg);
607  ML_ (linux_PRE_sys_msgsnd) (tid, ARG1, ARG2, ARG3, ARG4);
608  if ((ARG4 & VKI_IPC_NOWAIT) == 0)
609    *flags |= SfMayBlock;
610}
611
612PRE (sys_msgrcv)
613{
614  PRINT ("sys_msgrcv ( %ld, %#lx, %ld, %ld, %ld )", ARG1, ARG2, ARG3, ARG4,
615                                                    ARG5);
616  PRE_REG_READ5 (long, "msgrcv", int, msqid, struct msgbuf *, msgp,
617                 vki_size_t, msgsz, long, msgytp, int, msgflg);
618  ML_ (linux_PRE_sys_msgrcv) (tid, ARG1, ARG2, ARG3, ARG4, ARG5);
619  if ((ARG4 & VKI_IPC_NOWAIT) == 0)
620    *flags |= SfMayBlock;
621}
622
623POST (sys_msgrcv)
624{
625  ML_ (linux_POST_sys_msgrcv) (tid, RES, ARG1, ARG2, ARG3, ARG4, ARG5);
626}
627
628PRE (sys_msgctl)
629{
630  PRINT ("sys_msgctl ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3);
631  PRE_REG_READ3 (long, "msgctl", int, msqid, int, cmd, struct msqid_ds *, buf);
632  ML_ (linux_PRE_sys_msgctl) (tid, ARG1, ARG2, ARG3);
633}
634
635POST (sys_msgctl)
636{
637  ML_ (linux_POST_sys_msgctl) (tid, RES, ARG1, ARG2, ARG3);
638}
639
640PRE (sys_shmget)
641{
642  PRINT ("sys_shmget ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
643  PRE_REG_READ3 (long, "shmget", vki_key_t, key, vki_size_t, size, int,
644                 shmflg);
645}
646
647PRE (sys_shmdt)
648{
649  PRINT ("sys_shmdt ( %#lx )", ARG1);
650  PRE_REG_READ1 (long, "shmdt", const void *, shmaddr);
651  if (!ML_ (generic_PRE_sys_shmdt) (tid, ARG1))
652    SET_STATUS_Failure (VKI_EINVAL);
653}
654
655POST (sys_shmdt)
656
657{
658  ML_ (generic_POST_sys_shmdt) (tid, RES, ARG1);
659}
660
661PRE (sys_shmctl)
662{
663  PRINT ("sys_shmctl ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3);
664  PRE_REG_READ3 (long, "shmctl", int, shmid, int, cmd, struct shmid_ds *, buf);
665  ML_ (generic_PRE_sys_shmctl) (tid, ARG1, ARG2, ARG3);
666}
667
668POST (sys_shmctl)
669{
670  ML_ (generic_POST_sys_shmctl) (tid, RES, ARG1, ARG2, ARG3);
671}
672
673PRE (sys_shutdown)
674{
675  *flags |= SfMayBlock;
676  PRINT ("sys_shutdown ( %ld, %ld )", ARG1, ARG2);
677  PRE_REG_READ2 (int, "shutdown", int, s, int, how);
678}
679
680PRE (sys_bind)
681{
682  PRINT ("sys_bind ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
683  PRE_REG_READ3 (long, "bind", int, sockfd, struct sockaddr *, my_addr,
684                 int, addrlen);
685  ML_ (generic_PRE_sys_bind) (tid, ARG1, ARG2, ARG3);
686}
687
688PRE (sys_listen)
689{
690  PRINT ("sys_listen ( %ld, %ld )", ARG1, ARG2);
691  PRE_REG_READ2 (long, "listen", int, s, int, backlog);
692}
693
694PRE (sys_getsockname)
695{
696  PRINT ("sys_getsockname ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
697  PRE_REG_READ3 (long, "getsockname", int, s, struct sockaddr *, name,
698                 int *, namelen);
699  ML_ (generic_PRE_sys_getsockname) (tid, ARG1, ARG2, ARG3);
700}
701
702POST (sys_getsockname)
703{
704  vg_assert (SUCCESS);
705  ML_ (generic_POST_sys_getsockname) (tid, VG_ (mk_SysRes_Success) (RES),
706                                      ARG1, ARG2, ARG3);
707}
708
709PRE (sys_getpeername)
710{
711  PRINT ("sys_getpeername ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
712  PRE_REG_READ3 (long, "getpeername", int, s, struct sockaddr *, name,
713                 int *, namelen);
714  ML_ (generic_PRE_sys_getpeername) (tid, ARG1, ARG2, ARG3);
715}
716
717POST (sys_getpeername)
718{
719  vg_assert (SUCCESS);
720  ML_ (generic_POST_sys_getpeername) (tid, VG_ (mk_SysRes_Success) (RES),
721                                      ARG1, ARG2, ARG3);
722}
723
724PRE (sys_socketpair)
725{
726  PRINT ("sys_socketpair ( %ld, %ld, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4);
727  PRE_REG_READ4 (long, "socketpair", int, d, int, type, int,
728                 protocol, int *, sv);
729  ML_ (generic_PRE_sys_socketpair) (tid, ARG1, ARG2, ARG3, ARG4);
730}
731
732POST (sys_socketpair)
733{
734  vg_assert (SUCCESS);
735  ML_ (generic_POST_sys_socketpair) (tid, VG_ (mk_SysRes_Success) (RES),
736                                     ARG1, ARG2, ARG3, ARG4);
737}
738
739PRE (sys_send)
740{
741  *flags |= SfMayBlock;
742  PRINT ("sys_send ( %ld, %#lx, %ld, %lu )", ARG1, ARG2, ARG3, ARG4);
743  PRE_REG_READ4 (long, "send", int, s, const void *, msg, int, len,
744                 unsigned int, flags);
745  ML_ (generic_PRE_sys_send) (tid, ARG1, ARG2, ARG3);
746}
747
748PRE (sys_recv)
749{
750  *flags |= SfMayBlock;
751  PRINT ("sys_recv ( %ld, %#lx, %ld, %lu )", ARG1, ARG2, ARG3, ARG4);
752  PRE_REG_READ4 (long, "recv", int, s, void *, buf, int, len,
753                 unsigned int, flags);
754  ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3);
755}
756
757POST (sys_recv)
758{
759  ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3);
760}
761
762PRE (sys_mmap2)
763{
764  SysRes r;
765  // Exactly like old_mmap() except:
766  //  - all 6 args are passed in regs, rather than in a memory-block.
767  //  - the file offset is specified in pagesize units rather than bytes,
768  //    so that it can be used for files bigger than 2^32 bytes.
769  // pagesize or 4K-size units in offset?
770  vg_assert (VKI_PAGE_SIZE == 4096 || VKI_PAGE_SIZE == 4096 * 4
771             || VKI_PAGE_SIZE == 4096 * 16);
772  PRINT ("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )", ARG1, (ULong) ARG2,
773                                                         ARG3, ARG4,
774                                                         ARG5, ARG6);
775  PRE_REG_READ6 (long, "mmap2", unsigned long, start, unsigned long, length,
776                 unsigned long, prot, unsigned long, flags,
777                 unsigned long, fd, unsigned long, offset);
778  r =
779    ML_ (generic_PRE_sys_mmap) (tid, ARG1, ARG2, ARG3, ARG4, ARG5,
780                                VKI_PAGE_SIZE * (Off64T) ARG6);
781  SET_STATUS_from_SysRes (r);
782}
783
784PRE (sys_mmap)
785{
786  SysRes r;
787  //vg_assert(VKI_PAGE_SIZE == 4096);
788  PRINT ("sys_mmap ( %#lx, %llu, %lu, %lu, %lu, %ld )", ARG1, (ULong) ARG2,
789                                                        ARG3, ARG4, ARG5, ARG6);
790  PRE_REG_READ6 (long, "mmap", unsigned long, start, vki_size_t, length,
791                 int, prot, int, flags, int, fd, unsigned long, offset);
792  r =
793    ML_ (generic_PRE_sys_mmap) (tid, ARG1, ARG2, ARG3, ARG4, ARG5,
794                                (Off64T) ARG6);
795  SET_STATUS_from_SysRes (r);
796}
797
798// XXX: lstat64/fstat64/stat64 are generic, but not necessarily
799// applicable to every architecture -- I think only to 32-bit archs.
800// We're going to need something like linux/core_os32.h for such
801// things, eventually, I think.  --njn
802
803PRE (sys_lstat64)
804{
805  PRINT ("sys_lstat64 ( %#lx(%s), %#lx )", ARG1, (char *) ARG1, ARG2);
806  PRE_REG_READ2 (long, "lstat64", char *, file_name, struct stat64 *, buf);
807  PRE_MEM_RASCIIZ ("lstat64(file_name)", ARG1);
808  PRE_MEM_WRITE ("lstat64(buf)", ARG2, sizeof (struct vki_stat64));
809}
810
811POST (sys_lstat64)
812{
813  vg_assert (SUCCESS);
814  if (RES == 0)
815    {
816      POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64));
817    }
818}
819
820PRE (sys_stat64)
821{
822  PRINT ("sys_stat64 ( %#lx(%s), %#lx )", ARG1, (char *) ARG1, ARG2);
823  PRE_REG_READ2 (long, "stat64", char *, file_name, struct stat64 *, buf);
824  PRE_MEM_RASCIIZ ("stat64(file_name)", ARG1);
825  PRE_MEM_WRITE ("stat64(buf)", ARG2, sizeof (struct vki_stat64));
826}
827
828POST (sys_stat64)
829{
830  POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64));
831}
832
833PRE (sys_fstatat64)
834{
835  PRINT ("sys_fstatat64 ( %ld, %#lx(%s), %#lx )", ARG1, ARG2, (char *) ARG2,
836                                                  ARG3);
837  PRE_REG_READ3 (long, "fstatat64", int, dfd, char *, file_name,
838                 struct stat64 *, buf);
839  PRE_MEM_RASCIIZ ("fstatat64(file_name)", ARG2);
840  PRE_MEM_WRITE ("fstatat64(buf)", ARG3, sizeof (struct vki_stat64));
841}
842
843POST (sys_fstatat64)
844{
845  POST_MEM_WRITE (ARG3, sizeof (struct vki_stat64));
846}
847
848PRE (sys_fstat64)
849{
850  PRINT ("sys_fstat64 ( %ld, %#lx )", ARG1, ARG2);
851  PRE_REG_READ2 (long, "fstat64", unsigned long, fd, struct stat64 *, buf);
852  PRE_MEM_WRITE ("fstat64(buf)", ARG2, sizeof (struct vki_stat64));
853}
854
855POST (sys_fstat64)
856{
857  POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64));
858}
859
860PRE (sys_clone)
861  {
862    Bool badarg = False;
863    UInt cloneflags;
864    PRINT ("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )", ARG1, ARG2, ARG3,
865                                                        ARG4, ARG5);
866    PRE_REG_READ2 (int, "clone", unsigned long, flags,  void *, child_stack);
867    if (ARG1 & VKI_CLONE_PARENT_SETTID)
868      {
869        if (VG_ (tdict).track_pre_reg_read)
870          {
871            PRA3 ("clone", int *, parent_tidptr);
872          }
873        PRE_MEM_WRITE ("clone(parent_tidptr)", ARG3, sizeof (Int));
874        if (!VG_ (am_is_valid_for_client)(ARG3, sizeof (Int), VKI_PROT_WRITE))
875        {
876          badarg = True;
877        }
878      }
879    if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
880      {
881        if (VG_ (tdict).track_pre_reg_read)
882          {
883            PRA5 ("clone", int *, child_tidptr);
884          }
885        PRE_MEM_WRITE ("clone(child_tidptr)", ARG5, sizeof (Int));
886        if (!VG_ (am_is_valid_for_client)(ARG5, sizeof (Int), VKI_PROT_WRITE))
887          {
888            badarg = True;
889          }
890      }
891    if (badarg)
892      {
893        SET_STATUS_Failure (VKI_EFAULT);
894        return;
895      }
896    cloneflags = ARG1;
897    if (!ML_ (client_signal_OK) (ARG1 & VKI_CSIGNAL))
898      {
899        SET_STATUS_Failure (VKI_EINVAL);
900        return;
901      }
902    /* Only look at the flags we really care about */
903    switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
904           |VKI_CLONE_FILES | VKI_CLONE_VFORK))
905      {
906        case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
907        /* thread creation */
908        PRINT ("sys_clone1 ( %#lx, %#lx, %#lx, %#lx, %#lx )",
909               ARG1, ARG2, ARG3, ARG4, ARG5);
910        SET_STATUS_from_SysRes (do_clone (tid,
911                                          ARG1, /* flags */
912                                          (Addr) ARG2, /* child SP */
913                                          (Int *) ARG3, /* parent_tidptr */
914                                          (Int *) ARG5, /* child_tidptr */
915                                          (Addr) ARG4));	/* child_tls */
916
917        break;
918        case VKI_CLONE_VFORK | VKI_CLONE_VM:	/* vfork */
919          /* FALLTHROUGH - assume vfork == fork */
920          cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
921        case 0:  /* plain fork */
922          SET_STATUS_from_SysRes (ML_ (do_fork_clone) (tid,
923                                  cloneflags, /* flags */
924                                  (Int *) ARG3, /* parent_tidptr */
925                                  (Int *) ARG5));	/* child_tidptr */
926        break;
927        default:
928          /* should we just ENOSYS? */
929          VG_ (message) (Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
930          VG_ (message) (Vg_UserMsg, "\n");
931          VG_ (message) (Vg_UserMsg, "The only supported clone() uses are:\n");
932          VG_ (message) (Vg_UserMsg,
933                          " - via a threads library (LinuxThreads or NPTL)\n");
934          VG_ (message) (Vg_UserMsg,
935                          " - via the implementation of fork or vfork\n");
936          VG_ (unimplemented)("Valgrind does not support general clone().");
937    }
938    if (SUCCESS)
939      {
940        if (ARG1 & VKI_CLONE_PARENT_SETTID)
941          POST_MEM_WRITE (ARG3, sizeof (Int));
942        if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
943          POST_MEM_WRITE (ARG5, sizeof (Int));
944        /* Thread creation was successful; let the child have the chance
945         * to run */
946        *flags |= SfYieldAfter;
947      }
948}
949
950PRE (sys_sigreturn)
951{
952  ThreadState * tst;
953  PRINT ("sys_sigreturn ( )");
954  vg_assert (VG_ (is_valid_tid) (tid));
955  vg_assert (tid >= 1 && tid < VG_N_THREADS);
956  vg_assert (VG_ (is_running_thread) (tid));
957  tst = VG_ (get_ThreadState) (tid);
958  VG_ (sigframe_destroy) (tid, False);
959  /* Tell the driver not to update the guest state with the "result",
960     and set a bogus result to keep it happy. */
961  *flags |= SfNoWriteResult;
962  SET_STATUS_Success (0);
963   /* Check to see if any signals arose as a result of this. */
964  *flags |= SfPollAfter;
965}
966
967PRE (sys_rt_sigreturn)
968{
969  PRINT ("rt_sigreturn ( )");
970  vg_assert (VG_ (is_valid_tid) (tid));
971  vg_assert (tid >= 1 && tid < VG_N_THREADS);
972  vg_assert (VG_ (is_running_thread) (tid));
973  /* Restore register state from frame and remove it */
974  VG_ (sigframe_destroy) (tid, True);
975  /* Tell the driver not to update the guest state with the "result",
976     and set a bogus result to keep it happy. */
977  *flags |= SfNoWriteResult;
978  SET_STATUS_Success (0);
979  /* Check to see if any signals arose as a result of this. */
980  *flags |= SfPollAfter;
981}
982
983PRE (sys_set_thread_area)
984{
985   PRINT ("set_thread_area (%lx)", ARG1);
986   PRE_REG_READ1(long, "set_thread_area", unsigned long, addr);
987   SET_STATUS_from_SysRes( sys_set_tls( tid, ARG1 ) );
988}
989
990/* Very much MIPS specific */
991PRE (sys_cacheflush)
992{
993  PRINT ("cacheflush (%lx, %#lx, %#lx)", ARG1, ARG2, ARG3);
994  PRE_REG_READ3 (long, "cacheflush", void *, addrlow, void *, addrhigh, int,
995                 flags);
996  VG_ (discard_translations) ((Addr64) ARG1, ((ULong) ARG2) - ((ULong) ARG1) +
997                              1ULL /*paranoia */ , "PRE(sys_cacheflush)");
998  SET_STATUS_Success (0);
999}
1000
1001PRE(sys_pipe)
1002{
1003   PRINT("sys_pipe ( %#lx )", ARG1);
1004   PRE_REG_READ1(int, "pipe", int *, filedes);
1005   PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
1006}
1007
1008POST(sys_pipe)
1009{
1010   Int p0, p1;
1011   vg_assert(SUCCESS);
1012   p0 = RES;
1013   p1 = sr_ResEx(status->sres);
1014
1015   if (!ML_(fd_allowed)(p0, "pipe", tid, True) ||
1016       !ML_(fd_allowed)(p1, "pipe", tid, True)) {
1017      VG_(close)(p0);
1018      VG_(close)(p1);
1019      SET_STATUS_Failure( VKI_EMFILE );
1020   } else {
1021      if (VG_(clo_track_fds)) {
1022         ML_(record_fd_open_nameless)(tid, p0);
1023         ML_(record_fd_open_nameless)(tid, p1);
1024      }
1025   }
1026}
1027
1028#undef PRE
1029#undef POST
1030
1031/* ---------------------------------------------------------------------
1032   The mips/Linux syscall table
1033   ------------------------------------------------------------------ */
1034#define PLAX_(sysno, name)    WRAPPER_ENTRY_X_(mips_linux, sysno, name)
1035#define PLAXY(sysno, name)    WRAPPER_ENTRY_XY(mips_linux, sysno, name)
1036
1037// This table maps from __NR_xxx syscall numbers (from
1038// linux/include/asm-mips/unistd.h) to the appropriate PRE/POST sys_foo()
1039// wrappers on mips (as per sys_call_table in linux/arch/mips/kernel/entry.S).
1040//
1041
1042// For those syscalls not handled by Valgrind, the annotation indicate its
1043// arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
1044// (unknown).
1045
1046static SyscallTableEntry syscall_main_table[] = {
1047  //PLAXY (__NR_syscall, sys_syscall),	// 0
1048  GENX_ (__NR_exit, sys_exit),	// 1
1049  GENX_ (__NR_fork, sys_fork),	// 2
1050  GENXY (__NR_read, sys_read),	// 3
1051  GENX_ (__NR_write, sys_write),	// 4
1052  GENXY (__NR_open, sys_open),	// 5
1053  GENXY (__NR_close, sys_close),	// 6
1054  GENXY (__NR_waitpid, sys_waitpid),	// 7
1055  GENXY (__NR_creat, sys_creat),	// 8
1056  GENX_ (__NR_link, sys_link),	// 9
1057  GENX_ (__NR_unlink, sys_unlink),	// 10
1058  GENX_ (__NR_execve, sys_execve),	// 11
1059  GENX_ (__NR_chdir, sys_chdir),	// 12
1060  GENXY (__NR_time, sys_time),		// 13
1061  GENX_ (__NR_mknod, sys_mknod),	// 14
1062  GENX_ (__NR_chmod, sys_chmod),	// 15
1063  GENX_ (__NR_lchown, sys_lchown),	// 16
1064  LINX_ (__NR_lseek, sys_lseek),	// 19
1065  GENX_ (__NR_getpid, sys_getpid),	// 20
1066  LINX_ (__NR_mount, sys_mount),	// 21
1067  LINX_ (__NR_umount, sys_oldumount),	// 22
1068  GENX_ (__NR_setuid, sys_setuid),	// 23 ## P
1069  GENX_ (__NR_getuid, sys_getuid),	// 24 ## P
1070  LINX_ (__NR_stime, sys_stime),	// 25
1071  //..    PLAXY(__NR_ptrace,            sys_ptrace),            // 26
1072  GENX_ (__NR_alarm, sys_alarm),	// 27
1073  //..    //   (__NR_oldfstat,          sys_fstat),
1074  GENX_ (__NR_pause, sys_pause),	// 29
1075  LINX_ (__NR_utime, sys_utime),	// 30
1076  //..    GENX_(__NR_stty,              sys_ni_syscall),        // 31
1077  //..    GENX_(__NR_gtty,              sys_ni_syscall),        // 32
1078  GENX_ (__NR_access, sys_access),	// 33
1079  //..    GENX_(__NR_nice,              sys_nice),              // 34
1080  //..    GENX_(__NR_ftime,             sys_ni_syscall),        // 35
1081  //..    GENX_(__NR_sync,              sys_sync),              // 36
1082  GENX_ (__NR_kill, sys_kill),	// 37
1083  GENX_ (__NR_rename, sys_rename),	// 38
1084  GENX_ (__NR_mkdir, sys_mkdir),	// 39
1085  GENX_ (__NR_rmdir, sys_rmdir),	// 40
1086  GENXY (__NR_dup, sys_dup),	// 41
1087  PLAXY (__NR_pipe, sys_pipe),	// 42
1088  GENXY (__NR_times, sys_times),	// 43
1089  //..    GENX_(__NR_prof,              sys_ni_syscall),   // 44
1090  //..
1091  GENX_ (__NR_brk, sys_brk),	// 45
1092  GENX_ (__NR_setgid, sys_setgid),	// 46
1093  GENX_ (__NR_getgid, sys_getgid),	// 47
1094  //..    //   (__NR_signal,            sys_signal),       // 48 */* (ANSI C)
1095  GENX_ (__NR_geteuid, sys_geteuid),	// 49
1096  GENX_ (__NR_getegid, sys_getegid),	// 50
1097  //..    GENX_(__NR_acct,              sys_acct),         // 51
1098  LINX_ (__NR_umount2, sys_umount),	// 52
1099  //..    GENX_(__NR_lock,              sys_ni_syscall),   // 53
1100  LINXY (__NR_ioctl, sys_ioctl),	// 54
1101  LINXY (__NR_fcntl, sys_fcntl),	// 55
1102  //..    GENX_(__NR_mpx,               sys_ni_syscall),   // 56
1103  GENX_ (__NR_setpgid, sys_setpgid),	// 57
1104  //..    GENX_(__NR_ulimit,            sys_ni_syscall),        // 58
1105  //..    //   (__NR_oldolduname,       sys_olduname),          // 59
1106  GENX_ (__NR_umask, sys_umask),	// 60
1107  GENX_ (__NR_chroot, sys_chroot),	// 61
1108  //..    //   (__NR_ustat,             sys_ustat)              // 62 SVr4 -- deprecated
1109  GENXY (__NR_dup2, sys_dup2),	// 63
1110  GENX_ (__NR_getppid, sys_getppid),	// 64
1111  GENX_ (__NR_getpgrp, sys_getpgrp),	// 65
1112  GENX_ (__NR_setsid, sys_setsid),	// 66
1113  //   PLAXY(__NR_sigaction,         sys_sigaction),         // 67
1114  //..    //   (__NR_sgetmask,          sys_sgetmask),          // 68 */* (ANSI C)
1115  //..    //   (__NR_ssetmask,          sys_ssetmask),          // 69 */* (ANSI C)
1116  //..
1117  GENX_ (__NR_setreuid, sys_setreuid),	// 70
1118  GENX_ (__NR_setregid, sys_setregid),	// 71
1119  //   PLAX_(__NR_sigsuspend,        sys_sigsuspend),        // 72
1120  LINXY (__NR_sigpending, sys_sigpending),	// 73
1121  //..    //   (__NR_sethostname,       sys_sethostname),       // 74 */*
1122  //..
1123  GENX_ (__NR_setrlimit, sys_setrlimit),	// 75
1124  //..    GENXY(__NR_getrlimit,         sys_old_getrlimit),     // 76
1125  GENXY (__NR_getrusage, sys_getrusage),	// 77
1126  GENXY (__NR_gettimeofday, sys_gettimeofday),	// 78
1127  GENX_ (__NR_settimeofday, sys_settimeofday),  // 79
1128  //..
1129  GENXY (__NR_getgroups, sys_getgroups),	// 80
1130  GENX_ (__NR_setgroups, sys_setgroups),	// 81
1131  //..    PLAX_(__NR_select,            old_select),            // 82
1132  GENX_ (__NR_symlink, sys_symlink),	// 83
1133  //..    //   (__NR_oldlstat,          sys_lstat),             // 84 -- obsolete
1134  //..
1135  GENX_ (__NR_readlink, sys_readlink),	// 85
1136  //..    //   (__NR_uselib,            sys_uselib),            // 86 */Linux
1137  //..    //   (__NR_swapon,            sys_swapon),            // 87 */Linux
1138  //..    //   (__NR_reboot,            sys_reboot),            // 88 */Linux
1139  //..    //   (__NR_readdir,           old_readdir),           // 89 -- superseded
1140  PLAX_ (__NR_mmap, sys_mmap),	// 90
1141  GENXY (__NR_munmap, sys_munmap),	// 91
1142  GENX_ (__NR_truncate, sys_truncate),	// 92
1143  GENX_ (__NR_ftruncate, sys_ftruncate),	// 93
1144  GENX_ (__NR_fchmod, sys_fchmod),	// 94
1145  GENX_ (__NR_fchown, sys_fchown),	// 95
1146  GENX_ (__NR_getpriority, sys_getpriority),	// 96
1147  GENX_ (__NR_setpriority, sys_setpriority),	// 97
1148  //..    GENX_(__NR_profil,            sys_ni_syscall),        // 98
1149  GENXY (__NR_statfs, sys_statfs),	// 99
1150  //..
1151  GENXY (__NR_fstatfs, sys_fstatfs),	// 100
1152  //..    LINX_(__NR_ioperm,            sys_ioperm),            // 101
1153  LINXY (__NR_socketcall, sys_socketcall),	// 102
1154  LINXY (__NR_syslog, sys_syslog),	// 103
1155  GENXY (__NR_setitimer, sys_setitimer),	// 104
1156  //..
1157  //..    GENXY(__NR_getitimer,         sys_getitimer),         // 105
1158  GENXY (__NR_stat, sys_newstat),	// 106
1159  GENXY (__NR_lstat, sys_newlstat),	// 107
1160  GENXY (__NR_fstat, sys_newfstat),	// 108
1161  //..    //   (__NR_olduname,          sys_uname),             // 109 -- obsolete
1162  //..
1163  //..    GENX_(__NR_iopl,              sys_iopl),              // 110
1164  //..    LINX_(__NR_vhangup,           sys_vhangup),           // 111
1165  //..    GENX_(__NR_idle,              sys_ni_syscall),        // 112
1166  //..    //   (__NR_vm86old,           sys_vm86old),           // 113 x86/Linux-only
1167  GENXY (__NR_wait4, sys_wait4),	// 114
1168  //..
1169  //..    //   (__NR_swapoff,           sys_swapoff),           // 115 */Linux
1170  LINXY (__NR_sysinfo, sys_sysinfo),	// 116
1171  LINXY (__NR_ipc, sys_ipc),	// 117
1172  GENX_ (__NR_fsync, sys_fsync),	// 118
1173  PLAX_ (__NR_sigreturn, sys_sigreturn),	// 119 ?/Linux
1174  //..
1175  PLAX_ (__NR_clone, sys_clone),	// 120
1176  //..    //   (__NR_setdomainname,     sys_setdomainname),     // 121 */*(?)
1177  GENXY (__NR_uname, sys_newuname),	// 122
1178  //..    PLAX_(__NR_modify_ldt,        sys_modify_ldt),        // 123
1179  //..    LINXY(__NR_adjtimex,          sys_adjtimex),          // 124
1180  //..
1181  GENXY (__NR_mprotect, sys_mprotect),	// 125
1182  LINXY (__NR_sigprocmask, sys_sigprocmask),    // 126
1183  //..    // Nb: create_module() was removed 2.4-->2.6
1184  //..    GENX_(__NR_create_module,     sys_ni_syscall),        // 127
1185  //..    GENX_(__NR_init_module,       sys_init_module),       // 128
1186  //..    //   (__NR_delete_module,     sys_delete_module),     // 129 (*/Linux)?
1187  //..
1188  //..    // Nb: get_kernel_syms() was removed 2.4-->2.6
1189  //..    GENX_(__NR_get_kernel_syms,   sys_ni_syscall),        // 130
1190  //..    LINX_(__NR_quotactl,          sys_quotactl),          // 131
1191  GENX_ (__NR_getpgid, sys_getpgid),	// 132
1192  GENX_ (__NR_fchdir, sys_fchdir),	// 133
1193  //..    //   (__NR_bdflush,           sys_bdflush),           // 134 */Linux
1194  //..
1195  //..    //   (__NR_sysfs,             sys_sysfs),             // 135 SVr4
1196  LINX_ (__NR_personality, sys_personality),	// 136
1197  //..    GENX_(__NR_afs_syscall,       sys_ni_syscall),        // 137
1198  LINX_ (__NR_setfsuid, sys_setfsuid),	// 138
1199  LINX_ (__NR_setfsgid, sys_setfsgid),	// 139
1200  LINXY (__NR__llseek, sys_llseek),	// 140
1201  GENXY (__NR_getdents, sys_getdents),	// 141
1202  GENX_ (__NR__newselect, sys_select),	// 142
1203  GENX_ (__NR_flock, sys_flock),	// 143
1204  GENX_ (__NR_msync, sys_msync),	// 144
1205  //..
1206  GENXY (__NR_readv, sys_readv),	// 145
1207  GENX_ (__NR_writev, sys_writev),	// 146
1208  PLAX_ (__NR_cacheflush, sys_cacheflush),	// 147
1209  GENX_ (__NR_getsid, sys_getsid),	// 151
1210  GENX_ (__NR_fdatasync, sys_fdatasync),	// 152
1211  LINXY (__NR__sysctl, sys_sysctl),	// 153
1212  //..
1213  GENX_ (__NR_mlock, sys_mlock),	// 154
1214  GENX_ (__NR_munlock, sys_munlock),	// 155
1215  GENX_ (__NR_mlockall, sys_mlockall),	// 156
1216  LINX_ (__NR_munlockall, sys_munlockall),	// 157
1217  //..    LINXY(__NR_sched_setparam,    sys_sched_setparam),    // 158
1218  //..
1219  LINXY (__NR_sched_getparam, sys_sched_getparam),	// 159
1220  LINX_ (__NR_sched_setscheduler, sys_sched_setscheduler),	// 160
1221  LINX_ (__NR_sched_getscheduler, sys_sched_getscheduler),	// 161
1222  LINX_ (__NR_sched_yield, sys_sched_yield),	// 162
1223  LINX_ (__NR_sched_get_priority_max, sys_sched_get_priority_max),	// 163
1224  LINX_ (__NR_sched_get_priority_min, sys_sched_get_priority_min),	// 164
1225  //..    //LINX?(__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 165 */*
1226  GENXY (__NR_nanosleep, sys_nanosleep),	// 166
1227  GENX_ (__NR_mremap, sys_mremap),	// 167
1228  PLAXY (__NR_accept, sys_accept),	// 168
1229  PLAX_ (__NR_bind, sys_bind),	// 169
1230  PLAX_ (__NR_connect, sys_connect),	// 170
1231  PLAXY (__NR_getpeername, sys_getpeername),	// 171
1232  PLAXY (__NR_getsockname, sys_getsockname),	// 172
1233  PLAXY (__NR_getsockopt, sys_getsockopt),	// 173
1234  PLAX_ (__NR_listen, sys_listen),	// 174
1235  PLAXY (__NR_recv, sys_recv),	// 175
1236  PLAXY (__NR_recvfrom, sys_recvfrom),	// 176
1237  PLAXY (__NR_recvmsg, sys_recvmsg),	// 177
1238  PLAX_ (__NR_send, sys_send),	// 178
1239  PLAX_ (__NR_sendmsg, sys_sendmsg),	// 179
1240  PLAX_ (__NR_sendto, sys_sendto),	// 180
1241  PLAX_ (__NR_setsockopt, sys_setsockopt),	// 181
1242  PLAX_ (__NR_shutdown, sys_shutdown),  // 182
1243  PLAXY (__NR_socket, sys_socket),	// 183
1244  PLAXY (__NR_socketpair, sys_socketpair),	// 184
1245  LINX_ (__NR_setresuid, sys_setresuid),	// 185
1246  LINXY (__NR_getresuid, sys_getresuid),	// 186
1247  //..    GENX_(__NR_query_module,      sys_ni_syscall),        //
1248  GENXY (__NR_poll, sys_poll),	// 188
1249  //..    //   (__NR_nfsservctl,        sys_nfsservctl),        // 168 */Linux
1250  //..
1251  LINX_ (__NR_setresgid, sys_setresgid),	// 190
1252  LINXY (__NR_getresgid, sys_getresgid),	// 191
1253  LINXY (__NR_prctl, sys_prctl),	// 192
1254  PLAX_ (__NR_rt_sigreturn, sys_rt_sigreturn),	// 193
1255  LINXY (__NR_rt_sigaction, sys_rt_sigaction),	// 194
1256  LINXY (__NR_rt_sigprocmask, sys_rt_sigprocmask),	// 195
1257  LINXY (__NR_rt_sigpending, sys_rt_sigpending),	// 196
1258  LINXY (__NR_rt_sigtimedwait, sys_rt_sigtimedwait),	// 197
1259  LINXY (__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo),	// 198
1260  LINX_ (__NR_rt_sigsuspend, sys_rt_sigsuspend),	// 199
1261  GENXY (__NR_pread64, sys_pread64),	// 200
1262  GENX_ (__NR_pwrite64, sys_pwrite64),	// 201
1263  GENX_ (__NR_chown, sys_chown),   // 202
1264  GENXY (__NR_getcwd, sys_getcwd), // 203
1265  LINXY (__NR_capget, sys_capget), // 204
1266  //..
1267  //..    LINX_(__NR_capset,            sys_capset),            // 205
1268  GENXY (__NR_sigaltstack, sys_sigaltstack),	// 206
1269  LINXY (__NR_sendfile, sys_sendfile),	// 207
1270  //..    GENXY(__NR_getpmsg,           sys_getpmsg),           // 208
1271  //..    GENX_(__NR_putpmsg,           sys_putpmsg),           // 209
1272  // Nb: we treat vfork as fork
1273  //   GENX_(__NR_vfork,             sys_fork),              //
1274  GENXY (__NR_getrlimit, sys_getrlimit),	// 76
1275  //__NR_readahead      // 191 ppc/Linux only?
1276  PLAX_ (__NR_mmap2, sys_mmap2),	// 210
1277  //   GENX_(__NR_truncate64,        sys_truncate64),        // 211
1278  GENX_ (__NR_ftruncate64, sys_ftruncate64),	// 212
1279  //..
1280  PLAXY (__NR_stat64, sys_stat64),	// 213
1281  PLAXY (__NR_lstat64, sys_lstat64),	// 214
1282  PLAXY (__NR_fstat64, sys_fstat64),	// 215
1283  GENXY (__NR_getdents64, sys_getdents64),	// 219
1284  //..    //   (__NR_pivot_root,        sys_pivot_root),        //
1285  LINXY (__NR_fcntl64, sys_fcntl64),	// 220
1286  GENX_ (__NR_madvise, sys_madvise),	// 218
1287  GENXY (__NR_mincore, sys_mincore),	// 217
1288  LINX_ (__NR_gettid, sys_gettid),	// 222
1289  //..    LINX_(__NR_tkill,             sys_tkill),             // 208 */Linux
1290  //..    LINX_(__NR_setxattr,          sys_setxattr),          // 209
1291  //..    LINX_(__NR_lsetxattr,         sys_lsetxattr),         // 210
1292  //..    LINX_(__NR_fsetxattr,         sys_fsetxattr),         // 211
1293  LINXY (__NR_getxattr, sys_getxattr),	// 227
1294  LINXY (__NR_lgetxattr, sys_lgetxattr),	// 228
1295  LINXY (__NR_fgetxattr, sys_fgetxattr),	// 229
1296  LINXY (__NR_listxattr, sys_listxattr),	// 230
1297  LINXY (__NR_llistxattr, sys_llistxattr),	// 231
1298  LINXY (__NR_flistxattr, sys_flistxattr),	// 232
1299  LINX_ (__NR_removexattr, sys_removexattr),	// 233
1300  LINX_ (__NR_lremovexattr, sys_lremovexattr),	// 234
1301  LINX_ (__NR_fremovexattr, sys_fremovexattr),	// 235
1302  LINXY (__NR_futex, sys_futex),	// 238
1303  LINX_ (__NR_sched_setaffinity, sys_sched_setaffinity),	// 239
1304  LINXY (__NR_sched_getaffinity, sys_sched_getaffinity),	// 240
1305  /* 224 currently unused */
1306  // __NR_tuxcall                                               //
1307  LINXY (__NR_sendfile64, sys_sendfile64),	// 237
1308  //..
1309  LINX_ (__NR_io_setup, sys_io_setup),	// 241
1310  LINX_ (__NR_io_destroy, sys_io_destroy),	// 242
1311  LINXY (__NR_io_getevents, sys_io_getevents),	// 243
1312  LINX_ (__NR_io_submit, sys_io_submit),	// 244
1313  LINXY (__NR_io_cancel, sys_io_cancel),	// 245
1314  //..
1315  LINX_ (__NR_set_tid_address, sys_set_tid_address),	// 252
1316  LINX_ (__NR_fadvise64, sys_fadvise64),	// 254
1317  LINX_ (__NR_exit_group, sys_exit_group),	// 246
1318  //..    GENXY(__NR_lookup_dcookie,    sys_lookup_dcookie),    // 247
1319  LINXY (__NR_epoll_create, sys_epoll_create),	// 248
1320  LINX_ (__NR_epoll_ctl, sys_epoll_ctl),	// 249
1321  LINXY (__NR_epoll_wait, sys_epoll_wait),	// 250
1322  //..    //   (__NR_remap_file_pages,  sys_remap_file_pages),  // 239 */Linux
1323  LINXY (__NR_timer_create, sys_timer_create),	// 257
1324  LINXY (__NR_timer_settime, sys_timer_settime),	// 258
1325  LINXY (__NR_timer_gettime, sys_timer_gettime),	// 259
1326  LINX_ (__NR_timer_getoverrun, sys_timer_getoverrun),	// 260
1327  LINX_ (__NR_timer_delete, sys_timer_delete),	// 261
1328  LINX_ (__NR_clock_settime, sys_clock_settime),	// 262
1329  LINXY (__NR_clock_gettime, sys_clock_gettime),	// 263
1330  LINXY (__NR_clock_getres, sys_clock_getres),	// 264
1331  LINXY (__NR_clock_nanosleep, sys_clock_nanosleep),	// 265
1332  // __NR_swapcontext                                           //
1333  LINXY (__NR_tgkill, sys_tgkill),	// 266 */Linux
1334  //..    GENX_(__NR_utimes,            sys_utimes),            // 267
1335  GENXY (__NR_statfs64, sys_statfs64),	// 255
1336  GENXY (__NR_fstatfs64, sys_fstatfs64),	// 256
1337  LINXY (__NR_get_mempolicy, sys_get_mempolicy),	// 269
1338  LINX_ (__NR_set_mempolicy, sys_set_mempolicy),	// 270
1339  LINXY (__NR_mq_open, sys_mq_open),	// 271
1340  LINX_ (__NR_mq_unlink, sys_mq_unlink),	// 272
1341  LINX_ (__NR_mq_timedsend, sys_mq_timedsend),	// 273
1342  LINXY (__NR_mq_timedreceive, sys_mq_timedreceive),	// 274
1343  LINX_ (__NR_mq_notify, sys_mq_notify),	// 275
1344  LINXY (__NR_mq_getsetattr, sys_mq_getsetattr),	// 276
1345  // __NR_kexec_load                                            //
1346  LINX_ (__NR_inotify_init, sys_inotify_init),	// 275
1347  LINX_ (__NR_inotify_add_watch, sys_inotify_add_watch),	// 276
1348  LINX_ (__NR_inotify_rm_watch, sys_inotify_rm_watch),	// 277
1349  PLAX_ (__NR_set_thread_area, sys_set_thread_area),	// 283
1350  LINXY (__NR_openat, sys_openat),	// 288
1351  LINX_ (__NR_mkdirat, sys_mkdirat),	// 289
1352  LINX_ (__NR_mknodat, sys_mknodat),	// 290
1353  LINX_ (__NR_fchownat, sys_fchownat),	// 291
1354  LINX_ (__NR_futimesat, sys_futimesat),	// 292
1355  PLAXY (__NR_fstatat64, sys_fstatat64),	// 293
1356  LINX_ (__NR_unlinkat, sys_unlinkat),	// 294
1357  LINX_ (__NR_renameat, sys_renameat),	// 295
1358  LINX_ (__NR_linkat, sys_linkat),	// 296
1359  LINX_ (__NR_symlinkat, sys_symlinkat),	// 297
1360  LINX_ (__NR_readlinkat, sys_readlinkat),	// 298
1361  LINX_ (__NR_fchmodat, sys_fchmodat),	// 299
1362  LINX_ (__NR_faccessat, sys_faccessat),	// 300
1363  LINXY (__NR_ppoll, sys_ppoll),	// 302
1364  LINX_ (__NR_set_robust_list, sys_set_robust_list),	// 309
1365  LINXY (__NR_get_robust_list, sys_get_robust_list),	// 310
1366  LINXY (__NR_epoll_pwait, sys_epoll_pwait),	// 313
1367  LINX_ (__NR_utimensat, sys_utimensat),	// 316
1368  LINX_ (__NR_fallocate, sys_fallocate),	// 320
1369  LINXY (__NR_timerfd_create, sys_timerfd_create),    // 321
1370  LINXY (__NR_timerfd_gettime, sys_timerfd_gettime),  // 322
1371  LINXY (__NR_timerfd_settime, sys_timerfd_settime),  // 323
1372  LINXY (__NR_signalfd4, sys_signalfd4),	// 324
1373  LINX_ (__NR_eventfd2, sys_eventfd2),	// 325
1374  LINXY (__NR_pipe2, sys_pipe2),	// 328
1375  LINXY (__NR_inotify_init1, sys_inotify_init1),	// 329
1376  LINXY (__NR_prlimit64, sys_prlimit64) // 338
1377};
1378
1379SyscallTableEntry* ML_(get_linux_syscall_entry) (UInt sysno)
1380{
1381  const UInt syscall_main_table_size
1382   = sizeof (syscall_main_table) / sizeof (syscall_main_table[0]);
1383  /* Is it in the contiguous initial section of the table? */
1384  if (sysno < syscall_main_table_size)
1385    {
1386      SyscallTableEntry * sys = &syscall_main_table[sysno];
1387      if (sys->before == NULL)
1388        return NULL;    /* no entry */
1389      else
1390        return sys;
1391    }
1392  /* Can't find a wrapper */
1393  return NULL;
1394}
1395
1396#endif // defined(VGP_mips32_linux)
1397
1398/*--------------------------------------------------------------------*/
1399/*--- end                                     syswrap-mips-linux.c ---*/
1400/*--------------------------------------------------------------------*/
1401