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