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