1
2 /*--------------------------------------------------------------------*/
3 /*--- Platform-specific syscalls stuff. syswrap-mips32-linux.c ----*/
4 /*--------------------------------------------------------------------*/
5
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2010-2013 RT-RK
11 mips-valgrind@rt-rk.com
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29 */
30
31 #if defined(VGP_mips32_linux)
32 #include "pub_core_basics.h"
33 #include "pub_core_vki.h"
34 #include "pub_core_vkiscnums.h"
35 #include "pub_core_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 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, %llu, %ld, %ld, %ld, %ld )", ARG1, (ULong) ARG2,
537 ARG3, ARG4, ARG5, ARG6);
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, %llu, %lu, %lu, %lu, %ld )", ARG1, (ULong) ARG2,
550 ARG3, ARG4, ARG5, 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, (char *) 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, (char *) 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 PRINT ("sys_fstatat64 ( %ld, %#lx(%s), %#lx )", ARG1, ARG2, (char *) ARG2,
595 ARG3);
596 PRE_REG_READ3 (long, "fstatat64", int, dfd, char *, file_name,
597 struct stat64 *, buf);
598 PRE_MEM_RASCIIZ ("fstatat64(file_name)", ARG2);
599 PRE_MEM_WRITE ("fstatat64(buf)", ARG3, sizeof (struct vki_stat64));
600 }
601
POST(sys_fstatat64)602 POST (sys_fstatat64)
603 {
604 POST_MEM_WRITE (ARG3, sizeof (struct vki_stat64));
605 }
606
PRE(sys_fstat64)607 PRE (sys_fstat64)
608 {
609 PRINT ("sys_fstat64 ( %ld, %#lx )", ARG1, ARG2);
610 PRE_REG_READ2 (long, "fstat64", unsigned long, fd, struct stat64 *, buf);
611 PRE_MEM_WRITE ("fstat64(buf)", ARG2, sizeof (struct vki_stat64));
612 }
613
POST(sys_fstat64)614 POST (sys_fstat64)
615 {
616 POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64));
617 }
618
PRE(sys_clone)619 PRE (sys_clone)
620 {
621 Bool badarg = False;
622 UInt cloneflags;
623 PRINT ("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )", ARG1, ARG2, ARG3,
624 ARG4, ARG5);
625 PRE_REG_READ2 (int, "clone", unsigned long, flags, void *, child_stack);
626 if (ARG1 & VKI_CLONE_PARENT_SETTID)
627 {
628 if (VG_ (tdict).track_pre_reg_read)
629 {
630 PRA3 ("clone", int *, parent_tidptr);
631 }
632 PRE_MEM_WRITE ("clone(parent_tidptr)", ARG3, sizeof (Int));
633 if (!VG_ (am_is_valid_for_client)(ARG3, sizeof (Int), VKI_PROT_WRITE))
634 {
635 badarg = True;
636 }
637 }
638 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
639 {
640 if (VG_ (tdict).track_pre_reg_read)
641 {
642 PRA5 ("clone", int *, child_tidptr);
643 }
644 PRE_MEM_WRITE ("clone(child_tidptr)", ARG5, sizeof (Int));
645 if (!VG_ (am_is_valid_for_client)(ARG5, sizeof (Int), VKI_PROT_WRITE))
646 {
647 badarg = True;
648 }
649 }
650 if (badarg)
651 {
652 SET_STATUS_Failure (VKI_EFAULT);
653 return;
654 }
655 cloneflags = ARG1;
656 if (!ML_ (client_signal_OK) (ARG1 & VKI_CSIGNAL))
657 {
658 SET_STATUS_Failure (VKI_EINVAL);
659 return;
660 }
661 /* Only look at the flags we really care about */
662 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
663 |VKI_CLONE_FILES | VKI_CLONE_VFORK))
664 {
665 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
666 /* thread creation */
667 PRINT ("sys_clone1 ( %#lx, %#lx, %#lx, %#lx, %#lx )",
668 ARG1, ARG2, ARG3, ARG4, ARG5);
669 SET_STATUS_from_SysRes (do_clone (tid,
670 ARG1, /* flags */
671 (Addr) ARG2, /* child SP */
672 (Int *) ARG3, /* parent_tidptr */
673 (Int *) ARG5, /* child_tidptr */
674 (Addr) ARG4)); /* child_tls */
675
676 break;
677 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
678 /* FALLTHROUGH - assume vfork == fork */
679 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
680 case 0: /* plain fork */
681 SET_STATUS_from_SysRes (ML_ (do_fork_clone) (tid,
682 cloneflags, /* flags */
683 (Int *) ARG3, /* parent_tidptr */
684 (Int *) ARG5)); /* child_tidptr */
685 break;
686 default:
687 /* should we just ENOSYS? */
688 VG_ (message) (Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
689 VG_ (message) (Vg_UserMsg, "\n");
690 VG_ (message) (Vg_UserMsg, "The only supported clone() uses are:\n");
691 VG_ (message) (Vg_UserMsg,
692 " - via a threads library (LinuxThreads or NPTL)\n");
693 VG_ (message) (Vg_UserMsg,
694 " - via the implementation of fork or vfork\n");
695 VG_ (unimplemented)("Valgrind does not support general clone().");
696 }
697 if (SUCCESS)
698 {
699 if (ARG1 & VKI_CLONE_PARENT_SETTID)
700 POST_MEM_WRITE (ARG3, sizeof (Int));
701 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
702 POST_MEM_WRITE (ARG5, sizeof (Int));
703 /* Thread creation was successful; let the child have the chance
704 * to run */
705 *flags |= SfYieldAfter;
706 }
707 }
708
PRE(sys_sigreturn)709 PRE (sys_sigreturn)
710 {
711 PRINT ("sys_sigreturn ( )");
712 vg_assert (VG_ (is_valid_tid) (tid));
713 vg_assert (tid >= 1 && tid < VG_N_THREADS);
714 vg_assert (VG_ (is_running_thread) (tid));
715 VG_ (sigframe_destroy) (tid, False);
716 /* Tell the driver not to update the guest state with the "result",
717 and set a bogus result to keep it happy. */
718 *flags |= SfNoWriteResult;
719 SET_STATUS_Success (0);
720 /* Check to see if any signals arose as a result of this. */
721 *flags |= SfPollAfter;
722 }
723
PRE(sys_rt_sigreturn)724 PRE (sys_rt_sigreturn)
725 {
726 PRINT ("rt_sigreturn ( )");
727 vg_assert (VG_ (is_valid_tid) (tid));
728 vg_assert (tid >= 1 && tid < VG_N_THREADS);
729 vg_assert (VG_ (is_running_thread) (tid));
730 /* Restore register state from frame and remove it */
731 VG_ (sigframe_destroy) (tid, True);
732 /* Tell the driver not to update the guest state with the "result",
733 and set a bogus result to keep it happy. */
734 *flags |= SfNoWriteResult;
735 SET_STATUS_Success (0);
736 /* Check to see if any signals arose as a result of this. */
737 *flags |= SfPollAfter;
738 }
739
PRE(sys_set_thread_area)740 PRE (sys_set_thread_area)
741 {
742 PRINT ("set_thread_area (%lx)", ARG1);
743 PRE_REG_READ1(long, "set_thread_area", unsigned long, addr);
744 SET_STATUS_from_SysRes( sys_set_tls( tid, ARG1 ) );
745 }
746
747 /* Very much MIPS specific */
PRE(sys_cacheflush)748 PRE (sys_cacheflush)
749 {
750 PRINT ("cacheflush (%lx, %lx, %lx)", ARG1, ARG2, ARG3);
751 PRE_REG_READ3(long, "cacheflush", unsigned long, addr,
752 int, nbytes, int, cache);
753 VG_ (discard_translations) ((Addr)ARG1, (ULong) ARG2,
754 "PRE(sys_cacheflush)");
755 SET_STATUS_Success (0);
756 }
757
PRE(sys_pipe)758 PRE(sys_pipe)
759 {
760 PRINT("sys_pipe ( %#lx )", ARG1);
761 PRE_REG_READ1(int, "pipe", int *, filedes);
762 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
763 }
764
POST(sys_pipe)765 POST(sys_pipe)
766 {
767 Int p0, p1;
768 vg_assert(SUCCESS);
769 p0 = RES;
770 p1 = sr_ResEx(status->sres);
771
772 if (!ML_(fd_allowed)(p0, "pipe", tid, True) ||
773 !ML_(fd_allowed)(p1, "pipe", tid, True)) {
774 VG_(close)(p0);
775 VG_(close)(p1);
776 SET_STATUS_Failure( VKI_EMFILE );
777 } else {
778 if (VG_(clo_track_fds)) {
779 ML_(record_fd_open_nameless)(tid, p0);
780 ML_(record_fd_open_nameless)(tid, p1);
781 }
782 }
783 }
784
785 #undef PRE
786 #undef POST
787
788 /* ---------------------------------------------------------------------
789 The mips/Linux syscall table
790 ------------------------------------------------------------------ */
791 #define PLAX_(sysno, name) WRAPPER_ENTRY_X_(mips_linux, sysno, name)
792 #define PLAXY(sysno, name) WRAPPER_ENTRY_XY(mips_linux, sysno, name)
793
794 // This table maps from __NR_xxx syscall numbers (from
795 // linux/include/asm-mips/unistd.h) to the appropriate PRE/POST sys_foo()
796 // wrappers on mips (as per sys_call_table in linux/arch/mips/kernel/entry.S).
797 //
798
799 // For those syscalls not handled by Valgrind, the annotation indicate its
800 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
801 // (unknown).
802
803 static SyscallTableEntry syscall_main_table[] = {
804 //.. PLAXY (__NR_syscall, sys_syscall), // 0
805 GENX_ (__NR_exit, sys_exit), // 1
806 GENX_ (__NR_fork, sys_fork), // 2
807 GENXY (__NR_read, sys_read), // 3
808 GENX_ (__NR_write, sys_write), // 4
809 GENXY (__NR_open, sys_open), // 5
810 GENXY (__NR_close, sys_close), // 6
811 GENXY (__NR_waitpid, sys_waitpid), // 7
812 GENXY (__NR_creat, sys_creat), // 8
813 GENX_ (__NR_link, sys_link), // 9
814 GENX_ (__NR_unlink, sys_unlink), // 10
815 GENX_ (__NR_execve, sys_execve), // 11
816 GENX_ (__NR_chdir, sys_chdir), // 12
817 GENXY (__NR_time, sys_time), // 13
818 GENX_ (__NR_mknod, sys_mknod), // 14
819 GENX_ (__NR_chmod, sys_chmod), // 15
820 GENX_ (__NR_lchown, sys_lchown), // 16
821 //..
822 LINX_ (__NR_lseek, sys_lseek), // 19
823 GENX_ (__NR_getpid, sys_getpid), // 20
824 LINX_ (__NR_mount, sys_mount), // 21
825 LINX_ (__NR_umount, sys_oldumount), // 22
826 GENX_ (__NR_setuid, sys_setuid), // 23
827 GENX_ (__NR_getuid, sys_getuid), // 24
828 LINX_ (__NR_stime, sys_stime), // 25
829 //.. PLAXY(__NR_ptrace, sys_ptrace), // 26
830 GENX_ (__NR_alarm, sys_alarm), // 27
831 //.. // (__NR_oldfstat, sys_fstat), // 28
832 GENX_ (__NR_pause, sys_pause), // 29
833 LINX_ (__NR_utime, sys_utime), // 30
834 //.. GENX_(__NR_stty, sys_ni_syscall), // 31
835 //.. GENX_(__NR_gtty, sys_ni_syscall), // 32
836 GENX_ (__NR_access, sys_access), // 33
837 //.. GENX_(__NR_nice, sys_nice), // 34
838 //.. GENX_(__NR_ftime, sys_ni_syscall), // 35
839 //.. GENX_(__NR_sync, sys_sync), // 36
840 GENX_ (__NR_kill, sys_kill), // 37
841 GENX_ (__NR_rename, sys_rename), // 38
842 GENX_ (__NR_mkdir, sys_mkdir), // 39
843 GENX_ (__NR_rmdir, sys_rmdir), // 40
844 GENXY (__NR_dup, sys_dup), // 41
845 PLAXY (__NR_pipe, sys_pipe), // 42
846 GENXY (__NR_times, sys_times), // 43
847 //.. GENX_(__NR_prof, sys_ni_syscall), // 44
848 GENX_ (__NR_brk, sys_brk), // 45
849 GENX_ (__NR_setgid, sys_setgid), // 46
850 GENX_ (__NR_getgid, sys_getgid), // 47
851 //.. // (__NR_signal, sys_signal), // 48
852 GENX_ (__NR_geteuid, sys_geteuid), // 49
853 GENX_ (__NR_getegid, sys_getegid), // 50
854 //.. GENX_(__NR_acct, sys_acct), // 51
855 LINX_ (__NR_umount2, sys_umount), // 52
856 //.. GENX_(__NR_lock, sys_ni_syscall), // 53
857 LINXY (__NR_ioctl, sys_ioctl), // 54
858 LINXY (__NR_fcntl, sys_fcntl), // 55
859 //.. GENX_(__NR_mpx, sys_ni_syscall), // 56
860 GENX_ (__NR_setpgid, sys_setpgid), // 57
861 //.. GENX_(__NR_ulimit, sys_ni_syscall), // 58
862 //.. // (__NR_oldolduname, sys_olduname), // 59
863 GENX_ (__NR_umask, sys_umask), // 60
864 GENX_ (__NR_chroot, sys_chroot), // 61
865 //.. // (__NR_ustat, sys_ustat) // 62
866 GENXY (__NR_dup2, sys_dup2), // 63
867 GENX_ (__NR_getppid, sys_getppid), // 64
868 GENX_ (__NR_getpgrp, sys_getpgrp), // 65
869 GENX_ (__NR_setsid, sys_setsid), // 66
870 LINXY (__NR_sigaction, sys_sigaction), // 67
871 //.. // (__NR_sgetmask, sys_sgetmask), // 68
872 //.. // (__NR_ssetmask, sys_ssetmask), // 69
873 GENX_ (__NR_setreuid, sys_setreuid), // 70
874 GENX_ (__NR_setregid, sys_setregid), // 71
875 // PLAX_(__NR_sigsuspend, sys_sigsuspend), // 72
876 LINXY (__NR_sigpending, sys_sigpending), // 73
877 //.. // (__NR_sethostname, sys_sethostname), // 74
878 GENX_ (__NR_setrlimit, sys_setrlimit), // 75
879 GENXY (__NR_getrlimit, sys_getrlimit), // 76
880 GENXY (__NR_getrusage, sys_getrusage), // 77
881 GENXY (__NR_gettimeofday, sys_gettimeofday), // 78
882 GENX_ (__NR_settimeofday, sys_settimeofday), // 79
883 GENXY (__NR_getgroups, sys_getgroups), // 80
884 GENX_ (__NR_setgroups, sys_setgroups), // 81
885 //.. PLAX_(__NR_select, old_select), // 82
886 GENX_ (__NR_symlink, sys_symlink), // 83
887 //.. // (__NR_oldlstat, sys_lstat), // 84
888 GENX_ (__NR_readlink, sys_readlink), // 85
889 //.. // (__NR_uselib, sys_uselib), // 86
890 //.. // (__NR_swapon, sys_swapon), // 87
891 //.. // (__NR_reboot, sys_reboot), // 88
892 //.. // (__NR_readdir, old_readdir), // 89
893 PLAX_ (__NR_mmap, sys_mmap), // 90
894 GENXY (__NR_munmap, sys_munmap), // 91
895 GENX_ (__NR_truncate, sys_truncate), // 92
896 GENX_ (__NR_ftruncate, sys_ftruncate), // 93
897 GENX_ (__NR_fchmod, sys_fchmod), // 94
898 GENX_ (__NR_fchown, sys_fchown), // 95
899 GENX_ (__NR_getpriority, sys_getpriority), // 96
900 GENX_ (__NR_setpriority, sys_setpriority), // 97
901 //.. GENX_(__NR_profil, sys_ni_syscall), // 98
902 GENXY (__NR_statfs, sys_statfs), // 99
903 GENXY (__NR_fstatfs, sys_fstatfs), // 100
904 //.. LINX_(__NR_ioperm, sys_ioperm), // 101
905 LINXY (__NR_socketcall, sys_socketcall), // 102
906 LINXY (__NR_syslog, sys_syslog), // 103
907 GENXY (__NR_setitimer, sys_setitimer), // 104
908 //.. GENXY(__NR_getitimer, sys_getitimer), // 105
909 GENXY (__NR_stat, sys_newstat), // 106
910 GENXY (__NR_lstat, sys_newlstat), // 107
911 GENXY (__NR_fstat, sys_newfstat), // 108
912 //.. // (__NR_olduname, sys_uname), // 109
913 //.. GENX_(__NR_iopl, sys_iopl), // 110
914 //.. LINX_(__NR_vhangup, sys_vhangup), // 111
915 //.. GENX_(__NR_idle, sys_ni_syscall), // 112
916 //.. // (__NR_vm86old, sys_vm86old), // 113
917 GENXY (__NR_wait4, sys_wait4), // 114
918 //.. // (__NR_swapoff, sys_swapoff), // 115
919 LINXY (__NR_sysinfo, sys_sysinfo), // 116
920 LINXY (__NR_ipc, sys_ipc), // 117
921 GENX_ (__NR_fsync, sys_fsync), // 118
922 PLAX_ (__NR_sigreturn, sys_sigreturn), // 119
923 PLAX_ (__NR_clone, sys_clone), // 120
924 //.. // (__NR_setdomainname, sys_setdomainname), // 121
925 GENXY (__NR_uname, sys_newuname), // 122
926 //.. PLAX_(__NR_modify_ldt, sys_modify_ldt), // 123
927 //.. LINXY(__NR_adjtimex, sys_adjtimex), // 124
928 GENXY (__NR_mprotect, sys_mprotect), // 125
929 LINXY (__NR_sigprocmask, sys_sigprocmask), // 126
930 //.. GENX_(__NR_create_module, sys_ni_syscall), // 127
931 //.. GENX_(__NR_init_module, sys_init_module), // 128
932 //.. // (__NR_delete_module, sys_delete_module), // 129
933 //.. GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130
934 //.. LINX_(__NR_quotactl, sys_quotactl), // 131
935 GENX_ (__NR_getpgid, sys_getpgid), // 132
936 GENX_ (__NR_fchdir, sys_fchdir), // 133
937 //.. // (__NR_bdflush, sys_bdflush), // 134
938 //.. // (__NR_sysfs, sys_sysfs), // 135
939 LINX_ (__NR_personality, sys_personality), // 136
940 //.. GENX_(__NR_afs_syscall, sys_ni_syscall), // 137
941 LINX_ (__NR_setfsuid, sys_setfsuid), // 138
942 LINX_ (__NR_setfsgid, sys_setfsgid), // 139
943 LINXY (__NR__llseek, sys_llseek), // 140
944 GENXY (__NR_getdents, sys_getdents), // 141
945 GENX_ (__NR__newselect, sys_select), // 142
946 GENX_ (__NR_flock, sys_flock), // 143
947 GENX_ (__NR_msync, sys_msync), // 144
948 GENXY (__NR_readv, sys_readv), // 145
949 GENX_ (__NR_writev, sys_writev), // 146
950 PLAX_ (__NR_cacheflush, sys_cacheflush), // 147
951 GENX_ (__NR_getsid, sys_getsid), // 151
952 GENX_ (__NR_fdatasync, sys_fdatasync), // 152
953 LINXY (__NR__sysctl, sys_sysctl), // 153
954 GENX_ (__NR_mlock, sys_mlock), // 154
955 GENX_ (__NR_munlock, sys_munlock), // 155
956 GENX_ (__NR_mlockall, sys_mlockall), // 156
957 LINX_ (__NR_munlockall, sys_munlockall), // 157
958 //.. LINXY(__NR_sched_setparam, sys_sched_setparam), // 158
959 LINXY (__NR_sched_getparam, sys_sched_getparam), // 159
960 LINX_ (__NR_sched_setscheduler, sys_sched_setscheduler), // 160
961 LINX_ (__NR_sched_getscheduler, sys_sched_getscheduler), // 161
962 LINX_ (__NR_sched_yield, sys_sched_yield), // 162
963 LINX_ (__NR_sched_get_priority_max, sys_sched_get_priority_max), // 163
964 LINX_ (__NR_sched_get_priority_min, sys_sched_get_priority_min), // 164
965 //.. //LINX?(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 165
966 GENXY (__NR_nanosleep, sys_nanosleep), // 166
967 GENX_ (__NR_mremap, sys_mremap), // 167
968 LINXY (__NR_accept, sys_accept), // 168
969 LINX_ (__NR_bind, sys_bind), // 169
970 LINX_ (__NR_connect, sys_connect), // 170
971 LINXY (__NR_getpeername, sys_getpeername), // 171
972 LINXY (__NR_getsockname, sys_getsockname), // 172
973 LINXY (__NR_getsockopt, sys_getsockopt), // 173
974 LINX_ (__NR_listen, sys_listen), // 174
975 LINXY (__NR_recv, sys_recv), // 175
976 LINXY (__NR_recvfrom, sys_recvfrom), // 176
977 LINXY (__NR_recvmsg, sys_recvmsg), // 177
978 LINX_ (__NR_send, sys_send), // 178
979 LINX_ (__NR_sendmsg, sys_sendmsg), // 179
980 LINX_ (__NR_sendto, sys_sendto), // 180
981 LINX_ (__NR_setsockopt, sys_setsockopt), // 181
982 LINX_ (__NR_shutdown, sys_shutdown), // 182
983 LINXY (__NR_socket, sys_socket), // 183
984 LINXY (__NR_socketpair, sys_socketpair), // 184
985 LINX_ (__NR_setresuid, sys_setresuid), // 185
986 LINXY (__NR_getresuid, sys_getresuid), // 186
987 //.. GENX_(__NR_query_module, sys_ni_syscall), // 187
988 GENXY (__NR_poll, sys_poll), // 188
989 //..
990 LINX_ (__NR_setresgid, sys_setresgid), // 190
991 LINXY (__NR_getresgid, sys_getresgid), // 191
992 LINXY (__NR_prctl, sys_prctl), // 192
993 PLAX_ (__NR_rt_sigreturn, sys_rt_sigreturn), // 193
994 LINXY (__NR_rt_sigaction, sys_rt_sigaction), // 194
995 LINXY (__NR_rt_sigprocmask, sys_rt_sigprocmask), // 195
996 LINXY (__NR_rt_sigpending, sys_rt_sigpending), // 196
997 LINXY (__NR_rt_sigtimedwait, sys_rt_sigtimedwait), // 197
998 LINXY (__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo), // 198
999 LINX_ (__NR_rt_sigsuspend, sys_rt_sigsuspend), // 199
1000 GENXY (__NR_pread64, sys_pread64), // 200
1001 GENX_ (__NR_pwrite64, sys_pwrite64), // 201
1002 GENX_ (__NR_chown, sys_chown), // 202
1003 GENXY (__NR_getcwd, sys_getcwd), // 203
1004 LINXY (__NR_capget, sys_capget), // 204
1005 //.. LINX_(__NR_capset, sys_capset), // 205
1006 GENXY (__NR_sigaltstack, sys_sigaltstack), // 206
1007 LINXY (__NR_sendfile, sys_sendfile), // 207
1008 //.. GENXY(__NR_getpmsg, sys_getpmsg), // 208
1009 //.. GENX_(__NR_putpmsg, sys_putpmsg), // 209
1010 PLAX_ (__NR_mmap2, sys_mmap2), // 210
1011 // GENX_(__NR_truncate64, sys_truncate64), // 211
1012 GENX_ (__NR_ftruncate64, sys_ftruncate64), // 212
1013 PLAXY (__NR_stat64, sys_stat64), // 213
1014 PLAXY (__NR_lstat64, sys_lstat64), // 214
1015 PLAXY (__NR_fstat64, sys_fstat64), // 215
1016 //..
1017 GENXY (__NR_mincore, sys_mincore), // 217
1018 GENX_ (__NR_madvise, sys_madvise), // 218
1019 GENXY (__NR_getdents64, sys_getdents64), // 219
1020 LINXY (__NR_fcntl64, sys_fcntl64), // 220
1021 //..
1022 LINX_ (__NR_gettid, sys_gettid), // 222
1023 //..
1024 LINXY (__NR_getxattr, sys_getxattr), // 227
1025 LINXY (__NR_lgetxattr, sys_lgetxattr), // 228
1026 LINXY (__NR_fgetxattr, sys_fgetxattr), // 229
1027 LINXY (__NR_listxattr, sys_listxattr), // 230
1028 LINXY (__NR_llistxattr, sys_llistxattr), // 231
1029 LINXY (__NR_flistxattr, sys_flistxattr), // 232
1030 LINX_ (__NR_removexattr, sys_removexattr), // 233
1031 LINX_ (__NR_lremovexattr, sys_lremovexattr), // 234
1032 LINX_ (__NR_fremovexattr, sys_fremovexattr), // 235
1033 //..
1034 LINXY (__NR_sendfile64, sys_sendfile64), // 237
1035 LINXY (__NR_futex, sys_futex), // 238
1036 LINX_ (__NR_sched_setaffinity, sys_sched_setaffinity), // 239
1037 LINXY (__NR_sched_getaffinity, sys_sched_getaffinity), // 240
1038 LINX_ (__NR_io_setup, sys_io_setup), // 241
1039 LINX_ (__NR_io_destroy, sys_io_destroy), // 242
1040 LINXY (__NR_io_getevents, sys_io_getevents), // 243
1041 LINX_ (__NR_io_submit, sys_io_submit), // 244
1042 LINXY (__NR_io_cancel, sys_io_cancel), // 245
1043 LINX_ (__NR_exit_group, sys_exit_group), // 246
1044 //..
1045 LINXY (__NR_epoll_create, sys_epoll_create), // 248
1046 LINX_ (__NR_epoll_ctl, sys_epoll_ctl), // 249
1047 LINXY (__NR_epoll_wait, sys_epoll_wait), // 250
1048 //..
1049 LINX_ (__NR_set_tid_address, sys_set_tid_address), // 252
1050 LINX_ (__NR_fadvise64, sys_fadvise64), // 254
1051 GENXY (__NR_statfs64, sys_statfs64), // 255
1052 GENXY (__NR_fstatfs64, sys_fstatfs64), // 256
1053 //..
1054 LINXY (__NR_timer_create, sys_timer_create), // 257
1055 LINXY (__NR_timer_settime, sys_timer_settime), // 258
1056 LINXY (__NR_timer_gettime, sys_timer_gettime), // 259
1057 LINX_ (__NR_timer_getoverrun, sys_timer_getoverrun), // 260
1058 LINX_ (__NR_timer_delete, sys_timer_delete), // 261
1059 LINX_ (__NR_clock_settime, sys_clock_settime), // 262
1060 LINXY (__NR_clock_gettime, sys_clock_gettime), // 263
1061 LINXY (__NR_clock_getres, sys_clock_getres), // 264
1062 LINXY (__NR_clock_nanosleep, sys_clock_nanosleep), // 265
1063 LINXY (__NR_tgkill, sys_tgkill), // 266
1064 //.. GENX_(__NR_utimes, sys_utimes), // 267
1065 LINXY (__NR_get_mempolicy, sys_get_mempolicy), // 269
1066 LINX_ (__NR_set_mempolicy, sys_set_mempolicy), // 270
1067 LINXY (__NR_mq_open, sys_mq_open), // 271
1068 LINX_ (__NR_mq_unlink, sys_mq_unlink), // 272
1069 LINX_ (__NR_mq_timedsend, sys_mq_timedsend), // 273
1070 LINXY (__NR_mq_timedreceive, sys_mq_timedreceive), // 274
1071 LINX_ (__NR_mq_notify, sys_mq_notify), // 275
1072 LINXY (__NR_mq_getsetattr, sys_mq_getsetattr), // 276
1073 LINX_ (__NR_inotify_init, sys_inotify_init), // 275
1074 LINX_ (__NR_inotify_add_watch, sys_inotify_add_watch), // 276
1075 LINX_ (__NR_inotify_rm_watch, sys_inotify_rm_watch), // 277
1076 //..
1077 PLAX_ (__NR_set_thread_area, sys_set_thread_area), // 283
1078 //..
1079 LINXY (__NR_openat, sys_openat), // 288
1080 LINX_ (__NR_mkdirat, sys_mkdirat), // 289
1081 LINX_ (__NR_mknodat, sys_mknodat), // 290
1082 LINX_ (__NR_fchownat, sys_fchownat), // 291
1083 LINX_ (__NR_futimesat, sys_futimesat), // 292
1084 PLAXY (__NR_fstatat64, sys_fstatat64), // 293
1085 LINX_ (__NR_unlinkat, sys_unlinkat), // 294
1086 LINX_ (__NR_renameat, sys_renameat), // 295
1087 LINX_ (__NR_linkat, sys_linkat), // 296
1088 LINX_ (__NR_symlinkat, sys_symlinkat), // 297
1089 LINX_ (__NR_readlinkat, sys_readlinkat), // 298
1090 LINX_ (__NR_fchmodat, sys_fchmodat), // 299
1091 LINX_ (__NR_faccessat, sys_faccessat), // 300
1092 //..
1093 LINXY (__NR_ppoll, sys_ppoll), // 302
1094 //..
1095 LINX_ (__NR_set_robust_list, sys_set_robust_list), // 309
1096 LINXY (__NR_get_robust_list, sys_get_robust_list), // 310
1097 //..
1098 LINXY (__NR_epoll_pwait, sys_epoll_pwait), // 313
1099 //..
1100 LINX_ (__NR_utimensat, sys_utimensat), // 316
1101 //..
1102 LINX_ (__NR_fallocate, sys_fallocate), // 320
1103 LINXY (__NR_timerfd_create, sys_timerfd_create), // 321
1104 LINXY (__NR_timerfd_gettime, sys_timerfd_gettime), // 322
1105 LINXY (__NR_timerfd_settime, sys_timerfd_settime), // 323
1106 LINXY (__NR_signalfd4, sys_signalfd4), // 324
1107 LINXY (__NR_eventfd2, sys_eventfd2), // 325
1108 //..
1109 LINXY (__NR_pipe2, sys_pipe2), // 328
1110 LINXY (__NR_inotify_init1, sys_inotify_init1), // 329
1111 //..
1112 LINXY (__NR_prlimit64, sys_prlimit64), // 338
1113 //..
1114 LINXY (__NR_clock_adjtime, sys_clock_adjtime), // 341
1115 LINX_ (__NR_syncfs, sys_syncfs), // 342
1116 //..
1117 LINXY (__NR_process_vm_readv, sys_process_vm_readv), // 345
1118 LINX_ (__NR_process_vm_writev, sys_process_vm_writev), // 346
1119 //..
1120 LINXY(__NR_getrandom, sys_getrandom), // 353
1121 LINXY(__NR_memfd_create, sys_memfd_create) // 354
1122 };
1123
ML_(get_linux_syscall_entry)1124 SyscallTableEntry* ML_(get_linux_syscall_entry) (UInt sysno)
1125 {
1126 const UInt syscall_main_table_size
1127 = sizeof (syscall_main_table) / sizeof (syscall_main_table[0]);
1128 /* Is it in the contiguous initial section of the table? */
1129 if (sysno < syscall_main_table_size) {
1130 SyscallTableEntry * sys = &syscall_main_table[sysno];
1131 if (sys->before == NULL)
1132 return NULL; /* No entry. */
1133 else
1134 return sys;
1135 }
1136 /* Can't find a wrapper. */
1137 return NULL;
1138 }
1139
1140 #endif // defined(VGP_mips32_linux)
1141
1142 /*--------------------------------------------------------------------*/
1143 /*--- end syswrap-mips-linux.c ---*/
1144 /*--------------------------------------------------------------------*/
1145