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-2013 Nicholas Nethercote <njn@valgrind.org>
11 Copyright (C) 2005-2013 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 ".globl do_syscall_clone_ppc32_linux\n"
162 "do_syscall_clone_ppc32_linux:\n"
163 " stwu 1,-32(1)\n"
164 " stw 29,20(1)\n"
165 " stw 30,24(1)\n"
166 " stw 31,28(1)\n"
167 " mr 30,3\n" // preserve fn
168 " mr 31,6\n" // preserve arg
169
170 // setup child stack
171 " rlwinm 4,4,0,~0xf\n" // trim sp to multiple of 16 bytes
172 " li 0,0\n"
173 " stwu 0,-16(4)\n" // make initial stack frame
174 " mr 29,4\n" // preserve sp
175
176 // setup syscall
177 " li 0,"__NR_CLONE"\n" // syscall number
178 " mr 3,5\n" // syscall arg1: flags
179 // r4 already setup // syscall arg2: child_stack
180 " mr 5,8\n" // syscall arg3: parent_tid
181 " mr 6,2\n" // syscall arg4: REAL THREAD tls
182 " mr 7,7\n" // syscall arg5: child_tid
183 " mr 8,8\n" // syscall arg6: ????
184 " mr 9,9\n" // syscall arg7: ????
185
186 " sc\n" // clone()
187
188 " mfcr 4\n" // return CR in r4 (low word of ULong)
189 " cmpwi 3,0\n" // child if retval == 0
190 " bne 1f\n" // jump if !child
191
192 /* CHILD - call thread function */
193 /* Note: 2.4 kernel doesn't set the child stack pointer,
194 so we do it here.
195 That does leave a small window for a signal to be delivered
196 on the wrong stack, unfortunately. */
197 " mr 1,29\n"
198 " mtctr 30\n" // ctr reg = fn
199 " mr 3,31\n" // r3 = arg
200 " bctrl\n" // call fn()
201
202 // exit with result
203 " li 0,"__NR_EXIT"\n"
204 " sc\n"
205
206 // Exit returned?!
207 " .long 0\n"
208
209 // PARENT or ERROR - return
210 "1: lwz 29,20(1)\n"
211 " lwz 30,24(1)\n"
212 " lwz 31,28(1)\n"
213 " addi 1,1,32\n"
214 " blr\n"
215 ".previous\n"
216 );
217
218 #undef __NR_CLONE
219 #undef __NR_EXIT
220
221 // forward declarations
222 static void setup_child ( ThreadArchState*, ThreadArchState* );
223
224 /*
225 When a client clones, we need to keep track of the new thread. This means:
226 1. allocate a ThreadId+ThreadState+stack for the the thread
227
228 2. initialize the thread's new VCPU state
229
230 3. create the thread using the same args as the client requested,
231 but using the scheduler entrypoint for IP, and a separate stack
232 for SP.
233 */
do_clone(ThreadId ptid,UInt flags,Addr sp,Int * parent_tidptr,Int * child_tidptr,Addr child_tls)234 static SysRes do_clone ( ThreadId ptid,
235 UInt flags, Addr sp,
236 Int *parent_tidptr,
237 Int *child_tidptr,
238 Addr child_tls)
239 {
240 const Bool debug = False;
241
242 ThreadId ctid = VG_(alloc_ThreadState)();
243 ThreadState* ptst = VG_(get_ThreadState)(ptid);
244 ThreadState* ctst = VG_(get_ThreadState)(ctid);
245 ULong word64;
246 UWord* stack;
247 NSegment const* seg;
248 SysRes res;
249 vki_sigset_t blockall, savedmask;
250
251 VG_(sigfillset)(&blockall);
252
253 vg_assert(VG_(is_running_thread)(ptid));
254 vg_assert(VG_(is_valid_tid)(ctid));
255
256 stack = (UWord*)ML_(allocstack)(ctid);
257 if (stack == NULL) {
258 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
259 goto out;
260 }
261
262 //? /* make a stack frame */
263 //? stack -= 16;
264 //? *(UWord *)stack = 0;
265
266
267 /* Copy register state
268
269 Both parent and child return to the same place, and the code
270 following the clone syscall works out which is which, so we
271 don't need to worry about it.
272
273 The parent gets the child's new tid returned from clone, but the
274 child gets 0.
275
276 If the clone call specifies a NULL SP for the new thread, then
277 it actually gets a copy of the parent's SP.
278
279 The child's TLS register (r2) gets set to the tlsaddr argument
280 if the CLONE_SETTLS flag is set.
281 */
282 setup_child( &ctst->arch, &ptst->arch );
283
284 /* Make sys_clone appear to have returned Success(0) in the
285 child. */
286 { UInt old_cr = LibVEX_GuestPPC32_get_CR( &ctst->arch.vex );
287 /* %r3 = 0 */
288 ctst->arch.vex.guest_GPR3 = 0;
289 /* %cr0.so = 0 */
290 LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), &ctst->arch.vex );
291 }
292
293 if (sp != 0)
294 ctst->arch.vex.guest_GPR1 = sp;
295
296 ctst->os_state.parent = ptid;
297
298 /* inherit signal mask */
299 ctst->sig_mask = ptst->sig_mask;
300 ctst->tmp_sig_mask = ptst->sig_mask;
301
302 /* Start the child with its threadgroup being the same as the
303 parent's. This is so that any exit_group calls that happen
304 after the child is created but before it sets its
305 os_state.threadgroup field for real (in thread_wrapper in
306 syswrap-linux.c), really kill the new thread. a.k.a this avoids
307 a race condition in which the thread is unkillable (via
308 exit_group) because its threadgroup is not set. The race window
309 is probably only a few hundred or a few thousand cycles long.
310 See #226116. */
311 ctst->os_state.threadgroup = ptst->os_state.threadgroup;
312
313 /* We don't really know where the client stack is, because its
314 allocated by the client. The best we can do is look at the
315 memory mappings and try to derive some useful information. We
316 assume that esp starts near its highest possible value, and can
317 only go down to the start of the mmaped segment. */
318 seg = VG_(am_find_nsegment)(sp);
319 if (seg && seg->kind != SkResvn) {
320 ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(sp);
321 ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
322
323 VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
324
325 if (debug)
326 VG_(printf)("\ntid %d: guessed client stack range %#lx-%#lx\n",
327 ctid, seg->start, VG_PGROUNDUP(sp));
328 } else {
329 VG_(message)(Vg_UserMsg,
330 "!? New thread %d starts with R1(%#lx) unmapped\n",
331 ctid, sp);
332 ctst->client_stack_szB = 0;
333 }
334
335 /* Assume the clone will succeed, and tell any tool that wants to
336 know that this thread has come into existence. If the clone
337 fails, we'll send out a ll_exit notification for it at the out:
338 label below, to clean up. */
339 vg_assert(VG_(owns_BigLock_LL)(ptid));
340 VG_TRACK ( pre_thread_ll_create, ptid, ctid );
341
342 if (flags & VKI_CLONE_SETTLS) {
343 if (debug)
344 VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls);
345 ctst->arch.vex.guest_GPR2 = child_tls;
346 }
347
348 flags &= ~VKI_CLONE_SETTLS;
349
350 /* start the thread with everything blocked */
351 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
352
353 /* Create the new thread */
354 word64 = do_syscall_clone_ppc32_linux(
355 ML_(start_thread_NORETURN), stack, flags, &VG_(threads)[ctid],
356 child_tidptr, parent_tidptr, NULL
357 );
358 /* High half word64 is syscall return value. Low half is
359 the entire CR, from which we need to extract CR0.SO. */
360 /* VG_(printf)("word64 = 0x%llx\n", word64); */
361 res = VG_(mk_SysRes_ppc32_linux)(
362 /*val*/(UInt)(word64 >> 32),
363 /*errflag*/ (((UInt)word64) >> 28) & 1
364 );
365
366 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
367
368 out:
369 if (sr_isError(res)) {
370 /* clone failed */
371 VG_(cleanup_thread)(&ctst->arch);
372 ctst->status = VgTs_Empty;
373 /* oops. Better tell the tool the thread exited in a hurry :-) */
374 VG_TRACK( pre_thread_ll_exit, ctid );
375 }
376
377 return res;
378 }
379
380
381
382 /* ---------------------------------------------------------------------
383 More thread stuff
384 ------------------------------------------------------------------ */
385
VG_(cleanup_thread)386 void VG_(cleanup_thread) ( ThreadArchState* arch )
387 {
388 }
389
setup_child(ThreadArchState * child,ThreadArchState * parent)390 void setup_child ( /*OUT*/ ThreadArchState *child,
391 /*IN*/ ThreadArchState *parent )
392 {
393 /* We inherit our parent's guest state. */
394 child->vex = parent->vex;
395 child->vex_shadow1 = parent->vex_shadow1;
396 child->vex_shadow2 = parent->vex_shadow2;
397 }
398
399
400 /* ---------------------------------------------------------------------
401 PRE/POST wrappers for ppc32/Linux-specific syscalls
402 ------------------------------------------------------------------ */
403
404 #define PRE(name) DEFN_PRE_TEMPLATE(ppc32_linux, name)
405 #define POST(name) DEFN_POST_TEMPLATE(ppc32_linux, name)
406
407 /* Add prototypes for the wrappers declared here, so that gcc doesn't
408 harass us for not having prototypes. Really this is a kludge --
409 the right thing to do is to make these wrappers 'static' since they
410 aren't visible outside this file, but that requires even more macro
411 magic. */
412
413 DECL_TEMPLATE(ppc32_linux, sys_mmap);
414 DECL_TEMPLATE(ppc32_linux, sys_mmap2);
415 DECL_TEMPLATE(ppc32_linux, sys_stat64);
416 DECL_TEMPLATE(ppc32_linux, sys_lstat64);
417 DECL_TEMPLATE(ppc32_linux, sys_fstatat64);
418 DECL_TEMPLATE(ppc32_linux, sys_fstat64);
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_sigsuspend);
423 DECL_TEMPLATE(ppc32_linux, sys_spu_create);
424 DECL_TEMPLATE(ppc32_linux, sys_spu_run);
425
PRE(sys_mmap)426 PRE(sys_mmap)
427 {
428 SysRes r;
429
430 PRINT("sys_mmap ( %#lx, %llu, %ld, %ld, %ld, %ld )",
431 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
432 PRE_REG_READ6(long, "mmap",
433 unsigned long, start, unsigned long, length,
434 unsigned long, prot, unsigned long, flags,
435 unsigned long, fd, unsigned long, offset);
436
437 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
438 (Off64T)ARG6 );
439 SET_STATUS_from_SysRes(r);
440 }
441
PRE(sys_mmap2)442 PRE(sys_mmap2)
443 {
444 SysRes r;
445
446 // Exactly like old_mmap() except:
447 // - the file offset is specified in 4K units rather than bytes,
448 // so that it can be used for files bigger than 2^32 bytes.
449 PRINT("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )",
450 ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
451 PRE_REG_READ6(long, "mmap2",
452 unsigned long, start, unsigned long, length,
453 unsigned long, prot, unsigned long, flags,
454 unsigned long, fd, unsigned long, offset);
455
456 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
457 4096 * (Off64T)ARG6 );
458 SET_STATUS_from_SysRes(r);
459 }
460
461 // XXX: lstat64/fstat64/stat64 are generic, but not necessarily
462 // applicable to every architecture -- I think only to 32-bit archs.
463 // We're going to need something like linux/core_os32.h for such
464 // things, eventually, I think. --njn
PRE(sys_stat64)465 PRE(sys_stat64)
466 {
467 PRINT("sys_stat64 ( %#lx, %#lx )",ARG1,ARG2);
468 PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
469 PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
470 PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
471 }
472
POST(sys_stat64)473 POST(sys_stat64)
474 {
475 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
476 }
477
PRE(sys_lstat64)478 PRE(sys_lstat64)
479 {
480 PRINT("sys_lstat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2);
481 PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
482 PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
483 PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
484 }
485
POST(sys_lstat64)486 POST(sys_lstat64)
487 {
488 vg_assert(SUCCESS);
489 if (RES == 0) {
490 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
491 }
492 }
493
PRE(sys_fstatat64)494 PRE(sys_fstatat64)
495 {
496 PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )",ARG1,ARG2,(char*)ARG2,ARG3);
497 PRE_REG_READ3(long, "fstatat64",
498 int, dfd, char *, file_name, struct stat64 *, buf);
499 PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 );
500 PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) );
501 }
502
POST(sys_fstatat64)503 POST(sys_fstatat64)
504 {
505 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) );
506 }
507
PRE(sys_fstat64)508 PRE(sys_fstat64)
509 {
510 PRINT("sys_fstat64 ( %ld, %#lx )",ARG1,ARG2);
511 PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
512 PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
513 }
514
POST(sys_fstat64)515 POST(sys_fstat64)
516 {
517 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
518 }
519
520
521
522 //.. PRE(old_select, MayBlock)
523 //.. {
524 //.. /* struct sel_arg_struct {
525 //.. unsigned long n;
526 //.. fd_set *inp, *outp, *exp;
527 //.. struct timeval *tvp;
528 //.. };
529 //.. */
530 //.. PRE_REG_READ1(long, "old_select", struct sel_arg_struct *, args);
531 //.. PRE_MEM_READ( "old_select(args)", ARG1, 5*sizeof(UWord) );
532 //..
533 //.. {
534 //.. UInt* arg_struct = (UInt*)ARG1;
535 //.. UInt a1, a2, a3, a4, a5;
536 //..
537 //.. a1 = arg_struct[0];
538 //.. a2 = arg_struct[1];
539 //.. a3 = arg_struct[2];
540 //.. a4 = arg_struct[3];
541 //.. a5 = arg_struct[4];
542 //..
543 //.. PRINT("old_select ( %d, %p, %p, %p, %p )", a1,a2,a3,a4,a5);
544 //.. if (a2 != (Addr)NULL)
545 //.. PRE_MEM_READ( "old_select(readfds)", a2, a1/8 /* __FD_SETSIZE/8 */ );
546 //.. if (a3 != (Addr)NULL)
547 //.. PRE_MEM_READ( "old_select(writefds)", a3, a1/8 /* __FD_SETSIZE/8 */ );
548 //.. if (a4 != (Addr)NULL)
549 //.. PRE_MEM_READ( "old_select(exceptfds)", a4, a1/8 /* __FD_SETSIZE/8 */ );
550 //.. if (a5 != (Addr)NULL)
551 //.. PRE_MEM_READ( "old_select(timeout)", a5, sizeof(struct vki_timeval) );
552 //.. }
553 //.. }
554
PRE(sys_clone)555 PRE(sys_clone)
556 {
557 UInt cloneflags;
558
559 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4,ARG5);
560 PRE_REG_READ5(int, "clone",
561 unsigned long, flags,
562 void *, child_stack,
563 int *, parent_tidptr,
564 void *, child_tls,
565 int *, child_tidptr);
566
567 if (ARG1 & VKI_CLONE_PARENT_SETTID) {
568 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
569 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
570 VKI_PROT_WRITE)) {
571 SET_STATUS_Failure( VKI_EFAULT );
572 return;
573 }
574 }
575 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
576 PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
577 if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int),
578 VKI_PROT_WRITE)) {
579 SET_STATUS_Failure( VKI_EFAULT );
580 return;
581 }
582 }
583
584 cloneflags = ARG1;
585
586 if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
587 SET_STATUS_Failure( VKI_EINVAL );
588 return;
589 }
590
591 /* Only look at the flags we really care about */
592 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
593 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
594 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
595 /* thread creation */
596 SET_STATUS_from_SysRes(
597 do_clone(tid,
598 ARG1, /* flags */
599 (Addr)ARG2, /* child SP */
600 (Int *)ARG3, /* parent_tidptr */
601 (Int *)ARG5, /* child_tidptr */
602 (Addr)ARG4)); /* child_tls */
603 break;
604
605 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
606 /* FALLTHROUGH - assume vfork == fork */
607 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
608
609 case 0: /* plain fork */
610 SET_STATUS_from_SysRes(
611 ML_(do_fork_clone)(tid,
612 cloneflags, /* flags */
613 (Int *)ARG3, /* parent_tidptr */
614 (Int *)ARG5)); /* child_tidptr */
615 break;
616
617 default:
618 /* should we just ENOSYS? */
619 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
620 VG_(message)(Vg_UserMsg, "\n");
621 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
622 VG_(message)(Vg_UserMsg, " - via a threads library (LinuxThreads or NPTL)\n");
623 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork\n");
624 VG_(unimplemented)
625 ("Valgrind does not support general clone().");
626 }
627
628 if (SUCCESS) {
629 if (ARG1 & VKI_CLONE_PARENT_SETTID)
630 POST_MEM_WRITE(ARG3, sizeof(Int));
631 if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
632 POST_MEM_WRITE(ARG5, sizeof(Int));
633
634 /* Thread creation was successful; let the child have the chance
635 to run */
636 *flags |= SfYieldAfter;
637 }
638 }
639
PRE(sys_sigreturn)640 PRE(sys_sigreturn)
641 {
642 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
643 an explanation of what follows. */
644
645 //ThreadState* tst;
646 PRINT("sys_sigreturn ( )");
647
648 vg_assert(VG_(is_valid_tid)(tid));
649 vg_assert(tid >= 1 && tid < VG_N_THREADS);
650 vg_assert(VG_(is_running_thread)(tid));
651
652 ///* Adjust esp to point to start of frame; skip back up over
653 // sigreturn sequence's "popl %eax" and handler ret addr */
654 //tst = VG_(get_ThreadState)(tid);
655 //tst->arch.vex.guest_ESP -= sizeof(Addr)+sizeof(Word);
656 // Should we do something equivalent on ppc32? Who knows.
657
658 ///* This is only so that the EIP is (might be) useful to report if
659 // something goes wrong in the sigreturn */
660 //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
661 // Should we do something equivalent on ppc32? Who knows.
662
663 /* Restore register state from frame and remove it */
664 VG_(sigframe_destroy)(tid, False);
665
666 /* Tell the driver not to update the guest state with the "result",
667 and set a bogus result to keep it happy. */
668 *flags |= SfNoWriteResult;
669 SET_STATUS_Success(0);
670
671 /* Check to see if any signals arose as a result of this. */
672 *flags |= SfPollAfter;
673 }
674
PRE(sys_rt_sigreturn)675 PRE(sys_rt_sigreturn)
676 {
677 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
678 an explanation of what follows. */
679
680 //ThreadState* tst;
681 PRINT("rt_sigreturn ( )");
682
683 vg_assert(VG_(is_valid_tid)(tid));
684 vg_assert(tid >= 1 && tid < VG_N_THREADS);
685 vg_assert(VG_(is_running_thread)(tid));
686
687 ///* Adjust esp to point to start of frame; skip back up over handler
688 // ret addr */
689 //tst = VG_(get_ThreadState)(tid);
690 //tst->arch.vex.guest_ESP -= sizeof(Addr);
691 // Should we do something equivalent on ppc32? Who knows.
692
693 ///* This is only so that the EIP is (might be) useful to report if
694 // something goes wrong in the sigreturn */
695 //ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
696 // Should we do something equivalent on ppc32? Who knows.
697
698 /* Restore register state from frame and remove it */
699 VG_(sigframe_destroy)(tid, True);
700
701 /* Tell the driver not to update the guest state with the "result",
702 and set a bogus result to keep it happy. */
703 *flags |= SfNoWriteResult;
704 SET_STATUS_Success(0);
705
706 /* Check to see if any signals arose as a result of this. */
707 *flags |= SfPollAfter;
708 }
709
710
711 //.. PRE(sys_modify_ldt, Special)
712 //.. {
713 //.. PRINT("sys_modify_ldt ( %d, %p, %d )", ARG1,ARG2,ARG3);
714 //.. PRE_REG_READ3(int, "modify_ldt", int, func, void *, ptr,
715 //.. unsigned long, bytecount);
716 //..
717 //.. if (ARG1 == 0) {
718 //.. /* read the LDT into ptr */
719 //.. PRE_MEM_WRITE( "modify_ldt(ptr)", ARG2, ARG3 );
720 //.. }
721 //.. if (ARG1 == 1 || ARG1 == 0x11) {
722 //.. /* write the LDT with the entry pointed at by ptr */
723 //.. PRE_MEM_READ( "modify_ldt(ptr)", ARG2, sizeof(vki_modify_ldt_t) );
724 //.. }
725 //.. /* "do" the syscall ourselves; the kernel never sees it */
726 //.. SET_RESULT( VG_(sys_modify_ldt)( tid, ARG1, (void*)ARG2, ARG3 ) );
727 //..
728 //.. if (ARG1 == 0 && !VG_(is_kerror)(RES) && RES > 0) {
729 //.. POST_MEM_WRITE( ARG2, RES );
730 //.. }
731 //.. }
732
733 //.. PRE(sys_set_thread_area, Special)
734 //.. {
735 //.. PRINT("sys_set_thread_area ( %p )", ARG1);
736 //.. PRE_REG_READ1(int, "set_thread_area", struct user_desc *, u_info)
737 //.. PRE_MEM_READ( "set_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
738 //..
739 //.. /* "do" the syscall ourselves; the kernel never sees it */
740 //.. SET_RESULT( VG_(sys_set_thread_area)( tid, (void *)ARG1 ) );
741 //.. }
742
743 //.. PRE(sys_get_thread_area, Special)
744 //.. {
745 //.. PRINT("sys_get_thread_area ( %p )", ARG1);
746 //.. PRE_REG_READ1(int, "get_thread_area", struct user_desc *, u_info)
747 //.. PRE_MEM_WRITE( "get_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
748 //..
749 //.. /* "do" the syscall ourselves; the kernel never sees it */
750 //.. SET_RESULT( VG_(sys_get_thread_area)( tid, (void *)ARG1 ) );
751 //..
752 //.. if (!VG_(is_kerror)(RES)) {
753 //.. POST_MEM_WRITE( ARG1, sizeof(vki_modify_ldt_t) );
754 //.. }
755 //.. }
756
757 //.. // Parts of this are ppc32-specific, but the *PEEK* cases are generic.
758 //.. // XXX: Why is the memory pointed to by ARG3 never checked?
759 //.. PRE(sys_ptrace, 0)
760 //.. {
761 //.. PRINT("sys_ptrace ( %d, %d, %p, %p )", ARG1,ARG2,ARG3,ARG4);
762 //.. PRE_REG_READ4(int, "ptrace",
763 //.. long, request, long, pid, long, addr, long, data);
764 //.. switch (ARG1) {
765 //.. case VKI_PTRACE_PEEKTEXT:
766 //.. case VKI_PTRACE_PEEKDATA:
767 //.. case VKI_PTRACE_PEEKUSR:
768 //.. PRE_MEM_WRITE( "ptrace(peek)", ARG4,
769 //.. sizeof (long));
770 //.. break;
771 //.. case VKI_PTRACE_GETREGS:
772 //.. PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
773 //.. sizeof (struct vki_user_regs_struct));
774 //.. break;
775 //.. case VKI_PTRACE_GETFPREGS:
776 //.. PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
777 //.. sizeof (struct vki_user_i387_struct));
778 //.. break;
779 //.. case VKI_PTRACE_GETFPXREGS:
780 //.. PRE_MEM_WRITE( "ptrace(getfpxregs)", ARG4,
781 //.. sizeof(struct vki_user_fxsr_struct) );
782 //.. break;
783 //.. case VKI_PTRACE_SETREGS:
784 //.. PRE_MEM_READ( "ptrace(setregs)", ARG4,
785 //.. sizeof (struct vki_user_regs_struct));
786 //.. break;
787 //.. case VKI_PTRACE_SETFPREGS:
788 //.. PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
789 //.. sizeof (struct vki_user_i387_struct));
790 //.. break;
791 //.. case VKI_PTRACE_SETFPXREGS:
792 //.. PRE_MEM_READ( "ptrace(setfpxregs)", ARG4,
793 //.. sizeof(struct vki_user_fxsr_struct) );
794 //.. break;
795 //.. default:
796 //.. break;
797 //.. }
798 //.. }
799
800 //.. POST(sys_ptrace)
801 //.. {
802 //.. switch (ARG1) {
803 //.. case VKI_PTRACE_PEEKTEXT:
804 //.. case VKI_PTRACE_PEEKDATA:
805 //.. case VKI_PTRACE_PEEKUSR:
806 //.. POST_MEM_WRITE( ARG4, sizeof (long));
807 //.. break;
808 //.. case VKI_PTRACE_GETREGS:
809 //.. POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
810 //.. break;
811 //.. case VKI_PTRACE_GETFPREGS:
812 //.. POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
813 //.. break;
814 //.. case VKI_PTRACE_GETFPXREGS:
815 //.. POST_MEM_WRITE( ARG4, sizeof(struct vki_user_fxsr_struct) );
816 //.. break;
817 //.. default:
818 //.. break;
819 //.. }
820 //.. }
821
822 /* NB: This is an almost identical clone of versions for x86-linux and
823 arm-linux, which are themselves literally identical. */
PRE(sys_sigsuspend)824 PRE(sys_sigsuspend)
825 {
826 /* The C library interface to sigsuspend just takes a pointer to
827 a signal mask but this system call only takes the first word of
828 the signal mask as an argument so only 32 signals are supported.
829
830 In fact glibc normally uses rt_sigsuspend if it is available as
831 that takes a pointer to the signal mask so supports more signals.
832 */
833 *flags |= SfMayBlock;
834 PRINT("sys_sigsuspend ( %ld )", ARG1 );
835 PRE_REG_READ1(int, "sigsuspend", vki_old_sigset_t, mask);
836 }
837
PRE(sys_spu_create)838 PRE(sys_spu_create)
839 {
840 PRE_MEM_RASCIIZ("stat64(filename)", ARG1);
841 }
POST(sys_spu_create)842 POST(sys_spu_create)
843 {
844 vg_assert(SUCCESS);
845 }
846
PRE(sys_spu_run)847 PRE(sys_spu_run)
848 {
849 *flags |= SfMayBlock;
850 if (ARG2 != 0)
851 PRE_MEM_WRITE("npc", ARG2, sizeof(unsigned int));
852 PRE_MEM_READ("event", ARG3, sizeof(unsigned int));
853 }
POST(sys_spu_run)854 POST(sys_spu_run)
855 {
856 if (ARG2 != 0)
857 POST_MEM_WRITE(ARG2, sizeof(unsigned int));
858 }
859
860 #undef PRE
861 #undef POST
862
863 /* ---------------------------------------------------------------------
864 The ppc32/Linux syscall table
865 ------------------------------------------------------------------ */
866
867 /* Add an ppc32-linux specific wrapper to a syscall table. */
868 #define PLAX_(sysno, name) WRAPPER_ENTRY_X_(ppc32_linux, sysno, name)
869 #define PLAXY(sysno, name) WRAPPER_ENTRY_XY(ppc32_linux, sysno, name)
870
871 // This table maps from __NR_xxx syscall numbers (from
872 // linux/include/asm-ppc/unistd.h) to the appropriate PRE/POST sys_foo()
873 // wrappers on ppc32 (as per sys_call_table in linux/arch/ppc/kernel/entry.S).
874 //
875 // For those syscalls not handled by Valgrind, the annotation indicate its
876 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
877 // (unknown).
878
879 static SyscallTableEntry syscall_table[] = {
880 //.. (restart_syscall) // 0
881 GENX_(__NR_exit, sys_exit), // 1
882 GENX_(__NR_fork, sys_fork), // 2
883 GENXY(__NR_read, sys_read), // 3
884 GENX_(__NR_write, sys_write), // 4
885
886 GENXY(__NR_open, sys_open), // 5
887 GENXY(__NR_close, sys_close), // 6
888 GENXY(__NR_waitpid, sys_waitpid), // 7
889 GENXY(__NR_creat, sys_creat), // 8
890 GENX_(__NR_link, sys_link), // 9
891
892 GENX_(__NR_unlink, sys_unlink), // 10
893 GENX_(__NR_execve, sys_execve), // 11
894 GENX_(__NR_chdir, sys_chdir), // 12
895 GENXY(__NR_time, sys_time), // 13
896 GENX_(__NR_mknod, sys_mknod), // 14
897 //..
898 GENX_(__NR_chmod, sys_chmod), // 15
899 GENX_(__NR_lchown, sys_lchown), // 16 ## P
900 //.. GENX_(__NR_break, sys_ni_syscall), // 17
901 //.. // (__NR_oldstat, sys_stat), // 18 (obsolete)
902 LINX_(__NR_lseek, sys_lseek), // 19
903 //..
904 GENX_(__NR_getpid, sys_getpid), // 20
905 LINX_(__NR_mount, sys_mount), // 21
906 LINX_(__NR_umount, sys_oldumount), // 22
907 GENX_(__NR_setuid, sys_setuid), // 23 ## P
908 GENX_(__NR_getuid, sys_getuid), // 24 ## P
909 //..
910 //.. // (__NR_stime, sys_stime), // 25 * (SVr4,SVID,X/OPEN)
911 //.. PLAXY(__NR_ptrace, sys_ptrace), // 26
912 GENX_(__NR_alarm, sys_alarm), // 27
913 //.. // (__NR_oldfstat, sys_fstat), // 28 * L -- obsolete
914 GENX_(__NR_pause, sys_pause), // 29
915 //..
916 LINX_(__NR_utime, sys_utime), // 30
917 //.. GENX_(__NR_stty, sys_ni_syscall), // 31
918 //.. GENX_(__NR_gtty, sys_ni_syscall), // 32
919 GENX_(__NR_access, sys_access), // 33
920 //.. GENX_(__NR_nice, sys_nice), // 34
921 //..
922 //.. GENX_(__NR_ftime, sys_ni_syscall), // 35
923 //.. GENX_(__NR_sync, sys_sync), // 36
924 GENX_(__NR_kill, sys_kill), // 37
925 GENX_(__NR_rename, sys_rename), // 38
926 GENX_(__NR_mkdir, sys_mkdir), // 39
927
928 GENX_(__NR_rmdir, sys_rmdir), // 40
929 GENXY(__NR_dup, sys_dup), // 41
930 LINXY(__NR_pipe, sys_pipe), // 42
931 GENXY(__NR_times, sys_times), // 43
932 //.. GENX_(__NR_prof, sys_ni_syscall), // 44
933 //..
934 GENX_(__NR_brk, sys_brk), // 45
935 GENX_(__NR_setgid, sys_setgid), // 46
936 GENX_(__NR_getgid, sys_getgid), // 47
937 //.. // (__NR_signal, sys_signal), // 48 */* (ANSI C)
938 GENX_(__NR_geteuid, sys_geteuid), // 49
939
940 GENX_(__NR_getegid, sys_getegid), // 50
941 //.. GENX_(__NR_acct, sys_acct), // 51
942 LINX_(__NR_umount2, sys_umount), // 52
943 //.. GENX_(__NR_lock, sys_ni_syscall), // 53
944 LINXY(__NR_ioctl, sys_ioctl), // 54
945 //..
946 LINXY(__NR_fcntl, sys_fcntl), // 55
947 //.. GENX_(__NR_mpx, sys_ni_syscall), // 56
948 GENX_(__NR_setpgid, sys_setpgid), // 57
949 //.. GENX_(__NR_ulimit, sys_ni_syscall), // 58
950 //.. // (__NR_oldolduname, sys_olduname), // 59 Linux -- obsolete
951
952 GENX_(__NR_umask, sys_umask), // 60
953 GENX_(__NR_chroot, sys_chroot), // 61
954 //.. // (__NR_ustat, sys_ustat) // 62 SVr4 -- deprecated
955 GENXY(__NR_dup2, sys_dup2), // 63
956 GENX_(__NR_getppid, sys_getppid), // 64
957
958 GENX_(__NR_getpgrp, sys_getpgrp), // 65
959 GENX_(__NR_setsid, sys_setsid), // 66
960 LINXY(__NR_sigaction, sys_sigaction), // 67
961 //.. // (__NR_sgetmask, sys_sgetmask), // 68 */* (ANSI C)
962 //.. // (__NR_ssetmask, sys_ssetmask), // 69 */* (ANSI C)
963 //..
964 GENX_(__NR_setreuid, sys_setreuid), // 70
965 GENX_(__NR_setregid, sys_setregid), // 71
966 PLAX_(__NR_sigsuspend, sys_sigsuspend), // 72
967 LINXY(__NR_sigpending, sys_sigpending), // 73
968 //.. // (__NR_sethostname, sys_sethostname), // 74 */*
969 //..
970 GENX_(__NR_setrlimit, sys_setrlimit), // 75
971 //.. GENXY(__NR_getrlimit, sys_old_getrlimit), // 76
972 GENXY(__NR_getrusage, sys_getrusage), // 77
973 GENXY(__NR_gettimeofday, sys_gettimeofday), // 78
974 //.. GENX_(__NR_settimeofday, sys_settimeofday), // 79
975 //..
976 GENXY(__NR_getgroups, sys_getgroups), // 80
977 GENX_(__NR_setgroups, sys_setgroups), // 81
978 //.. PLAX_(__NR_select, old_select), // 82
979 GENX_(__NR_symlink, sys_symlink), // 83
980 //.. // (__NR_oldlstat, sys_lstat), // 84 -- obsolete
981 //..
982 GENX_(__NR_readlink, sys_readlink), // 85
983 //.. // (__NR_uselib, sys_uselib), // 86 */Linux
984 //.. // (__NR_swapon, sys_swapon), // 87 */Linux
985 //.. // (__NR_reboot, sys_reboot), // 88 */Linux
986 //.. // (__NR_readdir, old_readdir), // 89 -- superseded
987
988 PLAX_(__NR_mmap, sys_mmap), // 90
989 GENXY(__NR_munmap, sys_munmap), // 91
990 GENX_(__NR_truncate, sys_truncate), // 92
991 GENX_(__NR_ftruncate, sys_ftruncate), // 93
992 GENX_(__NR_fchmod, sys_fchmod), // 94
993
994 GENX_(__NR_fchown, sys_fchown), // 95
995 GENX_(__NR_getpriority, sys_getpriority), // 96
996 GENX_(__NR_setpriority, sys_setpriority), // 97
997 //.. GENX_(__NR_profil, sys_ni_syscall), // 98
998 GENXY(__NR_statfs, sys_statfs), // 99
999 //..
1000 GENXY(__NR_fstatfs, sys_fstatfs), // 100
1001 //.. LINX_(__NR_ioperm, sys_ioperm), // 101
1002 LINXY(__NR_socketcall, sys_socketcall), // 102
1003 LINXY(__NR_syslog, sys_syslog), // 103
1004 GENXY(__NR_setitimer, sys_setitimer), // 104
1005
1006 GENXY(__NR_getitimer, sys_getitimer), // 105
1007 GENXY(__NR_stat, sys_newstat), // 106
1008 GENXY(__NR_lstat, sys_newlstat), // 107
1009 GENXY(__NR_fstat, sys_newfstat), // 108
1010 //.. // (__NR_olduname, sys_uname), // 109 -- obsolete
1011 //..
1012 //.. GENX_(__NR_iopl, sys_iopl), // 110
1013 LINX_(__NR_vhangup, sys_vhangup), // 111
1014 //.. GENX_(__NR_idle, sys_ni_syscall), // 112
1015 //.. // (__NR_vm86old, sys_vm86old), // 113 x86/Linux-only
1016 GENXY(__NR_wait4, sys_wait4), // 114
1017 //..
1018 //.. // (__NR_swapoff, sys_swapoff), // 115 */Linux
1019 LINXY(__NR_sysinfo, sys_sysinfo), // 116
1020 LINXY(__NR_ipc, sys_ipc), // 117
1021 GENX_(__NR_fsync, sys_fsync), // 118
1022 PLAX_(__NR_sigreturn, sys_sigreturn), // 119 ?/Linux
1023 //..
1024 PLAX_(__NR_clone, sys_clone), // 120
1025 //.. // (__NR_setdomainname, sys_setdomainname), // 121 */*(?)
1026 GENXY(__NR_uname, sys_newuname), // 122
1027 //.. PLAX_(__NR_modify_ldt, sys_modify_ldt), // 123
1028 LINXY(__NR_adjtimex, sys_adjtimex), // 124
1029
1030 GENXY(__NR_mprotect, sys_mprotect), // 125
1031 LINXY(__NR_sigprocmask, sys_sigprocmask), // 126
1032 GENX_(__NR_create_module, sys_ni_syscall), // 127
1033 LINX_(__NR_init_module, sys_init_module), // 128
1034 LINX_(__NR_delete_module, sys_delete_module), // 129
1035 //..
1036 //.. // Nb: get_kernel_syms() was removed 2.4-->2.6
1037 //.. GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130
1038 //.. LINX_(__NR_quotactl, sys_quotactl), // 131
1039 GENX_(__NR_getpgid, sys_getpgid), // 132
1040 GENX_(__NR_fchdir, sys_fchdir), // 133
1041 //.. // (__NR_bdflush, sys_bdflush), // 134 */Linux
1042 //..
1043 //.. // (__NR_sysfs, sys_sysfs), // 135 SVr4
1044 LINX_(__NR_personality, sys_personality), // 136
1045 //.. GENX_(__NR_afs_syscall, sys_ni_syscall), // 137
1046 LINX_(__NR_setfsuid, sys_setfsuid), // 138
1047 LINX_(__NR_setfsgid, sys_setfsgid), // 139
1048
1049 LINXY(__NR__llseek, sys_llseek), // 140
1050 GENXY(__NR_getdents, sys_getdents), // 141
1051 GENX_(__NR__newselect, sys_select), // 142
1052 GENX_(__NR_flock, sys_flock), // 143
1053 GENX_(__NR_msync, sys_msync), // 144
1054 //..
1055 GENXY(__NR_readv, sys_readv), // 145
1056 GENX_(__NR_writev, sys_writev), // 146
1057 GENX_(__NR_getsid, sys_getsid), // 147
1058 GENX_(__NR_fdatasync, sys_fdatasync), // 148
1059 LINXY(__NR__sysctl, sys_sysctl), // 149
1060 //..
1061 GENX_(__NR_mlock, sys_mlock), // 150
1062 GENX_(__NR_munlock, sys_munlock), // 151
1063 GENX_(__NR_mlockall, sys_mlockall), // 152
1064 LINX_(__NR_munlockall, sys_munlockall), // 153
1065 LINXY(__NR_sched_setparam, sys_sched_setparam), // 154
1066 //..
1067 LINXY(__NR_sched_getparam, sys_sched_getparam), // 155
1068 LINX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 156
1069 LINX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 157
1070 LINX_(__NR_sched_yield, sys_sched_yield), // 158
1071 LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
1072
1073 LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
1074 LINXY(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 161
1075 GENXY(__NR_nanosleep, sys_nanosleep), // 162
1076 GENX_(__NR_mremap, sys_mremap), // 163
1077 LINX_(__NR_setresuid, sys_setresuid), // 164
1078
1079 LINXY(__NR_getresuid, sys_getresuid), // 165
1080
1081 //.. GENX_(__NR_query_module, sys_ni_syscall), // 166
1082 GENXY(__NR_poll, sys_poll), // 167
1083 //.. // (__NR_nfsservctl, sys_nfsservctl), // 168 */Linux
1084 //..
1085 LINX_(__NR_setresgid, sys_setresgid), // 169
1086 LINXY(__NR_getresgid, sys_getresgid), // 170
1087 LINXY(__NR_prctl, sys_prctl), // 171
1088 PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 172
1089 LINXY(__NR_rt_sigaction, sys_rt_sigaction), // 173
1090
1091 LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 174
1092 LINXY(__NR_rt_sigpending, sys_rt_sigpending), // 175
1093 LINXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait), // 176
1094 LINXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo), // 177
1095 LINX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 178
1096
1097 GENXY(__NR_pread64, sys_pread64), // 179
1098 GENX_(__NR_pwrite64, sys_pwrite64), // 180
1099 GENX_(__NR_chown, sys_chown), // 181
1100 GENXY(__NR_getcwd, sys_getcwd), // 182
1101 LINXY(__NR_capget, sys_capget), // 183
1102 LINX_(__NR_capset, sys_capset), // 184
1103 GENXY(__NR_sigaltstack, sys_sigaltstack), // 185
1104 LINXY(__NR_sendfile, sys_sendfile), // 186
1105 //.. GENXY(__NR_getpmsg, sys_getpmsg), // 187
1106 //.. GENX_(__NR_putpmsg, sys_putpmsg), // 188
1107
1108 // Nb: we treat vfork as fork
1109 GENX_(__NR_vfork, sys_fork), // 189
1110 GENXY(__NR_ugetrlimit, sys_getrlimit), // 190
1111 LINX_(__NR_readahead, sys_readahead), // 191 */Linux
1112 PLAX_(__NR_mmap2, sys_mmap2), // 192
1113 GENX_(__NR_truncate64, sys_truncate64), // 193
1114 GENX_(__NR_ftruncate64, sys_ftruncate64), // 194
1115 //..
1116
1117 PLAXY(__NR_stat64, sys_stat64), // 195
1118 PLAXY(__NR_lstat64, sys_lstat64), // 196
1119 PLAXY(__NR_fstat64, sys_fstat64), // 197
1120
1121 // __NR_pciconfig_read // 198
1122 // __NR_pciconfig_write // 199
1123 // __NR_pciconfig_iobase // 200
1124 // __NR_multiplexer // 201
1125
1126 GENXY(__NR_getdents64, sys_getdents64), // 202
1127 //.. // (__NR_pivot_root, sys_pivot_root), // 203 */Linux
1128 LINXY(__NR_fcntl64, sys_fcntl64), // 204
1129 GENX_(__NR_madvise, sys_madvise), // 205
1130 GENXY(__NR_mincore, sys_mincore), // 206
1131 LINX_(__NR_gettid, sys_gettid), // 207
1132 //.. LINX_(__NR_tkill, sys_tkill), // 208 */Linux
1133 LINX_(__NR_setxattr, sys_setxattr), // 209
1134 LINX_(__NR_lsetxattr, sys_lsetxattr), // 210
1135 LINX_(__NR_fsetxattr, sys_fsetxattr), // 211
1136 LINXY(__NR_getxattr, sys_getxattr), // 212
1137 LINXY(__NR_lgetxattr, sys_lgetxattr), // 213
1138 LINXY(__NR_fgetxattr, sys_fgetxattr), // 214
1139 LINXY(__NR_listxattr, sys_listxattr), // 215
1140 LINXY(__NR_llistxattr, sys_llistxattr), // 216
1141 LINXY(__NR_flistxattr, sys_flistxattr), // 217
1142 LINX_(__NR_removexattr, sys_removexattr), // 218
1143 LINX_(__NR_lremovexattr, sys_lremovexattr), // 219
1144 LINX_(__NR_fremovexattr, sys_fremovexattr), // 220
1145
1146 LINXY(__NR_futex, sys_futex), // 221
1147 LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 222
1148 LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 223
1149 /* 224 currently unused */
1150
1151 // __NR_tuxcall // 225
1152
1153 LINXY(__NR_sendfile64, sys_sendfile64), // 226
1154 //..
1155 LINX_(__NR_io_setup, sys_io_setup), // 227
1156 LINX_(__NR_io_destroy, sys_io_destroy), // 228
1157 LINXY(__NR_io_getevents, sys_io_getevents), // 229
1158 LINX_(__NR_io_submit, sys_io_submit), // 230
1159 LINXY(__NR_io_cancel, sys_io_cancel), // 231
1160 //..
1161 LINX_(__NR_set_tid_address, sys_set_tid_address), // 232
1162
1163 LINX_(__NR_fadvise64, sys_fadvise64), // 233 */(Linux?)
1164 LINX_(__NR_exit_group, sys_exit_group), // 234
1165 //.. GENXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 235
1166 LINXY(__NR_epoll_create, sys_epoll_create), // 236
1167 LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 237
1168 LINXY(__NR_epoll_wait, sys_epoll_wait), // 238
1169
1170 //.. // (__NR_remap_file_pages, sys_remap_file_pages), // 239 */Linux
1171 LINXY(__NR_timer_create, sys_timer_create), // 240
1172 LINXY(__NR_timer_settime, sys_timer_settime), // 241
1173 LINXY(__NR_timer_gettime, sys_timer_gettime), // 242
1174 LINX_(__NR_timer_getoverrun, sys_timer_getoverrun), // 243
1175 LINX_(__NR_timer_delete, sys_timer_delete), // 244
1176 LINX_(__NR_clock_settime, sys_clock_settime), // 245
1177 LINXY(__NR_clock_gettime, sys_clock_gettime), // 246
1178 LINXY(__NR_clock_getres, sys_clock_getres), // 247
1179 LINXY(__NR_clock_nanosleep, sys_clock_nanosleep), // 248
1180
1181 // __NR_swapcontext // 249
1182
1183 LINXY(__NR_tgkill, sys_tgkill), // 250 */Linux
1184 //.. GENX_(__NR_utimes, sys_utimes), // 251
1185 GENXY(__NR_statfs64, sys_statfs64), // 252
1186 GENXY(__NR_fstatfs64, sys_fstatfs64), // 253
1187 LINX_(__NR_fadvise64_64, sys_fadvise64_64), // 254 */(Linux?)
1188
1189 // __NR_rtas // 255
1190
1191 /* Number 256 is reserved for sys_debug_setcontext */
1192 /* Number 257 is reserved for vserver */
1193 /* Number 258 is reserved for new sys_remap_file_pages */
1194 LINX_(__NR_mbind, sys_mbind), // 259
1195 LINXY(__NR_get_mempolicy, sys_get_mempolicy), // 260
1196 LINX_(__NR_set_mempolicy, sys_set_mempolicy), // 261
1197
1198 LINXY(__NR_mq_open, sys_mq_open), // 262
1199 LINX_(__NR_mq_unlink, sys_mq_unlink), // 263
1200 LINX_(__NR_mq_timedsend, sys_mq_timedsend), // 264
1201 LINXY(__NR_mq_timedreceive, sys_mq_timedreceive), // 265
1202 LINX_(__NR_mq_notify, sys_mq_notify), // 266
1203 LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // 267
1204 // __NR_kexec_load // 268
1205
1206 /* Number 269 is reserved for sys_add_key */
1207 /* Number 270 is reserved for sys_request_key */
1208 /* Number 271 is reserved for sys_keyctl */
1209 /* Number 272 is reserved for sys_waitid */
1210 LINX_(__NR_ioprio_set, sys_ioprio_set), // 273
1211 LINX_(__NR_ioprio_get, sys_ioprio_get), // 274
1212
1213 LINX_(__NR_inotify_init, sys_inotify_init), // 275
1214 LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 276
1215 LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 277
1216 PLAXY(__NR_spu_run, sys_spu_run), // 278
1217 PLAX_(__NR_spu_create, sys_spu_create), // 279
1218
1219 LINX_(__NR_pselect6, sys_pselect6), // 280
1220 LINXY(__NR_ppoll, sys_ppoll), // 281
1221
1222 LINXY(__NR_openat, sys_openat), // 286
1223 LINX_(__NR_mkdirat, sys_mkdirat), // 287
1224 LINX_(__NR_mknodat, sys_mknodat), // 288
1225 LINX_(__NR_fchownat, sys_fchownat), // 289
1226 LINX_(__NR_futimesat, sys_futimesat), // 290
1227 PLAXY(__NR_fstatat64, sys_fstatat64), // 291
1228 LINX_(__NR_unlinkat, sys_unlinkat), // 292
1229 LINX_(__NR_renameat, sys_renameat), // 293
1230 LINX_(__NR_linkat, sys_linkat), // 294
1231 LINX_(__NR_symlinkat, sys_symlinkat), // 295
1232 LINX_(__NR_readlinkat, sys_readlinkat), // 296
1233 LINX_(__NR_fchmodat, sys_fchmodat), // 297
1234 LINX_(__NR_faccessat, sys_faccessat), // 298
1235 LINX_(__NR_set_robust_list, sys_set_robust_list), // 299
1236 LINXY(__NR_get_robust_list, sys_get_robust_list), // 300
1237 LINXY(__NR_move_pages, sys_move_pages), // 301
1238 LINXY(__NR_getcpu, sys_getcpu), // 302
1239 LINXY(__NR_epoll_pwait, sys_epoll_pwait), // 303
1240 LINX_(__NR_utimensat, sys_utimensat), // 304
1241 LINXY(__NR_signalfd, sys_signalfd), // 305
1242 LINXY(__NR_timerfd_create, sys_timerfd_create), // 306
1243 LINXY(__NR_eventfd, sys_eventfd), // 307
1244 LINX_(__NR_sync_file_range2, sys_sync_file_range2), // 308
1245 LINX_(__NR_fallocate, sys_fallocate), // 309
1246 // LINXY(__NR_subpage_prot, sys_ni_syscall), // 310
1247 LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 311
1248 LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 312
1249 LINXY(__NR_signalfd4, sys_signalfd4), // 313
1250 LINXY(__NR_eventfd2, sys_eventfd2), // 314
1251 LINXY(__NR_epoll_create1, sys_epoll_create1), // 315
1252 LINXY(__NR_dup3, sys_dup3), // 316
1253 LINXY(__NR_pipe2, sys_pipe2), // 317
1254 LINXY(__NR_inotify_init1, sys_inotify_init1), // 318
1255 LINXY(__NR_perf_event_open, sys_perf_event_open), // 319
1256 LINXY(__NR_preadv, sys_preadv), // 320
1257 LINX_(__NR_pwritev, sys_pwritev), // 321
1258 LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 322
1259
1260 LINX_(__NR_clock_adjtime, sys_clock_adjtime), // 347
1261
1262 LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 351
1263 LINX_(__NR_process_vm_writev, sys_process_vm_writev) // 352
1264 };
1265
ML_(get_linux_syscall_entry)1266 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1267 {
1268 const UInt syscall_table_size
1269 = sizeof(syscall_table) / sizeof(syscall_table[0]);
1270
1271 /* Is it in the contiguous initial section of the table? */
1272 if (sysno < syscall_table_size) {
1273 SyscallTableEntry* sys = &syscall_table[sysno];
1274 if (sys->before == NULL)
1275 return NULL; /* no entry */
1276 else
1277 return sys;
1278 }
1279
1280 /* Can't find a wrapper */
1281 return NULL;
1282 }
1283
1284 #endif // defined(VGP_ppc32_linux)
1285
1286 /*--------------------------------------------------------------------*/
1287 /*--- end ---*/
1288 /*--------------------------------------------------------------------*/
1289