drd: Add a consistency check
[valgrind.git] / coregrind / m_syswrap / syswrap-x86-linux.c
blobdcbf4251e3dedc13a70de11992eb51e050f969a2
2 /*--------------------------------------------------------------------*/
3 /*--- Platform-specific syscalls stuff. syswrap-x86-linux.c ---*/
4 /*--------------------------------------------------------------------*/
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
10 Copyright (C) 2000-2013 Nicholas Nethercote
11 njn@valgrind.org
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.
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.
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.
28 The GNU General Public License is contained in the file COPYING.
31 #if defined(VGP_x86_linux)
33 /* TODO/FIXME jrs 20050207: assignments to the syscall return result
34 in interrupted_syscall() need to be reviewed. They don't seem
35 to assign the shadow state.
38 #include "pub_core_basics.h"
39 #include "pub_core_vki.h"
40 #include "pub_core_vkiscnums.h"
41 #include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
42 #include "pub_core_threadstate.h"
43 #include "pub_core_aspacemgr.h"
44 #include "pub_core_debuglog.h"
45 #include "pub_core_libcbase.h"
46 #include "pub_core_libcassert.h"
47 #include "pub_core_libcprint.h"
48 #include "pub_core_libcproc.h"
49 #include "pub_core_libcsignal.h"
50 #include "pub_core_mallocfree.h"
51 #include "pub_core_options.h"
52 #include "pub_core_scheduler.h"
53 #include "pub_core_sigframe.h" // For VG_(sigframe_destroy)()
54 #include "pub_core_signals.h"
55 #include "pub_core_syscall.h"
56 #include "pub_core_syswrap.h"
57 #include "pub_core_tooliface.h"
58 #include "pub_core_stacks.h" // VG_(register_stack)
60 #include "priv_types_n_macros.h"
61 #include "priv_syswrap-generic.h" /* for decls of generic wrappers */
62 #include "priv_syswrap-linux.h" /* for decls of linux-ish wrappers */
63 #include "priv_syswrap-linux-variants.h" /* decls of linux variant wrappers */
64 #include "priv_syswrap-main.h"
67 /* ---------------------------------------------------------------------
68 clone() handling
69 ------------------------------------------------------------------ */
71 /* Call f(arg1), but first switch stacks, using 'stack' as the new
72 stack, and use 'retaddr' as f's return-to address. Also, clear all
73 the integer registers before entering f.*/
74 __attribute__((noreturn))
75 void ML_(call_on_new_stack_0_1) ( Addr stack,
76 Addr retaddr,
77 void (*f)(Word),
78 Word arg1 );
79 // 4(%esp) == stack
80 // 8(%esp) == retaddr
81 // 12(%esp) == f
82 // 16(%esp) == arg1
83 asm(
84 ".text\n"
85 ".globl vgModuleLocal_call_on_new_stack_0_1\n"
86 "vgModuleLocal_call_on_new_stack_0_1:\n"
87 " movl %esp, %esi\n" // remember old stack pointer
88 " movl 4(%esi), %esp\n" // set stack
89 " pushl 16(%esi)\n" // arg1 to stack
90 " pushl 8(%esi)\n" // retaddr to stack
91 " pushl 12(%esi)\n" // f to stack
92 " movl $0, %eax\n" // zero all GP regs
93 " movl $0, %ebx\n"
94 " movl $0, %ecx\n"
95 " movl $0, %edx\n"
96 " movl $0, %esi\n"
97 " movl $0, %edi\n"
98 " movl $0, %ebp\n"
99 " ret\n" // jump to f
100 " ud2\n" // should never get here
101 ".previous\n"
106 Perform a clone system call. clone is strange because it has
107 fork()-like return-twice semantics, so it needs special
108 handling here.
110 Upon entry, we have:
112 int (fn)(void*) in 0+FSZ(%esp)
113 void* child_stack in 4+FSZ(%esp)
114 int flags in 8+FSZ(%esp)
115 void* arg in 12+FSZ(%esp)
116 pid_t* child_tid in 16+FSZ(%esp)
117 pid_t* parent_tid in 20+FSZ(%esp)
118 void* tls_ptr in 24+FSZ(%esp)
120 System call requires:
122 int $__NR_clone in %eax
123 int flags in %ebx
124 void* child_stack in %ecx
125 pid_t* parent_tid in %edx
126 pid_t* child_tid in %edi
127 void* tls_ptr in %esi
129 Returns an Int encoded in the linux-x86 way, not a SysRes.
131 #define FSZ "4+4+4+4" /* frame size = retaddr+ebx+edi+esi */
132 #define __NR_CLONE VG_STRINGIFY(__NR_clone)
133 #define __NR_EXIT VG_STRINGIFY(__NR_exit)
135 extern
136 Int do_syscall_clone_x86_linux ( Word (*fn)(void *),
137 void* stack,
138 Int flags,
139 void* arg,
140 Int* child_tid,
141 Int* parent_tid,
142 vki_modify_ldt_t * );
143 asm(
144 ".text\n"
145 ".globl do_syscall_clone_x86_linux\n"
146 "do_syscall_clone_x86_linux:\n"
147 " push %ebx\n"
148 " push %edi\n"
149 " push %esi\n"
151 /* set up child stack with function and arg */
152 " movl 4+"FSZ"(%esp), %ecx\n" /* syscall arg2: child stack */
153 " movl 12+"FSZ"(%esp), %ebx\n" /* fn arg */
154 " movl 0+"FSZ"(%esp), %eax\n" /* fn */
155 " lea -8(%ecx), %ecx\n" /* make space on stack */
156 " movl %ebx, 4(%ecx)\n" /* fn arg */
157 " movl %eax, 0(%ecx)\n" /* fn */
159 /* get other args to clone */
160 " movl 8+"FSZ"(%esp), %ebx\n" /* syscall arg1: flags */
161 " movl 20+"FSZ"(%esp), %edx\n" /* syscall arg3: parent tid * */
162 " movl 16+"FSZ"(%esp), %edi\n" /* syscall arg5: child tid * */
163 " movl 24+"FSZ"(%esp), %esi\n" /* syscall arg4: tls_ptr * */
164 " movl $"__NR_CLONE", %eax\n"
165 " int $0x80\n" /* clone() */
166 " testl %eax, %eax\n" /* child if retval == 0 */
167 " jnz 1f\n"
169 /* CHILD - call thread function */
170 " popl %eax\n"
171 " call *%eax\n" /* call fn */
173 /* exit with result */
174 " movl %eax, %ebx\n" /* arg1: return value from fn */
175 " movl $"__NR_EXIT", %eax\n"
176 " int $0x80\n"
178 /* Hm, exit returned */
179 " ud2\n"
181 "1:\n" /* PARENT or ERROR */
182 " pop %esi\n"
183 " pop %edi\n"
184 " pop %ebx\n"
185 " ret\n"
186 ".previous\n"
189 #undef FSZ
190 #undef __NR_CLONE
191 #undef __NR_EXIT
194 // forward declarations
195 static void setup_child ( ThreadArchState*, ThreadArchState*, Bool );
196 static SysRes sys_set_thread_area ( ThreadId, vki_modify_ldt_t* );
199 When a client clones, we need to keep track of the new thread. This means:
200 1. allocate a ThreadId+ThreadState+stack for the the thread
202 2. initialize the thread's new VCPU state
204 3. create the thread using the same args as the client requested,
205 but using the scheduler entrypoint for EIP, and a separate stack
206 for ESP.
208 static SysRes do_clone ( ThreadId ptid,
209 UInt flags, Addr esp,
210 Int* parent_tidptr,
211 Int* child_tidptr,
212 vki_modify_ldt_t *tlsinfo)
214 static const Bool debug = False;
216 ThreadId ctid = VG_(alloc_ThreadState)();
217 ThreadState* ptst = VG_(get_ThreadState)(ptid);
218 ThreadState* ctst = VG_(get_ThreadState)(ctid);
219 UWord* stack;
220 SysRes res;
221 Int eax;
222 vki_sigset_t blockall, savedmask;
224 VG_(sigfillset)(&blockall);
226 vg_assert(VG_(is_running_thread)(ptid));
227 vg_assert(VG_(is_valid_tid)(ctid));
229 stack = (UWord*)ML_(allocstack)(ctid);
230 if (stack == NULL) {
231 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
232 goto out;
235 /* Copy register state
237 Both parent and child return to the same place, and the code
238 following the clone syscall works out which is which, so we
239 don't need to worry about it.
241 The parent gets the child's new tid returned from clone, but the
242 child gets 0.
244 If the clone call specifies a NULL esp for the new thread, then
245 it actually gets a copy of the parent's esp.
247 /* Note: the clone call done by the Quadrics Elan3 driver specifies
248 clone flags of 0xF00, and it seems to rely on the assumption
249 that the child inherits a copy of the parent's GDT.
250 setup_child takes care of setting that up. */
251 setup_child( &ctst->arch, &ptst->arch, True );
253 /* Make sys_clone appear to have returned Success(0) in the
254 child. */
255 ctst->arch.vex.guest_EAX = 0;
257 if (esp != 0)
258 ctst->arch.vex.guest_ESP = esp;
260 ctst->os_state.parent = ptid;
262 /* inherit signal mask */
263 ctst->sig_mask = ptst->sig_mask;
264 ctst->tmp_sig_mask = ptst->sig_mask;
266 /* Start the child with its threadgroup being the same as the
267 parent's. This is so that any exit_group calls that happen
268 after the child is created but before it sets its
269 os_state.threadgroup field for real (in thread_wrapper in
270 syswrap-linux.c), really kill the new thread. a.k.a this avoids
271 a race condition in which the thread is unkillable (via
272 exit_group) because its threadgroup is not set. The race window
273 is probably only a few hundred or a few thousand cycles long.
274 See #226116. */
275 ctst->os_state.threadgroup = ptst->os_state.threadgroup;
277 ML_(guess_and_register_stack) (esp, ctst);
279 /* Assume the clone will succeed, and tell any tool that wants to
280 know that this thread has come into existence. We cannot defer
281 it beyond this point because sys_set_thread_area, just below,
282 causes tCheck to assert by making references to the new ThreadId
283 if we don't state the new thread exists prior to that point.
284 If the clone fails, we'll send out a ll_exit notification for it
285 at the out: label below, to clean up. */
286 vg_assert(VG_(owns_BigLock_LL)(ptid));
287 VG_TRACK ( pre_thread_ll_create, ptid, ctid );
289 if (flags & VKI_CLONE_SETTLS) {
290 if (debug)
291 VG_(printf)("clone child has SETTLS: tls info at %p: idx=%d "
292 "base=%#lx limit=%x; esp=%#x fs=%x gs=%x\n",
293 tlsinfo, tlsinfo->entry_number,
294 tlsinfo->base_addr, tlsinfo->limit,
295 ptst->arch.vex.guest_ESP,
296 ctst->arch.vex.guest_FS, ctst->arch.vex.guest_GS);
297 res = sys_set_thread_area(ctid, tlsinfo);
298 if (sr_isError(res))
299 goto out;
302 flags &= ~VKI_CLONE_SETTLS;
304 /* start the thread with everything blocked */
305 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
307 /* Create the new thread */
308 eax = do_syscall_clone_x86_linux(
309 ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid],
310 child_tidptr, parent_tidptr, NULL
312 res = VG_(mk_SysRes_x86_linux)( eax );
314 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
316 out:
317 if (sr_isError(res)) {
318 /* clone failed */
319 VG_(cleanup_thread)(&ctst->arch);
320 ctst->status = VgTs_Empty;
321 /* oops. Better tell the tool the thread exited in a hurry :-) */
322 VG_TRACK( pre_thread_ll_exit, ctid );
325 return res;
329 /* ---------------------------------------------------------------------
330 LDT/GDT simulation
331 ------------------------------------------------------------------ */
333 /* Details of the LDT simulation
334 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
336 When a program runs natively, the linux kernel allows each *thread*
337 in it to have its own LDT. Almost all programs never do this --
338 it's wildly unportable, after all -- and so the kernel never
339 allocates the structure, which is just as well as an LDT occupies
340 64k of memory (8192 entries of size 8 bytes).
342 A thread may choose to modify its LDT entries, by doing the
343 __NR_modify_ldt syscall. In such a situation the kernel will then
344 allocate an LDT structure for it. Each LDT entry is basically a
345 (base, limit) pair. A virtual address in a specific segment is
346 translated to a linear address by adding the segment's base value.
347 In addition, the virtual address must not exceed the limit value.
349 To use an LDT entry, a thread loads one of the segment registers
350 (%cs, %ss, %ds, %es, %fs, %gs) with the index of the LDT entry (0
351 .. 8191) it wants to use. In fact, the required value is (index <<
352 3) + 7, but that's not important right now. Any normal instruction
353 which includes an addressing mode can then be made relative to that
354 LDT entry by prefixing the insn with a so-called segment-override
355 prefix, a byte which indicates which of the 6 segment registers
356 holds the LDT index.
358 Now, a key constraint is that valgrind's address checks operate in
359 terms of linear addresses. So we have to explicitly translate
360 virtual addrs into linear addrs, and that means doing a complete
361 LDT simulation.
363 Calls to modify_ldt are intercepted. For each thread, we maintain
364 an LDT (with the same normally-never-allocated optimisation that
365 the kernel does). This is updated as expected via calls to
366 modify_ldt.
368 When a thread does an amode calculation involving a segment
369 override prefix, the relevant LDT entry for the thread is
370 consulted. It all works.
372 There is a conceptual problem, which appears when switching back to
373 native execution, either temporarily to pass syscalls to the
374 kernel, or permanently, when debugging V. Problem at such points
375 is that it's pretty pointless to copy the simulated machine's
376 segment registers to the real machine, because we'd also need to
377 copy the simulated LDT into the real one, and that's prohibitively
378 expensive.
380 Fortunately it looks like no syscalls rely on the segment regs or
381 LDT being correct, so we can get away with it. Apart from that the
382 simulation is pretty straightforward. All 6 segment registers are
383 tracked, although only %ds, %es, %fs and %gs are allowed as
384 prefixes. Perhaps it could be restricted even more than that -- I
385 am not sure what is and isn't allowed in user-mode.
388 /* Translate a struct modify_ldt_ldt_s to a VexGuestX86SegDescr, using
389 the Linux kernel's logic (cut-n-paste of code in
390 linux/kernel/ldt.c). */
392 static
393 void translate_to_hw_format ( /* IN */ vki_modify_ldt_t* inn,
394 /* OUT */ VexGuestX86SegDescr* out,
395 Int oldmode )
397 UInt entry_1, entry_2;
398 vg_assert(8 == sizeof(VexGuestX86SegDescr));
400 if (0)
401 VG_(printf)("translate_to_hw_format: base %#lx, limit %d\n",
402 inn->base_addr, inn->limit );
404 /* Allow LDTs to be cleared by the user. */
405 if (inn->base_addr == 0 && inn->limit == 0) {
406 if (oldmode ||
407 (inn->contents == 0 &&
408 inn->read_exec_only == 1 &&
409 inn->seg_32bit == 0 &&
410 inn->limit_in_pages == 0 &&
411 inn->seg_not_present == 1 &&
412 inn->useable == 0 )) {
413 entry_1 = 0;
414 entry_2 = 0;
415 goto install;
419 entry_1 = ((inn->base_addr & 0x0000ffff) << 16) |
420 (inn->limit & 0x0ffff);
421 entry_2 = (inn->base_addr & 0xff000000) |
422 ((inn->base_addr & 0x00ff0000) >> 16) |
423 (inn->limit & 0xf0000) |
424 ((inn->read_exec_only ^ 1) << 9) |
425 (inn->contents << 10) |
426 ((inn->seg_not_present ^ 1) << 15) |
427 (inn->seg_32bit << 22) |
428 (inn->limit_in_pages << 23) |
429 0x7000;
430 if (!oldmode)
431 entry_2 |= (inn->useable << 20);
433 /* Install the new entry ... */
434 install:
435 out->LdtEnt.Words.word1 = entry_1;
436 out->LdtEnt.Words.word2 = entry_2;
439 /* Create a zeroed-out GDT. */
440 static VexGuestX86SegDescr* alloc_zeroed_x86_GDT ( void )
442 Int nbytes = VEX_GUEST_X86_GDT_NENT * sizeof(VexGuestX86SegDescr);
443 return VG_(calloc)("di.syswrap-x86.azxG.1", nbytes, 1);
446 /* Create a zeroed-out LDT. */
447 static VexGuestX86SegDescr* alloc_zeroed_x86_LDT ( void )
449 Int nbytes = VEX_GUEST_X86_LDT_NENT * sizeof(VexGuestX86SegDescr);
450 return VG_(calloc)("di.syswrap-x86.azxL.1", nbytes, 1);
453 /* Free up an LDT or GDT allocated by the above fns. */
454 static void free_LDT_or_GDT ( VexGuestX86SegDescr* dt )
456 vg_assert(dt);
457 VG_(free)(dt);
460 /* Copy contents between two existing LDTs. */
461 static void copy_LDT_from_to ( VexGuestX86SegDescr* src,
462 VexGuestX86SegDescr* dst )
464 Int i;
465 vg_assert(src);
466 vg_assert(dst);
467 for (i = 0; i < VEX_GUEST_X86_LDT_NENT; i++)
468 dst[i] = src[i];
471 /* Copy contents between two existing GDTs. */
472 static void copy_GDT_from_to ( VexGuestX86SegDescr* src,
473 VexGuestX86SegDescr* dst )
475 Int i;
476 vg_assert(src);
477 vg_assert(dst);
478 for (i = 0; i < VEX_GUEST_X86_GDT_NENT; i++)
479 dst[i] = src[i];
482 /* Free this thread's DTs, if it has any. */
483 static void deallocate_LGDTs_for_thread ( VexGuestX86State* vex )
485 vg_assert(sizeof(HWord) == sizeof(void*));
487 if (0)
488 VG_(printf)("deallocate_LGDTs_for_thread: "
489 "ldt = 0x%lx, gdt = 0x%lx\n",
490 vex->guest_LDT, vex->guest_GDT );
492 if (vex->guest_LDT != (HWord)NULL) {
493 free_LDT_or_GDT( (VexGuestX86SegDescr*)vex->guest_LDT );
494 vex->guest_LDT = (HWord)NULL;
497 if (vex->guest_GDT != (HWord)NULL) {
498 free_LDT_or_GDT( (VexGuestX86SegDescr*)vex->guest_GDT );
499 vex->guest_GDT = (HWord)NULL;
505 * linux/kernel/ldt.c
507 * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
508 * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
512 * read_ldt() is not really atomic - this is not a problem since
513 * synchronization of reads and writes done to the LDT has to be
514 * assured by user-space anyway. Writes are atomic, to protect
515 * the security checks done on new descriptors.
517 static
518 SysRes read_ldt ( ThreadId tid, UChar* ptr, UInt bytecount )
520 SysRes res;
521 UInt i, size;
522 UChar* ldt;
524 if (0)
525 VG_(printf)("read_ldt: tid = %d, ptr = %p, bytecount = %d\n",
526 tid, ptr, bytecount );
528 vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
529 vg_assert(8 == sizeof(VexGuestX86SegDescr));
531 ldt = (UChar*)(VG_(threads)[tid].arch.vex.guest_LDT);
532 res = VG_(mk_SysRes_Success)( 0 );
533 if (ldt == NULL)
534 /* LDT not allocated, meaning all entries are null */
535 goto out;
537 size = VEX_GUEST_X86_LDT_NENT * sizeof(VexGuestX86SegDescr);
538 if (size > bytecount)
539 size = bytecount;
541 res = VG_(mk_SysRes_Success)( size );
542 for (i = 0; i < size; i++)
543 ptr[i] = ldt[i];
545 out:
546 return res;
550 static
551 SysRes write_ldt ( ThreadId tid, void* ptr, UInt bytecount, Int oldmode )
553 SysRes res;
554 VexGuestX86SegDescr* ldt;
555 vki_modify_ldt_t* ldt_info;
557 if (0)
558 VG_(printf)("write_ldt: tid = %d, ptr = %p, "
559 "bytecount = %d, oldmode = %d\n",
560 tid, ptr, bytecount, oldmode );
562 vg_assert(8 == sizeof(VexGuestX86SegDescr));
563 vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
565 ldt = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_LDT;
566 ldt_info = (vki_modify_ldt_t*)ptr;
568 res = VG_(mk_SysRes_Error)( VKI_EINVAL );
569 if (bytecount != sizeof(vki_modify_ldt_t))
570 goto out;
572 res = VG_(mk_SysRes_Error)( VKI_EINVAL );
573 if (ldt_info->entry_number >= VEX_GUEST_X86_LDT_NENT)
574 goto out;
575 if (ldt_info->contents == 3) {
576 if (oldmode)
577 goto out;
578 if (ldt_info->seg_not_present == 0)
579 goto out;
582 /* If this thread doesn't have an LDT, we'd better allocate it
583 now. */
584 if (ldt == NULL) {
585 ldt = alloc_zeroed_x86_LDT();
586 VG_(threads)[tid].arch.vex.guest_LDT = (HWord)ldt;
589 /* Install the new entry ... */
590 translate_to_hw_format ( ldt_info, &ldt[ldt_info->entry_number], oldmode );
591 res = VG_(mk_SysRes_Success)( 0 );
593 out:
594 return res;
598 static SysRes sys_modify_ldt ( ThreadId tid,
599 Int func, void* ptr, UInt bytecount )
601 SysRes ret = VG_(mk_SysRes_Error)( VKI_ENOSYS );
603 switch (func) {
604 case 0:
605 ret = read_ldt(tid, ptr, bytecount);
606 break;
607 case 1:
608 ret = write_ldt(tid, ptr, bytecount, 1);
609 break;
610 case 2:
611 VG_(unimplemented)("sys_modify_ldt: func == 2");
612 /* god knows what this is about */
613 /* ret = read_default_ldt(ptr, bytecount); */
614 /*UNREACHED*/
615 break;
616 case 0x11:
617 ret = write_ldt(tid, ptr, bytecount, 0);
618 break;
620 return ret;
624 static SysRes sys_set_thread_area ( ThreadId tid, vki_modify_ldt_t* info )
626 Int idx;
627 VexGuestX86SegDescr* gdt;
629 vg_assert(8 == sizeof(VexGuestX86SegDescr));
630 vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
632 if (info == NULL)
633 return VG_(mk_SysRes_Error)( VKI_EFAULT );
635 gdt = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_GDT;
637 /* If the thread doesn't have a GDT, allocate it now. */
638 if (!gdt) {
639 gdt = alloc_zeroed_x86_GDT();
640 VG_(threads)[tid].arch.vex.guest_GDT = (HWord)gdt;
643 idx = info->entry_number;
645 if (idx == -1) {
646 /* Find and use the first free entry. Don't allocate entry
647 zero, because the hardware will never do that, and apparently
648 doing so confuses some code (perhaps stuff running on
649 Wine). */
650 for (idx = 1; idx < VEX_GUEST_X86_GDT_NENT; idx++) {
651 if (gdt[idx].LdtEnt.Words.word1 == 0
652 && gdt[idx].LdtEnt.Words.word2 == 0)
653 break;
656 if (idx == VEX_GUEST_X86_GDT_NENT)
657 return VG_(mk_SysRes_Error)( VKI_ESRCH );
658 } else if (idx < 0 || idx == 0 || idx >= VEX_GUEST_X86_GDT_NENT) {
659 /* Similarly, reject attempts to use GDT[0]. */
660 return VG_(mk_SysRes_Error)( VKI_EINVAL );
663 translate_to_hw_format(info, &gdt[idx], 0);
665 VG_TRACK( pre_mem_write, Vg_CoreSysCall, tid,
666 "set_thread_area(info->entry)",
667 (Addr) & info->entry_number, sizeof(unsigned int) );
668 info->entry_number = idx;
669 VG_TRACK( post_mem_write, Vg_CoreSysCall, tid,
670 (Addr) & info->entry_number, sizeof(unsigned int) );
672 return VG_(mk_SysRes_Success)( 0 );
676 static SysRes sys_get_thread_area ( ThreadId tid, vki_modify_ldt_t* info )
678 Int idx;
679 VexGuestX86SegDescr* gdt;
681 vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
682 vg_assert(8 == sizeof(VexGuestX86SegDescr));
684 if (info == NULL)
685 return VG_(mk_SysRes_Error)( VKI_EFAULT );
687 idx = info->entry_number;
689 if (idx < 0 || idx >= VEX_GUEST_X86_GDT_NENT)
690 return VG_(mk_SysRes_Error)( VKI_EINVAL );
692 gdt = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_GDT;
694 /* If the thread doesn't have a GDT, allocate it now. */
695 if (!gdt) {
696 gdt = alloc_zeroed_x86_GDT();
697 VG_(threads)[tid].arch.vex.guest_GDT = (HWord)gdt;
700 info->base_addr = ( gdt[idx].LdtEnt.Bits.BaseHi << 24 ) |
701 ( gdt[idx].LdtEnt.Bits.BaseMid << 16 ) |
702 gdt[idx].LdtEnt.Bits.BaseLow;
703 info->limit = ( gdt[idx].LdtEnt.Bits.LimitHi << 16 ) |
704 gdt[idx].LdtEnt.Bits.LimitLow;
705 info->seg_32bit = gdt[idx].LdtEnt.Bits.Default_Big;
706 info->contents = ( gdt[idx].LdtEnt.Bits.Type >> 2 ) & 0x3;
707 info->read_exec_only = ( gdt[idx].LdtEnt.Bits.Type & 0x1 ) ^ 0x1;
708 info->limit_in_pages = gdt[idx].LdtEnt.Bits.Granularity;
709 info->seg_not_present = gdt[idx].LdtEnt.Bits.Pres ^ 0x1;
710 info->useable = gdt[idx].LdtEnt.Bits.Sys;
711 info->reserved = 0;
713 return VG_(mk_SysRes_Success)( 0 );
716 /* ---------------------------------------------------------------------
717 More thread stuff
718 ------------------------------------------------------------------ */
720 void VG_(cleanup_thread) ( ThreadArchState* arch )
722 /* Release arch-specific resources held by this thread. */
723 /* On x86, we have to dump the LDT and GDT. */
724 deallocate_LGDTs_for_thread( &arch->vex );
728 static void setup_child ( /*OUT*/ ThreadArchState *child,
729 /*IN*/ ThreadArchState *parent,
730 Bool inherit_parents_GDT )
732 /* We inherit our parent's guest state. */
733 child->vex = parent->vex;
734 child->vex_shadow1 = parent->vex_shadow1;
735 child->vex_shadow2 = parent->vex_shadow2;
737 /* We inherit our parent's LDT. */
738 if (parent->vex.guest_LDT == (HWord)NULL) {
739 /* We hope this is the common case. */
740 child->vex.guest_LDT = (HWord)NULL;
741 } else {
742 /* No luck .. we have to take a copy of the parent's. */
743 child->vex.guest_LDT = (HWord)alloc_zeroed_x86_LDT();
744 copy_LDT_from_to( (VexGuestX86SegDescr*)parent->vex.guest_LDT,
745 (VexGuestX86SegDescr*)child->vex.guest_LDT );
748 /* Either we start with an empty GDT (the usual case) or inherit a
749 copy of our parents' one (Quadrics Elan3 driver -style clone
750 only). */
751 child->vex.guest_GDT = (HWord)NULL;
753 if (inherit_parents_GDT && parent->vex.guest_GDT != (HWord)NULL) {
754 child->vex.guest_GDT = (HWord)alloc_zeroed_x86_GDT();
755 copy_GDT_from_to( (VexGuestX86SegDescr*)parent->vex.guest_GDT,
756 (VexGuestX86SegDescr*)child->vex.guest_GDT );
761 /* ---------------------------------------------------------------------
762 PRE/POST wrappers for x86/Linux-specific syscalls
763 ------------------------------------------------------------------ */
765 #define PRE(name) DEFN_PRE_TEMPLATE(x86_linux, name)
766 #define POST(name) DEFN_POST_TEMPLATE(x86_linux, name)
768 /* Add prototypes for the wrappers declared here, so that gcc doesn't
769 harass us for not having prototypes. Really this is a kludge --
770 the right thing to do is to make these wrappers 'static' since they
771 aren't visible outside this file, but that requires even more macro
772 magic. */
773 DECL_TEMPLATE(x86_linux, sys_stat64);
774 DECL_TEMPLATE(x86_linux, sys_fstatat64);
775 DECL_TEMPLATE(x86_linux, sys_fstat64);
776 DECL_TEMPLATE(x86_linux, sys_lstat64);
777 DECL_TEMPLATE(x86_linux, sys_clone);
778 DECL_TEMPLATE(x86_linux, old_mmap);
779 DECL_TEMPLATE(x86_linux, sys_mmap2);
780 DECL_TEMPLATE(x86_linux, sys_sigreturn);
781 DECL_TEMPLATE(x86_linux, sys_rt_sigreturn);
782 DECL_TEMPLATE(x86_linux, sys_modify_ldt);
783 DECL_TEMPLATE(x86_linux, sys_set_thread_area);
784 DECL_TEMPLATE(x86_linux, sys_get_thread_area);
785 DECL_TEMPLATE(x86_linux, sys_ptrace);
786 DECL_TEMPLATE(x86_linux, sys_sigsuspend);
787 DECL_TEMPLATE(x86_linux, old_select);
788 DECL_TEMPLATE(x86_linux, sys_vm86old);
789 DECL_TEMPLATE(x86_linux, sys_vm86);
790 DECL_TEMPLATE(x86_linux, sys_syscall223);
792 PRE(old_select)
794 /* struct sel_arg_struct {
795 unsigned long n;
796 fd_set *inp, *outp, *exp;
797 struct timeval *tvp;
800 PRE_REG_READ1(long, "old_select", struct sel_arg_struct *, args);
801 PRE_MEM_READ( "old_select(args)", ARG1, 5*sizeof(UWord) );
802 *flags |= SfMayBlock;
804 UInt* arg_struct = (UInt*)ARG1;
805 UInt a1, a2, a3, a4, a5;
807 a1 = arg_struct[0];
808 a2 = arg_struct[1];
809 a3 = arg_struct[2];
810 a4 = arg_struct[3];
811 a5 = arg_struct[4];
813 PRINT("old_select ( %d, %#x, %#x, %#x, %#x )", a1,a2,a3,a4,a5);
814 if (a2 != (Addr)NULL)
815 PRE_MEM_READ( "old_select(readfds)", a2, a1/8 /* __FD_SETSIZE/8 */ );
816 if (a3 != (Addr)NULL)
817 PRE_MEM_READ( "old_select(writefds)", a3, a1/8 /* __FD_SETSIZE/8 */ );
818 if (a4 != (Addr)NULL)
819 PRE_MEM_READ( "old_select(exceptfds)", a4, a1/8 /* __FD_SETSIZE/8 */ );
820 if (a5 != (Addr)NULL)
821 PRE_MEM_READ( "old_select(timeout)", a5, sizeof(struct vki_timeval) );
825 PRE(sys_clone)
827 UInt cloneflags;
828 Bool badarg = False;
830 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
831 PRE_REG_READ2(int, "clone",
832 unsigned long, flags,
833 void *, child_stack);
835 if (ARG1 & VKI_CLONE_PARENT_SETTID) {
836 if (VG_(tdict).track_pre_reg_read) {
837 PRA3("clone", int *, parent_tidptr);
839 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
840 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
841 VKI_PROT_WRITE)) {
842 badarg = True;
845 if (ARG1 & VKI_CLONE_SETTLS) {
846 if (VG_(tdict).track_pre_reg_read) {
847 PRA4("clone", vki_modify_ldt_t *, tlsinfo);
849 PRE_MEM_READ("clone(tlsinfo)", ARG4, sizeof(vki_modify_ldt_t));
850 if (!VG_(am_is_valid_for_client)(ARG4, sizeof(vki_modify_ldt_t),
851 VKI_PROT_READ)) {
852 badarg = True;
855 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
856 if (VG_(tdict).track_pre_reg_read) {
857 PRA5("clone", int *, child_tidptr);
859 PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
860 if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int),
861 VKI_PROT_WRITE)) {
862 badarg = True;
866 if (badarg) {
867 SET_STATUS_Failure( VKI_EFAULT );
868 return;
871 cloneflags = ARG1;
873 if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
874 SET_STATUS_Failure( VKI_EINVAL );
875 return;
878 /* Be ultra-paranoid and filter out any clone-variants we don't understand:
879 - ??? specifies clone flags of 0x100011
880 - ??? specifies clone flags of 0x1200011.
881 - NPTL specifies clone flags of 0x7D0F00.
882 - The Quadrics Elan3 driver specifies clone flags of 0xF00.
883 - Newer Quadrics Elan3 drivers with NTPL support specify 0x410F00.
884 Everything else is rejected.
886 if (
887 1 ||
888 /* 11 Nov 05: for the time being, disable this ultra-paranoia.
889 The switch below probably does a good enough job. */
890 (cloneflags == 0x100011 || cloneflags == 0x1200011
891 || cloneflags == 0x7D0F00
892 || cloneflags == 0x790F00
893 || cloneflags == 0x3D0F00
894 || cloneflags == 0x410F00
895 || cloneflags == 0xF00
896 || cloneflags == 0xF21)) {
897 /* OK */
899 else {
900 /* Nah. We don't like it. Go away. */
901 goto reject;
904 /* Only look at the flags we really care about */
905 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
906 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
907 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
908 /* thread creation */
909 SET_STATUS_from_SysRes(
910 do_clone(tid,
911 ARG1, /* flags */
912 (Addr)ARG2, /* child ESP */
913 (Int *)ARG3, /* parent_tidptr */
914 (Int *)ARG5, /* child_tidptr */
915 (vki_modify_ldt_t *)ARG4)); /* set_tls */
916 break;
918 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
919 /* FALLTHROUGH - assume vfork == fork */
920 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
922 case 0: /* plain fork */
923 SET_STATUS_from_SysRes(
924 ML_(do_fork_clone)(tid,
925 cloneflags, /* flags */
926 (Int *)ARG3, /* parent_tidptr */
927 (Int *)ARG5)); /* child_tidptr */
928 break;
930 default:
931 reject:
932 /* should we just ENOSYS? */
933 VG_(message)(Vg_UserMsg, "\n");
934 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
935 VG_(message)(Vg_UserMsg, "\n");
936 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
937 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
938 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
939 VG_(message)(Vg_UserMsg, " - for the Quadrics Elan3 user-space driver\n");
940 VG_(unimplemented)
941 ("Valgrind does not support general clone().");
944 if (SUCCESS) {
945 if (ARG1 & VKI_CLONE_PARENT_SETTID)
946 POST_MEM_WRITE(ARG3, sizeof(Int));
947 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
948 POST_MEM_WRITE(ARG5, sizeof(Int));
950 /* Thread creation was successful; let the child have the chance
951 to run */
952 *flags |= SfYieldAfter;
956 PRE(sys_sigreturn)
958 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
959 an explanation of what follows. */
961 ThreadState* tst;
962 PRINT("sys_sigreturn ( )");
964 vg_assert(VG_(is_valid_tid)(tid));
965 vg_assert(tid >= 1 && tid < VG_N_THREADS);
966 vg_assert(VG_(is_running_thread)(tid));
968 /* Adjust esp to point to start of frame; skip back up over
969 sigreturn sequence's "popl %eax" and handler ret addr */
970 tst = VG_(get_ThreadState)(tid);
971 tst->arch.vex.guest_ESP -= sizeof(Addr)+sizeof(Word);
972 /* XXX why does ESP change differ from rt_sigreturn case below? */
974 /* This is only so that the EIP is (might be) useful to report if
975 something goes wrong in the sigreturn */
976 ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
978 /* Restore register state from frame and remove it */
979 VG_(sigframe_destroy)(tid, False);
981 /* Tell the driver not to update the guest state with the "result",
982 and set a bogus result to keep it happy. */
983 *flags |= SfNoWriteResult;
984 SET_STATUS_Success(0);
986 /* Check to see if any signals arose as a result of this. */
987 *flags |= SfPollAfter;
990 PRE(sys_rt_sigreturn)
992 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
993 an explanation of what follows. */
995 ThreadState* tst;
996 PRINT("sys_rt_sigreturn ( )");
998 vg_assert(VG_(is_valid_tid)(tid));
999 vg_assert(tid >= 1 && tid < VG_N_THREADS);
1000 vg_assert(VG_(is_running_thread)(tid));
1002 /* Adjust esp to point to start of frame; skip back up over handler
1003 ret addr */
1004 tst = VG_(get_ThreadState)(tid);
1005 tst->arch.vex.guest_ESP -= sizeof(Addr);
1006 /* XXX why does ESP change differ from sigreturn case above? */
1008 /* This is only so that the EIP is (might be) useful to report if
1009 something goes wrong in the sigreturn */
1010 ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
1012 /* Restore register state from frame and remove it */
1013 VG_(sigframe_destroy)(tid, True);
1015 /* Tell the driver not to update the guest state with the "result",
1016 and set a bogus result to keep it happy. */
1017 *flags |= SfNoWriteResult;
1018 SET_STATUS_Success(0);
1020 /* Check to see if any signals arose as a result of this. */
1021 *flags |= SfPollAfter;
1024 PRE(sys_modify_ldt)
1026 PRINT("sys_modify_ldt ( %ld, %#lx, %ld )", ARG1,ARG2,ARG3);
1027 PRE_REG_READ3(int, "modify_ldt", int, func, void *, ptr,
1028 unsigned long, bytecount);
1030 if (ARG1 == 0) {
1031 /* read the LDT into ptr */
1032 PRE_MEM_WRITE( "modify_ldt(ptr)", ARG2, ARG3 );
1034 if (ARG1 == 1 || ARG1 == 0x11) {
1035 /* write the LDT with the entry pointed at by ptr */
1036 PRE_MEM_READ( "modify_ldt(ptr)", ARG2, sizeof(vki_modify_ldt_t) );
1038 /* "do" the syscall ourselves; the kernel never sees it */
1039 SET_STATUS_from_SysRes( sys_modify_ldt( tid, ARG1, (void*)ARG2, ARG3 ) );
1041 if (ARG1 == 0 && SUCCESS && RES > 0) {
1042 POST_MEM_WRITE( ARG2, RES );
1046 PRE(sys_set_thread_area)
1048 PRINT("sys_set_thread_area ( %#lx )", ARG1);
1049 PRE_REG_READ1(int, "set_thread_area", struct user_desc *, u_info)
1050 PRE_MEM_READ( "set_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
1052 /* "do" the syscall ourselves; the kernel never sees it */
1053 SET_STATUS_from_SysRes( sys_set_thread_area( tid, (void *)ARG1 ) );
1056 PRE(sys_get_thread_area)
1058 PRINT("sys_get_thread_area ( %#lx )", ARG1);
1059 PRE_REG_READ1(int, "get_thread_area", struct user_desc *, u_info)
1060 PRE_MEM_WRITE( "get_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
1062 /* "do" the syscall ourselves; the kernel never sees it */
1063 SET_STATUS_from_SysRes( sys_get_thread_area( tid, (void *)ARG1 ) );
1065 if (SUCCESS) {
1066 POST_MEM_WRITE( ARG1, sizeof(vki_modify_ldt_t) );
1070 // Parts of this are x86-specific, but the *PEEK* cases are generic.
1072 // ARG3 is only used for pointers into the traced process's address
1073 // space and for offsets into the traced process's struct
1074 // user_regs_struct. It is never a pointer into this process's memory
1075 // space, and we should therefore not check anything it points to.
1076 PRE(sys_ptrace)
1078 PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
1079 PRE_REG_READ4(int, "ptrace",
1080 long, request, long, pid, long, addr, long, data);
1081 switch (ARG1) {
1082 case VKI_PTRACE_PEEKTEXT:
1083 case VKI_PTRACE_PEEKDATA:
1084 case VKI_PTRACE_PEEKUSR:
1085 PRE_MEM_WRITE( "ptrace(peek)", ARG4,
1086 sizeof (long));
1087 break;
1088 case VKI_PTRACE_GETREGS:
1089 PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
1090 sizeof (struct vki_user_regs_struct));
1091 break;
1092 case VKI_PTRACE_GETFPREGS:
1093 PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
1094 sizeof (struct vki_user_i387_struct));
1095 break;
1096 case VKI_PTRACE_GETFPXREGS:
1097 PRE_MEM_WRITE( "ptrace(getfpxregs)", ARG4,
1098 sizeof(struct vki_user_fxsr_struct) );
1099 break;
1100 case VKI_PTRACE_GET_THREAD_AREA:
1101 PRE_MEM_WRITE( "ptrace(get_thread_area)", ARG4,
1102 sizeof(struct vki_user_desc) );
1103 break;
1104 case VKI_PTRACE_SETREGS:
1105 PRE_MEM_READ( "ptrace(setregs)", ARG4,
1106 sizeof (struct vki_user_regs_struct));
1107 break;
1108 case VKI_PTRACE_SETFPREGS:
1109 PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
1110 sizeof (struct vki_user_i387_struct));
1111 break;
1112 case VKI_PTRACE_SETFPXREGS:
1113 PRE_MEM_READ( "ptrace(setfpxregs)", ARG4,
1114 sizeof(struct vki_user_fxsr_struct) );
1115 break;
1116 case VKI_PTRACE_SET_THREAD_AREA:
1117 PRE_MEM_READ( "ptrace(set_thread_area)", ARG4,
1118 sizeof(struct vki_user_desc) );
1119 break;
1120 case VKI_PTRACE_GETEVENTMSG:
1121 PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
1122 break;
1123 case VKI_PTRACE_GETSIGINFO:
1124 PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
1125 break;
1126 case VKI_PTRACE_SETSIGINFO:
1127 PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
1128 break;
1129 case VKI_PTRACE_GETREGSET:
1130 ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
1131 break;
1132 case VKI_PTRACE_SETREGSET:
1133 ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
1134 break;
1135 default:
1136 break;
1140 POST(sys_ptrace)
1142 switch (ARG1) {
1143 case VKI_PTRACE_PEEKTEXT:
1144 case VKI_PTRACE_PEEKDATA:
1145 case VKI_PTRACE_PEEKUSR:
1146 POST_MEM_WRITE( ARG4, sizeof (long));
1147 break;
1148 case VKI_PTRACE_GETREGS:
1149 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
1150 break;
1151 case VKI_PTRACE_GETFPREGS:
1152 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
1153 break;
1154 case VKI_PTRACE_GETFPXREGS:
1155 POST_MEM_WRITE( ARG4, sizeof(struct vki_user_fxsr_struct) );
1156 break;
1157 case VKI_PTRACE_GET_THREAD_AREA:
1158 POST_MEM_WRITE( ARG4, sizeof(struct vki_user_desc) );
1159 break;
1160 case VKI_PTRACE_GETEVENTMSG:
1161 POST_MEM_WRITE( ARG4, sizeof(unsigned long));
1162 break;
1163 case VKI_PTRACE_GETSIGINFO:
1164 /* XXX: This is a simplification. Different parts of the
1165 * siginfo_t are valid depending on the type of signal.
1167 POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
1168 break;
1169 case VKI_PTRACE_GETREGSET:
1170 ML_(linux_POST_getregset)(tid, ARG3, ARG4);
1171 break;
1172 default:
1173 break;
1177 PRE(old_mmap)
1179 /* struct mmap_arg_struct {
1180 unsigned long addr;
1181 unsigned long len;
1182 unsigned long prot;
1183 unsigned long flags;
1184 unsigned long fd;
1185 unsigned long offset;
1186 }; */
1187 UWord a1, a2, a3, a4, a5, a6;
1188 SysRes r;
1190 UWord* args = (UWord*)ARG1;
1191 PRE_REG_READ1(long, "old_mmap", struct mmap_arg_struct *, args);
1192 PRE_MEM_READ( "old_mmap(args)", (Addr)args, 6*sizeof(UWord) );
1194 a1 = args[1-1];
1195 a2 = args[2-1];
1196 a3 = args[3-1];
1197 a4 = args[4-1];
1198 a5 = args[5-1];
1199 a6 = args[6-1];
1201 PRINT("old_mmap ( %#lx, %llu, %ld, %ld, %ld, %ld )",
1202 a1, (ULong)a2, a3, a4, a5, a6 );
1204 r = ML_(generic_PRE_sys_mmap)( tid, a1, a2, a3, a4, a5, (Off64T)a6 );
1205 SET_STATUS_from_SysRes(r);
1208 PRE(sys_mmap2)
1210 SysRes r;
1212 // Exactly like old_mmap() except:
1213 // - all 6 args are passed in regs, rather than in a memory-block.
1214 // - the file offset is specified in pagesize units rather than bytes,
1215 // so that it can be used for files bigger than 2^32 bytes.
1216 // pagesize or 4K-size units in offset? For ppc32/64-linux, this is
1217 // 4K-sized. Assert that the page size is 4K here for safety.
1218 vg_assert(VKI_PAGE_SIZE == 4096);
1219 PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )",
1220 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
1221 PRE_REG_READ6(long, "mmap2",
1222 unsigned long, start, unsigned long, length,
1223 unsigned long, prot, unsigned long, flags,
1224 unsigned long, fd, unsigned long, offset);
1226 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
1227 4096 * (Off64T)ARG6 );
1228 SET_STATUS_from_SysRes(r);
1231 // XXX: lstat64/fstat64/stat64 are generic, but not necessarily
1232 // applicable to every architecture -- I think only to 32-bit archs.
1233 // We're going to need something like linux/core_os32.h for such
1234 // things, eventually, I think. --njn
1235 PRE(sys_lstat64)
1237 PRINT("sys_lstat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
1238 PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
1239 PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
1240 PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
1243 POST(sys_lstat64)
1245 vg_assert(SUCCESS);
1246 if (RES == 0) {
1247 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1251 PRE(sys_stat64)
1253 FUSE_COMPATIBLE_MAY_BLOCK();
1254 PRINT("sys_stat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
1255 PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
1256 PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
1257 PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
1260 POST(sys_stat64)
1262 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1265 PRE(sys_fstatat64)
1267 FUSE_COMPATIBLE_MAY_BLOCK();
1268 PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )",ARG1,ARG2,(char*)ARG2,ARG3);
1269 PRE_REG_READ3(long, "fstatat64",
1270 int, dfd, char *, file_name, struct stat64 *, buf);
1271 PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 );
1272 PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) );
1275 POST(sys_fstatat64)
1277 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) );
1280 PRE(sys_fstat64)
1282 PRINT("sys_fstat64 ( %ld, %#lx )",ARG1,ARG2);
1283 PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
1284 PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
1287 POST(sys_fstat64)
1289 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1292 /* NB: arm-linux has a clone of this one, and ppc32-linux has an almost
1293 identical version. */
1294 PRE(sys_sigsuspend)
1296 /* The C library interface to sigsuspend just takes a pointer to
1297 a signal mask but this system call has three arguments - the first
1298 two don't appear to be used by the kernel and are always passed as
1299 zero by glibc and the third is the first word of the signal mask
1300 so only 32 signals are supported.
1302 In fact glibc normally uses rt_sigsuspend if it is available as
1303 that takes a pointer to the signal mask so supports more signals.
1305 *flags |= SfMayBlock;
1306 PRINT("sys_sigsuspend ( %ld, %ld, %ld )", ARG1,ARG2,ARG3 );
1307 PRE_REG_READ3(int, "sigsuspend",
1308 int, history0, int, history1,
1309 vki_old_sigset_t, mask);
1312 PRE(sys_vm86old)
1314 PRINT("sys_vm86old ( %#lx )", ARG1);
1315 PRE_REG_READ1(int, "vm86old", struct vm86_struct *, info);
1316 PRE_MEM_WRITE( "vm86old(info)", ARG1, sizeof(struct vki_vm86_struct));
1319 POST(sys_vm86old)
1321 POST_MEM_WRITE( ARG1, sizeof(struct vki_vm86_struct));
1324 PRE(sys_vm86)
1326 PRINT("sys_vm86 ( %ld, %#lx )", ARG1,ARG2);
1327 PRE_REG_READ2(int, "vm86", unsigned long, fn, struct vm86plus_struct *, v86);
1328 if (ARG1 == VKI_VM86_ENTER || ARG1 == VKI_VM86_ENTER_NO_BYPASS)
1329 PRE_MEM_WRITE( "vm86(v86)", ARG2, sizeof(struct vki_vm86plus_struct));
1332 POST(sys_vm86)
1334 if (ARG1 == VKI_VM86_ENTER || ARG1 == VKI_VM86_ENTER_NO_BYPASS)
1335 POST_MEM_WRITE( ARG2, sizeof(struct vki_vm86plus_struct));
1339 /* ---------------------------------------------------------------
1340 PRE/POST wrappers for x86/Linux-variant specific syscalls
1341 ------------------------------------------------------------ */
1343 PRE(sys_syscall223)
1345 Int err;
1347 /* 223 is used by sys_bproc. If we're not on a declared bproc
1348 variant, fail in the usual way. */
1350 if (!KernelVariantiS(KernelVariant_bproc, VG_(clo_kernel_variant))) {
1351 PRINT("non-existent syscall! (syscall 223)");
1352 PRE_REG_READ0(long, "ni_syscall(223)");
1353 SET_STATUS_Failure( VKI_ENOSYS );
1354 return;
1357 err = ML_(linux_variant_PRE_sys_bproc)( ARG1, ARG2, ARG3,
1358 ARG4, ARG5, ARG6 );
1359 if (err) {
1360 SET_STATUS_Failure( err );
1361 return;
1363 /* Let it go through. */
1364 *flags |= SfMayBlock; /* who knows? play safe. */
1367 POST(sys_syscall223)
1369 ML_(linux_variant_POST_sys_bproc)( ARG1, ARG2, ARG3,
1370 ARG4, ARG5, ARG6 );
1373 #undef PRE
1374 #undef POST
1377 /* ---------------------------------------------------------------------
1378 The x86/Linux syscall table
1379 ------------------------------------------------------------------ */
1381 /* Add an x86-linux specific wrapper to a syscall table. */
1382 #define PLAX_(sysno, name) WRAPPER_ENTRY_X_(x86_linux, sysno, name)
1383 #define PLAXY(sysno, name) WRAPPER_ENTRY_XY(x86_linux, sysno, name)
1386 // This table maps from __NR_xxx syscall numbers (from
1387 // linux/include/asm-i386/unistd.h) to the appropriate PRE/POST sys_foo()
1388 // wrappers on x86 (as per sys_call_table in linux/arch/i386/kernel/entry.S).
1390 // For those syscalls not handled by Valgrind, the annotation indicate its
1391 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
1392 // (unknown).
1394 static SyscallTableEntry syscall_table[] = {
1395 //zz // (restart_syscall) // 0
1396 GENX_(__NR_exit, sys_exit), // 1
1397 GENX_(__NR_fork, sys_fork), // 2
1398 GENXY(__NR_read, sys_read), // 3
1399 GENX_(__NR_write, sys_write), // 4
1401 GENXY(__NR_open, sys_open), // 5
1402 GENXY(__NR_close, sys_close), // 6
1403 GENXY(__NR_waitpid, sys_waitpid), // 7
1404 GENXY(__NR_creat, sys_creat), // 8
1405 GENX_(__NR_link, sys_link), // 9
1407 GENX_(__NR_unlink, sys_unlink), // 10
1408 GENX_(__NR_execve, sys_execve), // 11
1409 GENX_(__NR_chdir, sys_chdir), // 12
1410 GENXY(__NR_time, sys_time), // 13
1411 GENX_(__NR_mknod, sys_mknod), // 14
1413 GENX_(__NR_chmod, sys_chmod), // 15
1414 //zz LINX_(__NR_lchown, sys_lchown16), // 16
1415 GENX_(__NR_break, sys_ni_syscall), // 17
1416 //zz // (__NR_oldstat, sys_stat), // 18 (obsolete)
1417 LINX_(__NR_lseek, sys_lseek), // 19
1419 GENX_(__NR_getpid, sys_getpid), // 20
1420 LINX_(__NR_mount, sys_mount), // 21
1421 LINX_(__NR_umount, sys_oldumount), // 22
1422 LINX_(__NR_setuid, sys_setuid16), // 23 ## P
1423 LINX_(__NR_getuid, sys_getuid16), // 24 ## P
1425 LINX_(__NR_stime, sys_stime), // 25 * (SVr4,SVID,X/OPEN)
1426 PLAXY(__NR_ptrace, sys_ptrace), // 26
1427 GENX_(__NR_alarm, sys_alarm), // 27
1428 //zz // (__NR_oldfstat, sys_fstat), // 28 * L -- obsolete
1429 GENX_(__NR_pause, sys_pause), // 29
1431 LINX_(__NR_utime, sys_utime), // 30
1432 GENX_(__NR_stty, sys_ni_syscall), // 31
1433 GENX_(__NR_gtty, sys_ni_syscall), // 32
1434 GENX_(__NR_access, sys_access), // 33
1435 GENX_(__NR_nice, sys_nice), // 34
1437 GENX_(__NR_ftime, sys_ni_syscall), // 35
1438 GENX_(__NR_sync, sys_sync), // 36
1439 GENX_(__NR_kill, sys_kill), // 37
1440 GENX_(__NR_rename, sys_rename), // 38
1441 GENX_(__NR_mkdir, sys_mkdir), // 39
1443 GENX_(__NR_rmdir, sys_rmdir), // 40
1444 GENXY(__NR_dup, sys_dup), // 41
1445 LINXY(__NR_pipe, sys_pipe), // 42
1446 GENXY(__NR_times, sys_times), // 43
1447 GENX_(__NR_prof, sys_ni_syscall), // 44
1448 //zz
1449 GENX_(__NR_brk, sys_brk), // 45
1450 LINX_(__NR_setgid, sys_setgid16), // 46
1451 LINX_(__NR_getgid, sys_getgid16), // 47
1452 //zz // (__NR_signal, sys_signal), // 48 */* (ANSI C)
1453 LINX_(__NR_geteuid, sys_geteuid16), // 49
1455 LINX_(__NR_getegid, sys_getegid16), // 50
1456 GENX_(__NR_acct, sys_acct), // 51
1457 LINX_(__NR_umount2, sys_umount), // 52
1458 GENX_(__NR_lock, sys_ni_syscall), // 53
1459 LINXY(__NR_ioctl, sys_ioctl), // 54
1461 LINXY(__NR_fcntl, sys_fcntl), // 55
1462 GENX_(__NR_mpx, sys_ni_syscall), // 56
1463 GENX_(__NR_setpgid, sys_setpgid), // 57
1464 GENX_(__NR_ulimit, sys_ni_syscall), // 58
1465 //zz // (__NR_oldolduname, sys_olduname), // 59 Linux -- obsolete
1466 //zz
1467 GENX_(__NR_umask, sys_umask), // 60
1468 GENX_(__NR_chroot, sys_chroot), // 61
1469 //zz // (__NR_ustat, sys_ustat) // 62 SVr4 -- deprecated
1470 GENXY(__NR_dup2, sys_dup2), // 63
1471 GENX_(__NR_getppid, sys_getppid), // 64
1473 GENX_(__NR_getpgrp, sys_getpgrp), // 65
1474 GENX_(__NR_setsid, sys_setsid), // 66
1475 LINXY(__NR_sigaction, sys_sigaction), // 67
1476 //zz // (__NR_sgetmask, sys_sgetmask), // 68 */* (ANSI C)
1477 //zz // (__NR_ssetmask, sys_ssetmask), // 69 */* (ANSI C)
1478 //zz
1479 LINX_(__NR_setreuid, sys_setreuid16), // 70
1480 LINX_(__NR_setregid, sys_setregid16), // 71
1481 PLAX_(__NR_sigsuspend, sys_sigsuspend), // 72
1482 LINXY(__NR_sigpending, sys_sigpending), // 73
1483 GENX_(__NR_sethostname, sys_sethostname), // 74
1484 //zz
1485 GENX_(__NR_setrlimit, sys_setrlimit), // 75
1486 GENXY(__NR_getrlimit, sys_old_getrlimit), // 76
1487 GENXY(__NR_getrusage, sys_getrusage), // 77
1488 GENXY(__NR_gettimeofday, sys_gettimeofday), // 78
1489 GENX_(__NR_settimeofday, sys_settimeofday), // 79
1491 LINXY(__NR_getgroups, sys_getgroups16), // 80
1492 LINX_(__NR_setgroups, sys_setgroups16), // 81
1493 PLAX_(__NR_select, old_select), // 82
1494 GENX_(__NR_symlink, sys_symlink), // 83
1495 //zz // (__NR_oldlstat, sys_lstat), // 84 -- obsolete
1496 //zz
1497 GENX_(__NR_readlink, sys_readlink), // 85
1498 //zz // (__NR_uselib, sys_uselib), // 86 */Linux
1499 //zz // (__NR_swapon, sys_swapon), // 87 */Linux
1500 //zz // (__NR_reboot, sys_reboot), // 88 */Linux
1501 //zz // (__NR_readdir, old_readdir), // 89 -- superseded
1502 //zz
1503 PLAX_(__NR_mmap, old_mmap), // 90
1504 GENXY(__NR_munmap, sys_munmap), // 91
1505 GENX_(__NR_truncate, sys_truncate), // 92
1506 GENX_(__NR_ftruncate, sys_ftruncate), // 93
1507 GENX_(__NR_fchmod, sys_fchmod), // 94
1509 LINX_(__NR_fchown, sys_fchown16), // 95
1510 GENX_(__NR_getpriority, sys_getpriority), // 96
1511 GENX_(__NR_setpriority, sys_setpriority), // 97
1512 GENX_(__NR_profil, sys_ni_syscall), // 98
1513 GENXY(__NR_statfs, sys_statfs), // 99
1515 GENXY(__NR_fstatfs, sys_fstatfs), // 100
1516 LINX_(__NR_ioperm, sys_ioperm), // 101
1517 LINXY(__NR_socketcall, sys_socketcall), // 102 x86/Linux-only
1518 LINXY(__NR_syslog, sys_syslog), // 103
1519 GENXY(__NR_setitimer, sys_setitimer), // 104
1521 GENXY(__NR_getitimer, sys_getitimer), // 105
1522 GENXY(__NR_stat, sys_newstat), // 106
1523 GENXY(__NR_lstat, sys_newlstat), // 107
1524 GENXY(__NR_fstat, sys_newfstat), // 108
1525 //zz // (__NR_olduname, sys_uname), // 109 -- obsolete
1526 //zz
1527 GENX_(__NR_iopl, sys_iopl), // 110
1528 LINX_(__NR_vhangup, sys_vhangup), // 111
1529 GENX_(__NR_idle, sys_ni_syscall), // 112
1530 PLAXY(__NR_vm86old, sys_vm86old), // 113 x86/Linux-only
1531 GENXY(__NR_wait4, sys_wait4), // 114
1532 //zz
1533 //zz // (__NR_swapoff, sys_swapoff), // 115 */Linux
1534 LINXY(__NR_sysinfo, sys_sysinfo), // 116
1535 LINXY(__NR_ipc, sys_ipc), // 117
1536 GENX_(__NR_fsync, sys_fsync), // 118
1537 PLAX_(__NR_sigreturn, sys_sigreturn), // 119 ?/Linux
1539 PLAX_(__NR_clone, sys_clone), // 120
1540 //zz // (__NR_setdomainname, sys_setdomainname), // 121 */*(?)
1541 GENXY(__NR_uname, sys_newuname), // 122
1542 PLAX_(__NR_modify_ldt, sys_modify_ldt), // 123
1543 LINXY(__NR_adjtimex, sys_adjtimex), // 124
1545 GENXY(__NR_mprotect, sys_mprotect), // 125
1546 LINXY(__NR_sigprocmask, sys_sigprocmask), // 126
1547 //zz // Nb: create_module() was removed 2.4-->2.6
1548 GENX_(__NR_create_module, sys_ni_syscall), // 127
1549 LINX_(__NR_init_module, sys_init_module), // 128
1550 LINX_(__NR_delete_module, sys_delete_module), // 129
1551 //zz
1552 //zz // Nb: get_kernel_syms() was removed 2.4-->2.6
1553 GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130
1554 LINX_(__NR_quotactl, sys_quotactl), // 131
1555 GENX_(__NR_getpgid, sys_getpgid), // 132
1556 GENX_(__NR_fchdir, sys_fchdir), // 133
1557 //zz // (__NR_bdflush, sys_bdflush), // 134 */Linux
1558 //zz
1559 //zz // (__NR_sysfs, sys_sysfs), // 135 SVr4
1560 LINX_(__NR_personality, sys_personality), // 136
1561 GENX_(__NR_afs_syscall, sys_ni_syscall), // 137
1562 LINX_(__NR_setfsuid, sys_setfsuid16), // 138
1563 LINX_(__NR_setfsgid, sys_setfsgid16), // 139
1565 LINXY(__NR__llseek, sys_llseek), // 140
1566 GENXY(__NR_getdents, sys_getdents), // 141
1567 GENX_(__NR__newselect, sys_select), // 142
1568 GENX_(__NR_flock, sys_flock), // 143
1569 GENX_(__NR_msync, sys_msync), // 144
1571 GENXY(__NR_readv, sys_readv), // 145
1572 GENX_(__NR_writev, sys_writev), // 146
1573 GENX_(__NR_getsid, sys_getsid), // 147
1574 GENX_(__NR_fdatasync, sys_fdatasync), // 148
1575 LINXY(__NR__sysctl, sys_sysctl), // 149
1577 GENX_(__NR_mlock, sys_mlock), // 150
1578 GENX_(__NR_munlock, sys_munlock), // 151
1579 GENX_(__NR_mlockall, sys_mlockall), // 152
1580 LINX_(__NR_munlockall, sys_munlockall), // 153
1581 LINXY(__NR_sched_setparam, sys_sched_setparam), // 154
1583 LINXY(__NR_sched_getparam, sys_sched_getparam), // 155
1584 LINX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 156
1585 LINX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 157
1586 LINX_(__NR_sched_yield, sys_sched_yield), // 158
1587 LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
1589 LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
1590 LINXY(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 161
1591 GENXY(__NR_nanosleep, sys_nanosleep), // 162
1592 GENX_(__NR_mremap, sys_mremap), // 163
1593 LINX_(__NR_setresuid, sys_setresuid16), // 164
1595 LINXY(__NR_getresuid, sys_getresuid16), // 165
1596 PLAXY(__NR_vm86, sys_vm86), // 166 x86/Linux-only
1597 GENX_(__NR_query_module, sys_ni_syscall), // 167
1598 GENXY(__NR_poll, sys_poll), // 168
1599 //zz // (__NR_nfsservctl, sys_nfsservctl), // 169 */Linux
1600 //zz
1601 LINX_(__NR_setresgid, sys_setresgid16), // 170
1602 LINXY(__NR_getresgid, sys_getresgid16), // 171
1603 LINXY(__NR_prctl, sys_prctl), // 172
1604 PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 173 x86/Linux only?
1605 LINXY(__NR_rt_sigaction, sys_rt_sigaction), // 174
1607 LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 175
1608 LINXY(__NR_rt_sigpending, sys_rt_sigpending), // 176
1609 LINXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait),// 177
1610 LINXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo),// 178
1611 LINX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 179
1613 GENXY(__NR_pread64, sys_pread64), // 180
1614 GENX_(__NR_pwrite64, sys_pwrite64), // 181
1615 LINX_(__NR_chown, sys_chown16), // 182
1616 GENXY(__NR_getcwd, sys_getcwd), // 183
1617 LINXY(__NR_capget, sys_capget), // 184
1619 LINX_(__NR_capset, sys_capset), // 185
1620 GENXY(__NR_sigaltstack, sys_sigaltstack), // 186
1621 LINXY(__NR_sendfile, sys_sendfile), // 187
1622 GENXY(__NR_getpmsg, sys_getpmsg), // 188
1623 GENX_(__NR_putpmsg, sys_putpmsg), // 189
1625 // Nb: we treat vfork as fork
1626 GENX_(__NR_vfork, sys_fork), // 190
1627 GENXY(__NR_ugetrlimit, sys_getrlimit), // 191
1628 PLAX_(__NR_mmap2, sys_mmap2), // 192
1629 GENX_(__NR_truncate64, sys_truncate64), // 193
1630 GENX_(__NR_ftruncate64, sys_ftruncate64), // 194
1632 PLAXY(__NR_stat64, sys_stat64), // 195
1633 PLAXY(__NR_lstat64, sys_lstat64), // 196
1634 PLAXY(__NR_fstat64, sys_fstat64), // 197
1635 GENX_(__NR_lchown32, sys_lchown), // 198
1636 GENX_(__NR_getuid32, sys_getuid), // 199
1638 GENX_(__NR_getgid32, sys_getgid), // 200
1639 GENX_(__NR_geteuid32, sys_geteuid), // 201
1640 GENX_(__NR_getegid32, sys_getegid), // 202
1641 GENX_(__NR_setreuid32, sys_setreuid), // 203
1642 GENX_(__NR_setregid32, sys_setregid), // 204
1644 GENXY(__NR_getgroups32, sys_getgroups), // 205
1645 GENX_(__NR_setgroups32, sys_setgroups), // 206
1646 GENX_(__NR_fchown32, sys_fchown), // 207
1647 LINX_(__NR_setresuid32, sys_setresuid), // 208
1648 LINXY(__NR_getresuid32, sys_getresuid), // 209
1650 LINX_(__NR_setresgid32, sys_setresgid), // 210
1651 LINXY(__NR_getresgid32, sys_getresgid), // 211
1652 GENX_(__NR_chown32, sys_chown), // 212
1653 GENX_(__NR_setuid32, sys_setuid), // 213
1654 GENX_(__NR_setgid32, sys_setgid), // 214
1656 LINX_(__NR_setfsuid32, sys_setfsuid), // 215
1657 LINX_(__NR_setfsgid32, sys_setfsgid), // 216
1658 LINX_(__NR_pivot_root, sys_pivot_root), // 217
1659 GENXY(__NR_mincore, sys_mincore), // 218
1660 GENX_(__NR_madvise, sys_madvise), // 219
1662 GENXY(__NR_getdents64, sys_getdents64), // 220
1663 LINXY(__NR_fcntl64, sys_fcntl64), // 221
1664 GENX_(222, sys_ni_syscall), // 222
1665 PLAXY(223, sys_syscall223), // 223 // sys_bproc?
1666 LINX_(__NR_gettid, sys_gettid), // 224
1668 LINX_(__NR_readahead, sys_readahead), // 225 */Linux
1669 LINX_(__NR_setxattr, sys_setxattr), // 226
1670 LINX_(__NR_lsetxattr, sys_lsetxattr), // 227
1671 LINX_(__NR_fsetxattr, sys_fsetxattr), // 228
1672 LINXY(__NR_getxattr, sys_getxattr), // 229
1674 LINXY(__NR_lgetxattr, sys_lgetxattr), // 230
1675 LINXY(__NR_fgetxattr, sys_fgetxattr), // 231
1676 LINXY(__NR_listxattr, sys_listxattr), // 232
1677 LINXY(__NR_llistxattr, sys_llistxattr), // 233
1678 LINXY(__NR_flistxattr, sys_flistxattr), // 234
1680 LINX_(__NR_removexattr, sys_removexattr), // 235
1681 LINX_(__NR_lremovexattr, sys_lremovexattr), // 236
1682 LINX_(__NR_fremovexattr, sys_fremovexattr), // 237
1683 LINXY(__NR_tkill, sys_tkill), // 238 */Linux
1684 LINXY(__NR_sendfile64, sys_sendfile64), // 239
1686 LINXY(__NR_futex, sys_futex), // 240
1687 LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 241
1688 LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 242
1689 PLAX_(__NR_set_thread_area, sys_set_thread_area), // 243
1690 PLAX_(__NR_get_thread_area, sys_get_thread_area), // 244
1692 LINXY(__NR_io_setup, sys_io_setup), // 245
1693 LINX_(__NR_io_destroy, sys_io_destroy), // 246
1694 LINXY(__NR_io_getevents, sys_io_getevents), // 247
1695 LINX_(__NR_io_submit, sys_io_submit), // 248
1696 LINXY(__NR_io_cancel, sys_io_cancel), // 249
1698 LINX_(__NR_fadvise64, sys_fadvise64), // 250 */(Linux?)
1699 GENX_(251, sys_ni_syscall), // 251
1700 LINX_(__NR_exit_group, sys_exit_group), // 252
1701 LINXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 253
1702 LINXY(__NR_epoll_create, sys_epoll_create), // 254
1704 LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 255
1705 LINXY(__NR_epoll_wait, sys_epoll_wait), // 256
1706 //zz // (__NR_remap_file_pages, sys_remap_file_pages), // 257 */Linux
1707 LINX_(__NR_set_tid_address, sys_set_tid_address), // 258
1708 LINXY(__NR_timer_create, sys_timer_create), // 259
1710 LINXY(__NR_timer_settime, sys_timer_settime), // (timer_create+1)
1711 LINXY(__NR_timer_gettime, sys_timer_gettime), // (timer_create+2)
1712 LINX_(__NR_timer_getoverrun, sys_timer_getoverrun),//(timer_create+3)
1713 LINX_(__NR_timer_delete, sys_timer_delete), // (timer_create+4)
1714 LINX_(__NR_clock_settime, sys_clock_settime), // (timer_create+5)
1716 LINXY(__NR_clock_gettime, sys_clock_gettime), // (timer_create+6)
1717 LINXY(__NR_clock_getres, sys_clock_getres), // (timer_create+7)
1718 LINXY(__NR_clock_nanosleep, sys_clock_nanosleep),// (timer_create+8) */*
1719 GENXY(__NR_statfs64, sys_statfs64), // 268
1720 GENXY(__NR_fstatfs64, sys_fstatfs64), // 269
1722 LINX_(__NR_tgkill, sys_tgkill), // 270 */Linux
1723 GENX_(__NR_utimes, sys_utimes), // 271
1724 LINX_(__NR_fadvise64_64, sys_fadvise64_64), // 272 */(Linux?)
1725 GENX_(__NR_vserver, sys_ni_syscall), // 273
1726 LINX_(__NR_mbind, sys_mbind), // 274 ?/?
1728 LINXY(__NR_get_mempolicy, sys_get_mempolicy), // 275 ?/?
1729 LINX_(__NR_set_mempolicy, sys_set_mempolicy), // 276 ?/?
1730 LINXY(__NR_mq_open, sys_mq_open), // 277
1731 LINX_(__NR_mq_unlink, sys_mq_unlink), // (mq_open+1)
1732 LINX_(__NR_mq_timedsend, sys_mq_timedsend), // (mq_open+2)
1734 LINXY(__NR_mq_timedreceive, sys_mq_timedreceive),// (mq_open+3)
1735 LINX_(__NR_mq_notify, sys_mq_notify), // (mq_open+4)
1736 LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // (mq_open+5)
1737 GENX_(__NR_sys_kexec_load, sys_ni_syscall), // 283
1738 LINXY(__NR_waitid, sys_waitid), // 284
1740 GENX_(285, sys_ni_syscall), // 285
1741 LINX_(__NR_add_key, sys_add_key), // 286
1742 LINX_(__NR_request_key, sys_request_key), // 287
1743 LINXY(__NR_keyctl, sys_keyctl), // 288
1744 LINX_(__NR_ioprio_set, sys_ioprio_set), // 289
1746 LINX_(__NR_ioprio_get, sys_ioprio_get), // 290
1747 LINX_(__NR_inotify_init, sys_inotify_init), // 291
1748 LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 292
1749 LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 293
1750 // LINX_(__NR_migrate_pages, sys_migrate_pages), // 294
1752 LINXY(__NR_openat, sys_openat), // 295
1753 LINX_(__NR_mkdirat, sys_mkdirat), // 296
1754 LINX_(__NR_mknodat, sys_mknodat), // 297
1755 LINX_(__NR_fchownat, sys_fchownat), // 298
1756 LINX_(__NR_futimesat, sys_futimesat), // 299
1758 PLAXY(__NR_fstatat64, sys_fstatat64), // 300
1759 LINX_(__NR_unlinkat, sys_unlinkat), // 301
1760 LINX_(__NR_renameat, sys_renameat), // 302
1761 LINX_(__NR_linkat, sys_linkat), // 303
1762 LINX_(__NR_symlinkat, sys_symlinkat), // 304
1764 LINX_(__NR_readlinkat, sys_readlinkat), // 305
1765 LINX_(__NR_fchmodat, sys_fchmodat), // 306
1766 LINX_(__NR_faccessat, sys_faccessat), // 307
1767 LINX_(__NR_pselect6, sys_pselect6), // 308
1768 LINXY(__NR_ppoll, sys_ppoll), // 309
1770 LINX_(__NR_unshare, sys_unshare), // 310
1771 LINX_(__NR_set_robust_list, sys_set_robust_list), // 311
1772 LINXY(__NR_get_robust_list, sys_get_robust_list), // 312
1773 LINX_(__NR_splice, sys_splice), // 313
1774 LINX_(__NR_sync_file_range, sys_sync_file_range), // 314
1776 LINX_(__NR_tee, sys_tee), // 315
1777 LINXY(__NR_vmsplice, sys_vmsplice), // 316
1778 LINXY(__NR_move_pages, sys_move_pages), // 317
1779 LINXY(__NR_getcpu, sys_getcpu), // 318
1780 LINXY(__NR_epoll_pwait, sys_epoll_pwait), // 319
1782 LINX_(__NR_utimensat, sys_utimensat), // 320
1783 LINXY(__NR_signalfd, sys_signalfd), // 321
1784 LINXY(__NR_timerfd_create, sys_timerfd_create), // 322
1785 LINXY(__NR_eventfd, sys_eventfd), // 323
1786 LINX_(__NR_fallocate, sys_fallocate), // 324
1788 LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 325
1789 LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 326
1790 LINXY(__NR_signalfd4, sys_signalfd4), // 327
1791 LINXY(__NR_eventfd2, sys_eventfd2), // 328
1792 LINXY(__NR_epoll_create1, sys_epoll_create1), // 329
1794 LINXY(__NR_dup3, sys_dup3), // 330
1795 LINXY(__NR_pipe2, sys_pipe2), // 331
1796 LINXY(__NR_inotify_init1, sys_inotify_init1), // 332
1797 LINXY(__NR_preadv, sys_preadv), // 333
1798 LINX_(__NR_pwritev, sys_pwritev), // 334
1800 LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 335
1801 LINXY(__NR_perf_event_open, sys_perf_event_open), // 336
1802 LINXY(__NR_recvmmsg, sys_recvmmsg), // 337
1803 LINXY(__NR_fanotify_init, sys_fanotify_init), // 338
1804 LINX_(__NR_fanotify_mark, sys_fanotify_mark), // 339
1806 LINXY(__NR_prlimit64, sys_prlimit64), // 340
1807 LINXY(__NR_name_to_handle_at, sys_name_to_handle_at),// 341
1808 LINXY(__NR_open_by_handle_at, sys_open_by_handle_at),// 342
1809 LINXY(__NR_clock_adjtime, sys_clock_adjtime), // 343
1810 // LINX_(__NR_syncfs, sys_ni_syscall), // 344
1812 LINXY(__NR_sendmmsg, sys_sendmmsg), // 345
1813 // LINX_(__NR_setns, sys_ni_syscall), // 346
1814 LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 347
1815 LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 348
1816 LINX_(__NR_kcmp, sys_kcmp), // 349
1818 // LIN__(__NR_finit_module, sys_ni_syscall), // 350
1819 // LIN__(__NR_sched_setattr, sys_ni_syscall), // 351
1820 // LIN__(__NR_sched_getattr, sys_ni_syscall), // 352
1821 // LIN__(__NR_renameat2, sys_ni_syscall), // 353
1822 // LIN__(__NR_seccomp, sys_ni_syscall), // 354
1824 LINXY(__NR_getrandom, sys_getrandom) // 355
1825 // LIN__(__NR_memfd_create, sys_ni_syscall), // 356
1826 // LIN__(__NR_bpf, sys_ni_syscall) // 357
1829 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1831 const UInt syscall_table_size
1832 = sizeof(syscall_table) / sizeof(syscall_table[0]);
1834 /* Is it in the contiguous initial section of the table? */
1835 if (sysno < syscall_table_size) {
1836 SyscallTableEntry* sys = &syscall_table[sysno];
1837 if (sys->before == NULL)
1838 return NULL; /* no entry */
1839 else
1840 return sys;
1843 /* Can't find a wrapper */
1844 return NULL;
1847 #endif // defined(VGP_x86_linux)
1849 /*--------------------------------------------------------------------*/
1850 /*--- end ---*/
1851 /*--------------------------------------------------------------------*/