]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/coregrind/m_syswrap/syswrap-ppc32-linux.c
update
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / coregrind / m_syswrap / syswrap-ppc32-linux.c
1
2 /*--------------------------------------------------------------------*/
3 /*--- Platform-specific syscalls stuff.      syswrap-ppc32-linux.c ---*/
4 /*--------------------------------------------------------------------*/
5
6 /*
7    This file is part of Valgrind, a dynamic binary instrumentation
8    framework.
9
10    Copyright (C) 2005-2010 Nicholas Nethercote <njn@valgrind.org>
11    Copyright (C) 2005-2010 Cerion Armour-Brown <cerion@open-works.co.uk>
12
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of the
16    License, or (at your option) any later version.
17
18    This program is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26    02111-1307, USA.
27
28    The GNU General Public License is contained in the file COPYING.
29 */
30
31 #if defined(VGP_ppc32_linux)
32
33 #include "pub_core_basics.h"
34 #include "pub_core_vki.h"
35 #include "pub_core_vkiscnums.h"
36 #include "pub_core_libcsetjmp.h"    // to keep _threadstate.h happy
37 #include "pub_core_threadstate.h"
38 #include "pub_core_aspacemgr.h"
39 #include "pub_core_debuglog.h"
40 #include "pub_core_libcbase.h"
41 #include "pub_core_libcassert.h"
42 #include "pub_core_libcprint.h"
43 #include "pub_core_libcproc.h"
44 #include "pub_core_libcsignal.h"
45 #include "pub_core_options.h"
46 #include "pub_core_scheduler.h"
47 #include "pub_core_sigframe.h"      // For VG_(sigframe_destroy)()
48 #include "pub_core_signals.h"
49 #include "pub_core_syscall.h"
50 #include "pub_core_syswrap.h"
51 #include "pub_core_tooliface.h"
52 #include "pub_core_stacks.h"        // VG_(register_stack)
53
54 #include "priv_types_n_macros.h"
55 #include "priv_syswrap-generic.h"   /* for decls of generic wrappers */
56 #include "priv_syswrap-linux.h"     /* for decls of linux-ish wrappers */
57 #include "priv_syswrap-main.h"
58
59
60 /* ---------------------------------------------------------------------
61    clone() handling
62    ------------------------------------------------------------------ */
63
64 /* Call f(arg1), but first switch stacks, using 'stack' as the new
65    stack, and use 'retaddr' as f's return-to address.  Also, clear all
66    the integer registers before entering f.*/
67 __attribute__((noreturn))
68 void ML_(call_on_new_stack_0_1) ( Addr stack,
69                                   Addr retaddr,
70                                   void (*f)(Word),
71                                   Word arg1 );
72 //    r3 = stack
73 //    r4 = retaddr
74 //    r5 = f
75 //    r6 = arg1
76 asm(
77 ".text\n"
78 ".globl vgModuleLocal_call_on_new_stack_0_1\n"
79 "vgModuleLocal_call_on_new_stack_0_1:\n"
80 "   mr    %r1,%r3\n\t"     // stack to %sp
81 "   mtlr  %r4\n\t"         // retaddr to %lr
82 "   mtctr %r5\n\t"         // f to count reg
83 "   mr %r3,%r6\n\t"        // arg1 to %r3
84 "   li 0,0\n\t"            // zero all GP regs
85 "   li 4,0\n\t"
86 "   li 5,0\n\t"
87 "   li 6,0\n\t"
88 "   li 7,0\n\t"
89 "   li 8,0\n\t"
90 "   li 9,0\n\t"
91 "   li 10,0\n\t"
92 "   li 11,0\n\t"
93 "   li 12,0\n\t"
94 "   li 13,0\n\t"
95 "   li 14,0\n\t"
96 "   li 15,0\n\t"
97 "   li 16,0\n\t"
98 "   li 17,0\n\t"
99 "   li 18,0\n\t"
100 "   li 19,0\n\t"
101 "   li 20,0\n\t"
102 "   li 21,0\n\t"
103 "   li 22,0\n\t"
104 "   li 23,0\n\t"
105 "   li 24,0\n\t"
106 "   li 25,0\n\t"
107 "   li 26,0\n\t"
108 "   li 27,0\n\t"
109 "   li 28,0\n\t"
110 "   li 29,0\n\t"
111 "   li 30,0\n\t"
112 "   li 31,0\n\t"
113 "   mtxer 0\n\t"           // CAB: Need this?
114 "   mtcr 0\n\t"            // CAB: Need this?
115 "   bctr\n\t"              // jump to dst
116 "   trap\n"                // should never get here
117 ".previous\n"
118 );
119
120
121 /*
122         Perform a clone system call.  clone is strange because it has
123         fork()-like return-twice semantics, so it needs special
124         handling here.
125
126         Upon entry, we have:
127
128             int (fn)(void*)     in r3
129             void* child_stack   in r4
130             int flags           in r5
131             void* arg           in r6
132             pid_t* child_tid    in r7
133             pid_t* parent_tid   in r8
134             void* ???           in r9
135
136         System call requires:
137
138             int    $__NR_clone  in r0  (sc number)
139             int    flags        in r3  (sc arg1)
140             void*  child_stack  in r4  (sc arg2)
141             pid_t* parent_tid   in r5  (sc arg3)
142             ??     child_tls    in r6  (sc arg4)
143             pid_t* child_tid    in r7  (sc arg5)
144             void*  ???          in r8  (sc arg6)
145
146         Returns an Int encoded in the linux-ppc32 way, not a SysRes.
147  */
148 #define __NR_CLONE        VG_STRINGIFY(__NR_clone)
149 #define __NR_EXIT         VG_STRINGIFY(__NR_exit)
150
151 extern
152 ULong do_syscall_clone_ppc32_linux ( Word (*fn)(void *), 
153                                      void* stack, 
154                                      Int   flags, 
155                                      void* arg,
156                                      Int*  child_tid, 
157                                      Int*  parent_tid, 
158                                      vki_modify_ldt_t * );
159 asm(
160 ".text\n"
161 "do_syscall_clone_ppc32_linux:\n"
162 "       stwu    1,-32(1)\n"
163 "       stw     29,20(1)\n"
164 "       stw     30,24(1)\n"
165 "       stw     31,28(1)\n"
166 "       mr      30,3\n"              // preserve fn
167 "       mr      31,6\n"              // preserve arg
168
169         // setup child stack
170 "       rlwinm  4,4,0,~0xf\n"        // trim sp to multiple of 16 bytes
171 "       li      0,0\n"
172 "       stwu    0,-16(4)\n"          // make initial stack frame
173 "       mr      29,4\n"              // preserve sp
174
175         // setup syscall
176 "       li      0,"__NR_CLONE"\n"    // syscall number
177 "       mr      3,5\n"               // syscall arg1: flags
178         // r4 already setup          // syscall arg2: child_stack
179 "       mr      5,8\n"               // syscall arg3: parent_tid
180 "       mr      6,2\n"               // syscall arg4: REAL THREAD tls
181 "       mr      7,7\n"               // syscall arg5: child_tid
182 "       mr      8,8\n"               // syscall arg6: ????
183 "       mr      9,9\n"               // syscall arg7: ????
184
185 "       sc\n"                        // clone()
186
187 "       mfcr    4\n"                 // return CR in r4 (low word of ULong)
188 "       cmpwi   3,0\n"               // child if retval == 0
189 "       bne     1f\n"                // jump if !child
190
191         /* CHILD - call thread function */
192         /* Note: 2.4 kernel doesn't set the child stack pointer,
193            so we do it here.
194            That does leave a small window for a signal to be delivered
195            on the wrong stack, unfortunately. */
196 "       mr      1,29\n"
197 "       mtctr   30\n"                // ctr reg = fn
198 "       mr      3,31\n"              // r3 = arg
199 "       bctrl\n"                     // call fn()
200
201         // exit with result
202 "       li      0,"__NR_EXIT"\n"
203 "       sc\n"
204
205         // Exit returned?!
206 "       .long   0\n"
207
208         // PARENT or ERROR - return
209 "1:     lwz     29,20(1)\n"
210 "       lwz     30,24(1)\n"
211 "       lwz     31,28(1)\n"
212 "       addi    1,1,32\n"
213 "       blr\n"
214 ".previous\n"
215 );
216
217 #undef __NR_CLONE
218 #undef __NR_EXIT
219
220 // forward declarations
221 static void setup_child ( ThreadArchState*, ThreadArchState* );
222
223 /* 
224    When a client clones, we need to keep track of the new thread.  This means:
225    1. allocate a ThreadId+ThreadState+stack for the the thread
226
227    2. initialize the thread's new VCPU state
228
229    3. create the thread using the same args as the client requested,
230    but using the scheduler entrypoint for IP, and a separate stack
231    for SP.
232  */
233 static SysRes do_clone ( ThreadId ptid, 
234                          UInt flags, Addr sp, 
235                          Int *parent_tidptr, 
236                          Int *child_tidptr, 
237                          Addr child_tls)
238 {
239    const Bool debug = False;
240
241    ThreadId     ctid = VG_(alloc_ThreadState)();
242    ThreadState* ptst = VG_(get_ThreadState)(ptid);
243    ThreadState* ctst = VG_(get_ThreadState)(ctid);
244    ULong        word64;
245    UWord*       stack;
246    NSegment const* seg;
247    SysRes       res;
248    vki_sigset_t blockall, savedmask;
249
250    VG_(sigfillset)(&blockall);
251
252    vg_assert(VG_(is_running_thread)(ptid));
253    vg_assert(VG_(is_valid_tid)(ctid));
254
255    stack = (UWord*)ML_(allocstack)(ctid);
256    if (stack == NULL) {
257       res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
258       goto out;
259    }
260
261 //?   /* make a stack frame */
262 //?   stack -= 16;
263 //?   *(UWord *)stack = 0;
264
265
266    /* Copy register state
267
268       Both parent and child return to the same place, and the code
269       following the clone syscall works out which is which, so we
270       don't need to worry about it.
271
272       The parent gets the child's new tid returned from clone, but the
273       child gets 0.
274
275       If the clone call specifies a NULL SP for the new thread, then
276       it actually gets a copy of the parent's SP.
277
278       The child's TLS register (r2) gets set to the tlsaddr argument
279       if the CLONE_SETTLS flag is set.
280    */
281    setup_child( &ctst->arch, &ptst->arch );
282
283    /* Make sys_clone appear to have returned Success(0) in the
284       child. */
285    { UInt old_cr = LibVEX_GuestPPC32_get_CR( &ctst->arch.vex );
286      /* %r3 = 0 */
287      ctst->arch.vex.guest_GPR3 = 0;
288      /* %cr0.so = 0 */
289      LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
290    }
291
292    if (sp != 0)
293       ctst->arch.vex.guest_GPR1 = sp;
294
295    ctst->os_state.parent = ptid;
296
297    /* inherit signal mask */
298    ctst->sig_mask = ptst->sig_mask;
299    ctst->tmp_sig_mask = ptst->sig_mask;
300
301    /* Start the child with its threadgroup being the same as the
302       parent's.  This is so that any exit_group calls that happen
303       after the child is created but before it sets its
304       os_state.threadgroup field for real (in thread_wrapper in
305       syswrap-linux.c), really kill the new thread.  a.k.a this avoids
306       a race condition in which the thread is unkillable (via
307       exit_group) because its threadgroup is not set.  The race window
308       is probably only a few hundred or a few thousand cycles long.
309       See #226116. */
310    ctst->os_state.threadgroup = ptst->os_state.threadgroup;
311
312    /* We don't really know where the client stack is, because its
313       allocated by the client.  The best we can do is look at the
314       memory mappings and try to derive some useful information.  We
315       assume that esp starts near its highest possible value, and can
316       only go down to the start of the mmaped segment. */
317    seg = VG_(am_find_nsegment)(sp);
318    if (seg && seg->kind != SkResvn) {
319       ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(sp);
320       ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
321
322       VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
323
324       if (debug)
325          VG_(printf)("\ntid %d: guessed client stack range %#lx-%#lx\n",
326                      ctid, seg->start, VG_PGROUNDUP(sp));
327    } else {
328       VG_(message)(Vg_UserMsg,
329                    "!? New thread %d starts with R1(%#lx) unmapped\n",
330                    ctid, sp);
331       ctst->client_stack_szB  = 0;
332    }
333
334    /* Assume the clone will succeed, and tell any tool that wants to
335       know that this thread has come into existence.  If the clone
336       fails, we'll send out a ll_exit notification for it at the out:
337       label below, to clean up. */
338    VG_TRACK ( pre_thread_ll_create, ptid, ctid );
339
340    if (flags & VKI_CLONE_SETTLS) {
341       if (debug)
342          VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls);
343       ctst->arch.vex.guest_GPR2 = child_tls;
344    }
345
346    flags &= ~VKI_CLONE_SETTLS;
347
348    /* start the thread with everything blocked */
349    VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
350
351    /* Create the new thread */
352    word64 = do_syscall_clone_ppc32_linux(
353                ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid],
354                child_tidptr, parent_tidptr, NULL
355             );
356    /* High half word64 is syscall return value.  Low half is
357       the entire CR, from which we need to extract CR0.SO. */
358    /* VG_(printf)("word64 = 0x%llx\n", word64); */
359    res = VG_(mk_SysRes_ppc32_linux)( 
360             /*val*/(UInt)(word64 >> 32), 
361             /*errflag*/ (((UInt)word64) >> 28) & 1 
362          );
363
364    VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
365
366   out:
367    if (sr_isError(res)) {
368       /* clone failed */
369       VG_(cleanup_thread)(&ctst->arch);
370       ctst->status = VgTs_Empty;
371       /* oops.  Better tell the tool the thread exited in a hurry :-) */
372       VG_TRACK( pre_thread_ll_exit, ctid );
373    }
374
375    return res;
376 }
377
378
379
380 /* ---------------------------------------------------------------------
381    More thread stuff
382    ------------------------------------------------------------------ */
383
384 void VG_(cleanup_thread) ( ThreadArchState* arch )
385 {
386 }  
387
388 void setup_child ( /*OUT*/ ThreadArchState *child,
389                    /*IN*/  ThreadArchState *parent )
390 {
391    /* We inherit our parent's guest state. */
392    child->vex = parent->vex;
393    child->vex_shadow1 = parent->vex_shadow1;
394    child->vex_shadow2 = parent->vex_shadow2;
395 }
396
397
398 /* ---------------------------------------------------------------------
399    PRE/POST wrappers for ppc32/Linux-specific syscalls
400    ------------------------------------------------------------------ */
401
402 #define PRE(name)       DEFN_PRE_TEMPLATE(ppc32_linux, name)
403 #define POST(name)      DEFN_POST_TEMPLATE(ppc32_linux, name)
404
405 /* Add prototypes for the wrappers declared here, so that gcc doesn't
406    harass us for not having prototypes.  Really this is a kludge --
407    the right thing to do is to make these wrappers 'static' since they
408    aren't visible outside this file, but that requires even more macro
409    magic. */
410
411 DECL_TEMPLATE(ppc32_linux, sys_socketcall);
412 DECL_TEMPLATE(ppc32_linux, sys_mmap);
413 DECL_TEMPLATE(ppc32_linux, sys_mmap2);
414 DECL_TEMPLATE(ppc32_linux, sys_stat64);
415 DECL_TEMPLATE(ppc32_linux, sys_lstat64);
416 DECL_TEMPLATE(ppc32_linux, sys_fstatat64);
417 DECL_TEMPLATE(ppc32_linux, sys_fstat64);
418 DECL_TEMPLATE(ppc32_linux, sys_ipc);
419 DECL_TEMPLATE(ppc32_linux, sys_clone);
420 DECL_TEMPLATE(ppc32_linux, sys_sigreturn);
421 DECL_TEMPLATE(ppc32_linux, sys_rt_sigreturn);
422 DECL_TEMPLATE(ppc32_linux, sys_sigaction);
423 DECL_TEMPLATE(ppc32_linux, sys_sigsuspend);
424 DECL_TEMPLATE(ppc32_linux, sys_spu_create);
425 DECL_TEMPLATE(ppc32_linux, sys_spu_run);
426
427 PRE(sys_socketcall)
428 {
429 #  define ARG2_0  (((UWord*)ARG2)[0])
430 #  define ARG2_1  (((UWord*)ARG2)[1])
431 #  define ARG2_2  (((UWord*)ARG2)[2])
432 #  define ARG2_3  (((UWord*)ARG2)[3])
433 #  define ARG2_4  (((UWord*)ARG2)[4])
434 #  define ARG2_5  (((UWord*)ARG2)[5])
435
436    *flags |= SfMayBlock;
437    PRINT("sys_socketcall ( %ld, %#lx )",ARG1,ARG2);
438    PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
439
440    switch (ARG1 /* request */) {
441
442    case VKI_SYS_SOCKETPAIR:
443      /* int socketpair(int d, int type, int protocol, int sv[2]); */
444       PRE_MEM_READ( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
445       ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
446       break;
447
448    case VKI_SYS_SOCKET:
449      /* int socket(int domain, int type, int protocol); */
450       PRE_MEM_READ( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
451       break;
452
453    case VKI_SYS_BIND:
454      /* int bind(int sockfd, struct sockaddr *my_addr,
455         int addrlen); */
456       PRE_MEM_READ( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
457       ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
458       break;
459
460    case VKI_SYS_LISTEN:
461      /* int listen(int s, int backlog); */
462       PRE_MEM_READ( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
463       break;
464
465    case VKI_SYS_ACCEPT: {
466      /* int accept(int s, struct sockaddr *addr, int *addrlen); */
467       PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
468       ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
469       break;
470    }
471
472    case VKI_SYS_ACCEPT4: {
473      /* int accept(int s, struct sockaddr *addr, int *addrlen, int args); */
474       PRE_MEM_READ( "socketcall.accept4(args)", ARG2, 4*sizeof(Addr) );
475       ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
476       break;
477    }
478
479    case VKI_SYS_SENDTO:
480      /* int sendto(int s, const void *msg, int len,
481                     unsigned int flags,
482                     const struct sockaddr *to, int tolen); */
483      PRE_MEM_READ( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
484      ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
485                                   ARG2_3, ARG2_4, ARG2_5 );
486      break;
487
488    case VKI_SYS_SEND:
489      /* int send(int s, const void *msg, size_t len, int flags); */
490      PRE_MEM_READ( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
491      ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
492      break;
493
494    case VKI_SYS_RECVFROM:
495      /* int recvfrom(int s, void *buf, int len, unsigned int flags,
496         struct sockaddr *from, int *fromlen); */
497      PRE_MEM_READ( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
498      ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
499                                     ARG2_3, ARG2_4, ARG2_5 );
500      break;
501
502    case VKI_SYS_RECV:
503      /* int recv(int s, void *buf, int len, unsigned int flags); */
504      /* man 2 recv says:
505          The  recv call is normally used only on a connected socket
506          (see connect(2)) and is identical to recvfrom with a  NULL
507          from parameter.
508      */
509      PRE_MEM_READ( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
510      ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
511      break;
512
513    case VKI_SYS_CONNECT:
514      /* int connect(int sockfd,
515         struct sockaddr *serv_addr, int addrlen ); */
516      PRE_MEM_READ( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
517      ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
518      break;
519
520    case VKI_SYS_SETSOCKOPT:
521      /* int setsockopt(int s, int level, int optname,
522         const void *optval, int optlen); */
523      PRE_MEM_READ( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
524      ML_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
525                                       ARG2_3, ARG2_4 );
526      break;
527
528    case VKI_SYS_GETSOCKOPT:
529      /* int getsockopt(int s, int level, int optname,
530         void *optval, socklen_t *optlen); */
531      PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
532      ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
533                                     ARG2_3, ARG2_4 );
534      break;
535
536    case VKI_SYS_GETSOCKNAME:
537      /* int getsockname(int s, struct sockaddr* name, int* namelen) */
538      PRE_MEM_READ( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
539      ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
540      break;
541
542    case VKI_SYS_GETPEERNAME:
543      /* int getpeername(int s, struct sockaddr* name, int* namelen) */
544      PRE_MEM_READ( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
545      ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
546      break;
547
548    case VKI_SYS_SHUTDOWN:
549      /* int shutdown(int s, int how); */
550      PRE_MEM_READ( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
551      break;
552
553    case VKI_SYS_SENDMSG: {
554      /* int sendmsg(int s, const struct msghdr *msg, int flags); */
555
556      /* this causes warnings, and I don't get why. glibc bug?
557       * (after all it's glibc providing the arguments array)
558        PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
559      */
560      ML_(generic_PRE_sys_sendmsg)( tid, ARG2_0, ARG2_1 );
561      break;
562    }
563
564    case VKI_SYS_RECVMSG: {
565      /* int recvmsg(int s, struct msghdr *msg, int flags); */
566
567      /* this causes warnings, and I don't get why. glibc bug?
568       * (after all it's glibc providing the arguments array)
569        PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
570      */
571      ML_(generic_PRE_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
572      break;
573    }
574
575    default:
576      VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
577      SET_STATUS_Failure( VKI_EINVAL );
578      break;
579    }
580 #  undef ARG2_0
581 #  undef ARG2_1
582 #  undef ARG2_2
583 #  undef ARG2_3
584 #  undef ARG2_4
585 #  undef ARG2_5
586 }
587
588 POST(sys_socketcall)
589 {
590 #  define ARG2_0  (((UWord*)ARG2)[0])
591 #  define ARG2_1  (((UWord*)ARG2)[1])
592 #  define ARG2_2  (((UWord*)ARG2)[2])
593 #  define ARG2_3  (((UWord*)ARG2)[3])
594 #  define ARG2_4  (((UWord*)ARG2)[4])
595 #  define ARG2_5  (((UWord*)ARG2)[5])
596
597   SysRes r;
598   vg_assert(SUCCESS);
599   switch (ARG1 /* request */) {
600
601   case VKI_SYS_SOCKETPAIR:
602     r = ML_(generic_POST_sys_socketpair)(
603                                          tid, VG_(mk_SysRes_Success)(RES),
604                                          ARG2_0, ARG2_1, ARG2_2, ARG2_3
605                                          );
606     SET_STATUS_from_SysRes(r);
607     break;
608
609   case VKI_SYS_SOCKET:
610     r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
611     SET_STATUS_from_SysRes(r);
612     break;
613
614   case VKI_SYS_BIND:
615     /* int bind(int sockfd, struct sockaddr *my_addr,
616        int addrlen); */
617     break;
618
619   case VKI_SYS_LISTEN:
620     /* int listen(int s, int backlog); */
621     break;
622
623   case VKI_SYS_ACCEPT:
624   case VKI_SYS_ACCEPT4:
625     /* int accept(int s, struct sockaddr *addr, int *addrlen); */
626     r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
627                                       ARG2_0, ARG2_1, ARG2_2 );
628     SET_STATUS_from_SysRes(r);
629     break;
630
631   case VKI_SYS_SENDTO:
632     break;
633
634   case VKI_SYS_SEND:
635     break;
636
637   case VKI_SYS_RECVFROM:
638     ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
639                                     ARG2_0, ARG2_1, ARG2_2,
640                                     ARG2_3, ARG2_4, ARG2_5 );
641     break;
642
643   case VKI_SYS_RECV:
644     ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
645     break;
646
647   case VKI_SYS_CONNECT:
648     break;
649
650   case VKI_SYS_SETSOCKOPT:
651     break;
652
653   case VKI_SYS_GETSOCKOPT:
654     ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
655                                     ARG2_0, ARG2_1,
656                                     ARG2_2, ARG2_3, ARG2_4 );
657     break;
658
659   case VKI_SYS_GETSOCKNAME:
660     ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
661                                        ARG2_0, ARG2_1, ARG2_2 );
662     break;
663
664   case VKI_SYS_GETPEERNAME:
665     ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
666                                        ARG2_0, ARG2_1, ARG2_2 );
667     break;
668
669   case VKI_SYS_SHUTDOWN:
670     break;
671
672   case VKI_SYS_SENDMSG:
673     break;
674
675   case VKI_SYS_RECVMSG:
676     ML_(generic_POST_sys_recvmsg)( tid, ARG2_0, ARG2_1 );
677     break;
678
679   default:
680     VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
681     VG_(core_panic)("... bye!\n");
682     break; /*NOTREACHED*/
683   }
684 #  undef ARG2_0
685 #  undef ARG2_1
686 #  undef ARG2_2
687 #  undef ARG2_3
688 #  undef ARG2_4
689 #  undef ARG2_5
690 }
691
692 PRE(sys_mmap)
693 {
694    SysRes r;
695
696    PRINT("sys_mmap ( %#lx, %llu, %ld, %ld, %ld, %ld )",
697          ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
698    PRE_REG_READ6(long, "mmap",
699                  unsigned long, start, unsigned long, length,
700                  unsigned long, prot,  unsigned long, flags,
701                  unsigned long, fd,    unsigned long, offset);
702
703    r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, 
704                                        (Off64T)ARG6 );
705    SET_STATUS_from_SysRes(r);
706 }
707
708 PRE(sys_mmap2)
709 {
710    SysRes r;
711
712    // Exactly like old_mmap() except:
713    //  - the file offset is specified in 4K units rather than bytes,
714    //    so that it can be used for files bigger than 2^32 bytes.
715    PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )",
716          ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
717    PRE_REG_READ6(long, "mmap2",
718                  unsigned long, start, unsigned long, length,
719                  unsigned long, prot,  unsigned long, flags,
720                  unsigned long, fd,    unsigned long, offset);
721
722    r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, 
723                                        4096 * (Off64T)ARG6 );
724    SET_STATUS_from_SysRes(r);
725 }
726
727 // XXX: lstat64/fstat64/stat64 are generic, but not necessarily
728 // applicable to every architecture -- I think only to 32-bit archs.
729 // We're going to need something like linux/core_os32.h for such
730 // things, eventually, I think.  --njn
731 PRE(sys_stat64)
732 {
733    PRINT("sys_stat64 ( %#lx, %#lx )",ARG1,ARG2);
734    PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
735    PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
736    PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
737 }
738
739 POST(sys_stat64)
740 {
741    POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
742 }
743
744 PRE(sys_lstat64)
745 {
746    PRINT("sys_lstat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
747    PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
748    PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
749    PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
750 }
751
752 POST(sys_lstat64)
753 {
754    vg_assert(SUCCESS);
755    if (RES == 0) {
756       POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
757    }
758 }
759
760 PRE(sys_fstatat64)
761 {
762   PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )",ARG1,ARG2,(char*)ARG2,ARG3);
763    PRE_REG_READ3(long, "fstatat64",
764                  int, dfd, char *, file_name, struct stat64 *, buf);
765    PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 );
766    PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) );
767 }
768
769 POST(sys_fstatat64)
770 {
771    POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) );
772 }
773
774 PRE(sys_fstat64)
775 {
776   PRINT("sys_fstat64 ( %ld, %#lx )",ARG1,ARG2);
777   PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
778   PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
779 }
780
781 POST(sys_fstat64)
782 {
783   POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
784 }
785
786 static Addr deref_Addr ( ThreadId tid, Addr a, Char* s )
787 {
788    Addr* a_p = (Addr*)a;
789    PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
790    return *a_p;
791 }
792
793 PRE(sys_ipc)
794 {
795   PRINT("sys_ipc ( %ld, %ld, %ld, %ld, %#lx, %ld )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
796   // XXX: this is simplistic -- some args are not used in all circumstances.
797   PRE_REG_READ6(int, "ipc",
798                 vki_uint, call, int, first, int, second, int, third,
799                 void *, ptr, long, fifth)
800
801     switch (ARG1 /* call */) {
802     case VKI_SEMOP:
803       ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
804       *flags |= SfMayBlock;
805       break;
806     case VKI_SEMGET:
807       break;
808     case VKI_SEMCTL:
809       {
810         UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
811         ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
812         break;
813       }
814     case VKI_SEMTIMEDOP:
815       ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
816       *flags |= SfMayBlock;
817       break;
818     case VKI_MSGSND:
819       ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
820       if ((ARG4 & VKI_IPC_NOWAIT) == 0)
821         *flags |= SfMayBlock;
822       break;
823     case VKI_MSGRCV:
824       {
825         Addr msgp;
826         Word msgtyp;
827
828         msgp = deref_Addr( tid,
829                            (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
830                            "msgrcv(msgp)" );
831         msgtyp = deref_Addr( tid,
832                              (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
833                              "msgrcv(msgp)" );
834
835         ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
836
837         if ((ARG4 & VKI_IPC_NOWAIT) == 0)
838           *flags |= SfMayBlock;
839         break;
840       }
841     case VKI_MSGGET:
842       break;
843     case VKI_MSGCTL:
844       ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
845       break;
846     case VKI_SHMAT:
847       {
848         UWord w;
849         PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
850         w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
851         if (w == 0)
852           SET_STATUS_Failure( VKI_EINVAL );
853         else
854           ARG5 = w;
855         break;
856       }
857     case VKI_SHMDT:
858       if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
859         SET_STATUS_Failure( VKI_EINVAL );
860       break;
861     case VKI_SHMGET:
862       break;
863     case VKI_SHMCTL: /* IPCOP_shmctl */
864       ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
865       break;
866     default:
867       VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %ld\n", ARG1 );
868       VG_(core_panic)("... bye!\n");
869       break; /*NOTREACHED*/
870     }
871 }
872
873 POST(sys_ipc)
874 {
875   vg_assert(SUCCESS);
876   switch (ARG1 /* call */) {
877   case VKI_SEMOP:
878   case VKI_SEMGET:
879     break;
880   case VKI_SEMCTL:
881     {
882       UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
883       ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
884       break;
885     }
886   case VKI_SEMTIMEDOP:
887   case VKI_MSGSND:
888     break;
889   case VKI_MSGRCV:
890     {
891       Addr msgp;
892       Word msgtyp;
893
894       msgp = deref_Addr( tid,
895                          (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
896                          "msgrcv(msgp)" );
897       msgtyp = deref_Addr( tid,
898                            (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
899                            "msgrcv(msgp)" );
900
901       ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
902       break;
903     }
904   case VKI_MSGGET:
905     break;
906   case VKI_MSGCTL:
907     ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
908     break;
909   case VKI_SHMAT:
910     {
911       Addr addr;
912
913       /* force readability. before the syscall it is
914        * indeed uninitialized, as can be seen in
915        * glibc/sysdeps/unix/sysv/linux/shmat.c */
916       POST_MEM_WRITE( ARG4, sizeof( Addr ) );
917
918       addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
919       ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
920       break;
921     }
922   case VKI_SHMDT:
923     ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
924     break;
925   case VKI_SHMGET:
926     break;
927   case VKI_SHMCTL:
928     ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
929     break;
930   default:
931     VG_(message)(Vg_DebugMsg,
932                  "FATAL: unhandled syscall(ipc) %ld\n",
933                  ARG1 );
934     VG_(core_panic)("... bye!\n");
935     break; /*NOTREACHED*/
936   }
937 }
938
939
940
941
942 //.. PRE(old_select, MayBlock)
943 //.. {
944 //..    /* struct sel_arg_struct {
945 //..       unsigned long n;
946 //..       fd_set *inp, *outp, *exp;
947 //..       struct timeval *tvp;
948 //..       };
949 //..    */
950 //..    PRE_REG_READ1(long, "old_select", struct sel_arg_struct *, args);
951 //..    PRE_MEM_READ( "old_select(args)", ARG1, 5*sizeof(UWord) );
952 //.. 
953 //..    {
954 //..       UInt* arg_struct = (UInt*)ARG1;
955 //..       UInt a1, a2, a3, a4, a5;
956 //.. 
957 //..       a1 = arg_struct[0];
958 //..       a2 = arg_struct[1];
959 //..       a3 = arg_struct[2];
960 //..       a4 = arg_struct[3];
961 //..       a5 = arg_struct[4];
962 //.. 
963 //..       PRINT("old_select ( %d, %p, %p, %p, %p )", a1,a2,a3,a4,a5);
964 //..       if (a2 != (Addr)NULL)
965 //..     PRE_MEM_READ( "old_select(readfds)",   a2, a1/8 /* __FD_SETSIZE/8 */ );
966 //..       if (a3 != (Addr)NULL)
967 //..     PRE_MEM_READ( "old_select(writefds)",  a3, a1/8 /* __FD_SETSIZE/8 */ );
968 //..       if (a4 != (Addr)NULL)
969 //..     PRE_MEM_READ( "old_select(exceptfds)", a4, a1/8 /* __FD_SETSIZE/8 */ );
970 //..       if (a5 != (Addr)NULL)
971 //..     PRE_MEM_READ( "old_select(timeout)", a5, sizeof(struct vki_timeval) );
972 //..    }
973 //.. }
974
975 PRE(sys_clone)
976 {
977    UInt cloneflags;
978
979    PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
980    PRE_REG_READ5(int, "clone",
981                  unsigned long, flags,
982                  void *,        child_stack,
983                  int *,         parent_tidptr,
984                  void *,        child_tls,
985                  int *,         child_tidptr);
986
987    if (ARG1 & VKI_CLONE_PARENT_SETTID) {
988       PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
989       if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), 
990                                              VKI_PROT_WRITE)) {
991          SET_STATUS_Failure( VKI_EFAULT );
992          return;
993       }
994    }
995    if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
996       PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
997       if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int), 
998                                              VKI_PROT_WRITE)) {
999          SET_STATUS_Failure( VKI_EFAULT );
1000          return;
1001       }
1002    }
1003
1004    cloneflags = ARG1;
1005
1006    if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
1007       SET_STATUS_Failure( VKI_EINVAL );
1008       return;
1009    }
1010
1011    /* Only look at the flags we really care about */
1012    switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS 
1013                          | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
1014    case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
1015       /* thread creation */
1016       SET_STATUS_from_SysRes(
1017          do_clone(tid,
1018                   ARG1,         /* flags */
1019                   (Addr)ARG2,   /* child SP */
1020                   (Int *)ARG3,  /* parent_tidptr */
1021                   (Int *)ARG5,  /* child_tidptr */
1022                   (Addr)ARG4)); /* child_tls */
1023       break;
1024
1025    case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
1026       /* FALLTHROUGH - assume vfork == fork */
1027       cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
1028
1029    case 0: /* plain fork */
1030       SET_STATUS_from_SysRes(
1031          ML_(do_fork_clone)(tid,
1032                        cloneflags,      /* flags */
1033                        (Int *)ARG3,     /* parent_tidptr */
1034                        (Int *)ARG5));   /* child_tidptr */
1035       break;
1036
1037    default:
1038       /* should we just ENOSYS? */
1039       VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
1040       VG_(message)(Vg_UserMsg, "\n");
1041       VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
1042       VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
1043       VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
1044       VG_(unimplemented)
1045          ("Valgrind does not support general clone().");
1046    }
1047
1048    if (SUCCESS) {
1049       if (ARG1 & VKI_CLONE_PARENT_SETTID)
1050          POST_MEM_WRITE(ARG3, sizeof(Int));
1051       if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
1052          POST_MEM_WRITE(ARG5, sizeof(Int));
1053
1054       /* Thread creation was successful; let the child have the chance
1055          to run */
1056       *flags |= SfYieldAfter;
1057    }
1058 }
1059
1060 PRE(sys_sigreturn)
1061 {
1062    /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
1063       an explanation of what follows. */
1064
1065    //ThreadState* tst;
1066    PRINT("sys_sigreturn ( )");
1067
1068    vg_assert(VG_(is_valid_tid)(tid));
1069    vg_assert(tid >= 1 && tid < VG_N_THREADS);
1070    vg_assert(VG_(is_running_thread)(tid));
1071
1072    ///* Adjust esp to point to start of frame; skip back up over
1073    //   sigreturn sequence's "popl %eax" and handler ret addr */
1074    //tst = VG_(get_ThreadState)(tid);
1075    //tst->arch.vex.guest_ESP -= sizeof(Addr)+sizeof(Word);
1076    // Should we do something equivalent on ppc32?  Who knows.
1077
1078    ///* This is only so that the EIP is (might be) useful to report if
1079    //   something goes wrong in the sigreturn */
1080    //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
1081    // Should we do something equivalent on ppc32?  Who knows.
1082
1083    /* Restore register state from frame and remove it */
1084    VG_(sigframe_destroy)(tid, False);
1085
1086    /* Tell the driver not to update the guest state with the "result",
1087       and set a bogus result to keep it happy. */
1088    *flags |= SfNoWriteResult;
1089    SET_STATUS_Success(0);
1090
1091    /* Check to see if any signals arose as a result of this. */
1092    *flags |= SfPollAfter;
1093 }
1094
1095 PRE(sys_rt_sigreturn)
1096 {
1097    /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
1098       an explanation of what follows. */
1099
1100    //ThreadState* tst;
1101    PRINT("rt_sigreturn ( )");
1102
1103    vg_assert(VG_(is_valid_tid)(tid));
1104    vg_assert(tid >= 1 && tid < VG_N_THREADS);
1105    vg_assert(VG_(is_running_thread)(tid));
1106
1107    ///* Adjust esp to point to start of frame; skip back up over handler
1108    //   ret addr */
1109    //tst = VG_(get_ThreadState)(tid);
1110    //tst->arch.vex.guest_ESP -= sizeof(Addr);
1111    // Should we do something equivalent on ppc32?  Who knows.
1112
1113    ///* This is only so that the EIP is (might be) useful to report if
1114    //   something goes wrong in the sigreturn */
1115    //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
1116    // Should we do something equivalent on ppc32?  Who knows.
1117
1118    /* Restore register state from frame and remove it */
1119    VG_(sigframe_destroy)(tid, True);
1120
1121    /* Tell the driver not to update the guest state with the "result",
1122       and set a bogus result to keep it happy. */
1123    *flags |= SfNoWriteResult;
1124    SET_STATUS_Success(0);
1125
1126    /* Check to see if any signals arose as a result of this. */
1127    *flags |= SfPollAfter;
1128 }
1129
1130
1131 //.. PRE(sys_modify_ldt, Special)
1132 //.. {
1133 //..    PRINT("sys_modify_ldt ( %d, %p, %d )", ARG1,ARG2,ARG3);
1134 //..    PRE_REG_READ3(int, "modify_ldt", int, func, void *, ptr,
1135 //..                  unsigned long, bytecount);
1136 //..    
1137 //..    if (ARG1 == 0) {
1138 //..       /* read the LDT into ptr */
1139 //..       PRE_MEM_WRITE( "modify_ldt(ptr)", ARG2, ARG3 );
1140 //..    }
1141 //..    if (ARG1 == 1 || ARG1 == 0x11) {
1142 //..       /* write the LDT with the entry pointed at by ptr */
1143 //..       PRE_MEM_READ( "modify_ldt(ptr)", ARG2, sizeof(vki_modify_ldt_t) );
1144 //..    }
1145 //..    /* "do" the syscall ourselves; the kernel never sees it */
1146 //..    SET_RESULT( VG_(sys_modify_ldt)( tid, ARG1, (void*)ARG2, ARG3 ) );
1147 //.. 
1148 //..    if (ARG1 == 0 && !VG_(is_kerror)(RES) && RES > 0) {
1149 //..       POST_MEM_WRITE( ARG2, RES );
1150 //..    }
1151 //.. }
1152
1153 //.. PRE(sys_set_thread_area, Special)
1154 //.. {
1155 //..    PRINT("sys_set_thread_area ( %p )", ARG1);
1156 //..    PRE_REG_READ1(int, "set_thread_area", struct user_desc *, u_info)
1157 //..    PRE_MEM_READ( "set_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
1158 //.. 
1159 //..    /* "do" the syscall ourselves; the kernel never sees it */
1160 //..    SET_RESULT( VG_(sys_set_thread_area)( tid, (void *)ARG1 ) );
1161 //.. }
1162
1163 //.. PRE(sys_get_thread_area, Special)
1164 //.. {
1165 //..    PRINT("sys_get_thread_area ( %p )", ARG1);
1166 //..    PRE_REG_READ1(int, "get_thread_area", struct user_desc *, u_info)
1167 //..    PRE_MEM_WRITE( "get_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
1168 //.. 
1169 //..    /* "do" the syscall ourselves; the kernel never sees it */
1170 //..    SET_RESULT( VG_(sys_get_thread_area)( tid, (void *)ARG1 ) );
1171 //.. 
1172 //..    if (!VG_(is_kerror)(RES)) {
1173 //..       POST_MEM_WRITE( ARG1, sizeof(vki_modify_ldt_t) );
1174 //..    }
1175 //.. }
1176
1177 //.. // Parts of this are ppc32-specific, but the *PEEK* cases are generic.
1178 //.. // XXX: Why is the memory pointed to by ARG3 never checked?
1179 //.. PRE(sys_ptrace, 0)
1180 //.. {
1181 //..    PRINT("sys_ptrace ( %d, %d, %p, %p )", ARG1,ARG2,ARG3,ARG4);
1182 //..    PRE_REG_READ4(int, "ptrace", 
1183 //..                  long, request, long, pid, long, addr, long, data);
1184 //..    switch (ARG1) {
1185 //..    case VKI_PTRACE_PEEKTEXT:
1186 //..    case VKI_PTRACE_PEEKDATA:
1187 //..    case VKI_PTRACE_PEEKUSR:
1188 //..       PRE_MEM_WRITE( "ptrace(peek)", ARG4, 
1189 //..                 sizeof (long));
1190 //..       break;
1191 //..    case VKI_PTRACE_GETREGS:
1192 //..       PRE_MEM_WRITE( "ptrace(getregs)", ARG4, 
1193 //..                 sizeof (struct vki_user_regs_struct));
1194 //..       break;
1195 //..    case VKI_PTRACE_GETFPREGS:
1196 //..       PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4, 
1197 //..                 sizeof (struct vki_user_i387_struct));
1198 //..       break;
1199 //..    case VKI_PTRACE_GETFPXREGS:
1200 //..       PRE_MEM_WRITE( "ptrace(getfpxregs)", ARG4, 
1201 //..                      sizeof(struct vki_user_fxsr_struct) );
1202 //..       break;
1203 //..    case VKI_PTRACE_SETREGS:
1204 //..       PRE_MEM_READ( "ptrace(setregs)", ARG4, 
1205 //..                 sizeof (struct vki_user_regs_struct));
1206 //..       break;
1207 //..    case VKI_PTRACE_SETFPREGS:
1208 //..       PRE_MEM_READ( "ptrace(setfpregs)", ARG4, 
1209 //..                 sizeof (struct vki_user_i387_struct));
1210 //..       break;
1211 //..    case VKI_PTRACE_SETFPXREGS:
1212 //..       PRE_MEM_READ( "ptrace(setfpxregs)", ARG4, 
1213 //..                      sizeof(struct vki_user_fxsr_struct) );
1214 //..       break;
1215 //..    default:
1216 //..       break;
1217 //..    }
1218 //.. }
1219
1220 //.. POST(sys_ptrace)
1221 //.. {
1222 //..    switch (ARG1) {
1223 //..    case VKI_PTRACE_PEEKTEXT:
1224 //..    case VKI_PTRACE_PEEKDATA:
1225 //..    case VKI_PTRACE_PEEKUSR:
1226 //..       POST_MEM_WRITE( ARG4, sizeof (long));
1227 //..       break;
1228 //..    case VKI_PTRACE_GETREGS:
1229 //..       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
1230 //..       break;
1231 //..    case VKI_PTRACE_GETFPREGS:
1232 //..       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
1233 //..       break;
1234 //..    case VKI_PTRACE_GETFPXREGS:
1235 //..       POST_MEM_WRITE( ARG4, sizeof(struct vki_user_fxsr_struct) );
1236 //..       break;
1237 //..    default:
1238 //..       break;
1239 //..    }
1240 //.. }
1241
1242 //.. // XXX: this duplicates a function in coregrind/vg_syscalls.c, yuk
1243 //.. static Addr deref_Addr ( ThreadId tid, Addr a, Char* s )
1244 //.. {
1245 //..    Addr* a_p = (Addr*)a;
1246 //..    PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
1247 //..    return *a_p;
1248 //.. }
1249
1250 //.. // XXX: should use the constants here (eg. SHMAT), not the numbers directly!
1251 //.. PRE(sys_ipc, 0)
1252 //.. {
1253 //..    PRINT("sys_ipc ( %d, %d, %d, %d, %p, %d )", ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
1254 //..    // XXX: this is simplistic -- some args are not used in all circumstances.
1255 //..    PRE_REG_READ6(int, "ipc",
1256 //..                  vki_uint, call, int, first, int, second, int, third,
1257 //..                  void *, ptr, long, fifth)
1258 //.. 
1259 //..    switch (ARG1 /* call */) {
1260 //..    case VKI_SEMOP:
1261 //..       ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
1262 //..       /* tst->sys_flags |= MayBlock; */
1263 //..       break;
1264 //..    case VKI_SEMGET:
1265 //..       break;
1266 //..    case VKI_SEMCTL:
1267 //..    {
1268 //..       UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
1269 //..       ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
1270 //..       break;
1271 //..    }
1272 //..    case VKI_SEMTIMEDOP:
1273 //..       ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
1274 //..       /* tst->sys_flags |= MayBlock; */
1275 //..       break;
1276 //..    case VKI_MSGSND:
1277 //..       ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
1278 //..       /* if ((ARG4 & VKI_IPC_NOWAIT) == 0)
1279 //..             tst->sys_flags |= MayBlock;
1280 //..       */
1281 //..       break;
1282 //..    case VKI_MSGRCV:
1283 //..    {
1284 //..       Addr msgp;
1285 //..       Word msgtyp;
1286 //..  
1287 //..       msgp = deref_Addr( tid,
1288 //..                     (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
1289 //..                     "msgrcv(msgp)" );
1290 //..       msgtyp = deref_Addr( tid,
1291 //..                       (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
1292 //..                       "msgrcv(msgp)" );
1293 //.. 
1294 //..       ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
1295 //.. 
1296 //..       /* if ((ARG4 & VKI_IPC_NOWAIT) == 0)
1297 //..             tst->sys_flags |= MayBlock;
1298 //..       */
1299 //..       break;
1300 //..    }
1301 //..    case VKI_MSGGET:
1302 //..       break;
1303 //..    case VKI_MSGCTL:
1304 //..       ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
1305 //..       break;
1306 //..    case VKI_SHMAT:
1307 //..       PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
1308 //..       ARG5 = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
1309 //..       if (ARG5 == 0)
1310 //..          SET_RESULT( -VKI_EINVAL );
1311 //..       break;
1312 //..    case VKI_SHMDT:
1313 //..       if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
1314 //..     SET_RESULT( -VKI_EINVAL );
1315 //..       break;
1316 //..    case VKI_SHMGET:
1317 //..       break;
1318 //..    case VKI_SHMCTL: /* IPCOP_shmctl */
1319 //..       ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
1320 //..       break;
1321 //..    default:
1322 //..       VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %d", ARG1 );
1323 //..       VG_(core_panic)("... bye!\n");
1324 //..       break; /*NOTREACHED*/
1325 //..    }   
1326 //.. }
1327
1328 //.. POST(sys_ipc)
1329 //.. {
1330 //..    switch (ARG1 /* call */) {
1331 //..    case VKI_SEMOP:
1332 //..    case VKI_SEMGET:
1333 //..       break;
1334 //..    case VKI_SEMCTL:
1335 //..    {
1336 //..       UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
1337 //..       ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
1338 //..       break;
1339 //..    }
1340 //..    case VKI_SEMTIMEDOP:
1341 //..    case VKI_MSGSND:
1342 //..       break;
1343 //..    case VKI_MSGRCV:
1344 //..    {
1345 //..       Addr msgp;
1346 //..       Word msgtyp;
1347 //.. 
1348 //..       msgp = deref_Addr( tid,
1349 //..                     (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
1350 //..                     "msgrcv(msgp)" );
1351 //..       msgtyp = deref_Addr( tid,
1352 //..                       (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
1353 //..                       "msgrcv(msgp)" );
1354 //.. 
1355 //..       ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
1356 //..       break;
1357 //..    }
1358 //..    case VKI_MSGGET:
1359 //..       break;
1360 //..    case VKI_MSGCTL:
1361 //..       ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
1362 //..       break;
1363 //..    case VKI_SHMAT:
1364 //..    {
1365 //..       Addr addr;
1366 //.. 
1367 //..       /* force readability. before the syscall it is
1368 //..        * indeed uninitialized, as can be seen in
1369 //..        * glibc/sysdeps/unix/sysv/linux/shmat.c */
1370 //..       POST_MEM_WRITE( ARG4, sizeof( Addr ) );
1371 //.. 
1372 //..       addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
1373 //..       if ( addr > 0 ) { 
1374 //..          ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
1375 //..       }
1376 //..       break;
1377 //..    }
1378 //..    case VKI_SHMDT:
1379 //..       ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
1380 //..       break;
1381 //..    case VKI_SHMGET:
1382 //..       break;
1383 //..    case VKI_SHMCTL:
1384 //..       ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
1385 //..       break;
1386 //..    default:
1387 //..       VG_(message)(Vg_DebugMsg,
1388 //..               "FATAL: unhandled syscall(ipc) %d",
1389 //..               ARG1 );
1390 //..       VG_(core_panic)("... bye!\n");
1391 //..       break; /*NOTREACHED*/
1392 //..    }
1393 //.. }
1394
1395
1396 /* Convert from non-RT to RT sigset_t's */
1397 static 
1398 void convert_sigset_to_rt(const vki_old_sigset_t *oldset, vki_sigset_t *set)
1399 {
1400    VG_(sigemptyset)(set);
1401    set->sig[0] = *oldset;
1402 }
1403 PRE(sys_sigaction)
1404 {
1405    vki_sigaction_toK_t   new, *newp;
1406    vki_sigaction_fromK_t old, *oldp;
1407
1408    PRINT("sys_sigaction ( %ld, %#lx, %#lx )", ARG1,ARG2,ARG3);
1409    PRE_REG_READ3(int, "sigaction",
1410                  int, signum, const struct old_sigaction *, act,
1411                  struct old_sigaction *, oldact);
1412
1413    newp = oldp = NULL;
1414
1415    if (ARG2 != 0) {
1416       struct vki_old_sigaction *sa = (struct vki_old_sigaction *)ARG2;
1417       PRE_MEM_READ( "sigaction(act->sa_handler)", (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
1418       PRE_MEM_READ( "sigaction(act->sa_mask)", (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
1419       PRE_MEM_READ( "sigaction(act->sa_flags)", (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
1420       if (ML_(safe_to_deref)(sa,sizeof(sa)) 
1421           && (sa->sa_flags & VKI_SA_RESTORER))
1422          PRE_MEM_READ( "sigaction(act->sa_restorer)", (Addr)&sa->sa_restorer, sizeof(sa->sa_restorer));
1423    }
1424
1425    if (ARG3 != 0) {
1426       PRE_MEM_WRITE( "sigaction(oldact)", ARG3, sizeof(struct vki_old_sigaction));
1427       oldp = &old;
1428    }
1429
1430    //jrs 20050207: what?!  how can this make any sense?
1431    //if (VG_(is_kerror)(SYSRES))
1432    //   return;
1433
1434    if (ARG2 != 0) {
1435       struct vki_old_sigaction *oldnew = (struct vki_old_sigaction *)ARG2;
1436
1437       new.ksa_handler = oldnew->ksa_handler;
1438       new.sa_flags = oldnew->sa_flags;
1439       new.sa_restorer = oldnew->sa_restorer;
1440       convert_sigset_to_rt(&oldnew->sa_mask, &new.sa_mask);
1441       newp = &new;
1442    }
1443
1444    SET_STATUS_from_SysRes( VG_(do_sys_sigaction)(ARG1, newp, oldp) );
1445
1446    if (ARG3 != 0 && SUCCESS && RES == 0) {
1447       struct vki_old_sigaction *oldold = (struct vki_old_sigaction *)ARG3;
1448
1449       oldold->ksa_handler = oldp->ksa_handler;
1450       oldold->sa_flags = oldp->sa_flags;
1451       oldold->sa_restorer = oldp->sa_restorer;
1452       oldold->sa_mask = oldp->sa_mask.sig[0];
1453    }
1454 }
1455
1456 POST(sys_sigaction)
1457 {
1458    vg_assert(SUCCESS);
1459    if (RES == 0 && ARG3 != 0)
1460       POST_MEM_WRITE( ARG3, sizeof(struct vki_old_sigaction));
1461 }
1462
1463 PRE(sys_sigsuspend)
1464 {
1465    /* The C library interface to sigsuspend just takes a pointer to
1466       a signal mask but this system call only takes the first word of
1467       the signal mask as an argument so only 32 signals are supported.
1468      
1469       In fact glibc normally uses rt_sigsuspend if it is available as
1470       that takes a pointer to the signal mask so supports more signals.
1471     */
1472    *flags |= SfMayBlock;
1473    PRINT("sys_sigsuspend ( %ld )", ARG1 );
1474    PRE_REG_READ1(int, "sigsuspend", vki_old_sigset_t, mask);
1475 }
1476
1477 PRE(sys_spu_create)
1478 {
1479    PRE_MEM_RASCIIZ("stat64(filename)", ARG1);
1480 }
1481 POST(sys_spu_create)
1482 {
1483    vg_assert(SUCCESS);
1484 }
1485
1486 PRE(sys_spu_run)
1487 {
1488    *flags |= SfMayBlock;
1489    if (ARG2 != 0)
1490       PRE_MEM_WRITE("npc", ARG2, sizeof(unsigned int));
1491    PRE_MEM_READ("event", ARG3, sizeof(unsigned int));
1492 }
1493 POST(sys_spu_run)
1494 {
1495    if (ARG2 != 0)
1496       POST_MEM_WRITE(ARG2, sizeof(unsigned int));
1497 }
1498
1499 #undef PRE
1500 #undef POST
1501
1502 /* ---------------------------------------------------------------------
1503    The ppc32/Linux syscall table
1504    ------------------------------------------------------------------ */
1505
1506 /* Add an ppc32-linux specific wrapper to a syscall table. */
1507 #define PLAX_(sysno, name)    WRAPPER_ENTRY_X_(ppc32_linux, sysno, name) 
1508 #define PLAXY(sysno, name)    WRAPPER_ENTRY_XY(ppc32_linux, sysno, name)
1509
1510 // This table maps from __NR_xxx syscall numbers (from
1511 // linux/include/asm-ppc/unistd.h) to the appropriate PRE/POST sys_foo()
1512 // wrappers on ppc32 (as per sys_call_table in linux/arch/ppc/kernel/entry.S).
1513 //
1514 // For those syscalls not handled by Valgrind, the annotation indicate its
1515 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
1516 // (unknown).
1517
1518 static SyscallTableEntry syscall_table[] = {
1519 //..   (restart_syscall)                                      // 0
1520    GENX_(__NR_exit,              sys_exit),              // 1
1521    GENX_(__NR_fork,              sys_fork),              // 2
1522    GENXY(__NR_read,              sys_read),              // 3
1523    GENX_(__NR_write,             sys_write),             // 4
1524
1525    GENXY(__NR_open,              sys_open),              // 5
1526    GENXY(__NR_close,             sys_close),             // 6
1527    GENXY(__NR_waitpid,           sys_waitpid),           // 7
1528    GENXY(__NR_creat,             sys_creat),             // 8
1529    GENX_(__NR_link,              sys_link),              // 9
1530
1531    GENX_(__NR_unlink,            sys_unlink),            // 10
1532    GENX_(__NR_execve,            sys_execve),            // 11
1533    GENX_(__NR_chdir,             sys_chdir),             // 12
1534    GENXY(__NR_time,              sys_time),              // 13
1535    GENX_(__NR_mknod,             sys_mknod),             // 14
1536 //.. 
1537    GENX_(__NR_chmod,             sys_chmod),             // 15
1538    GENX_(__NR_lchown,            sys_lchown),          // 16 ## P
1539 //..    GENX_(__NR_break,             sys_ni_syscall),        // 17
1540 //..    //   (__NR_oldstat,           sys_stat),              // 18 (obsolete)
1541    LINX_(__NR_lseek,             sys_lseek),             // 19
1542 //.. 
1543    GENX_(__NR_getpid,            sys_getpid),            // 20
1544    LINX_(__NR_mount,             sys_mount),             // 21
1545    LINX_(__NR_umount,            sys_oldumount),         // 22
1546    GENX_(__NR_setuid,            sys_setuid),            // 23 ## P
1547    GENX_(__NR_getuid,            sys_getuid),            // 24 ## P
1548 //.. 
1549 //..    //   (__NR_stime,             sys_stime),             // 25 * (SVr4,SVID,X/OPEN)
1550 //..    PLAXY(__NR_ptrace,            sys_ptrace),            // 26
1551    GENX_(__NR_alarm,             sys_alarm),             // 27
1552 //..    //   (__NR_oldfstat,          sys_fstat),             // 28 * L -- obsolete
1553    GENX_(__NR_pause,             sys_pause),             // 29
1554 //.. 
1555    LINX_(__NR_utime,             sys_utime),                  // 30
1556 //..    GENX_(__NR_stty,              sys_ni_syscall),        // 31
1557 //..    GENX_(__NR_gtty,              sys_ni_syscall),        // 32
1558    GENX_(__NR_access,            sys_access),            // 33
1559 //..    GENX_(__NR_nice,              sys_nice),              // 34
1560 //.. 
1561 //..    GENX_(__NR_ftime,             sys_ni_syscall),        // 35
1562 //..    GENX_(__NR_sync,              sys_sync),              // 36
1563    GENX_(__NR_kill,              sys_kill),              // 37
1564    GENX_(__NR_rename,            sys_rename),            // 38
1565    GENX_(__NR_mkdir,             sys_mkdir),             // 39
1566
1567    GENX_(__NR_rmdir,             sys_rmdir),             // 40
1568    GENXY(__NR_dup,               sys_dup),               // 41
1569    LINXY(__NR_pipe,              sys_pipe),              // 42
1570    GENXY(__NR_times,             sys_times),             // 43
1571 //..    GENX_(__NR_prof,              sys_ni_syscall),        // 44
1572 //.. 
1573    GENX_(__NR_brk,               sys_brk),               // 45
1574    GENX_(__NR_setgid,            sys_setgid),            // 46
1575    GENX_(__NR_getgid,            sys_getgid),            // 47
1576 //..    //   (__NR_signal,            sys_signal),            // 48 */* (ANSI C)
1577    GENX_(__NR_geteuid,           sys_geteuid),           // 49
1578
1579    GENX_(__NR_getegid,           sys_getegid),           // 50
1580 //..    GENX_(__NR_acct,              sys_acct),              // 51
1581    LINX_(__NR_umount2,           sys_umount),            // 52
1582 //..    GENX_(__NR_lock,              sys_ni_syscall),        // 53
1583    LINXY(__NR_ioctl,             sys_ioctl),             // 54
1584 //.. 
1585    LINXY(__NR_fcntl,             sys_fcntl),             // 55
1586 //..    GENX_(__NR_mpx,               sys_ni_syscall),        // 56
1587    GENX_(__NR_setpgid,           sys_setpgid),           // 57
1588 //..    GENX_(__NR_ulimit,            sys_ni_syscall),        // 58
1589 //..    //   (__NR_oldolduname,       sys_olduname),          // 59 Linux -- obsolete
1590
1591    GENX_(__NR_umask,             sys_umask),             // 60
1592    GENX_(__NR_chroot,            sys_chroot),            // 61
1593 //..    //   (__NR_ustat,             sys_ustat)              // 62 SVr4 -- deprecated
1594    GENXY(__NR_dup2,              sys_dup2),              // 63
1595    GENX_(__NR_getppid,           sys_getppid),           // 64
1596
1597    GENX_(__NR_getpgrp,           sys_getpgrp),           // 65
1598    GENX_(__NR_setsid,            sys_setsid),            // 66
1599    PLAXY(__NR_sigaction,         sys_sigaction),         // 67
1600 //..    //   (__NR_sgetmask,          sys_sgetmask),          // 68 */* (ANSI C)
1601 //..    //   (__NR_ssetmask,          sys_ssetmask),          // 69 */* (ANSI C)
1602 //.. 
1603    GENX_(__NR_setreuid,          sys_setreuid),          // 70
1604    GENX_(__NR_setregid,          sys_setregid),          // 71
1605    PLAX_(__NR_sigsuspend,        sys_sigsuspend),        // 72
1606    LINXY(__NR_sigpending,        sys_sigpending),        // 73
1607 //..    //   (__NR_sethostname,       sys_sethostname),       // 74 */*
1608 //.. 
1609    GENX_(__NR_setrlimit,         sys_setrlimit),              // 75
1610 //..    GENXY(__NR_getrlimit,         sys_old_getrlimit),     // 76
1611    GENXY(__NR_getrusage,         sys_getrusage),         // 77
1612    GENXY(__NR_gettimeofday,      sys_gettimeofday),           // 78
1613 //..    GENX_(__NR_settimeofday,      sys_settimeofday),      // 79
1614 //.. 
1615    GENXY(__NR_getgroups,         sys_getgroups),         // 80
1616    GENX_(__NR_setgroups,         sys_setgroups),         // 81
1617 //..    PLAX_(__NR_select,            old_select),            // 82
1618    GENX_(__NR_symlink,           sys_symlink),           // 83
1619 //..    //   (__NR_oldlstat,          sys_lstat),             // 84 -- obsolete
1620 //.. 
1621    GENX_(__NR_readlink,          sys_readlink),          // 85
1622 //..    //   (__NR_uselib,            sys_uselib),            // 86 */Linux
1623 //..    //   (__NR_swapon,            sys_swapon),            // 87 */Linux
1624 //..    //   (__NR_reboot,            sys_reboot),            // 88 */Linux
1625 //..    //   (__NR_readdir,           old_readdir),           // 89 -- superseded
1626
1627    PLAX_(__NR_mmap,              sys_mmap),                   // 90
1628    GENXY(__NR_munmap,            sys_munmap),                 // 91
1629    GENX_(__NR_truncate,          sys_truncate),          // 92
1630    GENX_(__NR_ftruncate,         sys_ftruncate),         // 93
1631    GENX_(__NR_fchmod,            sys_fchmod),            // 94
1632
1633    GENX_(__NR_fchown,            sys_fchown),            // 95
1634    GENX_(__NR_getpriority,       sys_getpriority),       // 96
1635    GENX_(__NR_setpriority,       sys_setpriority),       // 97
1636 //..    GENX_(__NR_profil,            sys_ni_syscall),        // 98
1637    GENXY(__NR_statfs,            sys_statfs),            // 99
1638 //.. 
1639    GENXY(__NR_fstatfs,           sys_fstatfs),           // 100
1640 //..    LINX_(__NR_ioperm,            sys_ioperm),            // 101
1641    PLAXY(__NR_socketcall,        sys_socketcall),        // 102
1642    LINXY(__NR_syslog,            sys_syslog),            // 103
1643    GENXY(__NR_setitimer,         sys_setitimer),         // 104
1644
1645    GENXY(__NR_getitimer,         sys_getitimer),         // 105
1646    GENXY(__NR_stat,              sys_newstat),           // 106
1647    GENXY(__NR_lstat,             sys_newlstat),          // 107
1648    GENXY(__NR_fstat,             sys_newfstat),          // 108
1649 //..    //   (__NR_olduname,          sys_uname),             // 109 -- obsolete
1650 //.. 
1651 //..    GENX_(__NR_iopl,              sys_iopl),              // 110
1652    LINX_(__NR_vhangup,           sys_vhangup),           // 111
1653 //..    GENX_(__NR_idle,              sys_ni_syscall),        // 112
1654 //..    //   (__NR_vm86old,           sys_vm86old),           // 113 x86/Linux-only
1655    GENXY(__NR_wait4,             sys_wait4),             // 114
1656 //.. 
1657 //..    //   (__NR_swapoff,           sys_swapoff),           // 115 */Linux 
1658    LINXY(__NR_sysinfo,           sys_sysinfo),           // 116
1659    PLAXY(__NR_ipc,               sys_ipc),               // 117
1660    GENX_(__NR_fsync,             sys_fsync),             // 118
1661    PLAX_(__NR_sigreturn,         sys_sigreturn),         // 119 ?/Linux
1662 //.. 
1663    PLAX_(__NR_clone,             sys_clone),             // 120
1664 //..    //   (__NR_setdomainname,     sys_setdomainname),     // 121 */*(?)
1665    GENXY(__NR_uname,             sys_newuname),          // 122
1666 //..    PLAX_(__NR_modify_ldt,        sys_modify_ldt),        // 123
1667    LINXY(__NR_adjtimex,          sys_adjtimex),          // 124
1668
1669    GENXY(__NR_mprotect,          sys_mprotect),          // 125
1670    LINXY(__NR_sigprocmask,       sys_sigprocmask),       // 126
1671    GENX_(__NR_create_module,     sys_ni_syscall),        // 127
1672    LINX_(__NR_init_module,       sys_init_module),       // 128
1673    LINX_(__NR_delete_module,     sys_delete_module),     // 129
1674 //.. 
1675 //..    // Nb: get_kernel_syms() was removed 2.4-->2.6
1676 //..    GENX_(__NR_get_kernel_syms,   sys_ni_syscall),        // 130
1677 //..    LINX_(__NR_quotactl,          sys_quotactl),          // 131
1678    GENX_(__NR_getpgid,           sys_getpgid),           // 132
1679    GENX_(__NR_fchdir,            sys_fchdir),            // 133
1680 //..    //   (__NR_bdflush,           sys_bdflush),           // 134 */Linux
1681 //.. 
1682 //..    //   (__NR_sysfs,             sys_sysfs),             // 135 SVr4
1683    LINX_(__NR_personality,       sys_personality),       // 136
1684 //..    GENX_(__NR_afs_syscall,       sys_ni_syscall),        // 137
1685    LINX_(__NR_setfsuid,          sys_setfsuid),          // 138
1686    LINX_(__NR_setfsgid,          sys_setfsgid),          // 139
1687
1688    LINXY(__NR__llseek,           sys_llseek),            // 140
1689    GENXY(__NR_getdents,          sys_getdents),          // 141
1690    GENX_(__NR__newselect,        sys_select),            // 142
1691    GENX_(__NR_flock,             sys_flock),             // 143
1692    GENX_(__NR_msync,             sys_msync),             // 144
1693 //.. 
1694    GENXY(__NR_readv,             sys_readv),             // 145
1695    GENX_(__NR_writev,            sys_writev),            // 146
1696    GENX_(__NR_getsid,            sys_getsid),            // 147
1697    GENX_(__NR_fdatasync,         sys_fdatasync),         // 148
1698    LINXY(__NR__sysctl,           sys_sysctl),            // 149
1699 //.. 
1700    GENX_(__NR_mlock,             sys_mlock),             // 150
1701    GENX_(__NR_munlock,           sys_munlock),           // 151
1702    GENX_(__NR_mlockall,          sys_mlockall),          // 152
1703    LINX_(__NR_munlockall,        sys_munlockall),        // 153
1704    LINXY(__NR_sched_setparam,    sys_sched_setparam),    // 154
1705 //.. 
1706    LINXY(__NR_sched_getparam,         sys_sched_getparam),        // 155
1707    LINX_(__NR_sched_setscheduler,     sys_sched_setscheduler),    // 156
1708    LINX_(__NR_sched_getscheduler,     sys_sched_getscheduler),    // 157
1709    LINX_(__NR_sched_yield,            sys_sched_yield),           // 158
1710    LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
1711
1712    LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
1713    LINXY(__NR_sched_rr_get_interval,  sys_sched_rr_get_interval), // 161
1714    GENXY(__NR_nanosleep,         sys_nanosleep),         // 162
1715    GENX_(__NR_mremap,            sys_mremap),            // 163
1716    LINX_(__NR_setresuid,         sys_setresuid),         // 164
1717
1718    LINXY(__NR_getresuid,         sys_getresuid),         // 165
1719
1720 //..    GENX_(__NR_query_module,      sys_ni_syscall),        // 166
1721    GENXY(__NR_poll,              sys_poll),              // 167
1722 //..    //   (__NR_nfsservctl,        sys_nfsservctl),        // 168 */Linux
1723 //.. 
1724    LINX_(__NR_setresgid,         sys_setresgid),         // 169
1725    LINXY(__NR_getresgid,         sys_getresgid),         // 170
1726    LINXY(__NR_prctl,             sys_prctl),             // 171
1727    PLAX_(__NR_rt_sigreturn,      sys_rt_sigreturn),      // 172
1728    LINXY(__NR_rt_sigaction,      sys_rt_sigaction),      // 173
1729
1730    LINXY(__NR_rt_sigprocmask,    sys_rt_sigprocmask),    // 174
1731    LINXY(__NR_rt_sigpending,     sys_rt_sigpending),     // 175
1732    LINXY(__NR_rt_sigtimedwait,   sys_rt_sigtimedwait),   // 176
1733    LINXY(__NR_rt_sigqueueinfo,   sys_rt_sigqueueinfo),   // 177
1734    LINX_(__NR_rt_sigsuspend,     sys_rt_sigsuspend),     // 178
1735
1736    GENXY(__NR_pread64,           sys_pread64),           // 179
1737    GENX_(__NR_pwrite64,          sys_pwrite64),          // 180
1738    GENX_(__NR_chown,             sys_chown),             // 181
1739    GENXY(__NR_getcwd,            sys_getcwd),            // 182
1740    LINXY(__NR_capget,            sys_capget),            // 183
1741    LINX_(__NR_capset,            sys_capset),            // 184
1742    GENXY(__NR_sigaltstack,       sys_sigaltstack),       // 185
1743    LINXY(__NR_sendfile,          sys_sendfile),          // 186
1744 //..    GENXY(__NR_getpmsg,           sys_getpmsg),           // 187
1745 //..    GENX_(__NR_putpmsg,           sys_putpmsg),           // 188
1746
1747    // Nb: we treat vfork as fork
1748    GENX_(__NR_vfork,             sys_fork),              // 189
1749    GENXY(__NR_ugetrlimit,        sys_getrlimit),         // 190
1750    LINX_(__NR_readahead,         sys_readahead),         // 191 */Linux
1751    PLAX_(__NR_mmap2,             sys_mmap2),             // 192
1752    GENX_(__NR_truncate64,        sys_truncate64),        // 193
1753    GENX_(__NR_ftruncate64,       sys_ftruncate64),       // 194
1754 //..    
1755
1756    PLAXY(__NR_stat64,            sys_stat64),            // 195
1757    PLAXY(__NR_lstat64,           sys_lstat64),           // 196
1758    PLAXY(__NR_fstat64,           sys_fstat64),           // 197
1759
1760 // __NR_pciconfig_read                                        // 198
1761 // __NR_pciconfig_write                                       // 199
1762 // __NR_pciconfig_iobase                                      // 200
1763 // __NR_multiplexer                                           // 201
1764
1765    GENXY(__NR_getdents64,        sys_getdents64),        // 202
1766 //..    //   (__NR_pivot_root,        sys_pivot_root),        // 203 */Linux
1767    LINXY(__NR_fcntl64,           sys_fcntl64),           // 204
1768    GENX_(__NR_madvise,           sys_madvise),           // 205
1769    GENXY(__NR_mincore,           sys_mincore),           // 206
1770    LINX_(__NR_gettid,            sys_gettid),            // 207
1771 //..    LINX_(__NR_tkill,             sys_tkill),             // 208 */Linux
1772 //..    LINX_(__NR_setxattr,          sys_setxattr),          // 209
1773 //..    LINX_(__NR_lsetxattr,         sys_lsetxattr),         // 210
1774 //..    LINX_(__NR_fsetxattr,         sys_fsetxattr),         // 211
1775    LINXY(__NR_getxattr,          sys_getxattr),          // 212
1776    LINXY(__NR_lgetxattr,         sys_lgetxattr),         // 213
1777    LINXY(__NR_fgetxattr,         sys_fgetxattr),         // 214
1778    LINXY(__NR_listxattr,         sys_listxattr),         // 215
1779    LINXY(__NR_llistxattr,        sys_llistxattr),        // 216
1780    LINXY(__NR_flistxattr,        sys_flistxattr),        // 217
1781    LINX_(__NR_removexattr,       sys_removexattr),       // 218
1782    LINX_(__NR_lremovexattr,      sys_lremovexattr),      // 219
1783    LINX_(__NR_fremovexattr,      sys_fremovexattr),      // 220
1784
1785    LINXY(__NR_futex,             sys_futex),                  // 221
1786    LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 222
1787    LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 223
1788 /* 224 currently unused */
1789
1790 // __NR_tuxcall                                               // 225
1791
1792    LINXY(__NR_sendfile64,        sys_sendfile64),        // 226
1793 //.. 
1794    LINX_(__NR_io_setup,          sys_io_setup),          // 227
1795    LINX_(__NR_io_destroy,        sys_io_destroy),        // 228
1796    LINXY(__NR_io_getevents,      sys_io_getevents),      // 229
1797    LINX_(__NR_io_submit,         sys_io_submit),         // 230
1798    LINXY(__NR_io_cancel,         sys_io_cancel),         // 231
1799 //.. 
1800    LINX_(__NR_set_tid_address,   sys_set_tid_address),   // 232
1801
1802    LINX_(__NR_fadvise64,         sys_fadvise64),         // 233 */(Linux?)
1803    LINX_(__NR_exit_group,        sys_exit_group),        // 234
1804 //..    GENXY(__NR_lookup_dcookie,    sys_lookup_dcookie),    // 235
1805    LINXY(__NR_epoll_create,      sys_epoll_create),      // 236
1806    LINX_(__NR_epoll_ctl,         sys_epoll_ctl),         // 237
1807    LINXY(__NR_epoll_wait,        sys_epoll_wait),        // 238
1808
1809 //..    //   (__NR_remap_file_pages,  sys_remap_file_pages),  // 239 */Linux
1810    LINXY(__NR_timer_create,      sys_timer_create),      // 240
1811    LINXY(__NR_timer_settime,     sys_timer_settime),     // 241
1812    LINXY(__NR_timer_gettime,     sys_timer_gettime),     // 242
1813    LINX_(__NR_timer_getoverrun,  sys_timer_getoverrun),  // 243
1814    LINX_(__NR_timer_delete,      sys_timer_delete),      // 244
1815    LINX_(__NR_clock_settime,     sys_clock_settime),     // 245
1816    LINXY(__NR_clock_gettime,     sys_clock_gettime),     // 246
1817    LINXY(__NR_clock_getres,      sys_clock_getres),      // 247
1818    LINXY(__NR_clock_nanosleep,   sys_clock_nanosleep),   // 248
1819
1820 // __NR_swapcontext                                           // 249
1821
1822    LINXY(__NR_tgkill,            sys_tgkill),            // 250 */Linux
1823 //..    GENX_(__NR_utimes,            sys_utimes),            // 251
1824    GENXY(__NR_statfs64,          sys_statfs64),          // 252
1825    GENXY(__NR_fstatfs64,         sys_fstatfs64),         // 253
1826    LINX_(__NR_fadvise64_64,      sys_fadvise64_64),      // 254 */(Linux?)
1827
1828 // __NR_rtas                                                  // 255
1829
1830 /* Number 256 is reserved for sys_debug_setcontext */
1831 /* Number 257 is reserved for vserver */
1832 /* Number 258 is reserved for new sys_remap_file_pages */
1833 /* Number 259 is reserved for new sys_mbind */
1834    LINXY(__NR_get_mempolicy,     sys_get_mempolicy),          // 260
1835    LINX_(__NR_set_mempolicy,     sys_set_mempolicy),          // 261
1836
1837    LINXY(__NR_mq_open,           sys_mq_open),           // 262
1838    LINX_(__NR_mq_unlink,         sys_mq_unlink),         // 263
1839    LINX_(__NR_mq_timedsend,      sys_mq_timedsend),      // 264
1840    LINXY(__NR_mq_timedreceive,   sys_mq_timedreceive),   // 265
1841    LINX_(__NR_mq_notify,         sys_mq_notify),         // 266
1842    LINXY(__NR_mq_getsetattr,     sys_mq_getsetattr),     // 267
1843 // __NR_kexec_load                                            // 268
1844
1845 /* Number 269 is reserved for sys_add_key */
1846 /* Number 270 is reserved for sys_request_key */
1847 /* Number 271 is reserved for sys_keyctl */
1848 /* Number 272 is reserved for sys_waitid */
1849    LINX_(__NR_ioprio_set,        sys_ioprio_set),         // 273
1850    LINX_(__NR_ioprio_get,        sys_ioprio_get),         // 274
1851
1852    LINX_(__NR_inotify_init,  sys_inotify_init),               // 275
1853    LINX_(__NR_inotify_add_watch,  sys_inotify_add_watch),     // 276
1854    LINX_(__NR_inotify_rm_watch,   sys_inotify_rm_watch),      // 277
1855    PLAXY(__NR_spu_run,            sys_spu_run),               // 278
1856    PLAX_(__NR_spu_create,         sys_spu_create),            // 279
1857
1858    LINXY(__NR_ppoll,             sys_ppoll),             // 281
1859
1860    LINXY(__NR_openat,            sys_openat),            // 286
1861    LINX_(__NR_mkdirat,           sys_mkdirat),           // 287
1862    LINX_(__NR_mknodat,           sys_mknodat),           // 288
1863    LINX_(__NR_fchownat,          sys_fchownat),          // 289
1864    LINX_(__NR_futimesat,         sys_futimesat),         // 290
1865    PLAXY(__NR_fstatat64,         sys_fstatat64),         // 291
1866    LINX_(__NR_unlinkat,          sys_unlinkat),          // 292
1867    LINX_(__NR_renameat,          sys_renameat),          // 293
1868    LINX_(__NR_linkat,            sys_linkat),            // 294
1869    LINX_(__NR_symlinkat,         sys_symlinkat),         // 295
1870    LINX_(__NR_readlinkat,        sys_readlinkat),        // 296
1871    LINX_(__NR_fchmodat,          sys_fchmodat),          // 297
1872    LINX_(__NR_faccessat,         sys_faccessat),         // 298
1873    LINX_(__NR_set_robust_list,   sys_set_robust_list),   // 299
1874    LINXY(__NR_get_robust_list,   sys_get_robust_list),   // 300
1875 //   LINX_(__NR_move_pages,        sys_ni_syscall),        // 301
1876    LINXY(__NR_getcpu,            sys_getcpu),            // 302
1877    LINXY(__NR_epoll_pwait,       sys_epoll_pwait),       // 303
1878    LINX_(__NR_utimensat,         sys_utimensat),         // 304
1879    LINXY(__NR_signalfd,          sys_signalfd),          // 305
1880    LINXY(__NR_timerfd_create,    sys_timerfd_create),    // 306
1881    LINX_(__NR_eventfd,           sys_eventfd),           // 307
1882    LINX_(__NR_sync_file_range2,  sys_sync_file_range2),  // 308
1883    LINX_(__NR_fallocate,         sys_fallocate),         // 309
1884 //   LINXY(__NR_subpage_prot,       sys_ni_syscall),       // 310
1885    LINXY(__NR_timerfd_settime,   sys_timerfd_settime),  // 311
1886    LINXY(__NR_timerfd_gettime,   sys_timerfd_gettime),  // 312
1887    LINXY(__NR_signalfd4,         sys_signalfd4),        // 313
1888    LINX_(__NR_eventfd2,          sys_eventfd2),         // 314
1889    LINXY(__NR_epoll_create1,     sys_epoll_create1),    // 315
1890    LINXY(__NR_dup3,              sys_dup3),             // 316
1891    LINXY(__NR_pipe2,             sys_pipe2),            // 317
1892    LINXY(__NR_inotify_init1,     sys_inotify_init1),    // 318
1893    LINXY(__NR_perf_counter_open, sys_perf_counter_open),// 319
1894    LINXY(__NR_preadv,            sys_preadv),           // 320
1895    LINX_(__NR_pwritev,           sys_pwritev),          // 321
1896    LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo) // 322
1897 };
1898
1899 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1900 {
1901    const UInt syscall_table_size
1902       = sizeof(syscall_table) / sizeof(syscall_table[0]);
1903
1904    /* Is it in the contiguous initial section of the table? */
1905    if (sysno < syscall_table_size) {
1906       SyscallTableEntry* sys = &syscall_table[sysno];
1907       if (sys->before == NULL)
1908          return NULL; /* no entry */
1909       else
1910          return sys;
1911    }
1912
1913    /* Can't find a wrapper */
1914    return NULL;
1915 }
1916
1917 #endif // defined(VGP_ppc32_linux)
1918
1919 /*--------------------------------------------------------------------*/
1920 /*--- end                                                          ---*/
1921 /*--------------------------------------------------------------------*/