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