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))
81 void 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
87 asm (
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
148 UInt 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
155 asm (
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
223 static void setup_child (ThreadArchState *, ThreadArchState *);
224 static SysRes sys_set_tls (ThreadId tid, Addr tlsptr);
225 static 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
do_clone(ThreadId ptid,UInt flags,Addr sp,Int * parent_tidptr,Int * child_tidptr,Addr child_tls)237 static 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 ????!!!!???
331 void
VG_(cleanup_thread)332 VG_ (cleanup_thread) (ThreadArchState * arch) { }
333
334 void
setup_child(ThreadArchState * child,ThreadArchState * parent)335 setup_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
sys_set_tls(ThreadId tid,Addr tlsptr)344 SysRes 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 ------------------------------------------------------------------ */
notify_core_of_mmap(Addr a,SizeT len,UInt prot,UInt flags,Int fd,Off64T offset)353 static 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
notify_tool_of_mmap(Addr a,SizeT len,UInt prot,ULong di_handle)370 static 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 */
mips_PRE_sys_mmap(ThreadId tid,UWord arg1,UWord arg2,UWord arg3,UWord arg4,UWord arg5,Off64T arg6)391 static 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);
517 DECL_TEMPLATE (mips_linux, sys_mmap);
518 DECL_TEMPLATE (mips_linux, sys_mmap2);
519 DECL_TEMPLATE (mips_linux, sys_stat64);
520 DECL_TEMPLATE (mips_linux, sys_lstat64);
521 DECL_TEMPLATE (mips_linux, sys_fstatat64);
522 DECL_TEMPLATE (mips_linux, sys_fstat64);
523 DECL_TEMPLATE (mips_linux, sys_clone);
524 DECL_TEMPLATE (mips_linux, sys_sigreturn);
525 DECL_TEMPLATE (mips_linux, sys_rt_sigreturn);
526 DECL_TEMPLATE (mips_linux, sys_cacheflush);
527 DECL_TEMPLATE (mips_linux, sys_set_thread_area);
528 DECL_TEMPLATE (mips_linux, sys_pipe);
529
PRE(sys_mmap2)530 PRE(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
PRE(sys_mmap)546 PRE(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
PRE(sys_lstat64)562 PRE (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
POST(sys_lstat64)570 POST (sys_lstat64)
571 {
572 vg_assert (SUCCESS);
573 if (RES == 0)
574 {
575 POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64));
576 }
577 }
578
PRE(sys_stat64)579 PRE (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
POST(sys_stat64)587 POST (sys_stat64)
588 {
589 POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64));
590 }
591
PRE(sys_fstatat64)592 PRE (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
POST(sys_fstatat64)604 POST (sys_fstatat64)
605 {
606 POST_MEM_WRITE (ARG3, sizeof (struct vki_stat64));
607 }
608
PRE(sys_fstat64)609 PRE (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
POST(sys_fstat64)616 POST (sys_fstat64)
617 {
618 POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64));
619 }
620
PRE(sys_clone)621 PRE (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
PRE(sys_sigreturn)711 PRE (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
PRE(sys_rt_sigreturn)726 PRE (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
PRE(sys_set_thread_area)742 PRE (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 */
PRE(sys_cacheflush)750 PRE (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
PRE(sys_pipe)760 PRE(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
POST(sys_pipe)767 POST(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
805 static 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
ML_(get_linux_syscall_entry)1126 SyscallTableEntry* 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