1
2/*--------------------------------------------------------------------*/
3/*--- Platform-specific syscalls stuff.    syswrap-mips64-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_mips64_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 "config.h"
68
69#include <errno.h>
70
71/* ---------------------------------------------------------------------
72                             clone() handling
73   ------------------------------------------------------------------ */
74
75/* Call f(arg1), but first switch stacks, using 'stack' as the new stack, and
76   use 'retaddr' as f's return-to address. Also, clear all the integer registers
77   before entering f. */
78__attribute__ ((noreturn))
79void ML_(call_on_new_stack_0_1) ( Addr stack,             /* $4 - $a0 */
80                                  Addr retaddr,           /* $5 - $a1 */
81                                  void (*f_desc) (Word),  /* $6 - $a2 */
82                                  Word arg1 );            /* $7 - $a3 */
83asm (
84".text\n"
85".globl vgModuleLocal_call_on_new_stack_0_1\n"
86"vgModuleLocal_call_on_new_stack_0_1:\n"
87"   move $29, $4\n"  /* set stack */
88"   move $4,  $7\n"  /* arg1 to $4 */
89"   move $25, $6\n"
90"   move $31, $5\n"  /* retaddr to $ra */
91"   jr $25\n"        /* jump to f */
92"   break 0x7\n"     /* should never get here */
93".previous\n"
94);
95
96/* Perform a clone system call.  clone is strange because it has fork()-like
97   return-twice semantics, so it needs special handling here.
98
99   Upon entry, we have:
100
101      word (fn)(void*)    in a0 = 4
102      void* child_stack   in a1 = 5
103      word flags          in a2 = 6
104      void* arg           in a3 = 7
105      pid_t* parent_tid   in a4 = 8
106      void* tls           in a5 = 9
107      pid_t* child_tid    in a6 = 10
108
109   System call requires:
110
111      int    $__NR_clone  in v0
112      int    flags        in a0 = 4
113      void*  child_stack  in a1 = 5
114      pid_t* parent_tid   in a2 = 6
115      void*  tls_ptr      in a3 = 7
116      pid_t* child_tid    in a4 = 8 */
117
118#define __NR_CLONE        __NR_clone
119#define __NR_EXIT         __NR_exit
120
121ULong do_syscall_clone_mips64_linux ( Word (*fn) (void *),  /* a0 - 4 */
122                                      void* stack,          /* a1 - 5 */
123                                      Int   flags,          /* a2 - 6 */
124                                      void* arg,            /* a3 - 7 */
125                                      Int*  parent_tid,     /* a4 - 8 */
126                                      void* /* Int tls */,  /* a5 - 9 */
127                                      Int*  child_tid );    /* a6 - 10 */
128
129asm(
130".text\n"
131".set noreorder\n"
132".set nomacro\n"
133".globl do_syscall_clone_mips64_linux\n"
134"do_syscall_clone_mips64_linux:\n"
135"   daddiu $29, $29, -32\n"
136"   sd $31, 0($29)\n"
137"   sd $30, 8($29)\n"
138"   sd $28, 16($29)\n"
139
140"   daddiu  $5, $5, -32\n"
141"   sd $4, 0($5)\n"   /* fn */
142"   sd $7, 8($5)\n"   /* arg */
143"   sd $6, 16($5)\n"  /* flags */
144
145/* 1. arg for syscalls */
146"   move $4, $6\n"   /* flags */
147"   move $6, $8\n"   /* parent */
148"   move $7, $a5\n"  /* tls */
149"   move $8, $a6\n"  /* child */
150
151/* 2. do a syscall to clone */
152"   li  $2, 5055\n"  /* syscall num for clone */
153"   syscall\n"
154
155/* 3. See if we are a child, call fn and after that exit */
156"   bnez $7, p_or_error\n"
157"   nop\n"
158
159"   bnez $2, p_or_error\n"
160"   nop\n"
161
162"   ld $25,0($29)\n"
163"   jalr $25\n"
164"   ld $4,8($29)\n"
165
166"   move $4, $2\n\t"  /* retval from fn is in $v0 */
167"   li $2, 5058\n\t"  /* NR_exit */
168"   syscall\n\t"
169"   nop\n\t"
170/* 4. If we are parent or error, just return to caller */
171"   p_or_error:\n"
172"   ld $31, 0($29)\n"
173"   ld $30, 8($29)\n"
174"   ld $28, 16($29)\n"
175"   jr $31\n"
176"   daddi $29,$29, 32\n"
177".previous\n"
178);
179
180#undef __NR_CLONE
181#undef __NR_EXIT
182
183/* forward declarations */
184static void setup_child ( ThreadArchState *, ThreadArchState *);
185static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr);
186
187/* When a client clones, we need to keep track of the new thread. This means:
188   1. allocate a ThreadId+ThreadState+stack for the thread
189
190   2. initialize the thread's new VCPU state
191
192   3. create the thread using the same args as the client requested, but using
193      the scheduler entrypoint for IP, and a separate stack for SP. */
194static SysRes do_clone ( ThreadId ptid,
195                         UInt flags, Addr sp,
196                         Int* parent_tidptr,
197                         Int* child_tidptr,
198                         Addr child_tls )
199{
200   const Bool debug = False;
201   ThreadId ctid = VG_ (alloc_ThreadState) ();
202   ThreadState * ptst = VG_ (get_ThreadState) (ptid);
203   ThreadState * ctst = VG_ (get_ThreadState) (ctid);
204   UInt ret = 0;
205   UWord * stack;
206   SysRes res;
207   vki_sigset_t blockall, savedmask;
208
209   VG_(sigfillset)(&blockall);
210   vg_assert(VG_(is_running_thread)(ptid));
211   vg_assert(VG_(is_valid_tid)(ctid));
212   stack = (UWord *)ML_(allocstack)(ctid);
213   if (stack == NULL) {
214      res = VG_(mk_SysRes_Error)(VKI_ENOMEM);
215      goto out;
216   }
217   setup_child(&ctst->arch, &ptst->arch);
218
219   /* on MIPS we need to set V0 and A3 to zero */
220   ctst->arch.vex.guest_r2 = 0;
221   ctst->arch.vex.guest_r7 = 0;
222   if (sp != 0)
223      ctst->arch.vex.guest_r29 = sp;
224
225   ctst->os_state.parent = ptid;
226   ctst->sig_mask = ptst->sig_mask;
227   ctst->tmp_sig_mask = ptst->sig_mask;
228
229   ctst->os_state.threadgroup = ptst->os_state.threadgroup;
230
231   ML_(guess_and_register_stack) (sp, ctst);
232
233   VG_TRACK(pre_thread_ll_create, ptid, ctid);
234   if (flags & VKI_CLONE_SETTLS) {
235       if (debug)
236         VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls);
237       res = sys_set_tls(ctid, child_tls);
238       if (sr_isError(res))
239          goto out;
240       ctst->arch.vex.guest_r27 = child_tls;
241   }
242
243   flags &= ~VKI_CLONE_SETTLS;
244   VG_ (sigprocmask) (VKI_SIG_SETMASK, &blockall, &savedmask);
245   /* Create the new thread */
246   ret = do_syscall_clone_mips64_linux(ML_(start_thread_NORETURN),
247                                       stack, flags, &VG_(threads)[ctid],
248                                       parent_tidptr, NULL /*child_tls*/,
249                                       child_tidptr);
250   if (debug)
251     VG_(printf)("ret: 0x%x\n", ret);
252
253   res = VG_(mk_SysRes_mips64_linux)( /* val */ ret, 0, /* errflag */ 0);
254
255   VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
256
257   out:
258   if (sr_isError (res)) {
259      VG_ (cleanup_thread) (&ctst->arch);
260      ctst->status = VgTs_Empty;
261      VG_TRACK (pre_thread_ll_exit, ctid);
262   }
263   ptst->arch.vex.guest_r2 = 0;
264
265   return res;
266}
267
268/* ---------------------------------------------------------------------
269                          More thread stuff
270   ------------------------------------------------------------------ */
271void VG_(cleanup_thread) ( ThreadArchState * arch ) { };
272
273void setup_child ( /* OUT */ ThreadArchState * child,
274                   /* IN  */ ThreadArchState * parent )
275{
276   /* We inherit our parent's guest state. */
277   child->vex = parent->vex;
278   child->vex_shadow1 = parent->vex_shadow1;
279   child->vex_shadow2 = parent->vex_shadow2;
280}
281
282SysRes sys_set_tls ( ThreadId tid, Addr tlsptr )
283{
284   VG_(threads)[tid].arch.vex.guest_ULR = tlsptr;
285   return VG_(mk_SysRes_Success)( 0 );
286}
287
288/* ---------------------------------------------------------------------
289           PRE/POST wrappers for mips/Linux-specific syscalls
290   ------------------------------------------------------------------ */
291
292#define PRE(name)       DEFN_PRE_TEMPLATE(mips_linux, name)
293#define POST(name)      DEFN_POST_TEMPLATE(mips_linux, name)
294
295/* Add prototypes for the wrappers declared here, so that gcc doesn't harass us
296   for not having prototypes. Really this is a kludge -- the right thing to do
297   is to make these wrappers 'static' since they aren't visible outside this
298   file, but that requires even more macro magic. */
299
300DECL_TEMPLATE (mips_linux, sys_set_thread_area);
301DECL_TEMPLATE (mips_linux, sys_clone);
302DECL_TEMPLATE (mips_linux, sys_tee);
303DECL_TEMPLATE (mips_linux, sys_splice);
304DECL_TEMPLATE (mips_linux, sys_vmsplice);
305DECL_TEMPLATE (mips_linux, sys_ustat);
306DECL_TEMPLATE (mips_linux, sys_sysfs);
307DECL_TEMPLATE (mips_linux, sys_swapon);
308DECL_TEMPLATE (mips_linux, sys_swapoff);
309DECL_TEMPLATE (mips_linux, sys_setdomainname);
310DECL_TEMPLATE (mips_linux, sys_sethostname);
311DECL_TEMPLATE (mips_linux, sys_reboot);
312DECL_TEMPLATE (mips_linux, sys_cacheflush);
313DECL_TEMPLATE (mips_linux, sys_sched_rr_get_interval);
314DECL_TEMPLATE (mips_linux, sys_unshare);
315DECL_TEMPLATE (mips_linux, sys_arch_prctl);
316DECL_TEMPLATE (mips_linux, sys_ptrace);
317DECL_TEMPLATE (mips_linux, sys_mmap);
318DECL_TEMPLATE (mips_linux, sys_rt_sigreturn);
319DECL_TEMPLATE (mips_linux, sys_pipe);
320
321PRE(sys_tee)
322{
323   PRINT("sys_tee ( %ld, %ld, %lu, %#lx )", SARG1, SARG2, ARG3, ARG4);
324   PRE_REG_READ4(long, "sys_tee", int, fdin, int, fdout, vki_size_t, len,
325                 int, flags);
326}
327
328PRE(sys_splice)
329{
330   PRINT("sys_splice ( %ld, %#lx, %ld, %#lx, %lu, %#lx )",
331         SARG1, ARG2, SARG3, ARG4, ARG5, ARG6);
332
333   PRE_REG_READ6(long, "sys_splice", int, fdin, vki_loff_t, sizein, int,
334                 fdout, vki_loff_t, sizeout, vki_size_t, len, int, flags);
335}
336
337PRE(sys_vmsplice)
338{
339   PRINT("sys_vmsplice ( %ld, %#lx, %lu, %ld )", SARG1, ARG2, ARG3, SARG4);
340   PRE_REG_READ4(long, "sys_vmsplice", int, fdin, struct vki_iovec *, v,
341                 vki_size_t, len, int, flags);
342}
343
344PRE(sys_unshare)
345{
346   PRINT("sys_unshare ( %lu )", ARG1);
347   PRE_REG_READ1(long, "sys_unshare", unsigned long, flags);
348}
349
350PRE(sys_sched_rr_get_interval)
351{
352   PRINT("sys_sched_rr_get_interval ( %ld, %#lx)", SARG1, ARG2);
353   PRE_REG_READ2(long, "sched_rr_get_interval", vki_pid_t, pid,
354                 struct timespec *, timer);
355   *flags |= SfMayBlock;
356}
357
358PRE(sys_ustat)
359{
360   PRINT("sys_ustat ( %#lx, %#lx)", ARG1, ARG2);
361   PRE_REG_READ2(long, "ustat", int, flags, const void *, path);
362}
363
364PRE(sys_swapon)
365{
366   PRINT("sys_swapon ( %#lx, %#lx )", ARG1, ARG2);
367   PRE_REG_READ2(long, "swapon", const void *, path, int, flags);
368}
369
370PRE(sys_swapoff)
371{
372   PRINT("sys_swapoff ( %#lx )", ARG1);
373   PRE_REG_READ1(long, "swapoff", const void *, path);
374}
375
376PRE(sys_sysfs)
377{
378   PRINT("sys_sysfs ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
379   PRE_REG_READ3(long, "sysfs", int, flags, int, desc, const void *, path);
380}
381
382/* Very much MIPS specific */
383PRE(sys_cacheflush)
384{
385   PRINT("cacheflush (%lx, %lx, %lx)", ARG1, ARG2, ARG3);
386   PRE_REG_READ3(long, "cacheflush", unsigned long, addr,
387                 unsigned long, nbytes, unsigned int, cache);
388   VG_ (discard_translations) ((Addr)ARG1, (ULong) ARG2,
389                               "PRE(sys_cacheflush)");
390   SET_STATUS_Success(0);
391}
392
393PRE(sys_reboot)
394{
395   PRINT("sys_reboot ( %ld, %ld, %lu, %#lx )", SARG1, ARG2, ARG3, ARG4);
396   // An approximation. ARG4 is only read conditionally by the kernel
397   PRE_REG_READ4(int, "reboot",
398                 int, magic1, int, magic2, unsigned int, cmd,
399                 void *, arg);
400
401   *flags |= SfMayBlock;
402}
403
404PRE(sys_setdomainname)
405{
406   PRINT ("sys_setdomainname ( %#lx, %ld )", ARG1, SARG2);
407   PRE_REG_READ2 (long, "setdomainname", const void *, name, int, len);
408}
409
410PRE(sys_sethostname)
411{
412   PRINT ("sys_sethostname ( %#lx, %ld )", ARG1, SARG2);
413   PRE_REG_READ2 (long, "sethostname", const void *, name, int, len);
414}
415
416PRE(sys_ptrace)
417{
418   PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", SARG1, SARG2, ARG3, ARG4);
419   PRE_REG_READ4(int, "ptrace",
420                 long, request, long, pid, unsigned long, addr,
421                 unsigned long, data);
422   switch (ARG1) {
423      case VKI_PTRACE_PEEKTEXT:
424      case VKI_PTRACE_PEEKDATA:
425      case VKI_PTRACE_PEEKUSR:
426         PRE_MEM_WRITE("ptrace(peek)", ARG4, sizeof(long));
427         break;
428      case VKI_PTRACE_GETEVENTMSG:
429         PRE_MEM_WRITE("ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
430         break;
431      case VKI_PTRACE_GETSIGINFO:
432         PRE_MEM_WRITE("ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
433         break;
434      case VKI_PTRACE_SETSIGINFO:
435         PRE_MEM_READ("ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
436         break;
437      case VKI_PTRACE_GETREGSET:
438         ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
439         break;
440      default:
441        break;
442   }
443}
444
445POST(sys_ptrace)
446{
447   switch (ARG1) {
448      case VKI_PTRACE_PEEKTEXT:
449      case VKI_PTRACE_PEEKDATA:
450      case VKI_PTRACE_PEEKUSR:
451         POST_MEM_WRITE (ARG4, sizeof(long));
452         break;
453      case VKI_PTRACE_GETEVENTMSG:
454         POST_MEM_WRITE (ARG4, sizeof(unsigned long));
455      break;
456      case VKI_PTRACE_GETSIGINFO:
457         POST_MEM_WRITE (ARG4, sizeof(vki_siginfo_t));
458         break;
459      case VKI_PTRACE_GETREGSET:
460         ML_(linux_POST_getregset)(tid, ARG3, ARG4);
461         break;
462      default:
463      break;
464   }
465}
466
467PRE (sys_mmap)
468{
469   SysRes r;
470   PRINT("sys_mmap ( %#lx, %lu, %ld, %ld, %ld, %lu )",
471         ARG1, ARG2, SARG3, SARG4, SARG5, ARG6);
472   PRE_REG_READ6(long, "mmap", unsigned long, start, vki_size_t, length,
473                 int, prot, int, flags, int, fd, unsigned long, offset);
474   r = ML_(generic_PRE_sys_mmap)(tid, ARG1, ARG2, ARG3, ARG4, ARG5,
475                                 (Off64T) ARG6);
476   SET_STATUS_from_SysRes(r);
477}
478
479PRE(sys_clone)
480{
481   Bool badarg = False;
482   UInt cloneflags;
483   PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )", ARG1, ARG2, ARG3,
484                                                      ARG4, ARG5);
485   PRE_REG_READ2(int, "clone", unsigned long, flags, void *, child_stack);
486   if (ARG1 & VKI_CLONE_PARENT_SETTID) {
487      if (VG_(tdict).track_pre_reg_read) {
488         PRA3("clone", int *, parent_tidptr);
489      }
490      PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
491      if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), VKI_PROT_WRITE)) {
492         badarg = True;
493      }
494   }
495   if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
496      if (VG_(tdict).track_pre_reg_read) {
497         PRA5("clone", int *, child_tidptr);
498      }
499      PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof (Int));
500      if (!VG_(am_is_valid_for_client)(ARG5, sizeof (Int), VKI_PROT_WRITE))
501         badarg = True;
502   }
503   if (badarg) {
504      SET_STATUS_Failure(VKI_EFAULT);
505      return;
506   }
507   cloneflags = ARG1;
508   if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
509      SET_STATUS_Failure(VKI_EINVAL);
510      return;
511   }
512   /* Only look at the flags we really care about */
513   switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
514           |VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
515      case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
516         /* thread creation */
517         SET_STATUS_from_SysRes(do_clone(tid,
518                                         ARG1,          /* flags */
519                                         (Addr)ARG2,    /* child SP */
520                                         (Int *)ARG3,   /* parent_tidptr */
521                                         (Int *)ARG5,   /* child_tidptr */
522                                         (Addr)ARG4));  /* child_tls */
523         break;
524
525      case VKI_CLONE_VFORK | VKI_CLONE_VM:  /* vfork */
526         /* FALLTHROUGH - assume vfork == fork */
527         cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
528      case 0:  /* plain fork */
529         SET_STATUS_from_SysRes(ML_(do_fork_clone)(tid,
530                                cloneflags,     /* flags */
531                                (Int *)ARG3,    /* parent_tidptr */
532                                (Int *)ARG5));  /* child_tidptr */
533         break;
534
535      default:
536         /* should we just ENOSYS? */
537         VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
538         VG_(message)(Vg_UserMsg, "\n");
539         VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
540         VG_(message)(Vg_UserMsg,
541                       " - via a threads library (LinuxThreads or NPTL)\n");
542         VG_(message)(Vg_UserMsg,
543                       " - via the implementation of fork or vfork\n");
544         VG_(unimplemented)("Valgrind does not support general clone().");
545   }
546   if (SUCCESS) {
547      if (ARG1 & VKI_CLONE_PARENT_SETTID)
548         POST_MEM_WRITE(ARG3, sizeof(Int));
549      if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
550         POST_MEM_WRITE(ARG5, sizeof(Int));
551      /* Thread creation was successful; let the child have the chance to run */
552      *flags |= SfYieldAfter;
553   }
554}
555
556PRE(sys_rt_sigreturn)
557{
558   /* See comments on PRE(sys_rt_sigreturn) in syswrap-s390x-linux.c for
559      an explanation of what follows. */
560   ThreadState* tst;
561   PRINT("sys_rt_sigreturn ( )");
562
563   vg_assert(VG_(is_valid_tid)(tid));
564   vg_assert(tid >= 1 && tid < VG_N_THREADS);
565   vg_assert(VG_(is_running_thread)(tid));
566
567   tst = VG_(get_ThreadState)(tid);
568
569   /* This is only so that the IA is (might be) useful to report if
570      something goes wrong in the sigreturn */
571   ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
572
573   /* Restore register state from frame and remove it */
574   VG_(sigframe_destroy)(tid, True);
575
576   /* Tell the driver not to update the guest state with the "result",
577      and set a bogus result to keep it happy. */
578   *flags |= SfNoWriteResult;
579   SET_STATUS_Success(0);
580
581   /* Check to see if any signals arose as a result of this. */
582   *flags |= SfPollAfter;
583}
584
585PRE(sys_set_thread_area)
586{
587   PRINT("set_thread_area (%lx)", ARG1);
588   PRE_REG_READ1(long, "set_thread_area", unsigned long, addr);
589   SET_STATUS_from_SysRes(sys_set_tls(tid, ARG1));
590}
591
592PRE(sys_pipe)
593{
594   PRINT("sys_pipe ( %#lx )", ARG1);
595   PRE_REG_READ1(int, "pipe", int *, filedes);
596   PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
597}
598
599POST(sys_pipe)
600{
601   Int p0, p1;
602   vg_assert(SUCCESS);
603   p0 = RES;
604   p1 = sr_ResEx(status->sres);
605
606   if (!ML_(fd_allowed)(p0, "pipe", tid, True) ||
607       !ML_(fd_allowed)(p1, "pipe", tid, True)) {
608      VG_(close)(p0);
609      VG_(close)(p1);
610      SET_STATUS_Failure( VKI_EMFILE );
611   } else {
612      if (VG_(clo_track_fds)) {
613         ML_(record_fd_open_nameless)(tid, p0);
614         ML_(record_fd_open_nameless)(tid, p1);
615      }
616   }
617}
618
619#undef PRE
620#undef POST
621
622/* ---------------------------------------------------------------------
623   The mips64/Linux syscall table
624   ------------------------------------------------------------------ */
625
626/* Add an mips64-linux specific wrapper to a syscall table. */
627#define PLAX_(sysno, name)    WRAPPER_ENTRY_X_(mips_linux, sysno, name)
628#define PLAXY(sysno, name)    WRAPPER_ENTRY_XY(mips_linux, sysno, name)
629
630static SyscallTableEntry syscall_main_table[] = {
631   GENXY (__NR_read, sys_read),  /* 5000 */
632   GENX_ (__NR_write, sys_write),
633   GENXY (__NR_open, sys_open),
634   GENXY (__NR_close, sys_close),
635   GENXY (__NR_stat, sys_newstat),
636   GENXY (__NR_fstat, sys_newfstat),
637   GENXY (__NR_lstat, sys_newlstat),
638   GENXY (__NR_poll, sys_poll),
639   LINX_ (__NR_lseek, sys_lseek),
640   PLAX_ (__NR_mmap, sys_mmap),
641   GENXY (__NR_mprotect, sys_mprotect),
642   GENXY (__NR_munmap, sys_munmap),
643   GENX_ (__NR_brk, sys_brk),
644   LINXY (__NR_rt_sigaction, sys_rt_sigaction),
645   LINXY (__NR_rt_sigprocmask, sys_rt_sigprocmask),
646   LINXY (__NR_ioctl, sys_ioctl),
647   LINXY (__NR_eventfd2, sys_eventfd2),
648   LINXY (__NR_signalfd4, sys_signalfd4),
649   GENXY (__NR_pread64, sys_pread64),
650   GENX_ (__NR_pwrite64, sys_pwrite64),
651   GENXY (__NR_readv, sys_readv),
652   GENX_ (__NR_writev, sys_writev),
653   GENX_ (__NR_access, sys_access),
654   PLAXY (__NR_pipe, sys_pipe),
655   LINXY (__NR_pipe2, sys_pipe2),
656   GENX_ (__NR__newselect,sys_select),
657   LINX_ (__NR_sched_yield, sys_sched_yield),
658   GENX_ (__NR_mremap, sys_mremap),
659   GENX_ (__NR_msync, sys_msync),
660   GENXY (__NR_mincore, sys_mincore),
661   GENX_ (__NR_madvise, sys_madvise),
662   LINX_ (__NR_shmget, sys_shmget),
663   LINXY (__NR_shmat, wrap_sys_shmat),
664   LINXY (__NR_shmctl, sys_shmctl),
665   GENXY (__NR_dup, sys_dup),
666   GENXY (__NR_dup2, sys_dup2),
667   LINXY (__NR_dup3, sys_dup3),
668   GENX_ (__NR_pause, sys_pause),
669   GENXY (__NR_nanosleep, sys_nanosleep),
670   GENXY (__NR_getitimer, sys_getitimer),
671   GENXY (__NR_setitimer, sys_setitimer),
672   GENX_ (__NR_alarm, sys_alarm),
673   GENX_ (__NR_getpid, sys_getpid),
674   /* LINX_(__NR_fallocate,sys_fallocate), */
675   LINXY (__NR_sendfile, sys_sendfile),
676   LINXY (__NR_socket, sys_socket),
677   LINX_ (__NR_connect, sys_connect),
678   LINXY (__NR_accept, sys_accept),
679   LINXY (__NR_accept4, sys_accept4),
680   LINX_ (__NR_sendto, sys_sendto),
681   LINXY (__NR_recvfrom, sys_recvfrom),
682   LINX_ (__NR_sendmsg, sys_sendmsg),
683   LINXY (__NR_recvmsg, sys_recvmsg),
684   LINX_ (__NR_shutdown, sys_shutdown),
685   LINX_ (__NR_bind, sys_bind),
686   LINX_ (__NR_listen, sys_listen),
687   LINXY (__NR_getsockname, sys_getsockname),
688   LINXY (__NR_getpeername, sys_getpeername),
689   LINXY (__NR_socketpair, sys_socketpair),
690   LINX_ (__NR_setsockopt, sys_setsockopt),
691   LINXY (__NR_getsockopt, sys_getsockopt),
692   PLAX_ (__NR_clone, sys_clone),
693   GENX_ (__NR_fork, sys_fork),
694   GENX_ (__NR_execve, sys_execve),
695   GENX_ (__NR_exit, sys_exit),
696   GENXY (__NR_wait4, sys_wait4),
697   GENX_ (__NR_kill, sys_kill),
698   GENXY (__NR_uname, sys_newuname),
699   LINX_ (__NR_semget, sys_semget),
700   LINX_ (__NR_semop, sys_semop),
701   LINXY (__NR_semctl, sys_semctl),
702   LINXY (__NR_shmdt, sys_shmdt),
703   LINX_ (__NR_msgget, sys_msgget),
704   LINX_ (__NR_msgsnd, sys_msgsnd),
705   LINXY (__NR_msgrcv, sys_msgrcv),
706   LINXY (__NR_msgctl, sys_msgctl),
707   LINXY (__NR_fcntl, sys_fcntl),
708   GENX_ (__NR_flock, sys_flock),
709   GENX_ (__NR_fsync, sys_fsync),
710   GENX_ (__NR_fdatasync, sys_fdatasync),
711   GENX_ (__NR_truncate, sys_truncate),
712   GENX_ (__NR_ftruncate, sys_ftruncate),
713   GENXY (__NR_getdents, sys_getdents),
714   GENXY (__NR_getcwd, sys_getcwd),
715   GENX_ (__NR_chdir, sys_chdir),
716   GENX_ (__NR_fchdir, sys_fchdir),
717   GENX_ (__NR_rename, sys_rename),
718   GENX_ (__NR_mkdir, sys_mkdir),
719   GENX_ (__NR_rmdir, sys_rmdir),
720   GENXY (__NR_creat, sys_creat),
721   GENX_ (__NR_link, sys_link),
722   GENX_ (__NR_unlink, sys_unlink),
723   GENX_ (__NR_symlink, sys_symlink),
724   GENX_ (__NR_readlink, sys_readlink),
725   GENX_ (__NR_chmod, sys_chmod),
726   GENX_ (__NR_fchmod, sys_fchmod),
727   GENX_ (__NR_chown, sys_chown),
728   GENX_ (__NR_fchown, sys_fchown),
729   GENX_ (__NR_lchown, sys_lchown),
730   GENX_ (__NR_umask, sys_umask),
731   GENXY (__NR_gettimeofday, sys_gettimeofday),
732   GENXY (__NR_getrlimit, sys_getrlimit),
733   GENXY (__NR_getrusage, sys_getrusage),
734   LINXY (__NR_sysinfo, sys_sysinfo),
735   GENXY (__NR_times, sys_times),
736   PLAXY (__NR_ptrace, sys_ptrace),
737   GENX_ (__NR_getuid, sys_getuid),
738   LINXY (__NR_syslog, sys_syslog),
739   GENX_ (__NR_getgid, sys_getgid),
740   GENX_ (__NR_setuid, sys_setuid),
741   GENX_ (__NR_setgid, sys_setgid),
742   GENX_ (__NR_geteuid, sys_geteuid),
743   GENX_ (__NR_getegid, sys_getegid),
744   GENX_ (__NR_setpgid, sys_setpgid),
745   GENX_ (__NR_getppid, sys_getppid),
746   GENX_ (__NR_getpgrp, sys_getpgrp),
747   GENX_ (__NR_setsid, sys_setsid),
748   GENX_ (__NR_setreuid, sys_setreuid),
749   GENX_ (__NR_setregid, sys_setregid),
750   GENXY (__NR_getgroups, sys_getgroups),
751   GENX_ (__NR_setgroups, sys_setgroups),
752   LINX_ (__NR_setresuid, sys_setresuid),
753   LINXY (__NR_getresuid, sys_getresuid),
754   LINX_ (__NR_setresgid, sys_setresgid),
755   LINXY (__NR_getresgid, sys_getresgid),
756   GENX_ (__NR_getpgid, sys_getpgid),
757   LINX_ (__NR_setfsuid, sys_setfsuid),
758   LINX_ (__NR_setfsgid, sys_setfsgid),
759   GENX_ (__NR_getsid, sys_getsid),
760   LINXY (__NR_capget, sys_capget),
761   LINX_ (__NR_capset, sys_capset),
762   LINXY (__NR_rt_sigpending, sys_rt_sigpending),
763   LINXY (__NR_rt_sigtimedwait, sys_rt_sigtimedwait),
764   LINXY (__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo),
765   LINX_ (__NR_rt_sigsuspend, sys_rt_sigsuspend),
766   GENXY (__NR_sigaltstack, sys_sigaltstack),
767   LINX_ (__NR_utime, sys_utime),
768   GENX_ (__NR_mknod, sys_mknod),
769   LINX_ (__NR_personality, sys_personality),
770   PLAX_ (__NR_ustat, sys_ustat),
771   GENXY (__NR_statfs, sys_statfs),
772   GENXY (__NR_fstatfs, sys_fstatfs),
773   PLAX_ (__NR_sysfs, sys_sysfs),
774   GENX_ (__NR_getpriority, sys_getpriority),
775   GENX_ (__NR_setpriority, sys_setpriority),
776   LINXY (__NR_sched_setparam, sys_sched_setparam),
777   LINXY (__NR_sched_getparam, sys_sched_getparam),
778   LINX_ (__NR_sched_setscheduler, sys_sched_setscheduler),
779   LINX_ (__NR_sched_getscheduler, sys_sched_getscheduler),
780   LINX_ (__NR_sched_get_priority_max, sys_sched_get_priority_max),
781   LINX_ (__NR_sched_get_priority_min, sys_sched_get_priority_min),
782   PLAX_ (__NR_sched_rr_get_interval, sys_sched_rr_get_interval),
783   GENX_ (__NR_mlock, sys_mlock),
784   GENX_ (__NR_munlock, sys_munlock),
785   GENX_ (__NR_mlockall, sys_mlockall),
786   LINX_ (__NR_munlockall, sys_munlockall),
787   LINX_ (__NR_vhangup, sys_vhangup),
788   LINX_ (__NR_pivot_root,sys_pivot_root),
789   LINXY (__NR__sysctl, sys_sysctl),
790   LINXY (__NR_prctl, sys_prctl),
791   LINXY (__NR_adjtimex, sys_adjtimex),
792   GENX_ (__NR_setrlimit, sys_setrlimit),
793   GENX_ (__NR_chroot, sys_chroot),
794   GENX_ (__NR_sync, sys_sync),
795   GENX_ (__NR_acct, sys_acct),
796   GENX_ (__NR_settimeofday, sys_settimeofday),
797   LINX_ (__NR_mount, sys_mount),
798   LINX_ (__NR_umount2, sys_umount),
799   PLAX_ (__NR_swapon, sys_swapon),
800   PLAX_ (__NR_swapoff, sys_swapoff),
801   PLAX_ (__NR_reboot, sys_reboot),
802   PLAX_ (__NR_sethostname, sys_sethostname),
803   PLAX_ (__NR_setdomainname, sys_setdomainname),
804   GENX_ (__NR_create_module, sys_ni_syscall),
805   LINX_ (__NR_init_module, sys_init_module),
806   LINX_ (__NR_delete_module, sys_delete_module),
807   GENX_ (__NR_get_kernel_syms, sys_ni_syscall),
808   GENX_ (__NR_query_module, sys_ni_syscall),
809   LINX_ (__NR_quotactl, sys_quotactl),
810   /* GENX_(__NR_nfsservctl,sys_nfsservctl), */
811   GENXY (__NR_getpmsg, sys_getpmsg),
812   GENX_ (__NR_putpmsg, sys_putpmsg),
813   GENX_ (__NR_afs_syscall, sys_ni_syscall),
814   /* GENX_(__NR_reserved177,sys_reserved177), */
815   LINX_ (__NR_gettid, sys_gettid),
816   /* GENX_(__NR_readahead,sys_readahead), */
817   LINX_ (__NR_setxattr, sys_setxattr),
818   LINX_ (__NR_lsetxattr, sys_lsetxattr),
819   LINX_ (__NR_fsetxattr, sys_fsetxattr),
820   LINXY (__NR_getxattr, sys_getxattr),
821   LINXY (__NR_lgetxattr, sys_lgetxattr),
822   LINXY (__NR_fgetxattr, sys_fgetxattr),
823   LINXY (__NR_listxattr, sys_listxattr),
824   LINXY (__NR_llistxattr, sys_llistxattr),
825   LINXY (__NR_flistxattr, sys_flistxattr),
826   LINX_ (__NR_removexattr, sys_removexattr),
827   LINX_ (__NR_lremovexattr, sys_lremovexattr),
828   LINX_ (__NR_fremovexattr, sys_fremovexattr),
829   LINXY (__NR_tkill, sys_tkill),
830   /* GENX_(__NR_reserved193,sys_reserved193), */
831   LINXY (__NR_futex, sys_futex),
832   LINX_ (__NR_sched_setaffinity, sys_sched_setaffinity),
833   LINXY (__NR_sched_getaffinity, sys_sched_getaffinity),
834   PLAX_ (__NR_cacheflush, sys_cacheflush),
835   LINXY (__NR_io_setup, sys_io_setup),
836   LINX_ (__NR_io_destroy, sys_io_destroy),
837   LINXY (__NR_io_getevents, sys_io_getevents),
838   LINX_ (__NR_io_submit, sys_io_submit),
839   LINXY (__NR_io_cancel, sys_io_cancel),
840   LINX_ (__NR_exit_group, sys_exit_group),
841   /* LINXY (__NR_lookup_dcookie, sys_lookup_dcookie), */
842   LINXY (__NR_epoll_create, sys_epoll_create),
843   LINXY (__NR_epoll_create1, sys_epoll_create1),
844   LINX_ (__NR_epoll_ctl, sys_epoll_ctl),
845   LINXY (__NR_epoll_wait, sys_epoll_wait),
846   PLAX_(__NR_rt_sigreturn,sys_rt_sigreturn),
847   /* LINXY(__NR_fcntl64,sys_fcntl64), */
848   LINX_ (__NR_set_tid_address, sys_set_tid_address),
849   LINX_ (__NR_semtimedop, sys_semtimedop),
850   LINX_ (__NR_fadvise64, sys_fadvise64),
851   LINXY (__NR_timer_create, sys_timer_create),
852   LINXY (__NR_timer_settime, sys_timer_settime),
853   LINXY (__NR_timer_gettime, sys_timer_gettime),
854   LINX_ (__NR_timer_getoverrun, sys_timer_getoverrun),
855   LINX_ (__NR_timer_delete, sys_timer_delete),
856   LINX_ (__NR_clock_settime, sys_clock_settime),
857   LINXY (__NR_clock_gettime, sys_clock_gettime),
858   LINXY (__NR_clock_getres, sys_clock_getres),
859   LINXY (__NR_clock_nanosleep, sys_clock_nanosleep),
860   LINX_ (__NR_tgkill, sys_tgkill),
861   GENX_ (__NR_utimes, sys_utimes),
862   LINX_ (__NR_mbind, sys_mbind),
863   LINXY (__NR_get_mempolicy, sys_get_mempolicy),
864   LINX_ (__NR_set_mempolicy, sys_set_mempolicy),
865   LINXY (__NR_mq_open, sys_mq_open),
866   LINX_ (__NR_mq_unlink, sys_mq_unlink),
867   LINX_ (__NR_mq_timedsend, sys_mq_timedsend),
868   LINXY (__NR_mq_timedreceive, sys_mq_timedreceive),
869   LINX_ (__NR_mq_notify, sys_mq_notify),
870   LINXY (__NR_mq_getsetattr, sys_mq_getsetattr),
871   GENX_ (__NR_vserver, sys_ni_syscall),
872   LINXY (__NR_waitid, sys_waitid),
873   LINX_ (__NR_add_key, sys_add_key),
874   LINX_ (__NR_request_key, sys_request_key),
875   LINXY (__NR_keyctl, sys_keyctl),
876   PLAX_ (__NR_set_thread_area, sys_set_thread_area),
877   LINX_ (__NR_inotify_init, sys_inotify_init),
878   LINX_ (__NR_inotify_add_watch, sys_inotify_add_watch),
879   LINX_ (__NR_inotify_rm_watch, sys_inotify_rm_watch),
880   LINXY (__NR_openat, sys_openat),
881   LINX_ (__NR_mkdirat, sys_mkdirat),
882   LINX_ (__NR_mknodat, sys_mknodat),
883   LINX_ (__NR_fchownat, sys_fchownat),
884   LINX_ (__NR_futimesat, sys_futimesat),
885   LINX_ (__NR_unlinkat, sys_unlinkat),
886   LINX_ (__NR_renameat, sys_renameat),
887   LINX_ (__NR_linkat, sys_linkat),
888   LINX_ (__NR_symlinkat, sys_symlinkat),
889   LINX_ (__NR_readlinkat, sys_readlinkat),
890   LINX_ (__NR_fchmodat, sys_fchmodat),
891   LINX_ (__NR_faccessat, sys_faccessat),
892   LINX_ (__NR_pselect6, sys_pselect6),
893   LINXY (__NR_ppoll, sys_ppoll),
894   PLAX_ (__NR_unshare, sys_unshare),
895   PLAX_ (__NR_splice, sys_splice),
896   LINX_ (__NR_sync_file_range, sys_sync_file_range),
897   PLAX_ (__NR_tee, sys_tee),
898   PLAX_ (__NR_vmsplice, sys_vmsplice),
899   LINX_ (__NR_set_robust_list, sys_set_robust_list),
900   LINXY (__NR_get_robust_list, sys_get_robust_list),
901   LINXY (__NR_epoll_pwait, sys_epoll_pwait),
902   LINX_ (__NR_ioprio_set, sys_ioprio_set),
903   LINX_ (__NR_ioprio_get, sys_ioprio_get),
904   LINX_ (__NR_utimensat, sys_utimensat),
905   LINXY (__NR_signalfd, sys_signalfd),
906   LINXY (__NR_eventfd, sys_eventfd),
907   LINX_ (__NR_fallocate, sys_fallocate),
908   LINXY (__NR_timerfd_create, sys_timerfd_create),
909   LINXY (__NR_timerfd_gettime, sys_timerfd_gettime),
910   LINXY (__NR_timerfd_settime, sys_timerfd_settime),
911   LINXY (__NR_newfstatat, sys_newfstatat),
912   LINXY (__NR_prlimit64, sys_prlimit64),
913   LINXY (__NR_clock_adjtime, sys_clock_adjtime),
914   LINXY (__NR_process_vm_readv, sys_process_vm_readv),
915   LINX_ (__NR_process_vm_writev, sys_process_vm_writev),
916   LINXY(__NR_getrandom, sys_getrandom),
917   LINXY(__NR_memfd_create, sys_memfd_create),
918   LINX_(__NR_syncfs, sys_syncfs)
919};
920
921SyscallTableEntry * ML_(get_linux_syscall_entry) ( UInt sysno )
922{
923   const UInt syscall_main_table_size
924      = sizeof(syscall_main_table) / sizeof(syscall_main_table[0]);
925
926   if (sysno < syscall_main_table_size) {
927      SyscallTableEntry * sys = &syscall_main_table[sysno];
928      if (sys->before == NULL)
929         return NULL;  /* no entry */
930      else
931         return sys;
932   }
933   /* Can't find a wrapper */
934   return NULL;
935}
936
937#endif  /* defined(VGP_mips64_linux) */
938
939/*--------------------------------------------------------------------*/
940/*--- end                                   syswrap-mips64-linux.c ---*/
941/*--------------------------------------------------------------------*/
942