1
2 /*--------------------------------------------------------------------*/
3 /*--- Platform-specific syscalls stuff. syswrap-amd64-linux.c ---*/
4 /*--------------------------------------------------------------------*/
5
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2000-2011 Nicholas Nethercote
11 njn@valgrind.org
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_amd64_linux)
32
33 #include "pub_core_basics.h"
34 #include "pub_core_vki.h"
35 #include "pub_core_vkiscnums.h"
36 #include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
37 #include "pub_core_threadstate.h"
38 #include "pub_core_aspacemgr.h"
39 #include "pub_core_debuglog.h"
40 #include "pub_core_options.h"
41 #include "pub_core_libcbase.h"
42 #include "pub_core_libcassert.h"
43 #include "pub_core_libcprint.h"
44 #include "pub_core_libcproc.h"
45 #include "pub_core_libcsignal.h"
46 #include "pub_core_scheduler.h"
47 #include "pub_core_sigframe.h"
48 #include "pub_core_signals.h"
49 #include "pub_core_syscall.h"
50 #include "pub_core_syswrap.h"
51 #include "pub_core_tooliface.h"
52 #include "pub_core_stacks.h" // VG_(register_stack)
53
54 #include "priv_types_n_macros.h"
55 #include "priv_syswrap-generic.h" /* for decls of generic wrappers */
56 #include "priv_syswrap-linux.h" /* for decls of linux-ish wrappers */
57 #include "priv_syswrap-linux-variants.h" /* decls of linux variant wrappers */
58 #include "priv_syswrap-main.h"
59
60
61 /* ---------------------------------------------------------------------
62 clone() handling
63 ------------------------------------------------------------------ */
64
65 /* Call f(arg1), but first switch stacks, using 'stack' as the new
66 stack, and use 'retaddr' as f's return-to address. Also, clear all
67 the integer registers before entering f. */
68 __attribute__((noreturn))
69 void ML_(call_on_new_stack_0_1) ( Addr stack,
70 Addr retaddr,
71 void (*f)(Word),
72 Word arg1 );
73 // %rdi == stack
74 // %rsi == retaddr
75 // %rdx == f
76 // %rcx == arg1
77 asm(
78 ".text\n"
79 ".globl vgModuleLocal_call_on_new_stack_0_1\n"
80 "vgModuleLocal_call_on_new_stack_0_1:\n"
81 " movq %rdi, %rsp\n" // set stack
82 " pushq %rsi\n" // retaddr to stack
83 " pushq %rdx\n" // f to stack
84 " pushq %rcx\n" // arg1 to stack
85 " movq $0, %rax\n" // zero all GP regs
86 " movq $0, %rbx\n"
87 " movq $0, %rcx\n"
88 " movq $0, %rdx\n"
89 " movq $0, %rsi\n"
90 " movq $0, %rdi\n"
91 " movq $0, %rbp\n"
92 " movq $0, %r8\n"
93 " movq $0, %r9\n"
94 " movq $0, %r10\n"
95 " movq $0, %r11\n"
96 " movq $0, %r12\n"
97 " movq $0, %r13\n"
98 " movq $0, %r14\n"
99 " movq $0, %r15\n"
100 " popq %rdi\n" // arg1 to correct arg reg
101 " ret\n" // jump to f
102 " ud2\n" // should never get here
103 ".previous\n"
104 );
105
106 /*
107 Perform a clone system call. clone is strange because it has
108 fork()-like return-twice semantics, so it needs special
109 handling here.
110
111 Upon entry, we have:
112
113 int (*fn)(void*) in %rdi
114 void* child_stack in %rsi
115 int flags in %rdx
116 void* arg in %rcx
117 pid_t* child_tid in %r8
118 pid_t* parent_tid in %r9
119 void* tls_ptr at 8(%rsp)
120
121 System call requires:
122
123 int $__NR_clone in %rax
124 int flags in %rdi
125 void* child_stack in %rsi
126 pid_t* parent_tid in %rdx
127 pid_t* child_tid in %r10
128 void* tls_ptr in %r8
129
130 Returns a Long encoded in the linux-amd64 way, not a SysRes.
131 */
132 #define __NR_CLONE VG_STRINGIFY(__NR_clone)
133 #define __NR_EXIT VG_STRINGIFY(__NR_exit)
134
135 extern
136 Long do_syscall_clone_amd64_linux ( Word (*fn)(void *),
137 void* stack,
138 Long flags,
139 void* arg,
140 Long* child_tid,
141 Long* parent_tid,
142 vki_modify_ldt_t * );
143 asm(
144 ".text\n"
145 "do_syscall_clone_amd64_linux:\n"
146 // set up child stack, temporarily preserving fn and arg
147 " subq $16, %rsi\n" // make space on stack
148 " movq %rcx, 8(%rsi)\n" // save arg
149 " movq %rdi, 0(%rsi)\n" // save fn
150
151 // setup syscall
152 " movq $"__NR_CLONE", %rax\n" // syscall number
153 " movq %rdx, %rdi\n" // syscall arg1: flags
154 // %rsi already setup // syscall arg2: child_stack
155 " movq %r9, %rdx\n" // syscall arg3: parent_tid
156 " movq %r8, %r10\n" // syscall arg4: child_tid
157 " movq 8(%rsp), %r8\n" // syscall arg5: tls_ptr
158
159 " syscall\n" // clone()
160
161 " testq %rax, %rax\n" // child if retval == 0
162 " jnz 1f\n"
163
164 // CHILD - call thread function
165 " pop %rax\n" // pop fn
166 " pop %rdi\n" // pop fn arg1: arg
167 " call *%rax\n" // call fn
168
169 // exit with result
170 " movq %rax, %rdi\n" // arg1: return value from fn
171 " movq $"__NR_EXIT", %rax\n"
172
173 " syscall\n"
174
175 // Exit returned?!
176 " ud2\n"
177
178 "1:\n" // PARENT or ERROR
179 " ret\n"
180 ".previous\n"
181 );
182
183 #undef __NR_CLONE
184 #undef __NR_EXIT
185
186
187 // forward declaration
188 static void setup_child ( ThreadArchState*, ThreadArchState* );
189
190 /*
191 When a client clones, we need to keep track of the new thread. This means:
192 1. allocate a ThreadId+ThreadState+stack for the the thread
193
194 2. initialize the thread's new VCPU state
195
196 3. create the thread using the same args as the client requested,
197 but using the scheduler entrypoint for EIP, and a separate stack
198 for ESP.
199 */
do_clone(ThreadId ptid,ULong flags,Addr rsp,Long * parent_tidptr,Long * child_tidptr,Addr tlsaddr)200 static SysRes do_clone ( ThreadId ptid,
201 ULong flags, Addr rsp,
202 Long* parent_tidptr,
203 Long* child_tidptr,
204 Addr tlsaddr )
205 {
206 static const Bool debug = False;
207
208 ThreadId ctid = VG_(alloc_ThreadState)();
209 ThreadState* ptst = VG_(get_ThreadState)(ptid);
210 ThreadState* ctst = VG_(get_ThreadState)(ctid);
211 UWord* stack;
212 NSegment const* seg;
213 SysRes res;
214 Long rax;
215 vki_sigset_t blockall, savedmask;
216
217 VG_(sigfillset)(&blockall);
218
219 vg_assert(VG_(is_running_thread)(ptid));
220 vg_assert(VG_(is_valid_tid)(ctid));
221
222 stack = (UWord*)ML_(allocstack)(ctid);
223 if (stack == NULL) {
224 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
225 goto out;
226 }
227
228 /* Copy register state
229
230 Both parent and child return to the same place, and the code
231 following the clone syscall works out which is which, so we
232 don't need to worry about it.
233
234 The parent gets the child's new tid returned from clone, but the
235 child gets 0.
236
237 If the clone call specifies a NULL rsp for the new thread, then
238 it actually gets a copy of the parent's rsp.
239 */
240 setup_child( &ctst->arch, &ptst->arch );
241
242 /* Make sys_clone appear to have returned Success(0) in the
243 child. */
244 ctst->arch.vex.guest_RAX = 0;
245
246 if (rsp != 0)
247 ctst->arch.vex.guest_RSP = rsp;
248
249 ctst->os_state.parent = ptid;
250
251 /* inherit signal mask */
252 ctst->sig_mask = ptst->sig_mask;
253 ctst->tmp_sig_mask = ptst->sig_mask;
254
255 /* Start the child with its threadgroup being the same as the
256 parent's. This is so that any exit_group calls that happen
257 after the child is created but before it sets its
258 os_state.threadgroup field for real (in thread_wrapper in
259 syswrap-linux.c), really kill the new thread. a.k.a this avoids
260 a race condition in which the thread is unkillable (via
261 exit_group) because its threadgroup is not set. The race window
262 is probably only a few hundred or a few thousand cycles long.
263 See #226116. */
264 ctst->os_state.threadgroup = ptst->os_state.threadgroup;
265
266 /* We don't really know where the client stack is, because its
267 allocated by the client. The best we can do is look at the
268 memory mappings and try to derive some useful information. We
269 assume that esp starts near its highest possible value, and can
270 only go down to the start of the mmaped segment. */
271 seg = VG_(am_find_nsegment)((Addr)rsp);
272 if (seg && seg->kind != SkResvn) {
273 ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(rsp);
274 ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
275
276 VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
277
278 if (debug)
279 VG_(printf)("tid %d: guessed client stack range %#lx-%#lx\n",
280 ctid, seg->start, VG_PGROUNDUP(rsp));
281 } else {
282 VG_(message)(Vg_UserMsg,
283 "!? New thread %d starts with RSP(%#lx) unmapped\n",
284 ctid, rsp);
285 ctst->client_stack_szB = 0;
286 }
287
288 /* Assume the clone will succeed, and tell any tool that wants to
289 know that this thread has come into existence. If the clone
290 fails, we'll send out a ll_exit notification for it at the out:
291 label below, to clean up. */
292 VG_TRACK ( pre_thread_ll_create, ptid, ctid );
293
294 if (flags & VKI_CLONE_SETTLS) {
295 if (debug)
296 VG_(printf)("clone child has SETTLS: tls at %#lx\n", tlsaddr);
297 ctst->arch.vex.guest_FS_ZERO = tlsaddr;
298 }
299
300 flags &= ~VKI_CLONE_SETTLS;
301
302 /* start the thread with everything blocked */
303 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
304
305 /* Create the new thread */
306 rax = do_syscall_clone_amd64_linux(
307 ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid],
308 child_tidptr, parent_tidptr, NULL
309 );
310 res = VG_(mk_SysRes_amd64_linux)( rax );
311
312 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
313
314 out:
315 if (sr_isError(res)) {
316 /* clone failed */
317 VG_(cleanup_thread)(&ctst->arch);
318 ctst->status = VgTs_Empty;
319 /* oops. Better tell the tool the thread exited in a hurry :-) */
320 VG_TRACK( pre_thread_ll_exit, ctid );
321 }
322
323 return res;
324 }
325
326
327 /* ---------------------------------------------------------------------
328 More thread stuff
329 ------------------------------------------------------------------ */
330
VG_(cleanup_thread)331 void VG_(cleanup_thread) ( ThreadArchState *arch )
332 {
333 }
334
setup_child(ThreadArchState * child,ThreadArchState * parent)335 void 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
344
345 /* ---------------------------------------------------------------------
346 PRE/POST wrappers for AMD64/Linux-specific syscalls
347 ------------------------------------------------------------------ */
348
349 #define PRE(name) DEFN_PRE_TEMPLATE(amd64_linux, name)
350 #define POST(name) DEFN_POST_TEMPLATE(amd64_linux, name)
351
352 /* Add prototypes for the wrappers declared here, so that gcc doesn't
353 harass us for not having prototypes. Really this is a kludge --
354 the right thing to do is to make these wrappers 'static' since they
355 aren't visible outside this file, but that requires even more macro
356 magic. */
357 DECL_TEMPLATE(amd64_linux, sys_clone);
358 DECL_TEMPLATE(amd64_linux, sys_rt_sigreturn);
359 DECL_TEMPLATE(amd64_linux, sys_socket);
360 DECL_TEMPLATE(amd64_linux, sys_setsockopt);
361 DECL_TEMPLATE(amd64_linux, sys_getsockopt);
362 DECL_TEMPLATE(amd64_linux, sys_connect);
363 DECL_TEMPLATE(amd64_linux, sys_accept);
364 DECL_TEMPLATE(amd64_linux, sys_accept4);
365 DECL_TEMPLATE(amd64_linux, sys_sendto);
366 DECL_TEMPLATE(amd64_linux, sys_recvfrom);
367 DECL_TEMPLATE(amd64_linux, sys_sendmsg);
368 DECL_TEMPLATE(amd64_linux, sys_recvmsg);
369 DECL_TEMPLATE(amd64_linux, sys_shutdown);
370 DECL_TEMPLATE(amd64_linux, sys_bind);
371 DECL_TEMPLATE(amd64_linux, sys_listen);
372 DECL_TEMPLATE(amd64_linux, sys_getsockname);
373 DECL_TEMPLATE(amd64_linux, sys_getpeername);
374 DECL_TEMPLATE(amd64_linux, sys_socketpair);
375 DECL_TEMPLATE(amd64_linux, sys_semget);
376 DECL_TEMPLATE(amd64_linux, sys_semop);
377 DECL_TEMPLATE(amd64_linux, sys_semtimedop);
378 DECL_TEMPLATE(amd64_linux, sys_semctl);
379 DECL_TEMPLATE(amd64_linux, sys_msgget);
380 DECL_TEMPLATE(amd64_linux, sys_msgrcv);
381 DECL_TEMPLATE(amd64_linux, sys_msgsnd);
382 DECL_TEMPLATE(amd64_linux, sys_msgctl);
383 DECL_TEMPLATE(amd64_linux, sys_shmget);
384 DECL_TEMPLATE(amd64_linux, wrap_sys_shmat);
385 DECL_TEMPLATE(amd64_linux, sys_shmdt);
386 DECL_TEMPLATE(amd64_linux, sys_shmdt);
387 DECL_TEMPLATE(amd64_linux, sys_shmctl);
388 DECL_TEMPLATE(amd64_linux, sys_arch_prctl);
389 DECL_TEMPLATE(amd64_linux, sys_ptrace);
390 DECL_TEMPLATE(amd64_linux, sys_fadvise64);
391 DECL_TEMPLATE(amd64_linux, sys_mmap);
392 DECL_TEMPLATE(amd64_linux, sys_syscall184);
393
394
PRE(sys_clone)395 PRE(sys_clone)
396 {
397 ULong cloneflags;
398
399 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
400 PRE_REG_READ5(int, "clone",
401 unsigned long, flags,
402 void *, child_stack,
403 int *, parent_tidptr,
404 int *, child_tidptr,
405 void *, tlsaddr);
406
407 if (ARG1 & VKI_CLONE_PARENT_SETTID) {
408 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
409 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), VKI_PROT_WRITE)) {
410 SET_STATUS_Failure( VKI_EFAULT );
411 return;
412 }
413 }
414 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
415 PRE_MEM_WRITE("clone(child_tidptr)", ARG4, sizeof(Int));
416 if (!VG_(am_is_valid_for_client)(ARG4, sizeof(Int), VKI_PROT_WRITE)) {
417 SET_STATUS_Failure( VKI_EFAULT );
418 return;
419 }
420 }
421
422 cloneflags = ARG1;
423
424 if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
425 SET_STATUS_Failure( VKI_EINVAL );
426 return;
427 }
428
429 /* Only look at the flags we really care about */
430 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
431 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
432 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
433 /* thread creation */
434 SET_STATUS_from_SysRes(
435 do_clone(tid,
436 ARG1, /* flags */
437 (Addr)ARG2, /* child ESP */
438 (Long *)ARG3, /* parent_tidptr */
439 (Long *)ARG4, /* child_tidptr */
440 (Addr)ARG5)); /* set_tls */
441 break;
442
443 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
444 /* FALLTHROUGH - assume vfork == fork */
445 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
446
447 case 0: /* plain fork */
448 SET_STATUS_from_SysRes(
449 ML_(do_fork_clone)(tid,
450 cloneflags, /* flags */
451 (Int *)ARG3, /* parent_tidptr */
452 (Int *)ARG4)); /* child_tidptr */
453 break;
454
455 default:
456 /* should we just ENOSYS? */
457 VG_(message)(Vg_UserMsg,
458 "Unsupported clone() flags: 0x%lx\n", ARG1);
459 VG_(message)(Vg_UserMsg,
460 "\n");
461 VG_(message)(Vg_UserMsg,
462 "The only supported clone() uses are:\n");
463 VG_(message)(Vg_UserMsg,
464 " - via a threads library (LinuxThreads or NPTL)\n");
465 VG_(message)(Vg_UserMsg,
466 " - via the implementation of fork or vfork\n");
467 VG_(unimplemented)
468 ("Valgrind does not support general clone().");
469 }
470
471 if (SUCCESS) {
472 if (ARG1 & VKI_CLONE_PARENT_SETTID)
473 POST_MEM_WRITE(ARG3, sizeof(Int));
474 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
475 POST_MEM_WRITE(ARG4, sizeof(Int));
476
477 /* Thread creation was successful; let the child have the chance
478 to run */
479 *flags |= SfYieldAfter;
480 }
481 }
482
PRE(sys_rt_sigreturn)483 PRE(sys_rt_sigreturn)
484 {
485 /* This isn't really a syscall at all - it's a misuse of the
486 syscall mechanism by m_sigframe. VG_(sigframe_create) sets the
487 return address of the signal frames it creates to be a short
488 piece of code which does this "syscall". The only purpose of
489 the syscall is to call VG_(sigframe_destroy), which restores the
490 thread's registers from the frame and then removes it.
491 Consequently we must ask the syswrap driver logic not to write
492 back the syscall "result" as that would overwrite the
493 just-restored register state. */
494
495 ThreadState* tst;
496 PRINT("sys_rt_sigreturn ( )");
497
498 vg_assert(VG_(is_valid_tid)(tid));
499 vg_assert(tid >= 1 && tid < VG_N_THREADS);
500 vg_assert(VG_(is_running_thread)(tid));
501
502 /* Adjust RSP to point to start of frame; skip back up over handler
503 ret addr */
504 tst = VG_(get_ThreadState)(tid);
505 tst->arch.vex.guest_RSP -= sizeof(Addr);
506
507 /* This is only so that the RIP is (might be) useful to report if
508 something goes wrong in the sigreturn. JRS 20070318: no idea
509 what this is for */
510 ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
511
512 /* Restore register state from frame and remove it, as
513 described above */
514 VG_(sigframe_destroy)(tid, True);
515
516 /* Tell the driver not to update the guest state with the "result",
517 and set a bogus result to keep it happy. */
518 *flags |= SfNoWriteResult;
519 SET_STATUS_Success(0);
520
521 /* Check to see if any signals arose as a result of this. */
522 *flags |= SfPollAfter;
523 }
524
PRE(sys_arch_prctl)525 PRE(sys_arch_prctl)
526 {
527 ThreadState* tst;
528 PRINT( "arch_prctl ( %ld, %lx )", ARG1, ARG2 );
529
530 vg_assert(VG_(is_valid_tid)(tid));
531 vg_assert(tid >= 1 && tid < VG_N_THREADS);
532 vg_assert(VG_(is_running_thread)(tid));
533
534 // Nb: can't use "ARG2".."ARG5" here because that's our own macro...
535 PRE_REG_READ2(long, "arch_prctl",
536 int, option, unsigned long, arg2);
537 // XXX: totally wrong... we need to look at the 'option' arg, and do
538 // PRE_MEM_READs/PRE_MEM_WRITEs as necessary...
539
540 /* "do" the syscall ourselves; the kernel never sees it */
541 if (ARG1 == VKI_ARCH_SET_FS) {
542 tst = VG_(get_ThreadState)(tid);
543 tst->arch.vex.guest_FS_ZERO = ARG2;
544 }
545 else if (ARG1 == VKI_ARCH_GET_FS) {
546 PRE_MEM_WRITE("arch_prctl(addr)", ARG2, sizeof(unsigned long));
547 tst = VG_(get_ThreadState)(tid);
548 *(unsigned long *)ARG2 = tst->arch.vex.guest_FS_ZERO;
549 POST_MEM_WRITE(ARG2, sizeof(unsigned long));
550 }
551 else {
552 VG_(core_panic)("Unsupported arch_prtctl option");
553 }
554
555 /* Note; the Status writeback to guest state that happens after
556 this wrapper returns does not change guest_FS_ZERO; hence that
557 direct assignment to the guest state is safe here. */
558 SET_STATUS_Success( 0 );
559 }
560
561 // Parts of this are amd64-specific, but the *PEEK* cases are generic.
562 //
563 // ARG3 is only used for pointers into the traced process's address
564 // space and for offsets into the traced process's struct
565 // user_regs_struct. It is never a pointer into this process's memory
566 // space, and we should therefore not check anything it points to.
PRE(sys_ptrace)567 PRE(sys_ptrace)
568 {
569 PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
570 PRE_REG_READ4(int, "ptrace",
571 long, request, long, pid, long, addr, long, data);
572 switch (ARG1) {
573 case VKI_PTRACE_PEEKTEXT:
574 case VKI_PTRACE_PEEKDATA:
575 case VKI_PTRACE_PEEKUSR:
576 PRE_MEM_WRITE( "ptrace(peek)", ARG4,
577 sizeof (long));
578 break;
579 case VKI_PTRACE_GETREGS:
580 PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
581 sizeof (struct vki_user_regs_struct));
582 break;
583 case VKI_PTRACE_GETFPREGS:
584 PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
585 sizeof (struct vki_user_i387_struct));
586 break;
587 case VKI_PTRACE_SETREGS:
588 PRE_MEM_READ( "ptrace(setregs)", ARG4,
589 sizeof (struct vki_user_regs_struct));
590 break;
591 case VKI_PTRACE_SETFPREGS:
592 PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
593 sizeof (struct vki_user_i387_struct));
594 break;
595 case VKI_PTRACE_GETEVENTMSG:
596 PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
597 break;
598 case VKI_PTRACE_GETSIGINFO:
599 PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
600 break;
601 case VKI_PTRACE_SETSIGINFO:
602 PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
603 break;
604 default:
605 break;
606 }
607 }
608
POST(sys_ptrace)609 POST(sys_ptrace)
610 {
611 switch (ARG1) {
612 case VKI_PTRACE_PEEKTEXT:
613 case VKI_PTRACE_PEEKDATA:
614 case VKI_PTRACE_PEEKUSR:
615 POST_MEM_WRITE( ARG4, sizeof (long));
616 break;
617 case VKI_PTRACE_GETREGS:
618 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
619 break;
620 case VKI_PTRACE_GETFPREGS:
621 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
622 break;
623 case VKI_PTRACE_GETEVENTMSG:
624 POST_MEM_WRITE( ARG4, sizeof(unsigned long));
625 break;
626 case VKI_PTRACE_GETSIGINFO:
627 /* XXX: This is a simplification. Different parts of the
628 * siginfo_t are valid depending on the type of signal.
629 */
630 POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
631 break;
632 default:
633 break;
634 }
635 }
636
PRE(sys_socket)637 PRE(sys_socket)
638 {
639 PRINT("sys_socket ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
640 PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
641 }
POST(sys_socket)642 POST(sys_socket)
643 {
644 SysRes r;
645 vg_assert(SUCCESS);
646 r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
647 SET_STATUS_from_SysRes(r);
648 }
649
PRE(sys_setsockopt)650 PRE(sys_setsockopt)
651 {
652 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
653 PRE_REG_READ5(long, "setsockopt",
654 int, s, int, level, int, optname,
655 const void *, optval, int, optlen);
656 ML_(generic_PRE_sys_setsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
657 }
658
PRE(sys_getsockopt)659 PRE(sys_getsockopt)
660 {
661 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
662 PRE_REG_READ5(long, "getsockopt",
663 int, s, int, level, int, optname,
664 void *, optval, int, *optlen);
665 ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
666 }
POST(sys_getsockopt)667 POST(sys_getsockopt)
668 {
669 vg_assert(SUCCESS);
670 ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES),
671 ARG1,ARG2,ARG3,ARG4,ARG5);
672 }
673
PRE(sys_connect)674 PRE(sys_connect)
675 {
676 *flags |= SfMayBlock;
677 PRINT("sys_connect ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
678 PRE_REG_READ3(long, "connect",
679 int, sockfd, struct sockaddr *, serv_addr, int, addrlen);
680 ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3);
681 }
682
PRE(sys_accept)683 PRE(sys_accept)
684 {
685 *flags |= SfMayBlock;
686 PRINT("sys_accept ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
687 PRE_REG_READ3(long, "accept",
688 int, s, struct sockaddr *, addr, int, *addrlen);
689 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
690 }
POST(sys_accept)691 POST(sys_accept)
692 {
693 SysRes r;
694 vg_assert(SUCCESS);
695 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
696 ARG1,ARG2,ARG3);
697 SET_STATUS_from_SysRes(r);
698 }
699
PRE(sys_accept4)700 PRE(sys_accept4)
701 {
702 *flags |= SfMayBlock;
703 PRINT("sys_accept4 ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
704 PRE_REG_READ4(long, "accept4",
705 int, s, struct sockaddr *, addr, int, *addrlen, int, flags);
706 ML_(generic_PRE_sys_accept)(tid, ARG1,ARG2,ARG3);
707 }
POST(sys_accept4)708 POST(sys_accept4)
709 {
710 SysRes r;
711 vg_assert(SUCCESS);
712 r = ML_(generic_POST_sys_accept)(tid, VG_(mk_SysRes_Success)(RES),
713 ARG1,ARG2,ARG3);
714 SET_STATUS_from_SysRes(r);
715 }
716
PRE(sys_sendto)717 PRE(sys_sendto)
718 {
719 *flags |= SfMayBlock;
720 PRINT("sys_sendto ( %ld, %#lx, %ld, %lu, %#lx, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
721 PRE_REG_READ6(long, "sendto",
722 int, s, const void *, msg, int, len,
723 unsigned int, flags,
724 const struct sockaddr *, to, int, tolen);
725 ML_(generic_PRE_sys_sendto)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
726 }
727
PRE(sys_recvfrom)728 PRE(sys_recvfrom)
729 {
730 *flags |= SfMayBlock;
731 PRINT("sys_recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
732 PRE_REG_READ6(long, "recvfrom",
733 int, s, void *, buf, int, len, unsigned int, flags,
734 struct sockaddr *, from, int *, fromlen);
735 ML_(generic_PRE_sys_recvfrom)(tid, ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
736 }
POST(sys_recvfrom)737 POST(sys_recvfrom)
738 {
739 vg_assert(SUCCESS);
740 ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
741 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
742 }
743
PRE(sys_sendmsg)744 PRE(sys_sendmsg)
745 {
746 *flags |= SfMayBlock;
747 PRINT("sys_sendmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
748 PRE_REG_READ3(long, "sendmsg",
749 int, s, const struct msghdr *, msg, int, flags);
750 ML_(generic_PRE_sys_sendmsg)(tid, ARG1,ARG2);
751 }
752
PRE(sys_recvmsg)753 PRE(sys_recvmsg)
754 {
755 *flags |= SfMayBlock;
756 PRINT("sys_recvmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
757 PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg, int, flags);
758 ML_(generic_PRE_sys_recvmsg)(tid, ARG1,ARG2);
759 }
POST(sys_recvmsg)760 POST(sys_recvmsg)
761 {
762 ML_(generic_POST_sys_recvmsg)(tid, ARG1,ARG2);
763 }
764
PRE(sys_shutdown)765 PRE(sys_shutdown)
766 {
767 *flags |= SfMayBlock;
768 PRINT("sys_shutdown ( %ld, %ld )",ARG1,ARG2);
769 PRE_REG_READ2(int, "shutdown", int, s, int, how);
770 }
771
PRE(sys_bind)772 PRE(sys_bind)
773 {
774 PRINT("sys_bind ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
775 PRE_REG_READ3(long, "bind",
776 int, sockfd, struct sockaddr *, my_addr, int, addrlen);
777 ML_(generic_PRE_sys_bind)(tid, ARG1,ARG2,ARG3);
778 }
779
PRE(sys_listen)780 PRE(sys_listen)
781 {
782 PRINT("sys_listen ( %ld, %ld )",ARG1,ARG2);
783 PRE_REG_READ2(long, "listen", int, s, int, backlog);
784 }
785
PRE(sys_getsockname)786 PRE(sys_getsockname)
787 {
788 PRINT("sys_getsockname ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
789 PRE_REG_READ3(long, "getsockname",
790 int, s, struct sockaddr *, name, int *, namelen);
791 ML_(generic_PRE_sys_getsockname)(tid, ARG1,ARG2,ARG3);
792 }
POST(sys_getsockname)793 POST(sys_getsockname)
794 {
795 vg_assert(SUCCESS);
796 ML_(generic_POST_sys_getsockname)(tid, VG_(mk_SysRes_Success)(RES),
797 ARG1,ARG2,ARG3);
798 }
799
PRE(sys_getpeername)800 PRE(sys_getpeername)
801 {
802 PRINT("sys_getpeername ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
803 PRE_REG_READ3(long, "getpeername",
804 int, s, struct sockaddr *, name, int *, namelen);
805 ML_(generic_PRE_sys_getpeername)(tid, ARG1,ARG2,ARG3);
806 }
POST(sys_getpeername)807 POST(sys_getpeername)
808 {
809 vg_assert(SUCCESS);
810 ML_(generic_POST_sys_getpeername)(tid, VG_(mk_SysRes_Success)(RES),
811 ARG1,ARG2,ARG3);
812 }
813
PRE(sys_socketpair)814 PRE(sys_socketpair)
815 {
816 PRINT("sys_socketpair ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
817 PRE_REG_READ4(long, "socketpair",
818 int, d, int, type, int, protocol, int*, sv);
819 ML_(generic_PRE_sys_socketpair)(tid, ARG1,ARG2,ARG3,ARG4);
820 }
POST(sys_socketpair)821 POST(sys_socketpair)
822 {
823 vg_assert(SUCCESS);
824 ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
825 ARG1,ARG2,ARG3,ARG4);
826 }
827
PRE(sys_semget)828 PRE(sys_semget)
829 {
830 PRINT("sys_semget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
831 PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
832 }
833
PRE(sys_semop)834 PRE(sys_semop)
835 {
836 *flags |= SfMayBlock;
837 PRINT("sys_semop ( %ld, %#lx, %lu )",ARG1,ARG2,ARG3);
838 PRE_REG_READ3(long, "semop",
839 int, semid, struct sembuf *, sops, unsigned, nsoops);
840 ML_(generic_PRE_sys_semop)(tid, ARG1,ARG2,ARG3);
841 }
842
PRE(sys_semtimedop)843 PRE(sys_semtimedop)
844 {
845 *flags |= SfMayBlock;
846 PRINT("sys_semtimedop ( %ld, %#lx, %lu, %#lx )",ARG1,ARG2,ARG3,ARG4);
847 PRE_REG_READ4(long, "semtimedop",
848 int, semid, struct sembuf *, sops, unsigned, nsoops,
849 struct timespec *, timeout);
850 ML_(generic_PRE_sys_semtimedop)(tid, ARG1,ARG2,ARG3,ARG4);
851 }
852
PRE(sys_semctl)853 PRE(sys_semctl)
854 {
855 switch (ARG3 & ~VKI_IPC_64) {
856 case VKI_IPC_INFO:
857 case VKI_SEM_INFO:
858 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
859 PRE_REG_READ4(long, "semctl",
860 int, semid, int, semnum, int, cmd, struct seminfo *, arg);
861 break;
862 case VKI_IPC_STAT:
863 case VKI_SEM_STAT:
864 case VKI_IPC_SET:
865 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
866 PRE_REG_READ4(long, "semctl",
867 int, semid, int, semnum, int, cmd, struct semid_ds *, arg);
868 break;
869 case VKI_GETALL:
870 case VKI_SETALL:
871 PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )",ARG1,ARG2,ARG3,ARG4);
872 PRE_REG_READ4(long, "semctl",
873 int, semid, int, semnum, int, cmd, unsigned short *, arg);
874 break;
875 default:
876 PRINT("sys_semctl ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
877 PRE_REG_READ3(long, "semctl",
878 int, semid, int, semnum, int, cmd);
879 break;
880 }
881 ML_(generic_PRE_sys_semctl)(tid, ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
882 }
POST(sys_semctl)883 POST(sys_semctl)
884 {
885 ML_(generic_POST_sys_semctl)(tid, RES,ARG1,ARG2,ARG3|VKI_IPC_64,ARG4);
886 }
887
PRE(sys_msgget)888 PRE(sys_msgget)
889 {
890 PRINT("sys_msgget ( %ld, %ld )",ARG1,ARG2);
891 PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
892 }
893
PRE(sys_msgsnd)894 PRE(sys_msgsnd)
895 {
896 PRINT("sys_msgsnd ( %ld, %#lx, %ld, %ld )",ARG1,ARG2,ARG3,ARG4);
897 PRE_REG_READ4(long, "msgsnd",
898 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz, int, msgflg);
899 ML_(linux_PRE_sys_msgsnd)(tid, ARG1,ARG2,ARG3,ARG4);
900 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
901 *flags |= SfMayBlock;
902 }
903
PRE(sys_msgrcv)904 PRE(sys_msgrcv)
905 {
906 PRINT("sys_msgrcv ( %ld, %#lx, %ld, %ld, %ld )",ARG1,ARG2,ARG3,ARG4,ARG5);
907 PRE_REG_READ5(long, "msgrcv",
908 int, msqid, struct msgbuf *, msgp, vki_size_t, msgsz,
909 long, msgytp, int, msgflg);
910 ML_(linux_PRE_sys_msgrcv)(tid, ARG1,ARG2,ARG3,ARG4,ARG5);
911 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
912 *flags |= SfMayBlock;
913 }
POST(sys_msgrcv)914 POST(sys_msgrcv)
915 {
916 ML_(linux_POST_sys_msgrcv)(tid, RES,ARG1,ARG2,ARG3,ARG4,ARG5);
917 }
918
PRE(sys_msgctl)919 PRE(sys_msgctl)
920 {
921 PRINT("sys_msgctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
922 PRE_REG_READ3(long, "msgctl",
923 int, msqid, int, cmd, struct msqid_ds *, buf);
924 ML_(linux_PRE_sys_msgctl)(tid, ARG1,ARG2,ARG3);
925 }
POST(sys_msgctl)926 POST(sys_msgctl)
927 {
928 ML_(linux_POST_sys_msgctl)(tid, RES,ARG1,ARG2,ARG3);
929 }
930
PRE(sys_shmget)931 PRE(sys_shmget)
932 {
933 PRINT("sys_shmget ( %ld, %ld, %ld )",ARG1,ARG2,ARG3);
934 PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
935 }
936
PRE(wrap_sys_shmat)937 PRE(wrap_sys_shmat)
938 {
939 UWord arg2tmp;
940 PRINT("wrap_sys_shmat ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3);
941 PRE_REG_READ3(long, "shmat",
942 int, shmid, const void *, shmaddr, int, shmflg);
943 arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1,ARG2,ARG3);
944 if (arg2tmp == 0)
945 SET_STATUS_Failure( VKI_EINVAL );
946 else
947 ARG2 = arg2tmp; // used in POST
948 }
POST(wrap_sys_shmat)949 POST(wrap_sys_shmat)
950 {
951 ML_(generic_POST_sys_shmat)(tid, RES,ARG1,ARG2,ARG3);
952 }
953
PRE(sys_shmdt)954 PRE(sys_shmdt)
955 {
956 PRINT("sys_shmdt ( %#lx )",ARG1);
957 PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
958 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
959 SET_STATUS_Failure( VKI_EINVAL );
960 }
POST(sys_shmdt)961 POST(sys_shmdt)
962 {
963 ML_(generic_POST_sys_shmdt)(tid, RES,ARG1);
964 }
965
PRE(sys_shmctl)966 PRE(sys_shmctl)
967 {
968 PRINT("sys_shmctl ( %ld, %ld, %#lx )",ARG1,ARG2,ARG3);
969 PRE_REG_READ3(long, "shmctl",
970 int, shmid, int, cmd, struct shmid_ds *, buf);
971 ML_(generic_PRE_sys_shmctl)(tid, ARG1,ARG2|VKI_IPC_64,ARG3);
972 }
POST(sys_shmctl)973 POST(sys_shmctl)
974 {
975 ML_(generic_POST_sys_shmctl)(tid, RES,ARG1,ARG2|VKI_IPC_64,ARG3);
976 }
977
PRE(sys_fadvise64)978 PRE(sys_fadvise64)
979 {
980 PRINT("sys_fadvise64 ( %ld, %ld, %lu, %ld )", ARG1,ARG2,ARG3,ARG4);
981 PRE_REG_READ4(long, "fadvise64",
982 int, fd, vki_loff_t, offset, vki_size_t, len, int, advice);
983 }
984
PRE(sys_mmap)985 PRE(sys_mmap)
986 {
987 SysRes r;
988
989 PRINT("sys_mmap ( %#lx, %llu, %ld, %ld, %d, %ld )",
990 ARG1, (ULong)ARG2, ARG3, ARG4, (Int)ARG5, ARG6 );
991 PRE_REG_READ6(long, "mmap",
992 unsigned long, start, unsigned long, length,
993 unsigned long, prot, unsigned long, flags,
994 unsigned long, fd, unsigned long, offset);
995
996 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
997 SET_STATUS_from_SysRes(r);
998 }
999
1000
1001 /* ---------------------------------------------------------------
1002 PRE/POST wrappers for AMD64/Linux-variant specific syscalls
1003 ------------------------------------------------------------ */
1004
PRE(sys_syscall184)1005 PRE(sys_syscall184)
1006 {
1007 Int err;
1008
1009 /* 184 is used by sys_bproc. If we're not on a declared bproc
1010 variant, fail in the usual way, since it is otherwise unused. */
1011
1012 if (!VG_(strstr)(VG_(clo_kernel_variant), "bproc")) {
1013 PRINT("non-existent syscall! (syscall 184)");
1014 PRE_REG_READ0(long, "ni_syscall(184)");
1015 SET_STATUS_Failure( VKI_ENOSYS );
1016 return;
1017 }
1018
1019 err = ML_(linux_variant_PRE_sys_bproc)( ARG1, ARG2, ARG3,
1020 ARG4, ARG5, ARG6 );
1021 if (err) {
1022 SET_STATUS_Failure( err );
1023 return;
1024 }
1025 /* Let it go through. */
1026 *flags |= SfMayBlock; /* who knows? play safe. */
1027 }
1028
POST(sys_syscall184)1029 POST(sys_syscall184)
1030 {
1031 ML_(linux_variant_POST_sys_bproc)( ARG1, ARG2, ARG3,
1032 ARG4, ARG5, ARG6 );
1033 }
1034
1035 #undef PRE
1036 #undef POST
1037
1038
1039 /* ---------------------------------------------------------------------
1040 The AMD64/Linux syscall table
1041 ------------------------------------------------------------------ */
1042
1043 /* Add an amd64-linux specific wrapper to a syscall table. */
1044 #define PLAX_(const, name) WRAPPER_ENTRY_X_(amd64_linux, const, name)
1045 #define PLAXY(const, name) WRAPPER_ENTRY_XY(amd64_linux, const, name)
1046
1047 // This table maps from __NR_xxx syscall numbers (from
1048 // linux/include/asm-x86_64/unistd.h) to the appropriate PRE/POST sys_foo()
1049 // wrappers on AMD64 (as per sys_call_table in
1050 // linux/arch/x86_64/kernel/entry.S).
1051 //
1052 // When implementing these wrappers, you need to work out if the wrapper is
1053 // generic, Linux-only (but arch-independent), or AMD64/Linux only.
1054
1055 static SyscallTableEntry syscall_table[] = {
1056 GENXY(__NR_read, sys_read), // 0
1057 GENX_(__NR_write, sys_write), // 1
1058 GENXY(__NR_open, sys_open), // 2
1059 GENXY(__NR_close, sys_close), // 3
1060 GENXY(__NR_stat, sys_newstat), // 4
1061
1062 GENXY(__NR_fstat, sys_newfstat), // 5
1063 GENXY(__NR_lstat, sys_newlstat), // 6
1064 GENXY(__NR_poll, sys_poll), // 7
1065 LINX_(__NR_lseek, sys_lseek), // 8
1066 PLAX_(__NR_mmap, sys_mmap), // 9
1067
1068 GENXY(__NR_mprotect, sys_mprotect), // 10
1069 GENXY(__NR_munmap, sys_munmap), // 11
1070 GENX_(__NR_brk, sys_brk), // 12
1071 LINXY(__NR_rt_sigaction, sys_rt_sigaction), // 13
1072 LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 14
1073
1074 PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 15
1075 LINXY(__NR_ioctl, sys_ioctl), // 16
1076 GENXY(__NR_pread64, sys_pread64), // 17
1077 GENX_(__NR_pwrite64, sys_pwrite64), // 18
1078 GENXY(__NR_readv, sys_readv), // 19
1079
1080 GENX_(__NR_writev, sys_writev), // 20
1081 GENX_(__NR_access, sys_access), // 21
1082 LINXY(__NR_pipe, sys_pipe), // 22
1083 GENX_(__NR_select, sys_select), // 23
1084 LINX_(__NR_sched_yield, sys_sched_yield), // 24
1085
1086 GENX_(__NR_mremap, sys_mremap), // 25
1087 GENX_(__NR_msync, sys_msync), // 26
1088 GENXY(__NR_mincore, sys_mincore), // 27
1089 GENX_(__NR_madvise, sys_madvise), // 28
1090 PLAX_(__NR_shmget, sys_shmget), // 29
1091
1092 PLAXY(__NR_shmat, wrap_sys_shmat), // 30
1093 PLAXY(__NR_shmctl, sys_shmctl), // 31
1094 GENXY(__NR_dup, sys_dup), // 32
1095 GENXY(__NR_dup2, sys_dup2), // 33
1096 GENX_(__NR_pause, sys_pause), // 34
1097
1098 GENXY(__NR_nanosleep, sys_nanosleep), // 35
1099 GENXY(__NR_getitimer, sys_getitimer), // 36
1100 GENX_(__NR_alarm, sys_alarm), // 37
1101 GENXY(__NR_setitimer, sys_setitimer), // 38
1102 GENX_(__NR_getpid, sys_getpid), // 39
1103
1104 LINXY(__NR_sendfile, sys_sendfile), // 40
1105 PLAXY(__NR_socket, sys_socket), // 41
1106 PLAX_(__NR_connect, sys_connect), // 42
1107 PLAXY(__NR_accept, sys_accept), // 43
1108 PLAX_(__NR_sendto, sys_sendto), // 44
1109
1110 PLAXY(__NR_recvfrom, sys_recvfrom), // 45
1111 PLAX_(__NR_sendmsg, sys_sendmsg), // 46
1112 PLAXY(__NR_recvmsg, sys_recvmsg), // 47
1113 PLAX_(__NR_shutdown, sys_shutdown), // 48
1114 PLAX_(__NR_bind, sys_bind), // 49
1115
1116 PLAX_(__NR_listen, sys_listen), // 50
1117 PLAXY(__NR_getsockname, sys_getsockname), // 51
1118 PLAXY(__NR_getpeername, sys_getpeername), // 52
1119 PLAXY(__NR_socketpair, sys_socketpair), // 53
1120 PLAX_(__NR_setsockopt, sys_setsockopt), // 54
1121
1122 PLAXY(__NR_getsockopt, sys_getsockopt), // 55
1123 PLAX_(__NR_clone, sys_clone), // 56
1124 GENX_(__NR_fork, sys_fork), // 57
1125 GENX_(__NR_vfork, sys_fork), // 58 treat as fork
1126 GENX_(__NR_execve, sys_execve), // 59
1127
1128 GENX_(__NR_exit, sys_exit), // 60
1129 GENXY(__NR_wait4, sys_wait4), // 61
1130 GENX_(__NR_kill, sys_kill), // 62
1131 GENXY(__NR_uname, sys_newuname), // 63
1132 PLAX_(__NR_semget, sys_semget), // 64
1133
1134 PLAX_(__NR_semop, sys_semop), // 65
1135 PLAXY(__NR_semctl, sys_semctl), // 66
1136 PLAXY(__NR_shmdt, sys_shmdt), // 67
1137 PLAX_(__NR_msgget, sys_msgget), // 68
1138 PLAX_(__NR_msgsnd, sys_msgsnd), // 69
1139
1140 PLAXY(__NR_msgrcv, sys_msgrcv), // 70
1141 PLAXY(__NR_msgctl, sys_msgctl), // 71
1142 LINXY(__NR_fcntl, sys_fcntl), // 72
1143 GENX_(__NR_flock, sys_flock), // 73
1144 GENX_(__NR_fsync, sys_fsync), // 74
1145
1146 GENX_(__NR_fdatasync, sys_fdatasync), // 75
1147 GENX_(__NR_truncate, sys_truncate), // 76
1148 GENX_(__NR_ftruncate, sys_ftruncate), // 77
1149 GENXY(__NR_getdents, sys_getdents), // 78
1150 GENXY(__NR_getcwd, sys_getcwd), // 79
1151
1152 GENX_(__NR_chdir, sys_chdir), // 80
1153 GENX_(__NR_fchdir, sys_fchdir), // 81
1154 GENX_(__NR_rename, sys_rename), // 82
1155 GENX_(__NR_mkdir, sys_mkdir), // 83
1156 GENX_(__NR_rmdir, sys_rmdir), // 84
1157
1158 GENXY(__NR_creat, sys_creat), // 85
1159 GENX_(__NR_link, sys_link), // 86
1160 GENX_(__NR_unlink, sys_unlink), // 87
1161 GENX_(__NR_symlink, sys_symlink), // 88
1162 GENX_(__NR_readlink, sys_readlink), // 89
1163
1164 GENX_(__NR_chmod, sys_chmod), // 90
1165 GENX_(__NR_fchmod, sys_fchmod), // 91
1166 GENX_(__NR_chown, sys_chown), // 92
1167 GENX_(__NR_fchown, sys_fchown), // 93
1168 GENX_(__NR_lchown, sys_lchown), // 94
1169
1170 GENX_(__NR_umask, sys_umask), // 95
1171 GENXY(__NR_gettimeofday, sys_gettimeofday), // 96
1172 GENXY(__NR_getrlimit, sys_getrlimit), // 97
1173 GENXY(__NR_getrusage, sys_getrusage), // 98
1174 LINXY(__NR_sysinfo, sys_sysinfo), // 99
1175
1176 GENXY(__NR_times, sys_times), // 100
1177 PLAXY(__NR_ptrace, sys_ptrace), // 101
1178 GENX_(__NR_getuid, sys_getuid), // 102
1179 LINXY(__NR_syslog, sys_syslog), // 103
1180 GENX_(__NR_getgid, sys_getgid), // 104
1181
1182 GENX_(__NR_setuid, sys_setuid), // 105
1183 GENX_(__NR_setgid, sys_setgid), // 106
1184 GENX_(__NR_geteuid, sys_geteuid), // 107
1185 GENX_(__NR_getegid, sys_getegid), // 108
1186 GENX_(__NR_setpgid, sys_setpgid), // 109
1187
1188 GENX_(__NR_getppid, sys_getppid), // 110
1189 GENX_(__NR_getpgrp, sys_getpgrp), // 111
1190 GENX_(__NR_setsid, sys_setsid), // 112
1191 GENX_(__NR_setreuid, sys_setreuid), // 113
1192 GENX_(__NR_setregid, sys_setregid), // 114
1193
1194 GENXY(__NR_getgroups, sys_getgroups), // 115
1195 GENX_(__NR_setgroups, sys_setgroups), // 116
1196 LINX_(__NR_setresuid, sys_setresuid), // 117
1197 LINXY(__NR_getresuid, sys_getresuid), // 118
1198 LINX_(__NR_setresgid, sys_setresgid), // 119
1199
1200 LINXY(__NR_getresgid, sys_getresgid), // 120
1201 GENX_(__NR_getpgid, sys_getpgid), // 121
1202 LINX_(__NR_setfsuid, sys_setfsuid), // 122
1203 LINX_(__NR_setfsgid, sys_setfsgid), // 123
1204 GENX_(__NR_getsid, sys_getsid), // 124
1205
1206 LINXY(__NR_capget, sys_capget), // 125
1207 LINX_(__NR_capset, sys_capset), // 126
1208 LINXY(__NR_rt_sigpending, sys_rt_sigpending), // 127
1209 LINXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait),// 128
1210 LINXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo),// 129
1211
1212 LINX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 130
1213 GENXY(__NR_sigaltstack, sys_sigaltstack), // 131
1214 LINX_(__NR_utime, sys_utime), // 132
1215 GENX_(__NR_mknod, sys_mknod), // 133
1216 // (__NR_uselib, sys_uselib), // 134
1217
1218 LINX_(__NR_personality, sys_personality), // 135
1219 // (__NR_ustat, sys_ustat), // 136
1220 GENXY(__NR_statfs, sys_statfs), // 137
1221 GENXY(__NR_fstatfs, sys_fstatfs), // 138
1222 // (__NR_sysfs, sys_sysfs), // 139
1223
1224 GENX_(__NR_getpriority, sys_getpriority), // 140
1225 GENX_(__NR_setpriority, sys_setpriority), // 141
1226 LINXY(__NR_sched_setparam, sys_sched_setparam), // 142
1227 LINXY(__NR_sched_getparam, sys_sched_getparam), // 143
1228 LINX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 144
1229
1230 LINX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 145
1231 LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max), // 146
1232 LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min), // 147
1233 LINXY(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 148
1234 GENX_(__NR_mlock, sys_mlock), // 149
1235
1236 GENX_(__NR_munlock, sys_munlock), // 150
1237 GENX_(__NR_mlockall, sys_mlockall), // 151
1238 LINX_(__NR_munlockall, sys_munlockall), // 152
1239 LINX_(__NR_vhangup, sys_vhangup), // 153
1240 // (__NR_modify_ldt, sys_modify_ldt), // 154
1241
1242 // (__NR_pivot_root, sys_pivot_root), // 155
1243 LINXY(__NR__sysctl, sys_sysctl), // 156
1244 LINXY(__NR_prctl, sys_prctl), // 157
1245 PLAX_(__NR_arch_prctl, sys_arch_prctl), // 158
1246 LINXY(__NR_adjtimex, sys_adjtimex), // 159
1247
1248 GENX_(__NR_setrlimit, sys_setrlimit), // 160
1249 GENX_(__NR_chroot, sys_chroot), // 161
1250 GENX_(__NR_sync, sys_sync), // 162
1251 // (__NR_acct, sys_acct), // 163
1252 GENX_(__NR_settimeofday, sys_settimeofday), // 164
1253
1254 LINX_(__NR_mount, sys_mount), // 165
1255 LINX_(__NR_umount2, sys_umount), // 166
1256 // (__NR_swapon, sys_swapon), // 167
1257 // (__NR_swapoff, sys_swapoff), // 168
1258 // (__NR_reboot, sys_reboot), // 169
1259
1260 // (__NR_sethostname, sys_sethostname), // 170
1261 // (__NR_setdomainname, sys_setdomainname), // 171
1262 GENX_(__NR_iopl, sys_iopl), // 172
1263 LINX_(__NR_ioperm, sys_ioperm), // 173
1264 GENX_(__NR_create_module, sys_ni_syscall), // 174
1265
1266 LINX_(__NR_init_module, sys_init_module), // 175
1267 LINX_(__NR_delete_module, sys_delete_module), // 176
1268 // (__NR_get_kernel_syms, sys_ni_syscall), // 177
1269 // (__NR_query_module, sys_ni_syscall), // 178
1270 LINX_(__NR_quotactl, sys_quotactl), // 179
1271
1272 // (__NR_nfsservctl, sys_nfsservctl), // 180
1273 // (__NR_getpmsg, sys_ni_syscall), // 181
1274 // (__NR_putpmsg, sys_ni_syscall), // 182
1275 // (__NR_afs_syscall, sys_ni_syscall), // 183
1276 PLAXY(184, sys_syscall184), // 184 // sys_bproc?
1277
1278 // (__NR_security, sys_ni_syscall), // 185
1279 LINX_(__NR_gettid, sys_gettid), // 186
1280 LINX_(__NR_readahead, sys_readahead), // 187
1281 LINX_(__NR_setxattr, sys_setxattr), // 188
1282 LINX_(__NR_lsetxattr, sys_lsetxattr), // 189
1283
1284 LINX_(__NR_fsetxattr, sys_fsetxattr), // 190
1285 LINXY(__NR_getxattr, sys_getxattr), // 191
1286 LINXY(__NR_lgetxattr, sys_lgetxattr), // 192
1287 LINXY(__NR_fgetxattr, sys_fgetxattr), // 193
1288 LINXY(__NR_listxattr, sys_listxattr), // 194
1289
1290 LINXY(__NR_llistxattr, sys_llistxattr), // 195
1291 LINXY(__NR_flistxattr, sys_flistxattr), // 196
1292 LINX_(__NR_removexattr, sys_removexattr), // 197
1293 LINX_(__NR_lremovexattr, sys_lremovexattr), // 198
1294 LINX_(__NR_fremovexattr, sys_fremovexattr), // 199
1295
1296 LINXY(__NR_tkill, sys_tkill), // 200
1297 GENXY(__NR_time, sys_time), /*was sys_time64*/ // 201
1298 LINXY(__NR_futex, sys_futex), // 202
1299 LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 203
1300 LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 204
1301
1302 // (__NR_set_thread_area, sys_ni_syscall), // 205
1303 LINXY(__NR_io_setup, sys_io_setup), // 206
1304 LINX_(__NR_io_destroy, sys_io_destroy), // 207
1305 LINXY(__NR_io_getevents, sys_io_getevents), // 208
1306 LINX_(__NR_io_submit, sys_io_submit), // 209
1307
1308 LINXY(__NR_io_cancel, sys_io_cancel), // 210
1309 // (__NR_get_thread_area, sys_ni_syscall), // 211
1310 LINXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 212
1311 LINXY(__NR_epoll_create, sys_epoll_create), // 213
1312 // (__NR_epoll_ctl_old, sys_ni_syscall), // 214
1313
1314 // (__NR_epoll_wait_old, sys_ni_syscall), // 215
1315 // (__NR_remap_file_pages, sys_remap_file_pages)// 216
1316 GENXY(__NR_getdents64, sys_getdents64), // 217
1317 LINX_(__NR_set_tid_address, sys_set_tid_address),// 218
1318 // (__NR_restart_syscall, sys_restart_syscall),// 219
1319
1320 PLAX_(__NR_semtimedop, sys_semtimedop), // 220
1321 PLAX_(__NR_fadvise64, sys_fadvise64), // 221
1322 LINXY(__NR_timer_create, sys_timer_create), // 222
1323 LINXY(__NR_timer_settime, sys_timer_settime), // 223
1324 LINXY(__NR_timer_gettime, sys_timer_gettime), // 224
1325
1326 LINX_(__NR_timer_getoverrun, sys_timer_getoverrun), // 225
1327 LINX_(__NR_timer_delete, sys_timer_delete), // 226
1328 LINX_(__NR_clock_settime, sys_clock_settime), // 227
1329 LINXY(__NR_clock_gettime, sys_clock_gettime), // 228
1330 LINXY(__NR_clock_getres, sys_clock_getres), // 229
1331
1332 LINXY(__NR_clock_nanosleep, sys_clock_nanosleep),// 230
1333 LINX_(__NR_exit_group, sys_exit_group), // 231
1334 LINXY(__NR_epoll_wait, sys_epoll_wait), // 232
1335 LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 233
1336 LINXY(__NR_tgkill, sys_tgkill), // 234
1337
1338 GENX_(__NR_utimes, sys_utimes), // 235
1339 // (__NR_vserver, sys_ni_syscall), // 236
1340 LINX_(__NR_mbind, sys_mbind), // 237
1341 LINX_(__NR_set_mempolicy, sys_set_mempolicy), // 238
1342 LINXY(__NR_get_mempolicy, sys_get_mempolicy), // 239
1343
1344 LINXY(__NR_mq_open, sys_mq_open), // 240
1345 LINX_(__NR_mq_unlink, sys_mq_unlink), // 241
1346 LINX_(__NR_mq_timedsend, sys_mq_timedsend), // 242
1347 LINXY(__NR_mq_timedreceive, sys_mq_timedreceive),// 243
1348 LINX_(__NR_mq_notify, sys_mq_notify), // 244
1349
1350 LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // 245
1351 // (__NR_kexec_load, sys_ni_syscall), // 246
1352 LINXY(__NR_waitid, sys_waitid), // 247
1353 LINX_(__NR_add_key, sys_add_key), // 248
1354 LINX_(__NR_request_key, sys_request_key), // 249
1355
1356 LINXY(__NR_keyctl, sys_keyctl), // 250
1357 LINX_(__NR_ioprio_set, sys_ioprio_set), // 251
1358 LINX_(__NR_ioprio_get, sys_ioprio_get), // 252
1359 LINX_(__NR_inotify_init, sys_inotify_init), // 253
1360 LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 254
1361
1362 LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 255
1363 // LINX_(__NR_migrate_pages, sys_migrate_pages), // 256
1364 LINXY(__NR_openat, sys_openat), // 257
1365 LINX_(__NR_mkdirat, sys_mkdirat), // 258
1366 LINX_(__NR_mknodat, sys_mknodat), // 259
1367
1368 LINX_(__NR_fchownat, sys_fchownat), // 260
1369 LINX_(__NR_futimesat, sys_futimesat), // 261
1370 LINXY(__NR_newfstatat, sys_newfstatat), // 262
1371 LINX_(__NR_unlinkat, sys_unlinkat), // 263
1372 LINX_(__NR_renameat, sys_renameat), // 264
1373
1374 LINX_(__NR_linkat, sys_linkat), // 265
1375 LINX_(__NR_symlinkat, sys_symlinkat), // 266
1376 LINX_(__NR_readlinkat, sys_readlinkat), // 267
1377 LINX_(__NR_fchmodat, sys_fchmodat), // 268
1378 LINX_(__NR_faccessat, sys_faccessat), // 269
1379
1380 LINX_(__NR_pselect6, sys_pselect6), // 270
1381 LINXY(__NR_ppoll, sys_ppoll), // 271
1382 // LINX_(__NR_unshare, sys_unshare), // 272
1383 LINX_(__NR_set_robust_list, sys_set_robust_list), // 273
1384 LINXY(__NR_get_robust_list, sys_get_robust_list), // 274
1385
1386 LINX_(__NR_splice, sys_splice), // 275
1387 // LINX_(__NR_tee, sys_ni_syscall), // 276
1388 LINX_(__NR_sync_file_range, sys_sync_file_range), // 277
1389 // LINX_(__NR_vmsplice, sys_ni_syscall), // 278
1390 // LINX_(__NR_move_pages, sys_ni_syscall), // 279
1391
1392 LINX_(__NR_utimensat, sys_utimensat), // 280
1393 LINXY(__NR_epoll_pwait, sys_epoll_pwait), // 281
1394 LINXY(__NR_signalfd, sys_signalfd), // 282
1395 LINXY(__NR_timerfd_create, sys_timerfd_create), // 283
1396 LINX_(__NR_eventfd, sys_eventfd), // 284
1397
1398 LINX_(__NR_fallocate, sys_fallocate), // 285
1399 LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 286
1400 LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 287
1401 PLAXY(__NR_accept4, sys_accept4), // 288
1402 LINXY(__NR_signalfd4, sys_signalfd4), // 289
1403
1404 LINX_(__NR_eventfd2, sys_eventfd2), // 290
1405 LINXY(__NR_epoll_create1, sys_epoll_create1), // 291
1406 LINXY(__NR_dup3, sys_dup3), // 292
1407 LINXY(__NR_pipe2, sys_pipe2), // 293
1408 LINXY(__NR_inotify_init1, sys_inotify_init1), // 294
1409
1410 LINXY(__NR_preadv, sys_preadv), // 295
1411 LINX_(__NR_pwritev, sys_pwritev), // 296
1412 LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 297
1413 LINXY(__NR_perf_event_open, sys_perf_event_open), // 298
1414 // LINX_(__NR_recvmmsg, sys_ni_syscall), // 299
1415
1416 // LINX_(__NR_fanotify_init, sys_ni_syscall), // 300
1417 // LINX_(__NR_fanotify_mark, sys_ni_syscall), // 301
1418 LINXY(__NR_prlimit64, sys_prlimit64) // 302
1419 // LINX_(__NR_name_to_handle_at, sys_ni_syscall), // 303
1420 // LINX_(__NR_open_by_handle_at, sys_ni_syscall), // 304
1421
1422 // LINX_(__NR_clock_adjtime, sys_ni_syscall), // 305
1423 // LINX_(__NR_syncfs, sys_ni_syscall), // 306
1424 // LINX_(__NR_sendmmsg, sys_ni_syscall), // 307
1425 // LINX_(__NR_setns, sys_ni_syscall), // 308
1426 };
1427
ML_(get_linux_syscall_entry)1428 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1429 {
1430 const UInt syscall_table_size
1431 = sizeof(syscall_table) / sizeof(syscall_table[0]);
1432
1433 /* Is it in the contiguous initial section of the table? */
1434 if (sysno < syscall_table_size) {
1435 SyscallTableEntry* sys = &syscall_table[sysno];
1436 if (sys->before == NULL)
1437 return NULL; /* no entry */
1438 else
1439 return sys;
1440 }
1441
1442 /* Can't find a wrapper */
1443 return NULL;
1444 }
1445
1446 #endif // defined(VGP_amd64_linux)
1447
1448 /*--------------------------------------------------------------------*/
1449 /*--- end ---*/
1450 /*--------------------------------------------------------------------*/
1451