blob: 4845f79fb8d7033b1fe58b9b54485f84e8ced37c [file] [log] [blame]
sewardj112711a2015-04-10 12:30:09 +00001
2/*--------------------------------------------------------------------*/
3/*--- Platform-specific syscalls stuff. syswrap-tilegx-linux.c ----*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
sewardjb3a1e4b2015-08-21 11:32:26 +000010 Copyright (C) 2010-2015 Tilera Corp.
sewardj112711a2015-04-10 12:30:09 +000011
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25 02111-1307, USA.
26
27 The GNU General Public License is contained in the file COPYING.
28*/
29
30/* Contributed by Zhi-Gang Liu */
31
32#if defined(VGP_tilegx_linux)
33#include "pub_core_basics.h"
34#include "pub_core_vki.h"
35#include "pub_core_vkiscnums.h"
sewardj112711a2015-04-10 12:30:09 +000036#include "pub_core_threadstate.h"
37#include "pub_core_aspacemgr.h"
38#include "pub_core_debuglog.h"
39#include "pub_core_libcbase.h"
40#include "pub_core_libcassert.h"
41#include "pub_core_libcprint.h"
42#include "pub_core_libcproc.h"
43#include "pub_core_libcsignal.h"
44#include "pub_core_options.h"
45#include "pub_core_scheduler.h"
46#include "pub_core_sigframe.h" // For VG_(sigframe_destroy)()
47#include "pub_core_signals.h"
48#include "pub_core_syscall.h"
49#include "pub_core_syswrap.h"
50#include "pub_core_tooliface.h"
51#include "pub_core_stacks.h" // VG_(register_stack)
52#include "pub_core_transtab.h" // VG_(discard_translations)
53#include "priv_types_n_macros.h"
54#include "priv_syswrap-generic.h" /* for decls of generic wrappers */
55#include "priv_syswrap-linux.h" /* for decls of linux wrappers */
56#include "priv_syswrap-main.h"
57
58#include "pub_core_debuginfo.h" // VG_(di_notify_*)
59#include "pub_core_xarray.h"
60#include "pub_core_clientstate.h" // VG_(brk_base), VG_(brk_limit)
61#include "pub_core_errormgr.h"
62#include "pub_core_libcfile.h"
63#include "pub_core_machine.h" // VG_(get_SP)
64#include "pub_core_mallocfree.h"
65#include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)()
66#include "pub_core_ume.h"
67
68#include "config.h"
69
70/* ---------------------------------------------------------------------
71 clone() handling
72 ------------------------------------------------------------------ */
73/* Call f(arg1), but first switch stacks, using 'stack' as the new
74 stack, and use 'retaddr' as f's return-to address. Also, clear all
75 the integer registers before entering f.*/
76
77__attribute__ ((noreturn))
78void ML_(call_on_new_stack_0_1) (Addr stack, Addr retaddr,
79 void (*f) (Word), Word arg1);
80 // r0 = stack
81 // r1 = retaddr
82 // r2 = f
83 // r3 = arg1
84 asm (
85 ".text\n"
86 ".globl vgModuleLocal_call_on_new_stack_0_1\n"
87 "vgModuleLocal_call_on_new_stack_0_1:\n"
88 " {\n"
89 " move sp, r0\n\t"
90 " move r51, r2\n\t"
91 " }\n"
92 " {\n"
93 " move r0, r3\n\t"
94 " move r1, zero\n\t"
95 " }\n"
96 " {\n"
97 " move r2, zero\n\t"
98 " move r3, zero\n\t"
99 " }\n"
100 " {\n"
101 " move r4, zero\n\t"
102 " move r5, zero\n\t"
103 " }\n"
104 " {\n"
105 " move r6, zero\n\t"
106 " move r7, zero\n\t"
107 " }\n"
108 " {\n"
109 " move r8, zero\n\t"
110 " move r9, zero\n\t"
111 " }\n"
112 " {\n"
113 " move r10, zero\n\t"
114 " move r11, zero\n\t"
115 " }\n"
116 " {\n"
117 " move r12, zero\n\t"
118 " move r13, zero\n\t"
119 " }\n"
120 " {\n"
121 " move r14, zero\n\t"
122 " move r15, zero\n\t"
123 " }\n"
124 " {\n"
125 " move r16, zero\n\t"
126 " move r17, zero\n\t"
127 " }\n"
128 " {\n"
129 " move r18, zero\n\t"
130 " move r19, zero\n\t"
131 " }\n"
132 " {\n"
133 " move r20, zero\n\t"
134 " move r21, zero\n\t"
135 " }\n"
136 " {\n"
137 " move r22, zero\n\t"
138 " move r23, zero\n\t"
139 " }\n"
140 " {\n"
141 " move r24, zero\n\t"
142 " move r25, zero\n\t"
143 " }\n"
144 " {\n"
145 " move r26, zero\n\t"
146 " move r27, zero\n\t"
147 " }\n"
148 " {\n"
149 " move r28, zero\n\t"
150 " move r29, zero\n\t"
151 " }\n"
152 " {\n"
153 " move r30, zero\n\t"
154 " move r31, zero\n\t"
155 " }\n"
156 " {\n"
157 " move r32, zero\n\t"
158 " move r33, zero\n\t"
159 " }\n"
160 " {\n"
161 " move r34, zero\n\t"
162 " move r35, zero\n\t"
163 " }\n"
164 " {\n"
165 " move r36, zero\n\t"
166 " move r37, zero\n\t"
167 " }\n"
168 " {\n"
169 " move r38, zero\n\t"
170 " move r39, zero\n\t"
171 " }\n"
172 " {\n"
173 " move r40, zero\n\t"
174 " move r41, zero\n\t"
175 " }\n"
176 " {\n"
177 " move r42, zero\n\t"
178 " move r43, zero\n\t"
179 " }\n"
180 " {\n"
181 " move r44, zero\n\t"
182 " move r45, zero\n\t"
183 " }\n"
184 " {\n"
185 " move r46, zero\n\t"
186 " move r47, zero\n\t"
187 " }\n"
188 " {\n"
189 " move r48, zero\n\t"
190 " move r49, zero\n\t"
191 " }\n"
192 " {\n"
193 " move r50, zero\n\t"
194 " jr r51\n\t"
195 " }\n"
196 " ill \n" // should never get here
197 );
198/*
199 Perform a clone system call. clone is strange because it has
200 fork()-like return-twice semantics, so it needs special
201 handling here.
202 Upon entry, we have:
203 int (fn)(void*) in r0
204 void* child_stack in r1
205 int flags in r2
206 void* arg in r3
207 pid_t* child_tid in r4
208 pid_t* parent_tid in r5
209 void* tls_ptr in r6
210
211 System call requires:
212 int $__NR_clone in r10
213 int flags in r0
214 void* child_stack in r1
215 pid_t* parent_tid in r2
216 void* tls_ptr in $r3
217 pid_t* child_tid in sr4
218
219 int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
220 void *parent_tidptr, void *tls, void *child_tidptr)
221
222 Returns an Int encoded in the linux-tilegx way, not a SysRes.
223*/
224#define __NR_CLONE VG_STRINGIFY(__NR_clone)
225#define __NR_EXIT VG_STRINGIFY(__NR_exit)
226
227Long do_syscall_clone_tilegx_linux ( Word (*fn) (void *), //r0
228 void *stack, //r1
229 Long flags, //r2
230 void *arg, //r3
231 Long * child_tid, //r4
232 Long * parent_tid, //r5
233 Long tls ); //r6
234 /*
235 stack
236 high -> 4 r29
237 3
238 2
239 1 r10
240 low -> 0 lr <- sp
241 */
242 asm (
243 ".text\n"
244 " .globl do_syscall_clone_tilegx_linux\n"
245 " do_syscall_clone_tilegx_linux:\n"
246 " beqz r0, .Linvalid\n"
247 " beqz r1, .Linvalid\n"
248 " {\n"
249 " st sp, r29; " // save r29 at top
250 " addli sp, sp, -32\n" // open new stack space
251 " }\n"
252
253 " move r29, sp; " // r29 <- sp
254 " st r29, lr\n" // save lr at 0(sp)
255
256 " addi r29, r29, 8\n"
257 " {\n"
258 " st r29, r10\n" // save r10 at 8(sp)
259 /* setup child stack */
260 " addi r1, r1, -32\n" // new stack frame for child
261 " }\n"
262 /* save fn */
263 " { st r1, r0; addi r1, r1, 8 }\n"
264 /* save args */
265 " { st r1, r3; addi r1, r1, 8 }\n"
266 /* save flags */
267 " { st r1, r2; addi r1, r1, -16 }\n"
268
269 /* Child stack layout
270
271 flags
272 args
273 r1-> fn
274 */
275 " {\n"
276 /* prepare args for clone. */
277 " move r0, r2\n" // arg0 = flags
278 /* arg1=r1 child stack */
279 " move r2, r5\n" // arg2 = parent tid
280 " }\n"
281 " {\n"
282 " move r3, r4\n" // arg3 = child tid
283 " move r4, r6\n" // arg4 = tls
284 " }\n"
285 " moveli r10, " __NR_CLONE "\n"
286 " swint1\n"
287
288 " beqz r0, .Lchild\n"
289 " move r29, sp\n"
290 " ld lr, r29\n" // Restore lr
291 " addi r29, r29, 8\n"
292 " {\n"
293 " ld r10, r29\n" // resotre r10
294 " addi sp, sp, 32\n"
295 " }\n"
296 " ld r29, sp\n"
297 " jrp lr\n"
298
299 ".Lchild:"
300 " move r2, sp\n"
301 " {\n"
302 " ld r3, r2\n"
303 " addi r2, r2, 8\n"
304 " }\n"
305 " ld r0, r2\n"
306 " jalr r3\n"
307 " moveli r10, " __NR_EXIT "\n"
308 " swint1\n"
309
310 ".Linvalid:"
311 " { movei r1, 22; jrp lr }\n"
312 );
313
314#undef __NR_CLONE
315#undef __NR_EXIT
316
317// forward declarations
318static void setup_child ( ThreadArchState *, ThreadArchState * );
319static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr );
320 /*
321 When a client clones, we need to keep track of the new thread. This means:
florianad4e9792015-07-05 21:53:33 +0000322 1. allocate a ThreadId+ThreadState+stack for the thread
sewardj112711a2015-04-10 12:30:09 +0000323 2. initialize the thread's new VCPU state
324 3. create the thread using the same args as the client requested,
325 but using the scheduler entrypoint for IP, and a separate stack
326 for SP.
327 */
328static SysRes do_clone ( ThreadId ptid,
329 Long flags, Addr sp,
330 Long * parent_tidptr,
331 Long * child_tidptr,
332 Addr child_tls )
333{
334 const Bool debug = False;
335 ThreadId ctid = VG_ (alloc_ThreadState) ();
336 ThreadState * ptst = VG_ (get_ThreadState) (ptid);
337 ThreadState * ctst = VG_ (get_ThreadState) (ctid);
338 Long ret = 0;
339 Long * stack;
sewardj112711a2015-04-10 12:30:09 +0000340 SysRes res;
341 vki_sigset_t blockall, savedmask;
342
343 VG_ (sigfillset) (&blockall);
344 vg_assert (VG_ (is_running_thread) (ptid));
345 vg_assert (VG_ (is_valid_tid) (ctid));
346 stack = (Long *) ML_ (allocstack) (ctid);
347 if (stack == NULL) {
348 res = VG_ (mk_SysRes_Error) (VKI_ENOMEM);
349 goto out;
350 }
351 setup_child (&ctst->arch, &ptst->arch);
352
353 /* On TILEGX we need to set r0 and r3 to zero */
354 ctst->arch.vex.guest_r0 = 0;
355 ctst->arch.vex.guest_r3 = 0;
356 if (sp != 0)
357 ctst->arch.vex.guest_r54 = sp;
358
359 ctst->os_state.parent = ptid;
360 ctst->sig_mask = ptst->sig_mask;
361 ctst->tmp_sig_mask = ptst->sig_mask;
362
363 /* Start the child with its threadgroup being the same as the
364 parent's. This is so that any exit_group calls that happen
365 after the child is created but before it sets its
366 os_state.threadgroup field for real (in thread_wrapper in
367 syswrap-linux.c), really kill the new thread. a.k.a this avoids
368 a race condition in which the thread is unkillable (via
369 exit_group) because its threadgroup is not set. The race window
370 is probably only a few hundred or a few thousand cycles long.
371 See #226116. */
372
373 ctst->os_state.threadgroup = ptst->os_state.threadgroup;
florian71e322f2015-04-20 17:00:02 +0000374 ML_(guess_and_register_stack) (sp, ctst);
sewardj112711a2015-04-10 12:30:09 +0000375
376 VG_TRACK (pre_thread_ll_create, ptid, ctid);
377 if (flags & VKI_CLONE_SETTLS) {
378 if (debug)
379 VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls);
380 ctst->arch.vex.guest_r53 = child_tls;
381 res = sys_set_tls(ctid, child_tls);
382 if (sr_isError(res))
383 goto out;
384 }
385
386 flags &= ~VKI_CLONE_SETTLS;
387 VG_ (sigprocmask) (VKI_SIG_SETMASK, &blockall, &savedmask);
388 /* Create the new thread */
389 ret = do_syscall_clone_tilegx_linux (ML_ (start_thread_NORETURN),
390 stack, flags, &VG_ (threads)[ctid],
391 child_tidptr, parent_tidptr,
392 (Long)NULL /*child_tls*/);
393
394 /* High half word64 is syscall return value. */
395 if (debug)
florianb26101c2015-08-08 21:45:33 +0000396 VG_(printf)("ret: 0x%llx\n", (ULong)ret);
sewardj112711a2015-04-10 12:30:09 +0000397
398 res = VG_(mk_SysRes_tilegx_linux) (/*val */ ret);
399
400 VG_ (sigprocmask) (VKI_SIG_SETMASK, &savedmask, NULL);
401
402 out:
403 if (sr_isError (res)) {
404 VG_(cleanup_thread) (&ctst->arch);
405 ctst->status = VgTs_Empty;
406 VG_TRACK (pre_thread_ll_exit, ctid);
407 }
408 ptst->arch.vex.guest_r0 = 0;
409
410 return res;
411}
412
413extern Addr do_brk ( Addr newbrk );
414
415extern
416SysRes do_mremap( Addr old_addr, SizeT old_len,
417 Addr new_addr, SizeT new_len,
418 UWord flags, ThreadId tid );
419
420extern Bool linux_kernel_2_6_22(void);
421
422/* ---------------------------------------------------------------------
423 More thread stuff
424 ------------------------------------------------------------------ */
425
426// TILEGX doesn't have any architecture specific thread stuff that
427// needs to be cleaned up.
428void
429VG_ (cleanup_thread) ( ThreadArchState * arch ) { }
430
431void
432setup_child ( /*OUT*/ ThreadArchState * child,
433 /*IN*/ ThreadArchState * parent )
434{
435 /* We inherit our parent's guest state. */
436 child->vex = parent->vex;
437 child->vex_shadow1 = parent->vex_shadow1;
438 child->vex_shadow2 = parent->vex_shadow2;
439}
440
441SysRes sys_set_tls ( ThreadId tid, Addr tlsptr )
442{
443 VG_(threads)[tid].arch.vex.guest_r53 = tlsptr;
444 return VG_(mk_SysRes_Success)( 0 );
445}
446
447
448/* ---------------------------------------------------------------------
449 PRE/POST wrappers for tilegx/Linux-specific syscalls
450 ------------------------------------------------------------------ */
451#define PRE(name) DEFN_PRE_TEMPLATE(tilegx_linux, name)
452#define POST(name) DEFN_POST_TEMPLATE(tilegx_linux, name)
453
454/* Add prototypes for the wrappers declared here, so that gcc doesn't
455 harass us for not having prototypes. Really this is a kludge --
456 the right thing to do is to make these wrappers 'static' since they
457 aren't visible outside this file, but that requires even more macro
458 magic. */
459
zliuf81fbe42015-04-15 03:22:17 +0000460DECL_TEMPLATE (tilegx_linux, sys_clone);
461DECL_TEMPLATE (tilegx_linux, sys_rt_sigreturn);
462DECL_TEMPLATE (tilegx_linux, sys_socket);
463DECL_TEMPLATE (tilegx_linux, sys_setsockopt);
464DECL_TEMPLATE (tilegx_linux, sys_getsockopt);
465DECL_TEMPLATE (tilegx_linux, sys_connect);
466DECL_TEMPLATE (tilegx_linux, sys_accept);
467DECL_TEMPLATE (tilegx_linux, sys_accept4);
468DECL_TEMPLATE (tilegx_linux, sys_sendto);
469DECL_TEMPLATE (tilegx_linux, sys_recvfrom);
470DECL_TEMPLATE (tilegx_linux, sys_sendmsg);
471DECL_TEMPLATE (tilegx_linux, sys_recvmsg);
472DECL_TEMPLATE (tilegx_linux, sys_shutdown);
473DECL_TEMPLATE (tilegx_linux, sys_bind);
474DECL_TEMPLATE (tilegx_linux, sys_listen);
475DECL_TEMPLATE (tilegx_linux, sys_getsockname);
476DECL_TEMPLATE (tilegx_linux, sys_getpeername);
477DECL_TEMPLATE (tilegx_linux, sys_socketpair);
478DECL_TEMPLATE (tilegx_linux, sys_semget);
479DECL_TEMPLATE (tilegx_linux, sys_semop);
480DECL_TEMPLATE (tilegx_linux, sys_semtimedop);
481DECL_TEMPLATE (tilegx_linux, sys_semctl);
482DECL_TEMPLATE (tilegx_linux, sys_msgget);
483DECL_TEMPLATE (tilegx_linux, sys_msgrcv);
484DECL_TEMPLATE (tilegx_linux, sys_msgsnd);
485DECL_TEMPLATE (tilegx_linux, sys_msgctl);
486DECL_TEMPLATE (tilegx_linux, sys_shmget);
487DECL_TEMPLATE (tilegx_linux, wrap_sys_shmat);
488DECL_TEMPLATE (tilegx_linux, sys_shmdt);
489DECL_TEMPLATE (tilegx_linux, sys_shmdt);
490DECL_TEMPLATE (tilegx_linux, sys_shmctl);
491DECL_TEMPLATE (tilegx_linux, sys_arch_prctl);
492DECL_TEMPLATE (tilegx_linux, sys_ptrace);
493DECL_TEMPLATE (tilegx_linux, sys_fadvise64);
494DECL_TEMPLATE (tilegx_linux, sys_mmap);
495DECL_TEMPLATE (tilegx_linux, sys_syscall184);
496DECL_TEMPLATE (tilegx_linux, sys_cacheflush);
497DECL_TEMPLATE (tilegx_linux, sys_set_dataplane);
sewardj112711a2015-04-10 12:30:09 +0000498
499PRE(sys_clone)
500{
501 ULong cloneflags;
502
503 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
504 PRE_REG_READ5(int, "clone",
505 unsigned long, flags,
506 void *, child_stack,
507 int *, parent_tidptr,
508 int *, child_tidptr,
509 void *, tlsaddr);
510
511 if (ARG1 & VKI_CLONE_PARENT_SETTID) {
512 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
513 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), VKI_PROT_WRITE)) {
514 SET_STATUS_Failure( VKI_EFAULT );
515 return;
516 }
517 }
518 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
519 PRE_MEM_WRITE("clone(child_tidptr)", ARG4, sizeof(Int));
520 if (!VG_(am_is_valid_for_client)(ARG4, sizeof(Int), VKI_PROT_WRITE)) {
521 SET_STATUS_Failure( VKI_EFAULT );
522 return;
523 }
524 }
525
526 cloneflags = ARG1;
527
528 if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
529 SET_STATUS_Failure( VKI_EINVAL );
530 return;
531 }
532
533 /* Only look at the flags we really care about */
534 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
535 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
536 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
537 /* thread creation */
538 SET_STATUS_from_SysRes(
539 do_clone(tid,
540 ARG1, /* flags */
541 (Addr)ARG2, /* child ESP */
542 (Long *)ARG3, /* parent_tidptr */
543 (Long *)ARG4, /* child_tidptr */
544 (Addr)ARG5)); /* set_tls */
545 break;
546
547 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
548 /* FALLTHROUGH - assume vfork == fork */
549 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
550
551 case 0: /* plain fork */
552 SET_STATUS_from_SysRes(
553 ML_(do_fork_clone)(tid,
554 cloneflags, /* flags */
555 (Int *)ARG3, /* parent_tidptr */
556 (Int *)ARG4)); /* child_tidptr */
557 break;
558
559 default:
560 /* should we just ENOSYS? */
561 VG_(message)(Vg_UserMsg,
562 "Unsupported clone() flags: 0x%lx\n", ARG1);
563 VG_(message)(Vg_UserMsg,
564 "\n");
565 VG_(message)(Vg_UserMsg,
566 "The only supported clone() uses are:\n");
567 VG_(message)(Vg_UserMsg,
568 " - via a threads library (LinuxThreads or NPTL)\n");
569 VG_(message)(Vg_UserMsg,
570 " - via the implementation of fork or vfork\n");
571 VG_(unimplemented)
572 ("Valgrind does not support general clone().");
573 }
574
575 if (SUCCESS) {
576 if (ARG1 & VKI_CLONE_PARENT_SETTID)
577 POST_MEM_WRITE(ARG3, sizeof(Int));
578 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
579 POST_MEM_WRITE(ARG4, sizeof(Int));
580
581 /* Thread creation was successful; let the child have the chance
582 to run */
583 *flags |= SfYieldAfter;
584 }
585}
586
587PRE(sys_rt_sigreturn)
588{
589 /* This isn't really a syscall at all - it's a misuse of the
590 syscall mechanism by m_sigframe. VG_(sigframe_create) sets the
591 return address of the signal frames it creates to be a short
592 piece of code which does this "syscall". The only purpose of
593 the syscall is to call VG_(sigframe_destroy), which restores the
594 thread's registers from the frame and then removes it.
595 Consequently we must ask the syswrap driver logic not to write
596 back the syscall "result" as that would overwrite the
597 just-restored register state. */
598
599 ThreadState* tst;
600 PRINT("sys_rt_sigreturn ( )");
601
602 vg_assert(VG_(is_valid_tid)(tid));
603 vg_assert(tid >= 1 && tid < VG_N_THREADS);
604 vg_assert(VG_(is_running_thread)(tid));
605
606 /* Adjust RSP to point to start of frame; skip back up over handler
607 ret addr */
608 tst = VG_(get_ThreadState)(tid);
609 tst->arch.vex.guest_r54 -= sizeof(Addr);
610
611 /* This is only so that the RIP is (might be) useful to report if
612 something goes wrong in the sigreturn. JRS 20070318: no idea
613 what this is for */
614 ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
615
616 /* Restore register state from frame and remove it, as
617 described above */
618 VG_(sigframe_destroy)(tid, True);
619
620 /* Tell the driver not to update the guest state with the "result",
621 and set a bogus result to keep it happy. */
622 *flags |= SfNoWriteResult;
623 SET_STATUS_Success(0);
624
625 /* Check to see if any signals arose as a result of this. */
626 *flags |= SfPollAfter;
627}
628
629PRE(sys_arch_prctl)
630{
florianb26101c2015-08-08 21:45:33 +0000631 PRINT( "arch_prctl ( %ld, %lx )", SARG1, ARG2 );
sewardj112711a2015-04-10 12:30:09 +0000632
633 vg_assert(VG_(is_valid_tid)(tid));
634 vg_assert(tid >= 1 && tid < VG_N_THREADS);
635 vg_assert(VG_(is_running_thread)(tid));
636
637 I_die_here;
638}
639
640// Parts of this are tilegx-specific, but the *PEEK* cases are generic.
641//
642// ARG3 is only used for pointers into the traced process's address
643// space and for offsets into the traced process's struct
644// user_regs_struct. It is never a pointer into this process's memory
645// space, and we should therefore not check anything it points to.
646PRE(sys_ptrace)
647{
florianb26101c2015-08-08 21:45:33 +0000648 PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", SARG1, SARG2, ARG3, ARG4);
sewardj112711a2015-04-10 12:30:09 +0000649 PRE_REG_READ4(int, "ptrace",
florianb26101c2015-08-08 21:45:33 +0000650 long, request, long, pid, unsigned long, addr, unsigned long, data);
sewardj112711a2015-04-10 12:30:09 +0000651 switch (ARG1) {
652 case VKI_PTRACE_PEEKTEXT:
653 case VKI_PTRACE_PEEKDATA:
654 case VKI_PTRACE_PEEKUSR:
655 PRE_MEM_WRITE( "ptrace(peek)", ARG4,
656 sizeof (long));
657 break;
658 case VKI_PTRACE_GETREGS:
659 PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
660 sizeof (struct vki_user_regs_struct));
661 break;
662#if 0 // FIXME
663 case VKI_PTRACE_GETFPREGS:
664 PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
665 sizeof (struct vki_user_i387_struct));
666 break;
667#endif
668 case VKI_PTRACE_SETREGS:
669 PRE_MEM_READ( "ptrace(setregs)", ARG4,
670 sizeof (struct vki_user_regs_struct));
671 break;
672#if 0 // FIXME
673 case VKI_PTRACE_SETFPREGS:
674 PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
675 sizeof (struct vki_user_i387_struct));
676 break;
677#endif
678 case VKI_PTRACE_GETEVENTMSG:
679 PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
680 break;
681 case VKI_PTRACE_GETSIGINFO:
682 PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
683 break;
684 case VKI_PTRACE_SETSIGINFO:
685 PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
686 break;
687 default:
688 break;
689 }
690}
691
692POST(sys_ptrace)
693{
694 switch (ARG1) {
695 case VKI_PTRACE_PEEKTEXT:
696 case VKI_PTRACE_PEEKDATA:
697 case VKI_PTRACE_PEEKUSR:
698 POST_MEM_WRITE( ARG4, sizeof (long));
699 break;
700 case VKI_PTRACE_GETREGS:
701 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
702 break;
703#if 0 // FIXME
704 case VKI_PTRACE_GETFPREGS:
705 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
706 break;
707#endif
708 case VKI_PTRACE_GETEVENTMSG:
709 POST_MEM_WRITE( ARG4, sizeof(unsigned long));
710 break;
711 case VKI_PTRACE_GETSIGINFO:
712 /* XXX: This is a simplification. Different parts of the
713 * siginfo_t are valid depending on the type of signal.
714 */
715 POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
716 break;
717 default:
718 break;
719 }
720}
721
722PRE(sys_socket)
723{
florianb26101c2015-08-08 21:45:33 +0000724 PRINT("sys_socket ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
sewardj112711a2015-04-10 12:30:09 +0000725 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
726}
727POST(sys_socket)
728{
729 SysRes r;
730 vg_assert(SUCCESS);
731 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
732 SET_STATUS_from_SysRes(r);
733}
734
735PRE(sys_setsockopt)
736{
florianb26101c2015-08-08 21:45:33 +0000737 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#lx, %ld )", SARG1, SARG2, SARG3,
738 ARG4, SARG5);
sewardj112711a2015-04-10 12:30:09 +0000739 PRE_REG_READ5(long, "setsockopt",
740 int, s, int, level, int, optname,
741 const void *, optval, int, optlen);
742 ML_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
743}
744
745PRE(sys_getsockopt)
746{
florianb26101c2015-08-08 21:45:33 +0000747 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#lx, %#lx )", SARG1, SARG2, SARG3,
748 ARG4, ARG5);
sewardj112711a2015-04-10 12:30:09 +0000749 PRE_REG_READ5(long, "getsockopt",
750 int, s, int, level, int, optname,
751 void *, optval, int, *optlen);
752 ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
753}
754POST(sys_getsockopt)
755{
756 vg_assert(SUCCESS);
757 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
758 ARG1,ARG2,ARG3,ARG4,ARG5);
759}
760
761PRE(sys_connect)
762{
763 *flags |= SfMayBlock;
florianb26101c2015-08-08 21:45:33 +0000764 PRINT("sys_connect ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3);
sewardj112711a2015-04-10 12:30:09 +0000765 PRE_REG_READ3(long, "connect",
766 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
767 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
768}
769
770PRE(sys_accept)
771{
772 *flags |= SfMayBlock;
florianb26101c2015-08-08 21:45:33 +0000773 PRINT("sys_accept ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
sewardj112711a2015-04-10 12:30:09 +0000774 PRE_REG_READ3(long, "accept",
florianb26101c2015-08-08 21:45:33 +0000775 int, s, struct sockaddr *, addr, int *, addrlen);
sewardj112711a2015-04-10 12:30:09 +0000776 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
777}
778POST(sys_accept)
779{
780 SysRes r;
781 vg_assert(SUCCESS);
782 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
783 ARG1,ARG2,ARG3);
784 SET_STATUS_from_SysRes(r);
785}
786
787PRE(sys_accept4)
788{
789 *flags |= SfMayBlock;
florianb26101c2015-08-08 21:45:33 +0000790 PRINT("sys_accept4 ( %ld, %#lx, %#lx, %ld )", SARG1, ARG2, ARG3, SARG4);
sewardj112711a2015-04-10 12:30:09 +0000791 PRE_REG_READ4(long, "accept4",
florianb26101c2015-08-08 21:45:33 +0000792 int, s, struct sockaddr *, addr, int *, addrlen, int, flags);
sewardj112711a2015-04-10 12:30:09 +0000793 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
794}
795POST(sys_accept4)
796{
797 SysRes r;
798 vg_assert(SUCCESS);
799 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
800 ARG1,ARG2,ARG3);
801 SET_STATUS_from_SysRes(r);
802}
803
804PRE(sys_sendto)
805{
806 *flags |= SfMayBlock;
florianb26101c2015-08-08 21:45:33 +0000807 PRINT("sys_sendto ( %ld, %#lx, %ld, %lu, %#lx, %ld )", SARG1, ARG2, SARG3,
808 ARG4, ARG5, SARG6);
sewardj112711a2015-04-10 12:30:09 +0000809 PRE_REG_READ6(long, "sendto",
810 int, s, const void *, msg, int, len,
811 unsigned int, flags,
812 const struct sockaddr *, to, int, tolen);
813 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
814}
815
816PRE(sys_recvfrom)
817{
818 *flags |= SfMayBlock;
florianb26101c2015-08-08 21:45:33 +0000819 PRINT("sys_recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )", SARG1, ARG2, SARG3,
820 ARG4, ARG5, ARG6);
sewardj112711a2015-04-10 12:30:09 +0000821 PRE_REG_READ6(long, "recvfrom",
822 int, s, void *, buf, int, len, unsigned int, flags,
823 struct sockaddr *, from, int *, fromlen);
824 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
825}
826POST(sys_recvfrom)
827{
828 vg_assert(SUCCESS);
829 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
830 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
831}
832
833PRE(sys_sendmsg)
834{
835 *flags |= SfMayBlock;
florianb26101c2015-08-08 21:45:33 +0000836 PRINT("sys_sendmsg ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3);
sewardj112711a2015-04-10 12:30:09 +0000837 PRE_REG_READ3(long, "sendmsg",
838 int, s, const struct msghdr *, msg, int, flags);
839 ML_(generic_PRE_sys_sendmsg)(tid, "msg", ARG2);
840}
841
842PRE(sys_recvmsg)
843{
844 *flags |= SfMayBlock;
florianb26101c2015-08-08 21:45:33 +0000845 PRINT("sys_recvmsg ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3);
sewardj112711a2015-04-10 12:30:09 +0000846 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg, int, flags);
847 ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *) ARG2);
848}
849
850POST(sys_recvmsg)
851{
852 ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2, RES);
853}
854
855PRE(sys_shutdown)
856{
857 *flags |= SfMayBlock;
florianb26101c2015-08-08 21:45:33 +0000858 PRINT("sys_shutdown ( %ld, %ld )", SARG1, SARG2);
sewardj112711a2015-04-10 12:30:09 +0000859 PRE_REG_READ2(int, "shutdown", int, s, int, how);
860}
861
862PRE(sys_bind)
863{
florianb26101c2015-08-08 21:45:33 +0000864 PRINT("sys_bind ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3);
sewardj112711a2015-04-10 12:30:09 +0000865 PRE_REG_READ3(long, "bind",
866 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
867 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
868}
869
870PRE(sys_listen)
871{
florianb26101c2015-08-08 21:45:33 +0000872 PRINT("sys_listen ( %ld, %ld )", SARG1, SARG2);
sewardj112711a2015-04-10 12:30:09 +0000873 PRE_REG_READ2(long, "listen", int, s, int, backlog);
874}
875
876PRE(sys_getsockname)
877{
florianb26101c2015-08-08 21:45:33 +0000878 PRINT("sys_getsockname ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
sewardj112711a2015-04-10 12:30:09 +0000879 PRE_REG_READ3(long, "getsockname",
880 int, s, struct sockaddr *, name, int *, namelen);
881 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
882}
883POST(sys_getsockname)
884{
885 vg_assert(SUCCESS);
886 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
887 ARG1,ARG2,ARG3);
888}
889
890PRE(sys_getpeername)
891{
florianb26101c2015-08-08 21:45:33 +0000892 PRINT("sys_getpeername ( %ld, %#lx, %#lx )", SARG1, ARG2, ARG3);
sewardj112711a2015-04-10 12:30:09 +0000893 PRE_REG_READ3(long, "getpeername",
894 int, s, struct sockaddr *, name, int *, namelen);
895 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
896}
897POST(sys_getpeername)
898{
899 vg_assert(SUCCESS);
900 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
901 ARG1,ARG2,ARG3);
902}
903
904PRE(sys_socketpair)
905{
florianb26101c2015-08-08 21:45:33 +0000906 PRINT("sys_socketpair ( %ld, %ld, %ld, %#lx )", SARG1, SARG2, SARG3, ARG4);
sewardj112711a2015-04-10 12:30:09 +0000907 PRE_REG_READ4(long, "socketpair",
908 int, d, int, type, int, protocol, int*, sv);
909 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
910}
911POST(sys_socketpair)
912{
913 vg_assert(SUCCESS);
914 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
915 ARG1,ARG2,ARG3,ARG4);
916}
917
918PRE(sys_semget)
919{
florianb26101c2015-08-08 21:45:33 +0000920 PRINT("sys_semget ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
sewardj112711a2015-04-10 12:30:09 +0000921 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
922}
923
924PRE(sys_semop)
925{
926 *flags |= SfMayBlock;
florianb26101c2015-08-08 21:45:33 +0000927 PRINT("sys_semop ( %ld, %#lx, %lu )", SARG1, ARG2, ARG3);
sewardj112711a2015-04-10 12:30:09 +0000928 PRE_REG_READ3(long, "semop",
929 int, semid, struct sembuf *, sops, unsigned, nsoops);
930 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
931}
932
933PRE(sys_semtimedop)
934{
935 *flags |= SfMayBlock;
florianb26101c2015-08-08 21:45:33 +0000936 PRINT("sys_semtimedop ( %ld, %#lx, %lu, %#lx )", SARG1, ARG2, ARG3, ARG4);
sewardj112711a2015-04-10 12:30:09 +0000937 PRE_REG_READ4(long, "semtimedop",
938 int, semid, struct sembuf *, sops, unsigned, nsoops,
939 struct timespec *, timeout);
940 ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
941}
942
943PRE(sys_semctl)
944{
945 switch (ARG3 & ~VKI_IPC_64) {
946 case VKI_IPC_INFO:
947 case VKI_SEM_INFO:
florianb26101c2015-08-08 21:45:33 +0000948 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )", SARG1, SARG2, SARG3, ARG4);
sewardj112711a2015-04-10 12:30:09 +0000949 PRE_REG_READ4(long, "semctl",
950 int, semid, int, semnum, int, cmd, struct seminfo *, arg);
951 break;
952 case VKI_IPC_STAT:
953 case VKI_SEM_STAT:
954 case VKI_IPC_SET:
florianb26101c2015-08-08 21:45:33 +0000955 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )", SARG1, SARG2, SARG3, ARG4);
sewardj112711a2015-04-10 12:30:09 +0000956 PRE_REG_READ4(long, "semctl",
957 int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
958 break;
959 case VKI_GETALL:
960 case VKI_SETALL:
florianb26101c2015-08-08 21:45:33 +0000961 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )", SARG1, SARG2, SARG3, ARG4);
sewardj112711a2015-04-10 12:30:09 +0000962 PRE_REG_READ4(long, "semctl",
963 int, semid, int, semnum, int, cmd, unsigned short *, arg);
964 break;
965 default:
florianb26101c2015-08-08 21:45:33 +0000966 PRINT("sys_semctl ( %ld, %ld, %ld )", SARG1, SARG2, SARG3);
sewardj112711a2015-04-10 12:30:09 +0000967 PRE_REG_READ3(long, "semctl",
968 int, semid, int, semnum, int, cmd);
969 break;
970 }
971 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
972}
973POST(sys_semctl)
974{
975 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
976}
977
978PRE(sys_msgget)
979{
florianb26101c2015-08-08 21:45:33 +0000980 PRINT("sys_msgget ( %ld, %ld )", SARG1, SARG2);
sewardj112711a2015-04-10 12:30:09 +0000981 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
982}
983
984PRE(sys_msgsnd)
985{
florianb26101c2015-08-08 21:45:33 +0000986 PRINT("sys_msgsnd ( %ld, %#lx, %lu, %ld )", SARG1, ARG2, ARG3, SARG4);
sewardj112711a2015-04-10 12:30:09 +0000987 PRE_REG_READ4(long, "msgsnd",
988 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
989 int, msgflg);
990 ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
991 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
992 *flags |= SfMayBlock;
993}
994
995PRE(sys_msgrcv)
996{
florianb26101c2015-08-08 21:45:33 +0000997 PRINT("sys_msgrcv ( %ld, %#lx, %lu, %ld, %ld )", SARG1, ARG2, ARG3,
998 SARG4, SARG5);
sewardj112711a2015-04-10 12:30:09 +0000999 PRE_REG_READ5(long, "msgrcv",
1000 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
1001 long, msgytp, int, msgflg);
1002 ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
1003 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
1004 *flags |= SfMayBlock;
1005}
1006POST(sys_msgrcv)
1007{
1008 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
1009}
1010
1011PRE(sys_msgctl)
1012{
florianb26101c2015-08-08 21:45:33 +00001013 PRINT("sys_msgctl ( %ld, %ld, %#lx )", SARG1, SARG2, ARG3);
sewardj112711a2015-04-10 12:30:09 +00001014 PRE_REG_READ3(long, "msgctl",
1015 int, msqid, int, cmd, struct msqid_ds *, buf);
1016 ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
1017}
1018POST(sys_msgctl)
1019{
1020 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
1021}
1022
1023PRE(sys_shmget)
1024{
florianb26101c2015-08-08 21:45:33 +00001025 PRINT("sys_shmget ( %ld, %lu, %ld )", SARG1, ARG2, SARG3);
sewardj112711a2015-04-10 12:30:09 +00001026 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
1027}
1028
1029PRE(wrap_sys_shmat)
1030{
1031 UWord arg2tmp;
florianb26101c2015-08-08 21:45:33 +00001032 PRINT("wrap_sys_shmat ( %ld, %#lx, %ld )", SARG1, ARG2, SARG3);
sewardj112711a2015-04-10 12:30:09 +00001033 PRE_REG_READ3(long, "shmat",
1034 int, shmid, const void *, shmaddr, int, shmflg);
1035 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
1036 if (arg2tmp == 0)
1037 SET_STATUS_Failure( VKI_EINVAL );
1038 else
1039 ARG2 = arg2tmp; // used in POST
1040}
1041POST(wrap_sys_shmat)
1042{
1043 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
1044}
1045
1046PRE(sys_shmdt)
1047{
1048 PRINT("sys_shmdt ( %#lx )",ARG1);
1049 PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
1050 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
1051 SET_STATUS_Failure( VKI_EINVAL );
1052}
1053POST(sys_shmdt)
1054{
1055 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
1056}
1057
1058PRE(sys_shmctl)
1059{
florianb26101c2015-08-08 21:45:33 +00001060 PRINT("sys_shmctl ( %ld, %ld, %#lx )", SARG1, SARG2, ARG3);
sewardj112711a2015-04-10 12:30:09 +00001061 PRE_REG_READ3(long, "shmctl",
1062 int, shmid, int, cmd, struct shmid_ds *, buf);
1063 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
1064}
1065POST(sys_shmctl)
1066{
1067 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
1068}
1069
1070PRE(sys_fadvise64)
1071{
florianb26101c2015-08-08 21:45:33 +00001072 PRINT("sys_fadvise64 ( %ld, %ld, %lu, %ld )", SARG1, SARG2, ARG3, SARG4);
sewardj112711a2015-04-10 12:30:09 +00001073 PRE_REG_READ4(long, "fadvise64",
1074 int, fd, vki_loff_t, offset, vki_size_t, len, int, advice);
1075}
1076
1077PRE(sys_mmap)
1078{
1079 SysRes r;
1080
florianb26101c2015-08-08 21:45:33 +00001081 PRINT("sys_mmap ( %#lx, %lu, %lu, %lu, %lu, %lu )",
1082 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
sewardj112711a2015-04-10 12:30:09 +00001083 PRE_REG_READ6(long, "mmap",
1084 unsigned long, start, unsigned long, length,
1085 unsigned long, prot, unsigned long, flags,
1086 unsigned long, fd, unsigned long, offset);
1087
1088 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
1089 SET_STATUS_from_SysRes(r);
1090}
1091
1092
1093/* ---------------------------------------------------------------
1094 PRE/POST wrappers for TILEGX/Linux-variant specific syscalls
1095 ------------------------------------------------------------ */
zliuf81fbe42015-04-15 03:22:17 +00001096PRE(sys_cacheflush)
1097{
florianb26101c2015-08-08 21:45:33 +00001098 PRINT("cacheflush (%lx, %ld, %ld)", ARG1, SARG2, SARG3);
zliuf81fbe42015-04-15 03:22:17 +00001099 PRE_REG_READ3(long, "cacheflush", unsigned long, addr,
1100 int, nbytes, int, cache);
1101 VG_ (discard_translations) ((Addr)ARG1, (ULong) ARG2,
1102 "PRE(sys_cacheflush)");
1103 SET_STATUS_Success(0);
1104}
sewardj112711a2015-04-10 12:30:09 +00001105
1106PRE(sys_set_dataplane)
1107{
1108 *flags |= SfMayBlock;
florianb26101c2015-08-08 21:45:33 +00001109 PRINT("sys_set_dataplane ( %lu )", ARG1);
sewardj112711a2015-04-10 12:30:09 +00001110 PRE_REG_READ1(long, "set_dataplane", unsigned long, flag);
1111}
1112
1113#undef PRE
1114#undef POST
1115
1116
1117/* ---------------------------------------------------------------------
1118 The TILEGX/Linux syscall table
1119 ------------------------------------------------------------------ */
1120
1121/* Add an tilegx-linux specific wrapper to a syscall table. */
1122#define PLAX_(const, name) WRAPPER_ENTRY_X_(tilegx_linux, const, name)
1123#define PLAXY(const, name) WRAPPER_ENTRY_XY(tilegx_linux, const, name)
1124
1125// This table maps from __NR_xxx syscall numbers (from
1126// linux/include/asm/unistd.h) to the appropriate PRE/POST sys_foo()
1127//
1128// When implementing these wrappers, you need to work out if the wrapper is
1129// generic, Linux-only (but arch-independent), or TILEGX/Linux only.
1130
1131static SyscallTableEntry syscall_table[] = {
1132
1133 LINXY(__NR_io_setup, sys_io_setup), // 0
1134 LINX_(__NR_io_destroy, sys_io_destroy), // 1
1135 LINX_(__NR_io_submit, sys_io_submit), // 2
1136 LINXY(__NR_io_cancel, sys_io_cancel), // 3
1137 LINXY(__NR_io_getevents, sys_io_getevents), // 4
1138 LINX_(__NR_setxattr, sys_setxattr), // 5
1139 LINX_(__NR_lsetxattr, sys_lsetxattr), // 6
1140 LINX_(__NR_fsetxattr, sys_fsetxattr), // 7
1141 LINXY(__NR_getxattr, sys_getxattr), // 8
1142 LINXY(__NR_lgetxattr, sys_lgetxattr), // 9
1143 LINXY(__NR_fgetxattr, sys_fgetxattr), // 10
1144 LINXY(__NR_listxattr, sys_listxattr), // 11
1145 LINXY(__NR_llistxattr, sys_llistxattr), // 12
1146 LINXY(__NR_flistxattr, sys_flistxattr), // 13
1147 LINX_(__NR_removexattr, sys_removexattr), // 14
1148 LINX_(__NR_lremovexattr, sys_lremovexattr), // 15
1149 LINX_(__NR_fremovexattr, sys_fremovexattr), // 16
1150 GENXY(__NR_getcwd, sys_getcwd), // 17
1151 LINXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 18
1152 LINX_(__NR_eventfd2, sys_eventfd2), // 19
1153 LINXY(__NR_epoll_create1, sys_epoll_create1), // 20
1154 LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 21
1155 LINXY(__NR_epoll_pwait, sys_epoll_pwait), // 22
1156 GENXY(__NR_dup, sys_dup), // 23
1157 GENXY(__NR_dup2, sys_dup2), // 23
1158 LINXY(__NR_dup3, sys_dup3), // 24
1159 LINXY(__NR_fcntl, sys_fcntl), // 25
1160 LINXY(__NR_inotify_init1, sys_inotify_init1), // 26
1161 LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 27
1162 LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 28
1163 LINXY(__NR_ioctl, sys_ioctl), // 29
1164 LINX_(__NR_ioprio_set, sys_ioprio_set), // 30
1165 LINX_(__NR_ioprio_get, sys_ioprio_get), // 31
1166 GENX_(__NR_flock, sys_flock), // 32
1167 LINX_(__NR_mknodat, sys_mknodat), // 33
1168 LINX_(__NR_mkdirat, sys_mkdirat), // 34
1169 LINX_(__NR_unlinkat, sys_unlinkat), // 35
1170 LINX_(__NR_symlinkat, sys_symlinkat), // 36
1171 LINX_(__NR_linkat, sys_linkat), // 37
1172 LINX_(__NR_renameat, sys_renameat), // 38
1173 LINX_(__NR_umount2, sys_umount), // 39
1174 LINX_(__NR_mount, sys_mount), // 40
1175
1176 GENXY(__NR_statfs, sys_statfs), // 43
1177 GENXY(__NR_fstatfs, sys_fstatfs), // 44
1178 GENX_(__NR_truncate, sys_truncate), // 45
1179 GENX_(__NR_ftruncate, sys_ftruncate), // 46
1180 LINX_(__NR_fallocate, sys_fallocate), // 47
1181 LINX_(__NR_faccessat, sys_faccessat), // 48
1182 GENX_(__NR_chdir, sys_chdir), // 49
1183 GENX_(__NR_fchdir, sys_fchdir), // 50
1184 GENX_(__NR_chroot, sys_chroot), // 51
1185 GENX_(__NR_fchmod, sys_fchmod), // 52
1186 LINX_(__NR_fchmodat, sys_fchmodat), // 53
1187 LINX_(__NR_fchownat, sys_fchownat), // 54
1188 GENX_(__NR_fchown, sys_fchown), // 55
1189 LINXY(__NR_openat, sys_openat), // 56
1190 GENXY(__NR_close, sys_close), // 57
1191 LINX_(__NR_vhangup, sys_vhangup), // 58
1192 LINXY(__NR_pipe2, sys_pipe2), // 59
1193 LINX_(__NR_quotactl, sys_quotactl), // 60
1194 GENXY(__NR_getdents64, sys_getdents64), // 61
1195 LINX_(__NR_lseek, sys_lseek), // 62
1196 GENXY(__NR_read, sys_read), // 63
1197 GENX_(__NR_write, sys_write), // 64
1198 GENXY(__NR_readv, sys_readv), // 65
1199 GENX_(__NR_writev, sys_writev), // 66
1200 GENXY(__NR_pread64, sys_pread64), // 67
1201 GENX_(__NR_pwrite64, sys_pwrite64), // 68
1202 LINXY(__NR_preadv, sys_preadv), // 69
1203 LINX_(__NR_pwritev, sys_pwritev), // 70
1204 LINXY(__NR_sendfile, sys_sendfile), // 71
Elliott Hughesa0664b92017-04-18 17:46:52 -07001205 LINXY(__NR_pselect6, sys_pselect6), // 72
sewardj112711a2015-04-10 12:30:09 +00001206 LINXY(__NR_ppoll, sys_ppoll), // 73
1207 LINXY(__NR_signalfd4, sys_signalfd4), // 74
1208 LINX_(__NR_splice, sys_splice), // 75
1209 LINX_(__NR_readlinkat, sys_readlinkat), // 78
1210 LINXY(__NR3264_fstatat, sys_newfstatat), // 79
1211 GENXY(__NR_fstat, sys_newfstat), // 80
1212 GENX_(__NR_sync, sys_sync), // 81
1213 GENX_(__NR_fsync, sys_fsync), // 82
1214 GENX_(__NR_fdatasync, sys_fdatasync), // 83
1215 LINX_(__NR_sync_file_range, sys_sync_file_range), // 84
1216 LINXY(__NR_timerfd_create, sys_timerfd_create), // 85
1217 LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 86
1218 LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 87
1219 LINX_(__NR_utimensat, sys_utimensat), // 88
1220
1221 LINXY(__NR_capget, sys_capget), // 90
1222 LINX_(__NR_capset, sys_capset), // 91
1223 LINX_(__NR_personality, sys_personality), // 92
1224 GENX_(__NR_exit, sys_exit), // 93
1225 LINX_(__NR_exit_group, sys_exit_group), // 94
1226 LINXY(__NR_waitid, sys_waitid), // 95
1227 LINX_(__NR_set_tid_address, sys_set_tid_address), // 96
1228 LINXY(__NR_futex, sys_futex), // 98
1229 LINX_(__NR_set_robust_list, sys_set_robust_list), // 99
1230 LINXY(__NR_get_robust_list, sys_get_robust_list), // 100
1231 GENXY(__NR_nanosleep, sys_nanosleep), // 101
1232 GENXY(__NR_getitimer, sys_getitimer), // 102
1233 GENXY(__NR_setitimer, sys_setitimer), // 103
1234 LINX_(__NR_init_module, sys_init_module), // 105
1235 LINX_(__NR_delete_module, sys_delete_module), // 106
1236 LINXY(__NR_timer_create, sys_timer_create), // 107
1237 LINXY(__NR_timer_gettime, sys_timer_gettime), // 108
1238 LINX_(__NR_timer_getoverrun, sys_timer_getoverrun), // 109
1239 LINXY(__NR_timer_settime, sys_timer_settime), // 110
1240 LINX_(__NR_timer_delete, sys_timer_delete), // 111
1241 LINX_(__NR_clock_settime, sys_clock_settime), // 112
1242 LINXY(__NR_clock_gettime, sys_clock_gettime), // 113
1243 LINXY(__NR_clock_getres, sys_clock_getres), // 114
1244 LINXY(__NR_clock_nanosleep, sys_clock_nanosleep), // 115
1245 LINXY(__NR_syslog, sys_syslog), // 116
1246 PLAXY(__NR_ptrace, sys_ptrace), // 117
1247 LINXY(__NR_sched_setparam, sys_sched_setparam), // 118
1248 LINX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 119
1249 LINX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 120
1250 LINXY(__NR_sched_getparam, sys_sched_getparam), // 121
1251 LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 122
1252 LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 123
1253 LINX_(__NR_sched_yield, sys_sched_yield), // 124
1254 LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max), // 125
1255 LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min), // 126
1256 LINXY(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 127
1257
1258 GENX_(__NR_kill, sys_kill), // 129
1259 LINXY(__NR_tkill, sys_tkill), // 130
1260 LINXY(__NR_tgkill, sys_tgkill), // 131
1261 GENXY(__NR_sigaltstack, sys_sigaltstack), // 132
1262 LINX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 133
1263 LINXY(__NR_rt_sigaction, sys_rt_sigaction), // 134
1264 LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 135
1265 LINXY(__NR_rt_sigpending, sys_rt_sigpending), // 136
1266 LINXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait), // 137
1267 LINXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo), // 138
1268 PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 139
1269 GENX_(__NR_setpriority, sys_setpriority), // 140
1270 GENX_(__NR_getpriority, sys_getpriority), // 141
1271
1272 GENX_(__NR_setregid, sys_setregid), // 143
1273 GENX_(__NR_setgid, sys_setgid), // 144
1274 GENX_(__NR_setreuid, sys_setreuid), // 145
1275 GENX_(__NR_setuid, sys_setuid), // 146
1276 LINX_(__NR_setresuid, sys_setresuid), // 147
1277 LINXY(__NR_getresuid, sys_getresuid), // 148
1278 LINX_(__NR_setresgid, sys_setresgid), // 149
1279 LINXY(__NR_getresgid, sys_getresgid), // 150
1280 LINX_(__NR_setfsuid, sys_setfsuid), // 151
1281 LINX_(__NR_setfsgid, sys_setfsgid), // 152
1282 GENXY(__NR_times, sys_times), // 153
1283 GENX_(__NR_setpgid, sys_setpgid), // 154
1284 GENX_(__NR_getpgid, sys_getpgid), // 155
1285 GENX_(__NR_getsid, sys_getsid), // 156
1286 GENX_(__NR_setsid, sys_setsid), // 157
1287 GENXY(__NR_getgroups, sys_getgroups), // 158
1288 GENX_(__NR_setgroups, sys_setgroups), // 159
1289 GENXY(__NR_uname, sys_newuname), // 160
1290 GENXY(__NR_getrlimit, sys_getrlimit), // 163
1291 GENX_(__NR_setrlimit, sys_setrlimit), // 164
1292 GENXY(__NR_getrusage, sys_getrusage), // 165
1293 GENX_(__NR_umask, sys_umask), // 166
1294 LINXY(__NR_prctl, sys_prctl), // 167
1295
1296 GENXY(__NR_gettimeofday, sys_gettimeofday), // 169
1297 GENX_(__NR_settimeofday, sys_settimeofday), // 170
1298 LINXY(__NR_adjtimex, sys_adjtimex), // 171
1299 GENX_(__NR_getpid, sys_getpid), // 172
1300 GENX_(__NR_getppid, sys_getppid), // 173
1301 GENX_(__NR_getuid, sys_getuid), // 174
1302 GENX_(__NR_geteuid, sys_geteuid), // 175
1303 GENX_(__NR_getgid, sys_getgid), // 176
1304 GENX_(__NR_getegid, sys_getegid), // 177
1305 LINX_(__NR_gettid, sys_gettid), // 178
1306 LINXY(__NR_sysinfo, sys_sysinfo), // 179
1307 LINXY(__NR_mq_open, sys_mq_open), // 180
1308 LINX_(__NR_mq_unlink, sys_mq_unlink), // 181
1309 LINX_(__NR_mq_timedsend, sys_mq_timedsend), // 182
1310 LINXY(__NR_mq_timedreceive, sys_mq_timedreceive), // 183
1311 LINX_(__NR_mq_notify, sys_mq_notify), // 184
1312 LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // 185
1313 PLAX_(__NR_msgget, sys_msgget), // 186
1314 PLAXY(__NR_msgctl, sys_msgctl), // 187
1315 PLAXY(__NR_msgrcv, sys_msgrcv), // 188
1316 PLAX_(__NR_msgsnd, sys_msgsnd), // 189
1317 PLAX_(__NR_semget, sys_semget), // 190
1318 PLAXY(__NR_semctl, sys_semctl), // 191
1319 PLAX_(__NR_semtimedop, sys_semtimedop), // 192
1320 PLAX_(__NR_semop, sys_semop), // 193
1321 PLAX_(__NR_shmget, sys_shmget), // 194
1322 PLAXY(__NR_shmat, wrap_sys_shmat), // 196
1323 PLAXY(__NR_shmctl, sys_shmctl), // 195
1324 PLAXY(__NR_shmdt, sys_shmdt), // 197
1325 PLAXY(__NR_socket, sys_socket), // 198
1326 PLAXY(__NR_socketpair, sys_socketpair), // 199
1327 PLAX_(__NR_bind, sys_bind), // 200
1328 PLAX_(__NR_listen, sys_listen), // 201
1329 PLAXY(__NR_accept, sys_accept), // 202
1330 PLAX_(__NR_connect, sys_connect), // 203
1331 PLAXY(__NR_getsockname, sys_getsockname), // 204
1332 PLAXY(__NR_getpeername, sys_getpeername), // 205
1333 PLAX_(__NR_sendto, sys_sendto), // 206
1334 PLAXY(__NR_recvfrom, sys_recvfrom), // 207
1335 PLAX_(__NR_setsockopt, sys_setsockopt), // 208
1336 PLAXY(__NR_getsockopt, sys_getsockopt), // 209
1337 PLAX_(__NR_shutdown, sys_shutdown), // 210
1338 PLAX_(__NR_sendmsg, sys_sendmsg), // 211
1339 PLAXY(__NR_recvmsg, sys_recvmsg), // 212
1340 LINX_(__NR_readahead, sys_readahead), // 213
1341 GENX_(__NR_brk, sys_brk), // 214
1342 GENXY(__NR_munmap, sys_munmap), // 215
1343 GENX_(__NR_mremap, sys_mremap), // 216
1344 LINX_(__NR_add_key, sys_add_key), // 217
1345 LINX_(__NR_request_key, sys_request_key), // 218
1346 LINXY(__NR_keyctl, sys_keyctl), // 219
1347 PLAX_(__NR_clone, sys_clone), // 220
1348 GENX_(__NR_execve, sys_execve), // 221
1349 PLAX_(__NR_mmap, sys_mmap), // 222
1350 GENXY(__NR_mprotect, sys_mprotect), // 226
1351 GENX_(__NR_msync, sys_msync), // 227
1352 GENX_(__NR_mlock, sys_mlock), // 228
1353 GENX_(__NR_munlock, sys_munlock), // 229
1354 GENX_(__NR_mlockall, sys_mlockall), // 230
1355 LINX_(__NR_munlockall, sys_munlockall), // 231
1356 GENX_(__NR_mincore, sys_mincore), // 232
1357 GENX_(__NR_madvise, sys_madvise), // 233
1358
1359 LINX_(__NR_mbind, sys_mbind), // 235
1360 LINXY(__NR_get_mempolicy, sys_get_mempolicy), // 236
1361 LINX_(__NR_set_mempolicy, sys_set_mempolicy), // 237
1362
1363 LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo), // 240
1364
1365 PLAXY(__NR_accept4, sys_accept4), // 242
1366
zliuf81fbe42015-04-15 03:22:17 +00001367 PLAX_(__NR_cacheflush, sys_cacheflush), // 245
sewardj112711a2015-04-10 12:30:09 +00001368 PLAX_(__NR_set_dataplane, sys_set_dataplane), // 246
1369
1370 GENXY(__NR_wait4, sys_wait4), // 260
1371};
1372
1373SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1374{
1375 const UInt syscall_table_size
1376 = sizeof(syscall_table) / sizeof(syscall_table[0]);
1377
1378 /* Is it in the contiguous initial section of the table? */
1379 if (sysno < syscall_table_size) {
1380 SyscallTableEntry* sys = &syscall_table[sysno];
1381 if (sys->before == NULL)
1382 return NULL; /* no entry */
1383 else
1384 return sys;
1385 }
1386 //vex_printf("sysno: %d\n", sysno);
1387
1388 /* Can't find a wrapper */
1389 return NULL;
1390}
1391
1392#endif // defined(VGP_tilegx_linux)
1393
1394/*--------------------------------------------------------------------*/
1395/*--- end syswrap-tilegx-linux.c ---*/
1396/*--------------------------------------------------------------------*/