syswrap-x86-linux.c revision 4279a8884ad1aee46dfe34b5df5950b51e93532c
1
2/*--------------------------------------------------------------------*/
3/*--- Platform-specific syscalls stuff.        syswrap-x86-linux.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
9
10   Copyright (C) 2000-2005 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/* TODO/FIXME jrs 20050207: assignments to the syscall return result
32   in interrupted_syscall() need to be reviewed.  They don't seem
33   to assign the shadow state.
34*/
35
36#include "pub_core_basics.h"
37#include "pub_core_threadstate.h"
38#include "pub_core_debuginfo.h"     // Needed for pub_core_aspacemgr :(
39#include "pub_core_aspacemgr.h"
40#include "pub_core_debuglog.h"
41#include "pub_core_libcbase.h"
42#include "pub_core_libcassert.h"
43#include "pub_core_libcmman.h"
44#include "pub_core_libcprint.h"
45#include "pub_core_libcproc.h"
46#include "pub_core_libcsignal.h"
47#include "pub_core_main.h"          // For VG_(shutdown_actions_NORETURN)()
48#include "pub_core_mallocfree.h"
49#include "pub_core_options.h"
50#include "pub_core_scheduler.h"
51#include "pub_core_sigframe.h"      // For VG_(sigframe_destroy)()
52#include "pub_core_signals.h"
53#include "pub_core_syscall.h"
54#include "pub_core_syswrap.h"
55#include "pub_core_tooliface.h"
56
57#include "priv_types_n_macros.h"
58#include "priv_syswrap-generic.h"    /* for decls of generic wrappers */
59#include "priv_syswrap-linux.h"      /* for decls of linux-ish wrappers */
60#include "priv_syswrap-main.h"
61
62#include "vki_unistd.h"              /* for the __NR_* constants */
63
64
65/* ---------------------------------------------------------------------
66   Stacks, thread wrappers
67   Note.  Why is this stuff here?
68   ------------------------------------------------------------------ */
69
70/*
71   Allocate a stack for this thread.
72
73   They're allocated lazily, but never freed.
74 */
75#define FILL	0xdeadbeef
76
77// Valgrind's stack size, in words.
78#define STACK_SIZE_W      16384
79
80static UWord* allocstack(ThreadId tid)
81{
82   ThreadState *tst = VG_(get_ThreadState)(tid);
83   UWord *esp;
84
85   if (tst->os_state.valgrind_stack_base == 0) {
86      void *stk = VG_(mmap)(0, STACK_SIZE_W * sizeof(UWord) + VKI_PAGE_SIZE,
87			    VKI_PROT_READ|VKI_PROT_WRITE,
88			    VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS,
89			    SF_VALGRIND,
90			    -1, 0);
91
92      if (stk != (void *)-1) {
93         VG_(mprotect)(stk, VKI_PAGE_SIZE, VKI_PROT_NONE); /* guard page */
94         tst->os_state.valgrind_stack_base = ((Addr)stk) + VKI_PAGE_SIZE;
95         tst->os_state.valgrind_stack_szB  = STACK_SIZE_W * sizeof(UWord);
96      } else
97      return (UWord*)-1;
98   }
99
100   for (esp = (UWord*) tst->os_state.valgrind_stack_base;
101        esp < (UWord*)(tst->os_state.valgrind_stack_base +
102                       tst->os_state.valgrind_stack_szB);
103        esp++)
104      *esp = FILL;
105   /* esp is left at top of stack */
106
107   if (0)
108      VG_(printf)("stack for tid %d at %p (%x); esp=%p\n",
109		  tid, tst->os_state.valgrind_stack_base,
110                  *(UWord*)(tst->os_state.valgrind_stack_base), esp);
111
112   return esp;
113}
114
115/* NB: this is identical the the amd64 version. */
116/* Return how many bytes of this stack have not been used */
117SSizeT VG_(stack_unused)(ThreadId tid)
118{
119   ThreadState *tst = VG_(get_ThreadState)(tid);
120   UWord* p;
121
122   for (p = (UWord*)tst->os_state.valgrind_stack_base;
123	p && (p < (UWord*)(tst->os_state.valgrind_stack_base +
124                           tst->os_state.valgrind_stack_szB));
125	p++)
126      if (*p != FILL)
127	 break;
128
129   if (0)
130      VG_(printf)("p=%p %x tst->os_state.valgrind_stack_base=%p\n",
131                  p, *p, tst->os_state.valgrind_stack_base);
132
133   return ((Addr)p) - tst->os_state.valgrind_stack_base;
134}
135
136
137/* Run a thread all the way to the end, then do appropriate exit actions
138   (this is the last-one-out-turn-off-the-lights bit).
139*/
140static void run_a_thread_NORETURN ( Word tidW )
141{
142   ThreadId tid = (ThreadId)tidW;
143
144   VG_(debugLog)(1, "syswrap-x86-linux",
145                    "run_a_thread_NORETURN(tid=%lld): "
146                       "ML_(thread_wrapper) called\n",
147                       (ULong)tidW);
148
149   /* Run the thread all the way through. */
150   VgSchedReturnCode src = ML_(thread_wrapper)(tid);
151
152   VG_(debugLog)(1, "syswrap-x86-linux",
153                    "run_a_thread_NORETURN(tid=%lld): "
154                       "ML_(thread_wrapper) done\n",
155                       (ULong)tidW);
156
157   Int c = VG_(count_living_threads)();
158   vg_assert(c >= 1); /* stay sane */
159
160   if (c == 1) {
161
162      VG_(debugLog)(1, "syswrap-x86-linux",
163                       "run_a_thread_NORETURN(tid=%lld): "
164                          "last one standing\n",
165                          (ULong)tidW);
166
167      /* We are the last one standing.  Keep hold of the lock and
168         carry on to show final tool results, then exit the entire system. */
169      VG_(shutdown_actions_NORETURN)(tid, src);
170
171   } else {
172
173      VG_(debugLog)(1, "syswrap-x86-linux",
174                       "run_a_thread_NORETURN(tid=%lld): "
175                          "not last one standing\n",
176                          (ULong)tidW);
177
178      /* OK, thread is dead, but others still exist.  Just exit. */
179      ThreadState *tst = VG_(get_ThreadState)(tid);
180
181      /* This releases the run lock */
182      VG_(exit_thread)(tid);
183      vg_assert(tst->status == VgTs_Zombie);
184
185      /* We have to use this sequence to terminate the thread to
186         prevent a subtle race.  If VG_(exit_thread)() had left the
187         ThreadState as Empty, then it could have been reallocated,
188         reusing the stack while we're doing these last cleanups.
189         Instead, VG_(exit_thread) leaves it as Zombie to prevent
190         reallocation.  We need to make sure we don't touch the stack
191         between marking it Empty and exiting.  Hence the
192         assembler. */
193      asm volatile (
194         "movl	%1, %0\n"	/* set tst->status = VgTs_Empty */
195         "movl	%2, %%eax\n"    /* set %eax = __NR_exit */
196         "movl	%3, %%ebx\n"    /* set %ebx = tst->os_state.exitcode */
197         "int	$0x80\n"	/* exit(tst->os_state.exitcode) */
198         : "=m" (tst->status)
199         : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode));
200
201      VG_(core_panic)("Thread exit failed?\n");
202   }
203
204   /*NOTREACHED*/
205   vg_assert(0);
206}
207
208
209/* Call f(arg1), but first switch stacks, using 'stack' as the new
210   stack, and use 'retaddr' as f's return-to address.  Also, clear all
211   the integer registers before entering f.*/
212__attribute__((noreturn))
213void call_on_new_stack_0_1 ( Addr stack,
214			     Addr retaddr,
215			     void (*f)(Word),
216                             Word arg1 );
217//  4(%esp) == stack
218//  8(%esp) == retaddr
219// 12(%esp) == f
220// 16(%esp) == arg1
221asm(
222"call_on_new_stack_0_1:\n"
223"   movl %esp, %esi\n"     // remember old stack pointer
224"   movl 4(%esi), %esp\n"  // set stack
225"   pushl 16(%esi)\n"      // arg1 to stack
226"   pushl  8(%esi)\n"      // retaddr to stack
227"   pushl 12(%esi)\n"      // f to stack
228"   movl $0, %eax\n"       // zero all GP regs
229"   movl $0, %ebx\n"
230"   movl $0, %ecx\n"
231"   movl $0, %edx\n"
232"   movl $0, %esi\n"
233"   movl $0, %edi\n"
234"   movl $0, %ebp\n"
235"   ret\n"                 // jump to f
236"   ud2\n"                 // should never get here
237);
238
239
240/*
241   Allocate a stack for the main thread, and run it all the way to the
242   end.
243*/
244void VG_(main_thread_wrapper_NORETURN)(ThreadId tid)
245{
246   VG_(debugLog)(1, "syswrap-x86-linux",
247                    "entering VG_(main_thread_wrapper_NORETURN)\n");
248
249   UWord* esp = allocstack(tid);
250
251   /* shouldn't be any other threads around yet */
252   vg_assert( VG_(count_living_threads)() == 1 );
253
254   call_on_new_stack_0_1(
255      (Addr)esp,              /* stack */
256      0,                      /*bogus return address*/
257      run_a_thread_NORETURN,  /* fn to call */
258      (Word)tid               /* arg to give it */
259   );
260
261   /*NOTREACHED*/
262   vg_assert(0);
263}
264
265
266static Int start_thread_NORETURN ( void* arg )
267{
268   ThreadState* tst = (ThreadState*)arg;
269   ThreadId     tid = tst->tid;
270
271   run_a_thread_NORETURN ( (Word)tid );
272   /*NOTREACHED*/
273   vg_assert(0);
274}
275
276
277/* ---------------------------------------------------------------------
278   clone() handling
279   ------------------------------------------------------------------ */
280
281/*
282        Perform a clone system call.  clone is strange because it has
283        fork()-like return-twice semantics, so it needs special
284        handling here.
285
286        Upon entry, we have:
287
288            int (fn)(void*)     in  0+FSZ(%esp)
289            void* child_stack   in  4+FSZ(%esp)
290            int flags           in  8+FSZ(%esp)
291            void* arg           in 12+FSZ(%esp)
292            pid_t* child_tid    in 16+FSZ(%esp)
293            pid_t* parent_tid   in 20+FSZ(%esp)
294            void* tls_ptr       in 24+FSZ(%esp)
295
296        System call requires:
297
298            int    $__NR_clone  in %eax
299            int    flags        in %ebx
300            void*  child_stack  in %ecx
301            pid_t* parent_tid   in %edx
302            pid_t* child_tid    in %edi
303            void*  tls_ptr      in %esi
304
305	Returns an Int encoded in the linux-x86 way, not a SysRes.
306 */
307#define STRINGIFZ(__str) #__str
308#define STRINGIFY(__str)  STRINGIFZ(__str)
309#define FSZ               "4+4+4+4" /* frame size = retaddr+ebx+edi+esi */
310#define __NR_CLONE        STRINGIFY(__NR_clone)
311#define __NR_EXIT         STRINGIFY(__NR_exit)
312
313extern
314Int do_syscall_clone_x86_linux ( Int (*fn)(void *),
315                                 void* stack,
316                                 Int   flags,
317                                 void* arg,
318                                 Int*  child_tid,
319                                 Int*  parent_tid,
320                                 vki_modify_ldt_t * );
321asm(
322"\n"
323"do_syscall_clone_x86_linux:\n"
324"        push    %ebx\n"
325"        push    %edi\n"
326"        push    %esi\n"
327
328         /* set up child stack with function and arg */
329"        movl     4+"FSZ"(%esp), %ecx\n"    /* syscall arg2: child stack */
330"        movl    12+"FSZ"(%esp), %ebx\n"    /* fn arg */
331"        movl     0+"FSZ"(%esp), %eax\n"    /* fn */
332"        lea     -8(%ecx), %ecx\n"          /* make space on stack */
333"        movl    %ebx, 4(%ecx)\n"           /*   fn arg */
334"        movl    %eax, 0(%ecx)\n"           /*   fn */
335
336         /* get other args to clone */
337"        movl     8+"FSZ"(%esp), %ebx\n"    /* syscall arg1: flags */
338"        movl    20+"FSZ"(%esp), %edx\n"    /* syscall arg3: parent tid * */
339"        movl    16+"FSZ"(%esp), %edi\n"    /* syscall arg5: child tid * */
340"        movl    24+"FSZ"(%esp), %esi\n"    /* syscall arg4: tls_ptr * */
341"        movl    $"__NR_CLONE", %eax\n"
342"        int     $0x80\n"                   /* clone() */
343"        testl   %eax, %eax\n"              /* child if retval == 0 */
344"        jnz     1f\n"
345
346         /* CHILD - call thread function */
347"        popl    %eax\n"
348"        call    *%eax\n"                   /* call fn */
349
350         /* exit with result */
351"        movl    %eax, %ebx\n"              /* arg1: return value from fn */
352"        movl    $"__NR_EXIT", %eax\n"
353"        int     $0x80\n"
354
355         /* Hm, exit returned */
356"        ud2\n"
357
358"1:\n"   /* PARENT or ERROR */
359"        pop     %esi\n"
360"        pop     %edi\n"
361"        pop     %ebx\n"
362"        ret\n"
363);
364
365#undef FSZ
366#undef __NR_CLONE
367#undef __NR_EXIT
368#undef STRINGIFY
369#undef STRINGIFZ
370
371
372// forward declarations
373static void setup_child ( ThreadArchState*, ThreadArchState*, Bool );
374static SysRes sys_set_thread_area ( ThreadId, vki_modify_ldt_t* );
375
376/*
377   When a client clones, we need to keep track of the new thread.  This means:
378   1. allocate a ThreadId+ThreadState+stack for the the thread
379
380   2. initialize the thread's new VCPU state
381
382   3. create the thread using the same args as the client requested,
383   but using the scheduler entrypoint for EIP, and a separate stack
384   for ESP.
385 */
386static SysRes do_clone ( ThreadId ptid,
387                         UInt flags, Addr esp,
388                         Int* parent_tidptr,
389                         Int* child_tidptr,
390                         vki_modify_ldt_t *tlsinfo)
391{
392   static const Bool debug = False;
393
394   ThreadId     ctid = VG_(alloc_ThreadState)();
395   ThreadState* ptst = VG_(get_ThreadState)(ptid);
396   ThreadState* ctst = VG_(get_ThreadState)(ctid);
397   UWord*       stack;
398   Segment*     seg;
399   SysRes       res;
400   Int          eax;
401   vki_sigset_t blockall, savedmask;
402
403   VG_(sigfillset)(&blockall);
404
405   vg_assert(VG_(is_running_thread)(ptid));
406   vg_assert(VG_(is_valid_tid)(ctid));
407
408   stack = allocstack(ctid);
409
410   /* Copy register state
411
412      Both parent and child return to the same place, and the code
413      following the clone syscall works out which is which, so we
414      don't need to worry about it.
415
416      The parent gets the child's new tid returned from clone, but the
417      child gets 0.
418
419      If the clone call specifies a NULL esp for the new thread, then
420      it actually gets a copy of the parent's esp.
421   */
422   /* Note: the clone call done by the Quadrics Elan3 driver specifies
423      clone flags of 0xF00, and it seems to rely on the assumption
424      that the child inherits a copy of the parent's GDT.
425      setup_child takes care of setting that up. */
426   setup_child( &ctst->arch, &ptst->arch, True );
427
428   /* Make sys_clone appear to have returned Success(0) in the
429      child. */
430   ctst->arch.vex.guest_EAX = 0;
431
432   if (esp != 0)
433      ctst->arch.vex.guest_ESP = esp;
434
435   ctst->os_state.parent = ptid;
436
437   /* inherit signal mask */
438   ctst->sig_mask     = ptst->sig_mask;
439   ctst->tmp_sig_mask = ptst->sig_mask;
440
441   /* We don't really know where the client stack is, because its
442      allocated by the client.  The best we can do is look at the
443      memory mappings and try to derive some useful information.  We
444      assume that esp starts near its highest possible value, and can
445      only go down to the start of the mmaped segment. */
446   seg = VG_(find_segment)((Addr)esp);
447   if (seg) {
448      ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(esp);
449      ctst->client_stack_szB  = ctst->client_stack_highest_word - seg->addr;
450
451      if (debug)
452	 VG_(printf)("tid %d: guessed client stack range %p-%p\n",
453		     ctid, seg->addr, VG_PGROUNDUP(esp));
454   } else {
455      VG_(message)(Vg_UserMsg, "!? New thread %d starts with ESP(%p) unmapped\n",
456		   ctid, esp);
457      ctst->client_stack_szB  = 0;
458   }
459
460   if (flags & VKI_CLONE_SETTLS) {
461      if (debug)
462	 VG_(printf)("clone child has SETTLS: tls info at %p: idx=%d "
463                     "base=%p limit=%x; esp=%p fs=%x gs=%x\n",
464		     tlsinfo, tlsinfo->entry_number,
465                     tlsinfo->base_addr, tlsinfo->limit,
466		     ptst->arch.vex.guest_ESP,
467		     ctst->arch.vex.guest_FS, ctst->arch.vex.guest_GS);
468      res = sys_set_thread_area(ctid, tlsinfo);
469      if (res.isError)
470	 goto out;
471   }
472
473   flags &= ~VKI_CLONE_SETTLS;
474
475   /* start the thread with everything blocked */
476   VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
477
478   /* Create the new thread */
479   eax = do_syscall_clone_x86_linux(
480            start_thread_NORETURN, stack, flags, &VG_(threads)[ctid],
481            child_tidptr, parent_tidptr, NULL
482         );
483   res = VG_(mk_SysRes_x86_linux)( eax );
484
485   VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
486
487  out:
488   if (res.isError) {
489      /* clone failed */
490      VG_(cleanup_thread)(&ctst->arch);
491      ctst->status = VgTs_Empty;
492   }
493
494   return res;
495}
496
497
498/* Do a clone which is really a fork() */
499static SysRes do_fork_clone ( ThreadId tid,
500                              UInt flags, Addr esp,
501                              Int* parent_tidptr,
502                              Int* child_tidptr )
503{
504   vki_sigset_t fork_saved_mask;
505   vki_sigset_t mask;
506   SysRes       res;
507
508   if (flags & (VKI_CLONE_SETTLS | VKI_CLONE_FS | VKI_CLONE_VM
509                | VKI_CLONE_FILES | VKI_CLONE_VFORK))
510      return VG_(mk_SysRes_Error)( VKI_EINVAL );
511
512   /* Block all signals during fork, so that we can fix things up in
513      the child without being interrupted. */
514   VG_(sigfillset)(&mask);
515   VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
516
517   /* Since this is the fork() form of clone, we don't need all that
518      VG_(clone) stuff */
519   res = VG_(do_syscall5)( __NR_clone, flags,
520                           (UWord)NULL, (UWord)parent_tidptr,
521                           (UWord)NULL, (UWord)child_tidptr );
522
523   if (!res.isError && res.val == 0) {
524      /* child */
525      VG_(do_atfork_child)(tid);
526
527      /* restore signal mask */
528      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
529   }
530   else
531   if (!res.isError && res.val > 0) {
532      /* parent */
533      if (VG_(clo_trace_syscalls))
534	  VG_(printf)("   clone(fork): process %d created child %d\n",
535                      VG_(getpid)(), res.val);
536
537      /* restore signal mask */
538      VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
539   }
540
541   return res;
542}
543
544/* ---------------------------------------------------------------------
545   LDT/GDT simulation
546   ------------------------------------------------------------------ */
547
548/* Details of the LDT simulation
549   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
550
551   When a program runs natively, the linux kernel allows each *thread*
552   in it to have its own LDT.  Almost all programs never do this --
553   it's wildly unportable, after all -- and so the kernel never
554   allocates the structure, which is just as well as an LDT occupies
555   64k of memory (8192 entries of size 8 bytes).
556
557   A thread may choose to modify its LDT entries, by doing the
558   __NR_modify_ldt syscall.  In such a situation the kernel will then
559   allocate an LDT structure for it.  Each LDT entry is basically a
560   (base, limit) pair.  A virtual address in a specific segment is
561   translated to a linear address by adding the segment's base value.
562   In addition, the virtual address must not exceed the limit value.
563
564   To use an LDT entry, a thread loads one of the segment registers
565   (%cs, %ss, %ds, %es, %fs, %gs) with the index of the LDT entry (0
566   .. 8191) it wants to use.  In fact, the required value is (index <<
567   3) + 7, but that's not important right now.  Any normal instruction
568   which includes an addressing mode can then be made relative to that
569   LDT entry by prefixing the insn with a so-called segment-override
570   prefix, a byte which indicates which of the 6 segment registers
571   holds the LDT index.
572
573   Now, a key constraint is that valgrind's address checks operate in
574   terms of linear addresses.  So we have to explicitly translate
575   virtual addrs into linear addrs, and that means doing a complete
576   LDT simulation.
577
578   Calls to modify_ldt are intercepted.  For each thread, we maintain
579   an LDT (with the same normally-never-allocated optimisation that
580   the kernel does).  This is updated as expected via calls to
581   modify_ldt.
582
583   When a thread does an amode calculation involving a segment
584   override prefix, the relevant LDT entry for the thread is
585   consulted.  It all works.
586
587   There is a conceptual problem, which appears when switching back to
588   native execution, either temporarily to pass syscalls to the
589   kernel, or permanently, when debugging V.  Problem at such points
590   is that it's pretty pointless to copy the simulated machine's
591   segment registers to the real machine, because we'd also need to
592   copy the simulated LDT into the real one, and that's prohibitively
593   expensive.
594
595   Fortunately it looks like no syscalls rely on the segment regs or
596   LDT being correct, so we can get away with it.  Apart from that the
597   simulation is pretty straightforward.  All 6 segment registers are
598   tracked, although only %ds, %es, %fs and %gs are allowed as
599   prefixes.  Perhaps it could be restricted even more than that -- I
600   am not sure what is and isn't allowed in user-mode.
601*/
602
603/* Translate a struct modify_ldt_ldt_s to a VexGuestX86SegDescr, using
604   the Linux kernel's logic (cut-n-paste of code in
605   linux/kernel/ldt.c).  */
606
607static
608void translate_to_hw_format ( /* IN  */ vki_modify_ldt_t* inn,
609                              /* OUT */ VexGuestX86SegDescr* out,
610                                        Int oldmode )
611{
612   UInt entry_1, entry_2;
613   vg_assert(8 == sizeof(VexGuestX86SegDescr));
614
615   if (0)
616      VG_(printf)("translate_to_hw_format: base %p, limit %d\n",
617                  inn->base_addr, inn->limit );
618
619   /* Allow LDTs to be cleared by the user. */
620   if (inn->base_addr == 0 && inn->limit == 0) {
621      if (oldmode ||
622          (inn->contents == 0      &&
623           inn->read_exec_only == 1   &&
624           inn->seg_32bit == 0      &&
625           inn->limit_in_pages == 0   &&
626           inn->seg_not_present == 1   &&
627           inn->useable == 0 )) {
628         entry_1 = 0;
629         entry_2 = 0;
630         goto install;
631      }
632   }
633
634   entry_1 = ((inn->base_addr & 0x0000ffff) << 16) |
635             (inn->limit & 0x0ffff);
636   entry_2 = (inn->base_addr & 0xff000000) |
637             ((inn->base_addr & 0x00ff0000) >> 16) |
638             (inn->limit & 0xf0000) |
639             ((inn->read_exec_only ^ 1) << 9) |
640             (inn->contents << 10) |
641             ((inn->seg_not_present ^ 1) << 15) |
642             (inn->seg_32bit << 22) |
643             (inn->limit_in_pages << 23) |
644             0x7000;
645   if (!oldmode)
646      entry_2 |= (inn->useable << 20);
647
648   /* Install the new entry ...  */
649  install:
650   out->LdtEnt.Words.word1 = entry_1;
651   out->LdtEnt.Words.word2 = entry_2;
652}
653
654/* Create a zeroed-out GDT. */
655static VexGuestX86SegDescr* alloc_zeroed_x86_GDT ( void )
656{
657   Int nbytes = VEX_GUEST_X86_GDT_NENT * sizeof(VexGuestX86SegDescr);
658   return VG_(arena_calloc)(VG_AR_CORE, nbytes, 1);
659}
660
661/* Create a zeroed-out LDT. */
662static VexGuestX86SegDescr* alloc_zeroed_x86_LDT ( void )
663{
664   Int nbytes = VEX_GUEST_X86_LDT_NENT * sizeof(VexGuestX86SegDescr);
665   return VG_(arena_calloc)(VG_AR_CORE, nbytes, 1);
666}
667
668/* Free up an LDT or GDT allocated by the above fns. */
669static void free_LDT_or_GDT ( VexGuestX86SegDescr* dt )
670{
671   vg_assert(dt);
672   VG_(arena_free)(VG_AR_CORE, (void*)dt);
673}
674
675/* Copy contents between two existing LDTs. */
676static void copy_LDT_from_to ( VexGuestX86SegDescr* src,
677                               VexGuestX86SegDescr* dst )
678{
679   Int i;
680   vg_assert(src);
681   vg_assert(dst);
682   for (i = 0; i < VEX_GUEST_X86_LDT_NENT; i++)
683      dst[i] = src[i];
684}
685
686/* Copy contents between two existing GDTs. */
687static void copy_GDT_from_to ( VexGuestX86SegDescr* src,
688                               VexGuestX86SegDescr* dst )
689{
690   Int i;
691   vg_assert(src);
692   vg_assert(dst);
693   for (i = 0; i < VEX_GUEST_X86_GDT_NENT; i++)
694      dst[i] = src[i];
695}
696
697/* Free this thread's DTs, if it has any. */
698static void deallocate_LGDTs_for_thread ( VexGuestX86State* vex )
699{
700   vg_assert(sizeof(HWord) == sizeof(void*));
701
702   if (0)
703      VG_(printf)("deallocate_LGDTs_for_thread: "
704                  "ldt = 0x%x, gdt = 0x%x\n",
705                  vex->guest_LDT, vex->guest_GDT );
706
707   if (vex->guest_LDT != (HWord)NULL) {
708      free_LDT_or_GDT( (VexGuestX86SegDescr*)vex->guest_LDT );
709      vex->guest_LDT = (HWord)NULL;
710   }
711
712   if (vex->guest_GDT != (HWord)NULL) {
713      free_LDT_or_GDT( (VexGuestX86SegDescr*)vex->guest_GDT );
714      vex->guest_GDT = (HWord)NULL;
715   }
716}
717
718
719/*
720 * linux/kernel/ldt.c
721 *
722 * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
723 * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
724 */
725
726/*
727 * read_ldt() is not really atomic - this is not a problem since
728 * synchronization of reads and writes done to the LDT has to be
729 * assured by user-space anyway. Writes are atomic, to protect
730 * the security checks done on new descriptors.
731 */
732static
733SysRes read_ldt ( ThreadId tid, UChar* ptr, UInt bytecount )
734{
735   SysRes res;
736   UInt   i, size;
737   UChar* ldt;
738
739   if (0)
740      VG_(printf)("read_ldt: tid = %d, ptr = %p, bytecount = %d\n",
741                  tid, ptr, bytecount );
742
743   vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
744   vg_assert(8 == sizeof(VexGuestX86SegDescr));
745
746   ldt = (Char*)(VG_(threads)[tid].arch.vex.guest_LDT);
747   res = VG_(mk_SysRes_Success)( 0 );
748   if (ldt == NULL)
749      /* LDT not allocated, meaning all entries are null */
750      goto out;
751
752   size = VEX_GUEST_X86_LDT_NENT * sizeof(VexGuestX86SegDescr);
753   if (size > bytecount)
754      size = bytecount;
755
756   res = VG_(mk_SysRes_Success)( size );
757   for (i = 0; i < size; i++)
758      ptr[i] = ldt[i];
759
760  out:
761   return res;
762}
763
764
765static
766SysRes write_ldt ( ThreadId tid, void* ptr, UInt bytecount, Int oldmode )
767{
768   SysRes res;
769   VexGuestX86SegDescr* ldt;
770   vki_modify_ldt_t* ldt_info;
771
772   if (0)
773      VG_(printf)("write_ldt: tid = %d, ptr = %p, "
774                  "bytecount = %d, oldmode = %d\n",
775                  tid, ptr, bytecount, oldmode );
776
777   vg_assert(8 == sizeof(VexGuestX86SegDescr));
778   vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
779
780   ldt      = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_LDT;
781   ldt_info = (vki_modify_ldt_t*)ptr;
782
783   res = VG_(mk_SysRes_Error)( VKI_EINVAL );
784   if (bytecount != sizeof(vki_modify_ldt_t))
785      goto out;
786
787   res = VG_(mk_SysRes_Error)( VKI_EINVAL );
788   if (ldt_info->entry_number >= VEX_GUEST_X86_LDT_NENT)
789      goto out;
790   if (ldt_info->contents == 3) {
791      if (oldmode)
792         goto out;
793      if (ldt_info->seg_not_present == 0)
794         goto out;
795   }
796
797   /* If this thread doesn't have an LDT, we'd better allocate it
798      now. */
799   if (ldt == (HWord)NULL) {
800      ldt = alloc_zeroed_x86_LDT();
801      VG_(threads)[tid].arch.vex.guest_LDT = (HWord)ldt;
802   }
803
804   /* Install the new entry ...  */
805   translate_to_hw_format ( ldt_info, &ldt[ldt_info->entry_number], oldmode );
806   res = VG_(mk_SysRes_Success)( 0 );
807
808  out:
809   return res;
810}
811
812
813static SysRes sys_modify_ldt ( ThreadId tid,
814                               Int func, void* ptr, UInt bytecount )
815{
816   SysRes ret = VG_(mk_SysRes_Error)( VKI_ENOSYS );
817
818   switch (func) {
819   case 0:
820      ret = read_ldt(tid, ptr, bytecount);
821      break;
822   case 1:
823      ret = write_ldt(tid, ptr, bytecount, 1);
824      break;
825   case 2:
826      VG_(unimplemented)("sys_modify_ldt: func == 2");
827      /* god knows what this is about */
828      /* ret = read_default_ldt(ptr, bytecount); */
829      /*UNREACHED*/
830      break;
831   case 0x11:
832      ret = write_ldt(tid, ptr, bytecount, 0);
833      break;
834   }
835   return ret;
836}
837
838
839static SysRes sys_set_thread_area ( ThreadId tid, vki_modify_ldt_t* info )
840{
841   Int                  idx;
842   VexGuestX86SegDescr* gdt;
843
844   vg_assert(8 == sizeof(VexGuestX86SegDescr));
845   vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
846
847   if (info == NULL)
848      return VG_(mk_SysRes_Error)( VKI_EFAULT );
849
850   gdt = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_GDT;
851
852   /* If the thread doesn't have a GDT, allocate it now. */
853   if (!gdt) {
854      gdt = alloc_zeroed_x86_GDT();
855      VG_(threads)[tid].arch.vex.guest_GDT = (HWord)gdt;
856   }
857
858   idx = info->entry_number;
859
860   if (idx == -1) {
861      /* Find and use the first free entry. */
862      for (idx = 0; idx < VEX_GUEST_X86_GDT_NENT; idx++) {
863         if (gdt[idx].LdtEnt.Words.word1 == 0
864             && gdt[idx].LdtEnt.Words.word2 == 0)
865            break;
866      }
867
868      if (idx == VEX_GUEST_X86_GDT_NENT)
869         return VG_(mk_SysRes_Error)( VKI_ESRCH );
870   } else if (idx < 0 || idx >= VEX_GUEST_X86_GDT_NENT) {
871      return VG_(mk_SysRes_Error)( VKI_EINVAL );
872   }
873
874   translate_to_hw_format(info, &gdt[idx], 0);
875
876   VG_TRACK( pre_mem_write, Vg_CoreSysCall, tid,
877             "set_thread_area(info->entry)",
878             (Addr) & info->entry_number, sizeof(unsigned int) );
879   info->entry_number = idx;
880   VG_TRACK( post_mem_write, Vg_CoreSysCall, tid,
881             (Addr) & info->entry_number, sizeof(unsigned int) );
882
883   return VG_(mk_SysRes_Success)( 0 );
884}
885
886
887static SysRes sys_get_thread_area ( ThreadId tid, vki_modify_ldt_t* info )
888{
889   Int idx;
890   VexGuestX86SegDescr* gdt;
891
892   vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
893   vg_assert(8 == sizeof(VexGuestX86SegDescr));
894
895   if (info == NULL)
896      return VG_(mk_SysRes_Error)( VKI_EFAULT );
897
898   idx = info->entry_number;
899
900   if (idx < 0 || idx >= VEX_GUEST_X86_GDT_NENT)
901      return VG_(mk_SysRes_Error)( VKI_EINVAL );
902
903   gdt = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_GDT;
904
905   /* If the thread doesn't have a GDT, allocate it now. */
906   if (!gdt) {
907      gdt = alloc_zeroed_x86_GDT();
908      VG_(threads)[tid].arch.vex.guest_GDT = (HWord)gdt;
909   }
910
911   info->base_addr = ( gdt[idx].LdtEnt.Bits.BaseHi << 24 ) |
912                     ( gdt[idx].LdtEnt.Bits.BaseMid << 16 ) |
913                     gdt[idx].LdtEnt.Bits.BaseLow;
914   info->limit = ( gdt[idx].LdtEnt.Bits.LimitHi << 16 ) |
915                   gdt[idx].LdtEnt.Bits.LimitLow;
916   info->seg_32bit = gdt[idx].LdtEnt.Bits.Default_Big;
917   info->contents = ( gdt[idx].LdtEnt.Bits.Type >> 2 ) & 0x3;
918   info->read_exec_only = ( gdt[idx].LdtEnt.Bits.Type & 0x1 ) ^ 0x1;
919   info->limit_in_pages = gdt[idx].LdtEnt.Bits.Granularity;
920   info->seg_not_present = gdt[idx].LdtEnt.Bits.Pres ^ 0x1;
921   info->useable = gdt[idx].LdtEnt.Bits.Sys;
922   info->reserved = 0;
923
924   return VG_(mk_SysRes_Success)( 0 );
925}
926
927/* ---------------------------------------------------------------------
928   More thread stuff
929   ------------------------------------------------------------------ */
930
931void VG_(cleanup_thread) ( ThreadArchState* arch )
932{
933   /* Release arch-specific resources held by this thread. */
934   /* On x86, we have to dump the LDT and GDT. */
935   deallocate_LGDTs_for_thread( &arch->vex );
936}
937
938
939static void setup_child ( /*OUT*/ ThreadArchState *child,
940                          /*IN*/  ThreadArchState *parent,
941                          Bool inherit_parents_GDT )
942{
943   /* We inherit our parent's guest state. */
944   child->vex = parent->vex;
945   child->vex_shadow = parent->vex_shadow;
946
947   /* We inherit our parent's LDT. */
948   if (parent->vex.guest_LDT == (HWord)NULL) {
949      /* We hope this is the common case. */
950      child->vex.guest_LDT = (HWord)NULL;
951   } else {
952      /* No luck .. we have to take a copy of the parent's. */
953      child->vex.guest_LDT = (HWord)alloc_zeroed_x86_LDT();
954      copy_LDT_from_to( (VexGuestX86SegDescr*)parent->vex.guest_LDT,
955                        (VexGuestX86SegDescr*)child->vex.guest_LDT );
956   }
957
958   /* Either we start with an empty GDT (the usual case) or inherit a
959      copy of our parents' one (Quadrics Elan3 driver -style clone
960      only). */
961   child->vex.guest_GDT = (HWord)NULL;
962
963   if (inherit_parents_GDT && parent->vex.guest_GDT != (HWord)NULL) {
964      child->vex.guest_GDT = (HWord)alloc_zeroed_x86_GDT();
965      copy_GDT_from_to( (VexGuestX86SegDescr*)parent->vex.guest_GDT,
966                        (VexGuestX86SegDescr*)child->vex.guest_GDT );
967   }
968}
969
970
971/* ---------------------------------------------------------------------
972   PRE/POST wrappers for x86/Linux-specific syscalls
973   ------------------------------------------------------------------ */
974
975#define PRE(name)       DEFN_PRE_TEMPLATE(x86_linux, name)
976#define POST(name)      DEFN_POST_TEMPLATE(x86_linux, name)
977
978/* Add prototypes for the wrappers declared here, so that gcc doesn't
979   harass us for not having prototypes.  Really this is a kludge --
980   the right thing to do is to make these wrappers 'static' since they
981   aren't visible outside this file, but that requires even more macro
982   magic. */
983DECL_TEMPLATE(x86_linux, sys_socketcall);
984DECL_TEMPLATE(x86_linux, sys_stat64);
985DECL_TEMPLATE(x86_linux, sys_fstat64);
986DECL_TEMPLATE(x86_linux, sys_lstat64);
987DECL_TEMPLATE(x86_linux, sys_clone);
988DECL_TEMPLATE(x86_linux, old_mmap);
989DECL_TEMPLATE(x86_linux, sys_sigreturn);
990DECL_TEMPLATE(x86_linux, sys_ipc);
991DECL_TEMPLATE(x86_linux, sys_rt_sigreturn);
992DECL_TEMPLATE(x86_linux, sys_modify_ldt);
993DECL_TEMPLATE(x86_linux, sys_set_thread_area);
994DECL_TEMPLATE(x86_linux, sys_get_thread_area);
995DECL_TEMPLATE(x86_linux, sys_ptrace);
996DECL_TEMPLATE(x86_linux, sys_sigaction);
997DECL_TEMPLATE(x86_linux, old_select);
998
999PRE(old_select)
1000{
1001   /* struct sel_arg_struct {
1002      unsigned long n;
1003      fd_set *inp, *outp, *exp;
1004      struct timeval *tvp;
1005      };
1006   */
1007   PRE_REG_READ1(long, "old_select", struct sel_arg_struct *, args);
1008   PRE_MEM_READ( "old_select(args)", ARG1, 5*sizeof(UWord) );
1009   *flags |= SfMayBlock;
1010   {
1011      UInt* arg_struct = (UInt*)ARG1;
1012      UInt a1, a2, a3, a4, a5;
1013
1014      a1 = arg_struct[0];
1015      a2 = arg_struct[1];
1016      a3 = arg_struct[2];
1017      a4 = arg_struct[3];
1018      a5 = arg_struct[4];
1019
1020      PRINT("old_select ( %d, %p, %p, %p, %p )", a1,a2,a3,a4,a5);
1021      if (a2 != (Addr)NULL)
1022         PRE_MEM_READ( "old_select(readfds)",   a2, a1/8 /* __FD_SETSIZE/8 */ );
1023      if (a3 != (Addr)NULL)
1024         PRE_MEM_READ( "old_select(writefds)",  a3, a1/8 /* __FD_SETSIZE/8 */ );
1025      if (a4 != (Addr)NULL)
1026         PRE_MEM_READ( "old_select(exceptfds)", a4, a1/8 /* __FD_SETSIZE/8 */ );
1027      if (a5 != (Addr)NULL)
1028         PRE_MEM_READ( "old_select(timeout)", a5, sizeof(struct vki_timeval) );
1029   }
1030}
1031
1032PRE(sys_clone)
1033{
1034   UInt cloneflags;
1035
1036   PRINT("sys_clone ( %x, %p, %p, %p, %p )",ARG1,ARG2,ARG3,ARG4,ARG5);
1037   PRE_REG_READ5(int, "clone",
1038                 unsigned long, flags,
1039                 void *, child_stack,
1040                 int *, parent_tidptr,
1041                 vki_modify_ldt_t *, tlsinfo,
1042                 int *, child_tidptr);
1043
1044   if (ARG1 & VKI_CLONE_PARENT_SETTID) {
1045      PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
1046      if (!VG_(is_addressable)(ARG3, sizeof(Int), VKI_PROT_WRITE)) {
1047         SET_STATUS_Failure( VKI_EFAULT );
1048         return;
1049      }
1050   }
1051   if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
1052      PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
1053      if (!VG_(is_addressable)(ARG5, sizeof(Int), VKI_PROT_WRITE)) {
1054         SET_STATUS_Failure( VKI_EFAULT );
1055         return;
1056      }
1057   }
1058   if (ARG1 & VKI_CLONE_SETTLS) {
1059      PRE_MEM_READ("clone(tls_user_desc)", ARG4, sizeof(vki_modify_ldt_t));
1060      if (!VG_(is_addressable)(ARG4, sizeof(vki_modify_ldt_t), VKI_PROT_READ)) {
1061         SET_STATUS_Failure( VKI_EFAULT );
1062         return;
1063      }
1064   }
1065
1066   cloneflags = ARG1;
1067
1068   if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
1069      SET_STATUS_Failure( VKI_EINVAL );
1070      return;
1071   }
1072
1073   /* Be ultra-paranoid and filter out any clone-variants we don't understand:
1074      - ??? specifies clone flags of 0x100011
1075      - ??? specifies clone flags of 0x1200011.
1076      - NPTL specifies clone flags of 0x7D0F00.
1077      - The Quadrics Elan3 driver specifies clone flags of 0xF00.
1078      Everything else is rejected.
1079   */
1080   if (
1081          (cloneflags == 0x100011 || cloneflags == 0x1200011
1082                                  || cloneflags == 0x7D0F00
1083                                  || cloneflags == 0x790F00
1084                                  || cloneflags == 0x3D0F00
1085                                  || cloneflags == 0xF00
1086                                  || cloneflags == 0xF21)) {
1087     /* OK */
1088   }
1089   else {
1090      /* Nah.  We don't like it.  Go away. */
1091      goto reject;
1092   }
1093
1094   /* Only look at the flags we really care about */
1095   switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
1096                         | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
1097   case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
1098      /* thread creation */
1099      SET_STATUS_from_SysRes(
1100         do_clone(tid,
1101                  ARG1,         /* flags */
1102                  (Addr)ARG2,   /* child ESP */
1103                  (Int *)ARG3,  /* parent_tidptr */
1104                  (Int *)ARG5,  /* child_tidptr */
1105                  (vki_modify_ldt_t *)ARG4)); /* set_tls */
1106      break;
1107
1108   case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
1109      /* FALLTHROUGH - assume vfork == fork */
1110      cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
1111
1112   case 0: /* plain fork */
1113      SET_STATUS_from_SysRes(
1114         do_fork_clone(tid,
1115                       cloneflags,      /* flags */
1116                       (Addr)ARG2,      /* child ESP */
1117                       (Int *)ARG3,     /* parent_tidptr */
1118                       (Int *)ARG5));   /* child_tidptr */
1119      break;
1120
1121   default:
1122   reject:
1123      /* should we just ENOSYS? */
1124      VG_(message)(Vg_UserMsg, "");
1125      VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%x", ARG1);
1126      VG_(message)(Vg_UserMsg, "");
1127      VG_(message)(Vg_UserMsg, "The only supported clone() uses are:");
1128      VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)");
1129      VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork");
1130      VG_(message)(Vg_UserMsg, " - for the Quadrics Elan3 user-space driver");
1131      VG_(unimplemented)
1132         ("Valgrind does not support general clone().");
1133   }
1134
1135   if (SUCCESS) {
1136      if (ARG1 & VKI_CLONE_PARENT_SETTID)
1137         POST_MEM_WRITE(ARG3, sizeof(Int));
1138      if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
1139         POST_MEM_WRITE(ARG5, sizeof(Int));
1140
1141      /* Thread creation was successful; let the child have the chance
1142         to run */
1143      *flags |= SfYieldAfter;
1144   }
1145}
1146
1147PRE(sys_sigreturn)
1148{
1149   ThreadState* tst;
1150   PRINT("sigreturn ( )");
1151
1152   vg_assert(VG_(is_valid_tid)(tid));
1153   vg_assert(tid >= 1 && tid < VG_N_THREADS);
1154   vg_assert(VG_(is_running_thread)(tid));
1155
1156   /* Adjust esp to point to start of frame; skip back up over
1157      sigreturn sequence's "popl %eax" and handler ret addr */
1158   tst = VG_(get_ThreadState)(tid);
1159   tst->arch.vex.guest_ESP -= sizeof(Addr)+sizeof(Word);
1160
1161   /* This is only so that the EIP is (might be) useful to report if
1162      something goes wrong in the sigreturn */
1163   ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
1164
1165   VG_(sigframe_destroy)(tid, False);
1166
1167   /* For unclear reasons, it appears we need the syscall to return
1168      without changing %EAX.  Since %EAX is the return value, and can
1169      denote either success or failure, we must set up so that the
1170      driver logic copies it back unchanged.  Also, note %EAX is of
1171      the guest registers written by VG_(sigframe_destroy). */
1172   SET_STATUS_from_SysRes( VG_(mk_SysRes_x86_linux)( tst->arch.vex.guest_EAX ) );
1173
1174   /* Check to see if some any signals arose as a result of this. */
1175   *flags |= SfPollAfter;
1176}
1177
1178PRE(sys_rt_sigreturn)
1179{
1180   ThreadState* tst;
1181   PRINT("rt_sigreturn ( )");
1182
1183   vg_assert(VG_(is_valid_tid)(tid));
1184   vg_assert(tid >= 1 && tid < VG_N_THREADS);
1185   vg_assert(VG_(is_running_thread)(tid));
1186
1187   /* Adjust esp to point to start of frame; skip back up over handler
1188      ret addr */
1189   tst = VG_(get_ThreadState)(tid);
1190   tst->arch.vex.guest_ESP -= sizeof(Addr);
1191
1192   /* This is only so that the EIP is (might be) useful to report if
1193      something goes wrong in the sigreturn */
1194   ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
1195
1196   VG_(sigframe_destroy)(tid, True);
1197
1198   /* For unclear reasons, it appears we need the syscall to return
1199      without changing %EAX.  Since %EAX is the return value, and can
1200      denote either success or failure, we must set up so that the
1201      driver logic copies it back unchanged.  Also, note %EAX is of
1202      the guest registers written by VG_(sigframe_destroy). */
1203   SET_STATUS_from_SysRes( VG_(mk_SysRes_x86_linux)( tst->arch.vex.guest_EAX ) );
1204
1205   /* Check to see if some any signals arose as a result of this. */
1206   *flags |= SfPollAfter;
1207}
1208
1209PRE(sys_modify_ldt)
1210{
1211   PRINT("sys_modify_ldt ( %d, %p, %d )", ARG1,ARG2,ARG3);
1212   PRE_REG_READ3(int, "modify_ldt", int, func, void *, ptr,
1213                 unsigned long, bytecount);
1214
1215   if (ARG1 == 0) {
1216      /* read the LDT into ptr */
1217      PRE_MEM_WRITE( "modify_ldt(ptr)", ARG2, ARG3 );
1218   }
1219   if (ARG1 == 1 || ARG1 == 0x11) {
1220      /* write the LDT with the entry pointed at by ptr */
1221      PRE_MEM_READ( "modify_ldt(ptr)", ARG2, sizeof(vki_modify_ldt_t) );
1222   }
1223   /* "do" the syscall ourselves; the kernel never sees it */
1224   SET_STATUS_from_SysRes( sys_modify_ldt( tid, ARG1, (void*)ARG2, ARG3 ) );
1225
1226   if (ARG1 == 0 && SUCCESS && RES > 0) {
1227      POST_MEM_WRITE( ARG2, RES );
1228   }
1229}
1230
1231PRE(sys_set_thread_area)
1232{
1233   PRINT("sys_set_thread_area ( %p )", ARG1);
1234   PRE_REG_READ1(int, "set_thread_area", struct user_desc *, u_info)
1235   PRE_MEM_READ( "set_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
1236
1237   /* "do" the syscall ourselves; the kernel never sees it */
1238   SET_STATUS_from_SysRes( sys_set_thread_area( tid, (void *)ARG1 ) );
1239}
1240
1241PRE(sys_get_thread_area)
1242{
1243   PRINT("sys_get_thread_area ( %p )", ARG1);
1244   PRE_REG_READ1(int, "get_thread_area", struct user_desc *, u_info)
1245   PRE_MEM_WRITE( "get_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
1246
1247   /* "do" the syscall ourselves; the kernel never sees it */
1248   SET_STATUS_from_SysRes( sys_get_thread_area( tid, (void *)ARG1 ) );
1249
1250   if (SUCCESS) {
1251      POST_MEM_WRITE( ARG1, sizeof(vki_modify_ldt_t) );
1252   }
1253}
1254
1255// Parts of this are x86-specific, but the *PEEK* cases are generic.
1256// XXX: Why is the memory pointed to by ARG3 never checked?
1257PRE(sys_ptrace)
1258{
1259   PRINT("sys_ptrace ( %d, %d, %p, %p )", ARG1,ARG2,ARG3,ARG4);
1260   PRE_REG_READ4(int, "ptrace",
1261                 long, request, long, pid, long, addr, long, data);
1262   switch (ARG1) {
1263   case VKI_PTRACE_PEEKTEXT:
1264   case VKI_PTRACE_PEEKDATA:
1265   case VKI_PTRACE_PEEKUSR:
1266      PRE_MEM_WRITE( "ptrace(peek)", ARG4,
1267		     sizeof (long));
1268      break;
1269   case VKI_PTRACE_GETREGS:
1270      PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
1271		     sizeof (struct vki_user_regs_struct));
1272      break;
1273   case VKI_PTRACE_GETFPREGS:
1274      PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
1275		     sizeof (struct vki_user_i387_struct));
1276      break;
1277   case VKI_PTRACE_GETFPXREGS:
1278      PRE_MEM_WRITE( "ptrace(getfpxregs)", ARG4,
1279                     sizeof(struct vki_user_fxsr_struct) );
1280      break;
1281   case VKI_PTRACE_SETREGS:
1282      PRE_MEM_READ( "ptrace(setregs)", ARG4,
1283		     sizeof (struct vki_user_regs_struct));
1284      break;
1285   case VKI_PTRACE_SETFPREGS:
1286      PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
1287		     sizeof (struct vki_user_i387_struct));
1288      break;
1289   case VKI_PTRACE_SETFPXREGS:
1290      PRE_MEM_READ( "ptrace(setfpxregs)", ARG4,
1291                     sizeof(struct vki_user_fxsr_struct) );
1292      break;
1293   default:
1294      break;
1295   }
1296}
1297
1298POST(sys_ptrace)
1299{
1300   switch (ARG1) {
1301   case VKI_PTRACE_PEEKTEXT:
1302   case VKI_PTRACE_PEEKDATA:
1303   case VKI_PTRACE_PEEKUSR:
1304      POST_MEM_WRITE( ARG4, sizeof (long));
1305      break;
1306   case VKI_PTRACE_GETREGS:
1307      POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
1308      break;
1309   case VKI_PTRACE_GETFPREGS:
1310      POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
1311      break;
1312   case VKI_PTRACE_GETFPXREGS:
1313      POST_MEM_WRITE( ARG4, sizeof(struct vki_user_fxsr_struct) );
1314      break;
1315   default:
1316      break;
1317   }
1318}
1319
1320static Addr deref_Addr ( ThreadId tid, Addr a, Char* s )
1321{
1322   Addr* a_p = (Addr*)a;
1323   PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
1324   return *a_p;
1325}
1326
1327PRE(sys_ipc)
1328{
1329   PRINT("sys_ipc ( %d, %d, %d, %d, %p, %d )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
1330   // XXX: this is simplistic -- some args are not used in all circumstances.
1331   PRE_REG_READ6(int, "ipc",
1332                 vki_uint, call, int, first, int, second, int, third,
1333                 void *, ptr, long, fifth)
1334
1335   switch (ARG1 /* call */) {
1336   case VKI_SEMOP:
1337      ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
1338      *flags |= SfMayBlock;
1339      break;
1340   case VKI_SEMGET:
1341      break;
1342   case VKI_SEMCTL:
1343   {
1344      UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
1345      ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
1346      break;
1347   }
1348   case VKI_SEMTIMEDOP:
1349      ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
1350      *flags |= SfMayBlock;
1351      break;
1352   case VKI_MSGSND:
1353      ML_(generic_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
1354      if ((ARG4 & VKI_IPC_NOWAIT) == 0)
1355         *flags |= SfMayBlock;
1356      break;
1357   case VKI_MSGRCV:
1358   {
1359      Addr msgp;
1360      Word msgtyp;
1361
1362      msgp = deref_Addr( tid,
1363			 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
1364			 "msgrcv(msgp)" );
1365      msgtyp = deref_Addr( tid,
1366			   (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
1367			   "msgrcv(msgp)" );
1368
1369      ML_(generic_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
1370
1371      if ((ARG4 & VKI_IPC_NOWAIT) == 0)
1372         *flags |= SfMayBlock;
1373      break;
1374   }
1375   case VKI_MSGGET:
1376      break;
1377   case VKI_MSGCTL:
1378      ML_(generic_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
1379      break;
1380   case VKI_SHMAT:
1381   {
1382      UWord w;
1383      PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
1384      w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
1385      if (w == 0)
1386         SET_STATUS_Failure( VKI_EINVAL );
1387      else
1388         ARG5 = w;
1389      break;
1390   }
1391   case VKI_SHMDT:
1392      if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
1393	 SET_STATUS_Failure( VKI_EINVAL );
1394      break;
1395   case VKI_SHMGET:
1396      break;
1397   case VKI_SHMCTL: /* IPCOP_shmctl */
1398      ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
1399      break;
1400   default:
1401      VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %d", ARG1 );
1402      VG_(core_panic)("... bye!\n");
1403      break; /*NOTREACHED*/
1404   }
1405}
1406
1407POST(sys_ipc)
1408{
1409   vg_assert(SUCCESS);
1410   switch (ARG1 /* call */) {
1411   case VKI_SEMOP:
1412   case VKI_SEMGET:
1413      break;
1414   case VKI_SEMCTL:
1415   {
1416      UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
1417      ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
1418      break;
1419   }
1420   case VKI_SEMTIMEDOP:
1421   case VKI_MSGSND:
1422      break;
1423   case VKI_MSGRCV:
1424   {
1425      Addr msgp;
1426      Word msgtyp;
1427
1428      msgp = deref_Addr( tid,
1429			 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
1430			 "msgrcv(msgp)" );
1431      msgtyp = deref_Addr( tid,
1432			   (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
1433			   "msgrcv(msgp)" );
1434
1435      ML_(generic_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
1436      break;
1437   }
1438   case VKI_MSGGET:
1439      break;
1440   case VKI_MSGCTL:
1441      ML_(generic_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
1442      break;
1443   case VKI_SHMAT:
1444   {
1445      Addr addr;
1446
1447      /* force readability. before the syscall it is
1448       * indeed uninitialized, as can be seen in
1449       * glibc/sysdeps/unix/sysv/linux/shmat.c */
1450      POST_MEM_WRITE( ARG4, sizeof( Addr ) );
1451
1452      addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
1453      if ( addr > 0 ) {
1454         ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
1455      }
1456      break;
1457   }
1458   case VKI_SHMDT:
1459      ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
1460      break;
1461   case VKI_SHMGET:
1462      break;
1463   case VKI_SHMCTL:
1464      ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
1465      break;
1466   default:
1467      VG_(message)(Vg_DebugMsg,
1468		   "FATAL: unhandled syscall(ipc) %d",
1469		   ARG1 );
1470      VG_(core_panic)("... bye!\n");
1471      break; /*NOTREACHED*/
1472   }
1473}
1474
1475PRE(old_mmap)
1476{
1477   /* struct mmap_arg_struct {
1478         unsigned long addr;
1479         unsigned long len;
1480         unsigned long prot;
1481         unsigned long flags;
1482         unsigned long fd;
1483         unsigned long offset;
1484   }; */
1485   UWord a1, a2, a3, a4, a5, a6;
1486
1487   UWord* args = (UWord*)ARG1;
1488   PRE_REG_READ1(long, "old_mmap", struct mmap_arg_struct *, args);
1489   PRE_MEM_READ( "old_mmap(args)", (Addr)args, 6*sizeof(UWord) );
1490
1491   a1 = args[0];
1492   a2 = args[1];
1493   a3 = args[2];
1494   a4 = args[3];
1495   a5 = args[4];
1496   a6 = args[5];
1497
1498   PRINT("old_mmap ( %p, %llu, %d, %d, %d, %d )",
1499         a1, (ULong)a2, a3, a4, a5, a6 );
1500
1501   if (a2 == 0) {
1502      /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
1503         shall be established. */
1504      SET_STATUS_Failure( VKI_EINVAL );
1505      return;
1506   }
1507
1508   if (/*(a4 & VKI_MAP_FIXED) &&*/ (0 != (a1 & (VKI_PAGE_SIZE-1)))) {
1509      /* zap any misaligned addresses. */
1510      SET_STATUS_Failure( VKI_EINVAL );
1511      return;
1512   }
1513
1514   if (a4 & VKI_MAP_FIXED) {
1515      if (!ML_(valid_client_addr)(a1, a2, tid, "old_mmap")) {
1516         PRINT("old_mmap failing: %p-%p\n", a1, a1+a2);
1517         SET_STATUS_Failure( VKI_ENOMEM );
1518      }
1519   } else {
1520      Addr a = VG_(find_map_space)(a1, a2, True);
1521      if (0) VG_(printf)("find_map_space(%p, %d) -> %p\n",a1,a2,a);
1522      if (a == 0 && a1 != 0) {
1523         a1 = VG_(find_map_space)(0, a2, True);
1524      }
1525      else
1526         a1 = a;
1527      if (a1 == 0)
1528         SET_STATUS_Failure( VKI_ENOMEM );
1529      else
1530         a4 |= VKI_MAP_FIXED;
1531   }
1532
1533   if (! FAILURE) {
1534      SysRes res = VG_(mmap_native)((void*)a1, a2, a3, a4, a5, a6);
1535      SET_STATUS_from_SysRes(res);
1536      if (!res.isError) {
1537         vg_assert(ML_(valid_client_addr)(res.val, a2, tid, "old_mmap"));
1538         ML_(mmap_segment)( (Addr)res.val, a2, a3, a4, a5, a6 );
1539      }
1540   }
1541
1542   if (0)
1543   VG_(printf)("old_mmap( %p, fixed %d ) -> %s(%p)\n",
1544               args[0],
1545               args[3]&VKI_MAP_FIXED,
1546               FAILURE ? "Fail" : "Success", RES_unchecked);
1547
1548   /* Stay sane */
1549   if (SUCCESS && (args[3] & VKI_MAP_FIXED))
1550      vg_assert(RES == args[0]);
1551}
1552
1553// XXX: lstat64/fstat64/stat64 are generic, but not necessarily
1554// applicable to every architecture -- I think only to 32-bit archs.
1555// We're going to need something like linux/core_os32.h for such
1556// things, eventually, I think.  --njn
1557PRE(sys_lstat64)
1558{
1559   PRINT("sys_lstat64 ( %p(%s), %p )",ARG1,ARG1,ARG2);
1560   PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
1561   PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
1562   PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
1563}
1564
1565POST(sys_lstat64)
1566{
1567   vg_assert(SUCCESS);
1568   if (RES == 0) {
1569      POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1570   }
1571}
1572
1573PRE(sys_stat64)
1574{
1575   PRINT("sys_stat64 ( %p, %p )",ARG1,ARG2);
1576   PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
1577   PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
1578   PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
1579}
1580
1581POST(sys_stat64)
1582{
1583   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1584}
1585
1586PRE(sys_fstat64)
1587{
1588   PRINT("sys_fstat64 ( %d, %p )",ARG1,ARG2);
1589   PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
1590   PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
1591}
1592
1593POST(sys_fstat64)
1594{
1595   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1596}
1597
1598PRE(sys_socketcall)
1599{
1600#  define ARG2_0  (((UWord*)ARG2)[0])
1601#  define ARG2_1  (((UWord*)ARG2)[1])
1602#  define ARG2_2  (((UWord*)ARG2)[2])
1603#  define ARG2_3  (((UWord*)ARG2)[3])
1604#  define ARG2_4  (((UWord*)ARG2)[4])
1605#  define ARG2_5  (((UWord*)ARG2)[5])
1606
1607   *flags |= SfMayBlock;
1608   PRINT("sys_socketcall ( %d, %p )",ARG1,ARG2);
1609   PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
1610
1611   switch (ARG1 /* request */) {
1612
1613   case VKI_SYS_SOCKETPAIR:
1614      /* int socketpair(int d, int type, int protocol, int sv[2]); */
1615      PRE_MEM_READ( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
1616      ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
1617      break;
1618
1619   case VKI_SYS_SOCKET:
1620      /* int socket(int domain, int type, int protocol); */
1621      PRE_MEM_READ( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
1622      break;
1623
1624   case VKI_SYS_BIND:
1625      /* int bind(int sockfd, struct sockaddr *my_addr,
1626                  int addrlen); */
1627      PRE_MEM_READ( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
1628      ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
1629      break;
1630
1631   case VKI_SYS_LISTEN:
1632      /* int listen(int s, int backlog); */
1633      PRE_MEM_READ( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
1634      break;
1635
1636   case VKI_SYS_ACCEPT: {
1637      /* int accept(int s, struct sockaddr *addr, int *addrlen); */
1638      PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
1639      ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
1640      break;
1641   }
1642
1643   case VKI_SYS_SENDTO:
1644      /* int sendto(int s, const void *msg, int len,
1645                    unsigned int flags,
1646                    const struct sockaddr *to, int tolen); */
1647      PRE_MEM_READ( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
1648      ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
1649                                   ARG2_3, ARG2_4, ARG2_5 );
1650      break;
1651
1652   case VKI_SYS_SEND:
1653      /* int send(int s, const void *msg, size_t len, int flags); */
1654      PRE_MEM_READ( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
1655      ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
1656      break;
1657
1658   case VKI_SYS_RECVFROM:
1659      /* int recvfrom(int s, void *buf, int len, unsigned int flags,
1660         struct sockaddr *from, int *fromlen); */
1661      PRE_MEM_READ( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
1662      ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
1663                                     ARG2_3, ARG2_4, ARG2_5 );
1664      break;
1665
1666   case VKI_SYS_RECV:
1667      /* int recv(int s, void *buf, int len, unsigned int flags); */
1668      /* man 2 recv says:
1669         The  recv call is normally used only on a connected socket
1670         (see connect(2)) and is identical to recvfrom with a  NULL
1671         from parameter.
1672      */
1673      PRE_MEM_READ( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
1674      ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
1675      break;
1676
1677   case VKI_SYS_CONNECT:
1678      /* int connect(int sockfd,
1679                     struct sockaddr *serv_addr, int addrlen ); */
1680      PRE_MEM_READ( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
1681      ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
1682      break;
1683
1684   case VKI_SYS_SETSOCKOPT:
1685      /* int setsockopt(int s, int level, int optname,
1686                        const void *optval, int optlen); */
1687      PRE_MEM_READ( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
1688      ML_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
1689                                       ARG2_3, ARG2_4 );
1690      break;
1691
1692   case VKI_SYS_GETSOCKOPT:
1693      /* int getsockopt(int s, int level, int optname,
1694                        void *optval, socklen_t *optlen); */
1695      PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
1696      ML_(generic_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
1697                                       ARG2_3, ARG2_4 );
1698      break;
1699
1700   case VKI_SYS_GETSOCKNAME:
1701      /* int getsockname(int s, struct sockaddr* name, int* namelen) */
1702      PRE_MEM_READ( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
1703      ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
1704      break;
1705
1706   case VKI_SYS_GETPEERNAME:
1707      /* int getpeername(int s, struct sockaddr* name, int* namelen) */
1708      PRE_MEM_READ( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
1709      ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
1710      break;
1711
1712   case VKI_SYS_SHUTDOWN:
1713      /* int shutdown(int s, int how); */
1714      PRE_MEM_READ( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
1715      break;
1716
1717   case VKI_SYS_SENDMSG: {
1718      /* int sendmsg(int s, const struct msghdr *msg, int flags); */
1719
1720      /* this causes warnings, and I don't get why. glibc bug?
1721       * (after all it's glibc providing the arguments array)
1722       PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
1723      */
1724      ML_(generic_PRE_sys_sendmsg)( tid, ARG2_0, ARG2_1 );
1725      break;
1726   }
1727
1728   case VKI_SYS_RECVMSG: {
1729      /* int recvmsg(int s, struct msghdr *msg, int flags); */
1730
1731      /* this causes warnings, and I don't get why. glibc bug?
1732       * (after all it's glibc providing the arguments array)
1733       PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
1734      */
1735      ML_(generic_PRE_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
1736      break;
1737   }
1738
1739   default:
1740      VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%x",ARG1);
1741      SET_STATUS_Failure( VKI_EINVAL );
1742      break;
1743   }
1744#  undef ARG2_0
1745#  undef ARG2_1
1746#  undef ARG2_2
1747#  undef ARG2_3
1748#  undef ARG2_4
1749#  undef ARG2_5
1750}
1751
1752POST(sys_socketcall)
1753{
1754#  define ARG2_0  (((UWord*)ARG2)[0])
1755#  define ARG2_1  (((UWord*)ARG2)[1])
1756#  define ARG2_2  (((UWord*)ARG2)[2])
1757#  define ARG2_3  (((UWord*)ARG2)[3])
1758#  define ARG2_4  (((UWord*)ARG2)[4])
1759#  define ARG2_5  (((UWord*)ARG2)[5])
1760
1761   SysRes r;
1762   vg_assert(SUCCESS);
1763   switch (ARG1 /* request */) {
1764
1765   case VKI_SYS_SOCKETPAIR:
1766      r = ML_(generic_POST_sys_socketpair)(
1767             tid, VG_(mk_SysRes_Success)(RES),
1768             ARG2_0, ARG2_1, ARG2_2, ARG2_3
1769          );
1770      SET_STATUS_from_SysRes(r);
1771      break;
1772
1773   case VKI_SYS_SOCKET:
1774      r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
1775      SET_STATUS_from_SysRes(r);
1776      break;
1777
1778   case VKI_SYS_BIND:
1779      /* int bind(int sockfd, struct sockaddr *my_addr,
1780			int addrlen); */
1781      break;
1782
1783   case VKI_SYS_LISTEN:
1784      /* int listen(int s, int backlog); */
1785      break;
1786
1787   case VKI_SYS_ACCEPT:
1788      /* int accept(int s, struct sockaddr *addr, int *addrlen); */
1789     r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
1790                                            ARG2_0, ARG2_1, ARG2_2 );
1791     SET_STATUS_from_SysRes(r);
1792     break;
1793
1794   case VKI_SYS_SENDTO:
1795      break;
1796
1797   case VKI_SYS_SEND:
1798      break;
1799
1800   case VKI_SYS_RECVFROM:
1801      ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
1802                                           ARG2_0, ARG2_1, ARG2_2,
1803                                           ARG2_3, ARG2_4, ARG2_5 );
1804      break;
1805
1806   case VKI_SYS_RECV:
1807      ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
1808      break;
1809
1810   case VKI_SYS_CONNECT:
1811      break;
1812
1813   case VKI_SYS_SETSOCKOPT:
1814      break;
1815
1816   case VKI_SYS_GETSOCKOPT:
1817      ML_(generic_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
1818                                             ARG2_0, ARG2_1,
1819                                             ARG2_2, ARG2_3, ARG2_4 );
1820      break;
1821
1822   case VKI_SYS_GETSOCKNAME:
1823      ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
1824                                              ARG2_0, ARG2_1, ARG2_2 );
1825      break;
1826
1827   case VKI_SYS_GETPEERNAME:
1828      ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
1829                                              ARG2_0, ARG2_1, ARG2_2 );
1830      break;
1831
1832   case VKI_SYS_SHUTDOWN:
1833      break;
1834
1835   case VKI_SYS_SENDMSG:
1836      break;
1837
1838   case VKI_SYS_RECVMSG:
1839     ML_(generic_POST_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
1840     break;
1841
1842   default:
1843      VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%x",ARG1);
1844      VG_(core_panic)("... bye!\n");
1845      break; /*NOTREACHED*/
1846   }
1847#  undef ARG2_0
1848#  undef ARG2_1
1849#  undef ARG2_2
1850#  undef ARG2_3
1851#  undef ARG2_4
1852#  undef ARG2_5
1853}
1854
1855/* Convert from non-RT to RT sigset_t's */
1856static
1857void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
1858{
1859   VG_(sigemptyset)(set);
1860   set->sig[0] = *oldset;
1861}
1862PRE(sys_sigaction)
1863{
1864   struct vki_sigaction new, old;
1865   struct vki_sigaction *newp, *oldp;
1866
1867   PRINT("sys_sigaction ( %d, %p, %p )", ARG1,ARG2,ARG3);
1868   PRE_REG_READ3(int, "sigaction",
1869                 int, signum, const struct old_sigaction *, act,
1870                 struct old_sigaction *, oldact);
1871
1872   newp = oldp = NULL;
1873
1874   if (ARG2 != 0) {
1875      struct vki_old_sigaction *sa = (struct vki_old_sigaction *)ARG2;
1876      PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
1877      PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
1878      PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
1879      if (sa->sa_flags & VKI_SA_RESTORER)
1880         PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
1881   }
1882
1883   if (ARG3 != 0) {
1884      PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
1885      oldp = &old;
1886   }
1887
1888   //jrs 20050207: what?!  how can this make any sense?
1889   //if (VG_(is_kerror)(SYSRES))
1890   //   return;
1891
1892   if (ARG2 != 0) {
1893      struct vki_old_sigaction *oldnew = (struct vki_old_sigaction *)ARG2;
1894
1895      new.ksa_handler = oldnew->ksa_handler;
1896      new.sa_flags = oldnew->sa_flags;
1897      new.sa_restorer = oldnew->sa_restorer;
1898      convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
1899      newp = &new;
1900   }
1901
1902   SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
1903
1904   if (ARG3 != 0 && SUCCESS && RES == 0) {
1905      struct vki_old_sigaction *oldold = (struct vki_old_sigaction *)ARG3;
1906
1907      oldold->ksa_handler = oldp->ksa_handler;
1908      oldold->sa_flags = oldp->sa_flags;
1909      oldold->sa_restorer = oldp->sa_restorer;
1910      oldold->sa_mask = oldp->sa_mask.sig[0];
1911   }
1912}
1913
1914POST(sys_sigaction)
1915{
1916   vg_assert(SUCCESS);
1917   if (RES == 0 && ARG3 != 0)
1918      POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
1919}
1920
1921#undef PRE
1922#undef POST
1923
1924
1925/* ---------------------------------------------------------------------
1926   The x86/Linux syscall table
1927   ------------------------------------------------------------------ */
1928
1929/* Add an x86-linux specific wrapper to a syscall table. */
1930#define PLAX_(sysno, name)    WRAPPER_ENTRY_X_(x86_linux, sysno, name)
1931#define PLAXY(sysno, name)    WRAPPER_ENTRY_XY(x86_linux, sysno, name)
1932
1933
1934// This table maps from __NR_xxx syscall numbers (from
1935// linux/include/asm-i386/unistd.h) to the appropriate PRE/POST sys_foo()
1936// wrappers on x86 (as per sys_call_table in linux/arch/i386/kernel/entry.S).
1937//
1938// For those syscalls not handled by Valgrind, the annotation indicate its
1939// arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
1940// (unknown).
1941
1942const SyscallTableEntry ML_(syscall_table)[] = {
1943//zz    //   (restart_syscall)                             // 0
1944   GENX_(__NR_exit,              sys_exit),           // 1
1945   GENX_(__NR_fork,              sys_fork),           // 2
1946   GENXY(__NR_read,              sys_read),           // 3
1947   GENX_(__NR_write,             sys_write),          // 4
1948
1949   GENXY(__NR_open,              sys_open),           // 5
1950   GENXY(__NR_close,             sys_close),          // 6
1951   GENXY(__NR_waitpid,           sys_waitpid),        // 7
1952   GENXY(__NR_creat,             sys_creat),          // 8
1953   GENX_(__NR_link,              sys_link),           // 9
1954
1955   GENX_(__NR_unlink,            sys_unlink),         // 10
1956   GENX_(__NR_execve,            sys_execve),         // 11
1957   GENX_(__NR_chdir,             sys_chdir),          // 12
1958   GENXY(__NR_time,              sys_time),           // 13
1959   GENX_(__NR_mknod,             sys_mknod),          // 14
1960
1961   GENX_(__NR_chmod,             sys_chmod),          // 15
1962//zz    //   (__NR_lchown,            sys_lchown16),       // 16 ## P
1963   GENX_(__NR_break,             sys_ni_syscall),     // 17
1964//zz    //   (__NR_oldstat,           sys_stat),           // 18 (obsolete)
1965   GENX_(__NR_lseek,             sys_lseek),          // 19
1966
1967   GENX_(__NR_getpid,            sys_getpid),         // 20
1968   LINX_(__NR_mount,             sys_mount),          // 21
1969   LINX_(__NR_umount,            sys_oldumount),      // 22
1970   GENX_(__NR_setuid,            sys_setuid16),       // 23 ## P
1971   GENX_(__NR_getuid,            sys_getuid16),       // 24 ## P
1972//zz
1973//zz    //   (__NR_stime,             sys_stime),          // 25 * (SVr4,SVID,X/OPEN)
1974   PLAXY(__NR_ptrace,            sys_ptrace),         // 26
1975   GENX_(__NR_alarm,             sys_alarm),          // 27
1976//zz    //   (__NR_oldfstat,          sys_fstat),          // 28 * L -- obsolete
1977   GENX_(__NR_pause,             sys_pause),          // 29
1978
1979   GENX_(__NR_utime,             sys_utime),          // 30
1980   GENX_(__NR_stty,              sys_ni_syscall),     // 31
1981   GENX_(__NR_gtty,              sys_ni_syscall),     // 32
1982   GENX_(__NR_access,            sys_access),         // 33
1983   GENX_(__NR_nice,              sys_nice),           // 34
1984
1985   GENX_(__NR_ftime,             sys_ni_syscall),     // 35
1986   GENX_(__NR_sync,              sys_sync),           // 36
1987   GENX_(__NR_kill,              sys_kill),           // 37
1988   GENX_(__NR_rename,            sys_rename),         // 38
1989   GENX_(__NR_mkdir,             sys_mkdir),          // 39
1990
1991   GENX_(__NR_rmdir,             sys_rmdir),          // 40
1992   GENXY(__NR_dup,               sys_dup),            // 41
1993   GENXY(__NR_pipe,              sys_pipe),           // 42
1994   GENXY(__NR_times,             sys_times),          // 43
1995   GENX_(__NR_prof,              sys_ni_syscall),     // 44
1996//zz
1997   GENX_(__NR_brk,               sys_brk),            // 45
1998   GENX_(__NR_setgid,            sys_setgid16),       // 46
1999   GENX_(__NR_getgid,            sys_getgid16),       // 47
2000//zz    //   (__NR_signal,            sys_signal),         // 48 */* (ANSI C)
2001   GENX_(__NR_geteuid,           sys_geteuid16),      // 49
2002
2003   GENX_(__NR_getegid,           sys_getegid16),      // 50
2004   GENX_(__NR_acct,              sys_acct),           // 51
2005   LINX_(__NR_umount2,           sys_umount),         // 52
2006   GENX_(__NR_lock,              sys_ni_syscall),     // 53
2007   GENXY(__NR_ioctl,             sys_ioctl),          // 54
2008
2009   GENXY(__NR_fcntl,             sys_fcntl),          // 55
2010   GENX_(__NR_mpx,               sys_ni_syscall),     // 56
2011   GENX_(__NR_setpgid,           sys_setpgid),        // 57
2012   GENX_(__NR_ulimit,            sys_ni_syscall),     // 58
2013//zz    //   (__NR_oldolduname,       sys_olduname),       // 59 Linux -- obsolete
2014//zz
2015   GENX_(__NR_umask,             sys_umask),          // 60
2016   GENX_(__NR_chroot,            sys_chroot),         // 61
2017//zz    //   (__NR_ustat,             sys_ustat)           // 62 SVr4 -- deprecated
2018   GENXY(__NR_dup2,              sys_dup2),           // 63
2019   GENX_(__NR_getppid,           sys_getppid),        // 64
2020
2021   GENX_(__NR_getpgrp,           sys_getpgrp),        // 65
2022   GENX_(__NR_setsid,            sys_setsid),         // 66
2023   PLAXY(__NR_sigaction,         sys_sigaction),      // 67
2024//zz    //   (__NR_sgetmask,          sys_sgetmask),       // 68 */* (ANSI C)
2025//zz    //   (__NR_ssetmask,          sys_ssetmask),       // 69 */* (ANSI C)
2026//zz
2027   GENX_(__NR_setreuid,          sys_setreuid16),     // 70
2028   GENX_(__NR_setregid,          sys_setregid16),     // 71
2029//zz    GENX_(__NR_sigsuspend,        sys_sigsuspend),     // 72
2030   GENXY(__NR_sigpending,        sys_sigpending),     // 73
2031//zz    //   (__NR_sethostname,       sys_sethostname),    // 74 */*
2032//zz
2033   GENX_(__NR_setrlimit,         sys_setrlimit),      // 75
2034   GENXY(__NR_getrlimit,         sys_old_getrlimit),  // 76
2035   GENXY(__NR_getrusage,         sys_getrusage),      // 77
2036   GENXY(__NR_gettimeofday,      sys_gettimeofday),   // 78
2037   GENX_(__NR_settimeofday,      sys_settimeofday),   // 79
2038
2039   GENXY(__NR_getgroups,         sys_getgroups16),    // 80
2040   GENX_(__NR_setgroups,         sys_setgroups16),    // 81
2041   PLAX_(__NR_select,            old_select),         // 82
2042   GENX_(__NR_symlink,           sys_symlink),        // 83
2043//zz    //   (__NR_oldlstat,          sys_lstat),          // 84 -- obsolete
2044//zz
2045   GENX_(__NR_readlink,          sys_readlink),       // 85
2046//zz    //   (__NR_uselib,            sys_uselib),         // 86 */Linux
2047//zz    //   (__NR_swapon,            sys_swapon),         // 87 */Linux
2048//zz    //   (__NR_reboot,            sys_reboot),         // 88 */Linux
2049//zz    //   (__NR_readdir,           old_readdir),        // 89 -- superseded
2050//zz
2051   PLAX_(__NR_mmap,              old_mmap),           // 90
2052   GENXY(__NR_munmap,            sys_munmap),         // 91
2053   GENX_(__NR_truncate,          sys_truncate),       // 92
2054   GENX_(__NR_ftruncate,         sys_ftruncate),      // 93
2055   GENX_(__NR_fchmod,            sys_fchmod),         // 94
2056
2057   GENX_(__NR_fchown,            sys_fchown16),       // 95
2058   GENX_(__NR_getpriority,       sys_getpriority),    // 96
2059   GENX_(__NR_setpriority,       sys_setpriority),    // 97
2060   GENX_(__NR_profil,            sys_ni_syscall),     // 98
2061   GENXY(__NR_statfs,            sys_statfs),         // 99
2062
2063   GENXY(__NR_fstatfs,           sys_fstatfs),        // 100
2064   LINX_(__NR_ioperm,            sys_ioperm),         // 101
2065   PLAXY(__NR_socketcall,        sys_socketcall),     // 102 x86/Linux-only
2066   LINXY(__NR_syslog,            sys_syslog),         // 103
2067   GENXY(__NR_setitimer,         sys_setitimer),      // 104
2068
2069   GENXY(__NR_getitimer,         sys_getitimer),      // 105
2070   GENXY(__NR_stat,              sys_newstat),        // 106
2071   GENXY(__NR_lstat,             sys_newlstat),       // 107
2072   GENXY(__NR_fstat,             sys_newfstat),       // 108
2073//zz    //   (__NR_olduname,          sys_uname),          // 109 -- obsolete
2074//zz
2075   GENX_(__NR_iopl,              sys_iopl),           // 110
2076   LINX_(__NR_vhangup,           sys_vhangup),        // 111
2077   GENX_(__NR_idle,              sys_ni_syscall),     // 112
2078//zz    //   (__NR_vm86old,           sys_vm86old),        // 113 x86/Linux-only
2079   GENXY(__NR_wait4,             sys_wait4),          // 114
2080//zz
2081//zz    //   (__NR_swapoff,           sys_swapoff),        // 115 */Linux
2082   LINXY(__NR_sysinfo,           sys_sysinfo),        // 116
2083   PLAXY(__NR_ipc,               sys_ipc),            // 117
2084   GENX_(__NR_fsync,             sys_fsync),          // 118
2085   PLAX_(__NR_sigreturn,         sys_sigreturn),      // 119 ?/Linux
2086
2087   PLAX_(__NR_clone,             sys_clone),          // 120
2088//zz    //   (__NR_setdomainname,     sys_setdomainname),  // 121 */*(?)
2089   GENXY(__NR_uname,             sys_newuname),       // 122
2090   PLAX_(__NR_modify_ldt,        sys_modify_ldt),     // 123
2091//zz    LINXY(__NR_adjtimex,          sys_adjtimex),       // 124
2092//zz
2093   GENXY(__NR_mprotect,          sys_mprotect),       // 125
2094   GENXY(__NR_sigprocmask,       sys_sigprocmask),    // 126
2095//zz    // Nb: create_module() was removed 2.4-->2.6
2096   GENX_(__NR_create_module,     sys_ni_syscall),     // 127
2097   GENX_(__NR_init_module,       sys_init_module),    // 128
2098//zz    //   (__NR_delete_module,     sys_delete_module),  // 129 (*/Linux)?
2099//zz
2100//zz    // Nb: get_kernel_syms() was removed 2.4-->2.6
2101   GENX_(__NR_get_kernel_syms,   sys_ni_syscall),     // 130
2102   GENX_(__NR_quotactl,          sys_quotactl),       // 131
2103   GENX_(__NR_getpgid,           sys_getpgid),        // 132
2104   GENX_(__NR_fchdir,            sys_fchdir),         // 133
2105//zz    //   (__NR_bdflush,           sys_bdflush),        // 134 */Linux
2106//zz
2107//zz    //   (__NR_sysfs,             sys_sysfs),          // 135 SVr4
2108   LINX_(__NR_personality,       sys_personality),    // 136
2109   GENX_(__NR_afs_syscall,       sys_ni_syscall),     // 137
2110   LINX_(__NR_setfsuid,          sys_setfsuid16),     // 138
2111   LINX_(__NR_setfsgid,          sys_setfsgid16),     // 139
2112
2113   LINXY(__NR__llseek,           sys_llseek),         // 140
2114   GENXY(__NR_getdents,          sys_getdents),       // 141
2115   GENX_(__NR__newselect,        sys_select),         // 142
2116   GENX_(__NR_flock,             sys_flock),          // 143
2117   GENX_(__NR_msync,             sys_msync),          // 144
2118
2119   GENXY(__NR_readv,             sys_readv),          // 145
2120   GENX_(__NR_writev,            sys_writev),         // 146
2121   GENX_(__NR_getsid,            sys_getsid),         // 147
2122   GENX_(__NR_fdatasync,         sys_fdatasync),      // 148
2123   LINXY(__NR__sysctl,           sys_sysctl),         // 149
2124
2125   GENX_(__NR_mlock,             sys_mlock),          // 150
2126   GENX_(__NR_munlock,           sys_munlock),        // 151
2127   GENX_(__NR_mlockall,          sys_mlockall),       // 152
2128   GENX_(__NR_munlockall,        sys_munlockall),     // 153
2129   GENXY(__NR_sched_setparam,    sys_sched_setparam), // 154
2130
2131   GENXY(__NR_sched_getparam,         sys_sched_getparam),        // 155
2132   GENX_(__NR_sched_setscheduler,     sys_sched_setscheduler),    // 156
2133   GENX_(__NR_sched_getscheduler,     sys_sched_getscheduler),    // 157
2134   GENX_(__NR_sched_yield,            sys_sched_yield),           // 158
2135   GENX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
2136
2137   GENX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
2138//zz    //   (__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 161 */*
2139   GENXY(__NR_nanosleep,         sys_nanosleep),      // 162
2140   GENX_(__NR_mremap,            sys_mremap),         // 163
2141   LINX_(__NR_setresuid,         sys_setresuid16),    // 164
2142
2143   LINXY(__NR_getresuid,         sys_getresuid16),    // 165
2144//zz    //   (__NR_vm86,              sys_vm86),           // 166 x86/Linux-only
2145   GENX_(__NR_query_module,      sys_ni_syscall),     // 167
2146   GENXY(__NR_poll,              sys_poll),           // 168
2147//zz    //   (__NR_nfsservctl,        sys_nfsservctl),     // 169 */Linux
2148//zz
2149   LINX_(__NR_setresgid,         sys_setresgid16),    // 170
2150   LINXY(__NR_getresgid,         sys_getresgid16),    // 171
2151   LINX_(__NR_prctl,             sys_prctl),          // 172
2152   PLAX_(__NR_rt_sigreturn,      sys_rt_sigreturn),   // 173 x86/Linux only?
2153   GENXY(__NR_rt_sigaction,      sys_rt_sigaction),   // 174
2154
2155   GENXY(__NR_rt_sigprocmask,    sys_rt_sigprocmask), // 175
2156   GENXY(__NR_rt_sigpending,     sys_rt_sigpending),  // 176
2157   GENXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),// 177
2158   GENXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),// 178
2159   GENX_(__NR_rt_sigsuspend,     sys_rt_sigsuspend),  // 179
2160
2161   GENXY(__NR_pread64,           sys_pread64),        // 180
2162   GENX_(__NR_pwrite64,          sys_pwrite64),       // 181
2163   GENX_(__NR_chown,             sys_chown16),        // 182
2164   GENXY(__NR_getcwd,            sys_getcwd),         // 183
2165   GENXY(__NR_capget,            sys_capget),         // 184
2166
2167   GENX_(__NR_capset,            sys_capset),         // 185
2168   GENXY(__NR_sigaltstack,       sys_sigaltstack),    // 186
2169   LINXY(__NR_sendfile,          sys_sendfile),       // 187
2170   GENXY(__NR_getpmsg,           sys_getpmsg),        // 188
2171   GENX_(__NR_putpmsg,           sys_putpmsg),        // 189
2172
2173   // Nb: we treat vfork as fork
2174   GENX_(__NR_vfork,             sys_fork),           // 190
2175   GENXY(__NR_ugetrlimit,        sys_getrlimit),      // 191
2176   GENXY(__NR_mmap2,             sys_mmap2),          // 192
2177   GENX_(__NR_truncate64,        sys_truncate64),     // 193
2178   GENX_(__NR_ftruncate64,       sys_ftruncate64),    // 194
2179
2180   PLAXY(__NR_stat64,            sys_stat64),         // 195
2181   PLAXY(__NR_lstat64,           sys_lstat64),        // 196
2182   PLAXY(__NR_fstat64,           sys_fstat64),        // 197
2183   GENX_(__NR_lchown32,          sys_lchown),         // 198
2184   GENX_(__NR_getuid32,          sys_getuid),         // 199
2185
2186   GENX_(__NR_getgid32,          sys_getgid),         // 200
2187   GENX_(__NR_geteuid32,         sys_geteuid),        // 201
2188   GENX_(__NR_getegid32,         sys_getegid),        // 202
2189   GENX_(__NR_setreuid32,        sys_setreuid),       // 203
2190   GENX_(__NR_setregid32,        sys_setregid),       // 204
2191
2192   GENXY(__NR_getgroups32,       sys_getgroups),      // 205
2193   GENX_(__NR_setgroups32,       sys_setgroups),      // 206
2194   GENX_(__NR_fchown32,          sys_fchown),         // 207
2195   LINX_(__NR_setresuid32,       sys_setresuid),      // 208
2196   LINXY(__NR_getresuid32,       sys_getresuid),      // 209
2197
2198   LINX_(__NR_setresgid32,       sys_setresgid),      // 210
2199   LINXY(__NR_getresgid32,       sys_getresgid),      // 211
2200   GENX_(__NR_chown32,           sys_chown),          // 212
2201   GENX_(__NR_setuid32,          sys_setuid),         // 213
2202   GENX_(__NR_setgid32,          sys_setgid),         // 214
2203
2204   LINX_(__NR_setfsuid32,        sys_setfsuid),       // 215
2205   LINX_(__NR_setfsgid32,        sys_setfsgid),       // 216
2206//zz    //   (__NR_pivot_root,        sys_pivot_root),     // 217 */Linux
2207   GENXY(__NR_mincore,           sys_mincore),        // 218
2208   GENX_(__NR_madvise,           sys_madvise),        // 219
2209
2210   GENXY(__NR_getdents64,        sys_getdents64),     // 220
2211   GENXY(__NR_fcntl64,           sys_fcntl64),        // 221
2212   GENX_(222,                    sys_ni_syscall),     // 222
2213   GENX_(223,                    sys_ni_syscall),     // 223
2214   LINX_(__NR_gettid,            sys_gettid),         // 224
2215
2216//zz    //   (__NR_readahead,         sys_readahead),      // 225 */(Linux?)
2217   GENX_(__NR_setxattr,          sys_setxattr),       // 226
2218   GENX_(__NR_lsetxattr,         sys_lsetxattr),      // 227
2219   GENX_(__NR_fsetxattr,         sys_fsetxattr),      // 228
2220   GENXY(__NR_getxattr,          sys_getxattr),       // 229
2221
2222   GENXY(__NR_lgetxattr,         sys_lgetxattr),      // 230
2223   GENXY(__NR_fgetxattr,         sys_fgetxattr),      // 231
2224   GENXY(__NR_listxattr,         sys_listxattr),      // 232
2225   GENXY(__NR_llistxattr,        sys_llistxattr),     // 233
2226   GENXY(__NR_flistxattr,        sys_flistxattr),     // 234
2227
2228   GENX_(__NR_removexattr,       sys_removexattr),    // 235
2229   GENX_(__NR_lremovexattr,      sys_lremovexattr),   // 236
2230   GENX_(__NR_fremovexattr,      sys_fremovexattr),   // 237
2231//zz    LINX_(__NR_tkill,             sys_tkill),          // 238 */Linux
2232   LINXY(__NR_sendfile64,        sys_sendfile64),     // 239
2233
2234   LINXY(__NR_futex,             sys_futex),             // 240
2235   GENX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 241
2236   GENXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 242
2237   PLAX_(__NR_set_thread_area,   sys_set_thread_area),   // 243
2238   PLAX_(__NR_get_thread_area,   sys_get_thread_area),   // 244
2239
2240   LINX_(__NR_io_setup,          sys_io_setup),       // 245
2241   LINX_(__NR_io_destroy,        sys_io_destroy),     // 246
2242   LINXY(__NR_io_getevents,      sys_io_getevents),   // 247
2243   LINX_(__NR_io_submit,         sys_io_submit),      // 248
2244   LINXY(__NR_io_cancel,         sys_io_cancel),      // 249
2245
2246   LINX_(__NR_fadvise64,         sys_fadvise64),      // 250 */(Linux?)
2247   GENX_(251,                    sys_ni_syscall),     // 251
2248   LINX_(__NR_exit_group,        sys_exit_group),     // 252
2249   GENXY(__NR_lookup_dcookie,    sys_lookup_dcookie), // 253
2250   LINXY(__NR_epoll_create,      sys_epoll_create),   // 254
2251
2252   LINX_(__NR_epoll_ctl,         sys_epoll_ctl),         // 255
2253   LINXY(__NR_epoll_wait,        sys_epoll_wait),        // 256
2254//zz    //   (__NR_remap_file_pages,  sys_remap_file_pages),  // 257 */Linux
2255   LINX_(__NR_set_tid_address,   sys_set_tid_address),   // 258
2256   GENXY(__NR_timer_create,      sys_timer_create),      // 259
2257
2258   GENXY(__NR_timer_settime,     sys_timer_settime),  // (timer_create+1)
2259   GENXY(__NR_timer_gettime,     sys_timer_gettime),  // (timer_create+2)
2260   GENX_(__NR_timer_getoverrun,  sys_timer_getoverrun),//(timer_create+3)
2261   GENX_(__NR_timer_delete,      sys_timer_delete),   // (timer_create+4)
2262   GENX_(__NR_clock_settime,     sys_clock_settime),  // (timer_create+5)
2263
2264   GENXY(__NR_clock_gettime,     sys_clock_gettime),  // (timer_create+6)
2265   GENXY(__NR_clock_getres,      sys_clock_getres),   // (timer_create+7)
2266   GENXY(__NR_clock_nanosleep,   sys_clock_nanosleep),// (timer_create+8) */*
2267   GENXY(__NR_statfs64,          sys_statfs64),       // 268
2268   GENXY(__NR_fstatfs64,         sys_fstatfs64),      // 269
2269
2270   LINX_(__NR_tgkill,            sys_tgkill),         // 270 */Linux
2271   GENX_(__NR_utimes,            sys_utimes),         // 271
2272   LINX_(__NR_fadvise64_64,      sys_fadvise64_64),   // 272 */(Linux?)
2273   GENX_(__NR_vserver,           sys_ni_syscall),     // 273
2274//zz    //   (__NR_mbind,             sys_mbind),          // 274 ?/?
2275//zz
2276   LINXY(__NR_get_mempolicy,     sys_get_mempolicy),  // 275 ?/?
2277   LINX_(__NR_set_mempolicy,     sys_set_mempolicy),  // 276 ?/?
2278   LINXY(__NR_mq_open,           sys_mq_open),        // 277
2279   LINX_(__NR_mq_unlink,         sys_mq_unlink),      // (mq_open+1)
2280   LINX_(__NR_mq_timedsend,      sys_mq_timedsend),   // (mq_open+2)
2281
2282   LINXY(__NR_mq_timedreceive,   sys_mq_timedreceive),// (mq_open+3)
2283   LINX_(__NR_mq_notify,         sys_mq_notify),      // (mq_open+4)
2284   LINXY(__NR_mq_getsetattr,     sys_mq_getsetattr),  // (mq_open+5)
2285   GENX_(__NR_sys_kexec_load,    sys_ni_syscall),     // 283
2286   GENXY(__NR_waitid,            sys_waitid),         // 284
2287
2288   GENX_(285,                    sys_ni_syscall),     // 285
2289//   LINX_(__NR_add_key,           sys_add_key),        // 286
2290//   LINX_(__NR_request_key,       sys_request_key),    // 287
2291//   LINXY(__NR_keyctl,            sys_keyctl),         // 288
2292//   LINX_(__NR_ioprio_set,        sys_ioprio_set),     // 289
2293
2294//   LINX_(__NR_ioprio_get,        sys_ioprio_get),     // 290
2295   LINX_(__NR_inotify_init,	 sys_inotify_init),   // 291
2296   LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 292
2297   LINX_(__NR_inotify_rm_watch,	 sys_inotify_rm_watch), // 293
2298};
2299
2300const UInt ML_(syscall_table_size) =
2301            sizeof(ML_(syscall_table)) / sizeof(ML_(syscall_table)[0]);
2302
2303/*--------------------------------------------------------------------*/
2304/*--- end                                                          ---*/
2305/*--------------------------------------------------------------------*/
2306