1
2 /*--------------------------------------------------------------------*/
3 /*--- Platform-specific syscalls stuff. syswrap-s390x-linux.c ---*/
4 /*--------------------------------------------------------------------*/
5
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright IBM Corp. 2010-2012
11
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25 02111-1307, USA.
26
27 The GNU General Public License is contained in the file COPYING.
28 */
29
30 /* Contributed by Christian Borntraeger */
31
32 #if defined(VGP_s390x_linux)
33
34 #include "pub_core_basics.h"
35 #include "pub_core_vki.h"
36 #include "pub_core_vkiscnums.h"
37 #include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
38 #include "pub_core_threadstate.h"
39 #include "pub_core_aspacemgr.h"
40 #include "pub_core_debuglog.h"
41 #include "pub_core_libcbase.h"
42 #include "pub_core_libcassert.h"
43 #include "pub_core_libcprint.h"
44 #include "pub_core_libcproc.h"
45 #include "pub_core_libcsignal.h"
46 #include "pub_core_mallocfree.h"
47 #include "pub_core_options.h"
48 #include "pub_core_scheduler.h"
49 #include "pub_core_sigframe.h" // For VG_(sigframe_destroy)()
50 #include "pub_core_signals.h"
51 #include "pub_core_syscall.h"
52 #include "pub_core_syswrap.h"
53 #include "pub_core_tooliface.h"
54 #include "pub_core_stacks.h" // VG_(register_stack)
55
56 #include "priv_types_n_macros.h"
57 #include "priv_syswrap-generic.h" /* for decls of generic wrappers */
58 #include "priv_syswrap-linux.h" /* for decls of linux-ish wrappers */
59 #include "priv_syswrap-linux-variants.h" /* decls of linux variant wrappers */
60 #include "priv_syswrap-main.h"
61
62
63 /* ---------------------------------------------------------------------
64 clone() handling
65 ------------------------------------------------------------------ */
66
67 /* Call f(arg1), but first switch stacks, using 'stack' as the new
68 stack, and use 'retaddr' as f's return-to address. Also, clear all
69 the integer registers before entering f.
70 Thought: Why are we clearing the GPRs ? The callee pointed to by f
71 is a regular C function which will play by the ABI rules. So there is
72 no need to zero out the GPRs. If we assumed that f accesses registers at
73 will, then it would make sense to create a defined register state.
74 But then, why only for the GPRs and not the FPRs ? */
75 __attribute__((noreturn))
76 void ML_(call_on_new_stack_0_1) ( Addr stack,
77 Addr retaddr,
78 void (*f)(Word),
79 Word arg1 );
80 /* Upon entering this function we have the following setup:
81 r2 = stack
82 r3 = retaddr
83 r4 = f_desc
84 r5 = arg1
85 */
86 asm(
87 ".text\n"
88 ".align 4\n"
89 ".globl vgModuleLocal_call_on_new_stack_0_1\n"
90 ".type vgModuleLocal_call_on_new_stack_0_1, @function\n"
91 "vgModuleLocal_call_on_new_stack_0_1:\n"
92 " lgr %r15,%r2\n" // stack to r15
93 " lgr %r14,%r3\n" // retaddr to r14
94 " lgr %r2,%r5\n" // arg1 to r2
95 // zero all gprs to get a defined state
96 " lghi %r0,0\n"
97 " lghi %r1,0\n"
98 // r2 holds the argument for the callee
99 " lghi %r3,0\n"
100 // r4 holds the callee address
101 " lghi %r5,0\n"
102 " lghi %r6,0\n"
103 " lghi %r7,0\n"
104 " lghi %r8,0\n"
105 " lghi %r9,0\n"
106 " lghi %r10,0\n"
107 " lghi %r11,0\n"
108 " lghi %r12,0\n"
109 " lghi %r13,0\n"
110 // r14 holds the return address for the callee
111 // r15 is the stack pointer
112 " br %r4\n" // jump to f
113 ".previous\n"
114 );
115
116 /*
117 Perform a clone system call. clone is strange because it has
118 fork()-like return-twice semantics, so it needs special
119 handling here.
120
121 Upon entry, we have:
122 void* child_stack in r2
123 long flags in r3
124 int* parent_tid in r4
125 int* child_tid in r5
126 int* child_tid in r6
127 Word (*fn)(void *) 160(r15)
128 void *arg 168(r15)
129
130 System call requires:
131 void* child_stack in r2 (sc arg1)
132 long flags in r3 (sc arg2)
133 int* parent_tid in r4 (sc arg3)
134 int* child_tid in r5 (sc arg4)
135 void* tlsaddr in r6 (sc arg5)
136
137 Returns a ULong encoded as: top half is %cr following syscall,
138 low half is syscall return value (r3).
139 */
140 #define __NR_CLONE VG_STRINGIFY(__NR_clone)
141 #define __NR_EXIT VG_STRINGIFY(__NR_exit)
142
143 extern
144 ULong do_syscall_clone_s390x_linux ( void *stack,
145 ULong flags,
146 Int *child_tid,
147 Int *parent_tid,
148 Addr tlsaddr,
149 Word (*fn)(void *),
150 void *arg);
151 asm(
152 " .text\n"
153 " .align 4\n"
154 ".globl do_syscall_clone_s390x_linux\n"
155 "do_syscall_clone_s390x_linux:\n"
156 " lg %r1, 160(%r15)\n" // save fn from parent stack into r1
157 " lg %r0, 168(%r15)\n" // save arg from parent stack into r0
158 " aghi %r2, -160\n" // create stack frame for child
159 // all syscall parameters are already in place (r2-r6)
160 " svc " __NR_CLONE"\n" // clone()
161 " ltgr %r2,%r2\n" // child if retval == 0
162 " jne 1f\n"
163
164 // CHILD - call thread function
165 " lgr %r2, %r0\n" // get arg from r0
166 " basr %r14,%r1\n" // call fn
167
168 // exit. The result is already in r2
169 " svc " __NR_EXIT"\n"
170
171 // Exit returned?!
172 " j +2\n"
173
174 "1:\n" // PARENT or ERROR
175 " br %r14\n"
176 ".previous\n"
177 );
178
179 #undef __NR_CLONE
180 #undef __NR_EXIT
181
VG_(cleanup_thread)182 void VG_(cleanup_thread) ( ThreadArchState* arch )
183 {
184 /* only used on x86 for descriptor tables */
185 }
186
setup_child(ThreadArchState * child,ThreadArchState * parent)187 static void setup_child ( /*OUT*/ ThreadArchState *child,
188 /*IN*/ ThreadArchState *parent )
189 {
190 /* We inherit our parent's guest state. */
191 child->vex = parent->vex;
192 child->vex_shadow1 = parent->vex_shadow1;
193 child->vex_shadow2 = parent->vex_shadow2;
194 }
195
196
197 /*
198 When a client clones, we need to keep track of the new thread. This means:
199 1. allocate a ThreadId+ThreadState+stack for the the thread
200
201 2. initialize the thread's new VCPU state
202
203 3. create the thread using the same args as the client requested,
204 but using the scheduler entrypoint for IP, and a separate stack
205 for SP.
206 */
do_clone(ThreadId ptid,Addr sp,ULong flags,Int * parent_tidptr,Int * child_tidptr,Addr tlsaddr)207 static SysRes do_clone ( ThreadId ptid,
208 Addr sp, ULong flags,
209 Int *parent_tidptr,
210 Int *child_tidptr,
211 Addr tlsaddr)
212 {
213 static const Bool debug = False;
214
215 ThreadId ctid = VG_(alloc_ThreadState)();
216 ThreadState* ptst = VG_(get_ThreadState)(ptid);
217 ThreadState* ctst = VG_(get_ThreadState)(ctid);
218 UWord* stack;
219 NSegment const* seg;
220 SysRes res;
221 ULong r2;
222 vki_sigset_t blockall, savedmask;
223
224 VG_(sigfillset)(&blockall);
225
226 vg_assert(VG_(is_running_thread)(ptid));
227 vg_assert(VG_(is_valid_tid)(ctid));
228
229 stack = (UWord*)ML_(allocstack)(ctid);
230 if (stack == NULL) {
231 res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
232 goto out;
233 }
234
235 /* Copy register state
236
237 Both parent and child return to the same place, and the code
238 following the clone syscall works out which is which, so we
239 don't need to worry about it.
240
241 The parent gets the child's new tid returned from clone, but the
242 child gets 0.
243
244 If the clone call specifies a NULL sp for the new thread, then
245 it actually gets a copy of the parent's sp.
246 */
247 setup_child( &ctst->arch, &ptst->arch );
248
249 /* Make sys_clone appear to have returned Success(0) in the
250 child. */
251 ctst->arch.vex.guest_r2 = 0;
252
253 if (sp != 0)
254 ctst->arch.vex.guest_r15 = sp;
255
256 ctst->os_state.parent = ptid;
257
258 /* inherit signal mask */
259 ctst->sig_mask = ptst->sig_mask;
260 ctst->tmp_sig_mask = ptst->sig_mask;
261
262 /* have the parents thread group */
263 ctst->os_state.threadgroup = ptst->os_state.threadgroup;
264
265 /* We don't really know where the client stack is, because its
266 allocated by the client. The best we can do is look at the
267 memory mappings and try to derive some useful information. We
268 assume that esp starts near its highest possible value, and can
269 only go down to the start of the mmaped segment. */
270 seg = VG_(am_find_nsegment)((Addr)sp);
271 if (seg && seg->kind != SkResvn) {
272 ctst->client_stack_highest_word = (Addr)VG_PGROUNDUP(sp);
273 ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
274
275 VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
276
277 if (debug)
278 VG_(printf)("tid %d: guessed client stack range %#lx-%#lx\n",
279 ctid, seg->start, VG_PGROUNDUP(sp));
280 } else {
281 VG_(message)(Vg_UserMsg,
282 "!? New thread %d starts with SP(%#lx) unmapped\n",
283 ctid, sp);
284 ctst->client_stack_szB = 0;
285 }
286
287 /* Assume the clone will succeed, and tell any tool that wants to
288 know that this thread has come into existence. If the clone
289 fails, we'll send out a ll_exit notification for it at the out:
290 label below, to clean up. */
291 vg_assert(VG_(owns_BigLock_LL)(ptid));
292 VG_TRACK ( pre_thread_ll_create, ptid, ctid );
293
294 if (flags & VKI_CLONE_SETTLS) {
295 if (debug)
296 VG_(printf)("clone child has SETTLS: tls at %#lx\n", tlsaddr);
297 ctst->arch.vex.guest_a0 = (UInt) (tlsaddr >> 32);
298 ctst->arch.vex.guest_a1 = (UInt) tlsaddr;
299 }
300 flags &= ~VKI_CLONE_SETTLS;
301
302 /* start the thread with everything blocked */
303 VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
304
305 /* Create the new thread */
306 r2 = do_syscall_clone_s390x_linux(
307 stack, flags, child_tidptr, parent_tidptr, tlsaddr,
308 ML_(start_thread_NORETURN), &VG_(threads)[ctid]);
309
310 res = VG_(mk_SysRes_s390x_linux)( r2 );
311
312 VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
313
314 out:
315 if (sr_isError(res)) {
316 /* clone failed */
317 ctst->status = VgTs_Empty;
318 /* oops. Better tell the tool the thread exited in a hurry :-) */
319 VG_TRACK( pre_thread_ll_exit, ctid );
320 }
321
322 return res;
323
324 }
325
326
327
328 /* ---------------------------------------------------------------------
329 PRE/POST wrappers for s390x/Linux-specific syscalls
330 ------------------------------------------------------------------ */
331
332 #define PRE(name) DEFN_PRE_TEMPLATE(s390x_linux, name)
333 #define POST(name) DEFN_POST_TEMPLATE(s390x_linux, name)
334
335 /* Add prototypes for the wrappers declared here, so that gcc doesn't
336 harass us for not having prototypes. Really this is a kludge --
337 the right thing to do is to make these wrappers 'static' since they
338 aren't visible outside this file, but that requires even more macro
339 magic. */
340
341 DECL_TEMPLATE(s390x_linux, sys_ptrace);
342 DECL_TEMPLATE(s390x_linux, sys_socketcall);
343 DECL_TEMPLATE(s390x_linux, sys_mmap);
344 DECL_TEMPLATE(s390x_linux, sys_ipc);
345 DECL_TEMPLATE(s390x_linux, sys_clone);
346 DECL_TEMPLATE(s390x_linux, sys_sigreturn);
347 DECL_TEMPLATE(s390x_linux, sys_rt_sigreturn);
348 DECL_TEMPLATE(s390x_linux, sys_fadvise64);
349
350 // PEEK TEXT,DATA and USER are common to all architectures
351 // PEEKUSR_AREA and POKEUSR_AREA are special, having a memory area
352 // containing the real addr, data, and len field pointed to by ARG3
353 // instead of ARG4
PRE(sys_ptrace)354 PRE(sys_ptrace)
355 {
356 PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
357 PRE_REG_READ4(int, "ptrace",
358 long, request, long, pid, long, addr, long, data);
359 switch (ARG1) {
360 case VKI_PTRACE_PEEKTEXT:
361 case VKI_PTRACE_PEEKDATA:
362 case VKI_PTRACE_PEEKUSR:
363 PRE_MEM_WRITE( "ptrace(peek)", ARG4,
364 sizeof (long));
365 break;
366 case VKI_PTRACE_GETEVENTMSG:
367 PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
368 break;
369 case VKI_PTRACE_GETSIGINFO:
370 PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
371 break;
372 case VKI_PTRACE_SETSIGINFO:
373 PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
374 break;
375 case VKI_PTRACE_PEEKUSR_AREA:
376 {
377 vki_ptrace_area *pa;
378
379 /* Reads a part of the user area into memory at pa->process_addr */
380 pa = (vki_ptrace_area *) ARG3;
381 PRE_MEM_READ("ptrace(peekusrarea ptrace_area->len)",
382 (unsigned long) &pa->vki_len, sizeof(pa->vki_len));
383 PRE_MEM_READ("ptrace(peekusrarea ptrace_area->kernel_addr)",
384 (unsigned long) &pa->vki_kernel_addr, sizeof(pa->vki_kernel_addr));
385 PRE_MEM_READ("ptrace(peekusrarea ptrace_area->process_addr)",
386 (unsigned long) &pa->vki_process_addr, sizeof(pa->vki_process_addr));
387 PRE_MEM_WRITE("ptrace(peekusrarea *(ptrace_area->process_addr))",
388 pa->vki_process_addr, pa->vki_len);
389 break;
390 }
391 case VKI_PTRACE_POKEUSR_AREA:
392 {
393 vki_ptrace_area *pa;
394
395 /* Updates a part of the user area from memory at pa->process_addr */
396 pa = (vki_ptrace_area *) ARG3;
397 PRE_MEM_READ("ptrace(pokeusrarea ptrace_area->len)",
398 (unsigned long) &pa->vki_len, sizeof(pa->vki_len));
399 PRE_MEM_READ("ptrace(pokeusrarea ptrace_area->kernel_addr)",
400 (unsigned long) &pa->vki_kernel_addr,
401 sizeof(pa->vki_kernel_addr));
402 PRE_MEM_READ("ptrace(pokeusrarea ptrace_area->process_addr)",
403 (unsigned long) &pa->vki_process_addr,
404 sizeof(pa->vki_process_addr));
405 PRE_MEM_READ("ptrace(pokeusrarea *(ptrace_area->process_addr))",
406 pa->vki_process_addr, pa->vki_len);
407 break;
408 }
409 default:
410 break;
411 }
412 }
413
POST(sys_ptrace)414 POST(sys_ptrace)
415 {
416 switch (ARG1) {
417 case VKI_PTRACE_PEEKTEXT:
418 case VKI_PTRACE_PEEKDATA:
419 case VKI_PTRACE_PEEKUSR:
420 POST_MEM_WRITE( ARG4, sizeof (long));
421 break;
422 case VKI_PTRACE_GETEVENTMSG:
423 POST_MEM_WRITE( ARG4, sizeof(unsigned long));
424 break;
425 case VKI_PTRACE_GETSIGINFO:
426 /* XXX: This is a simplification. Different parts of the
427 * siginfo_t are valid depending on the type of signal.
428 */
429 POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
430 break;
431 case VKI_PTRACE_PEEKUSR_AREA:
432 {
433 vki_ptrace_area *pa;
434
435 pa = (vki_ptrace_area *) ARG3;
436 POST_MEM_WRITE(pa->vki_process_addr, pa->vki_len);
437 }
438 default:
439 break;
440 }
441 }
442
443
PRE(sys_socketcall)444 PRE(sys_socketcall)
445 {
446 # define ARG2_0 (((UWord*)ARG2)[0])
447 # define ARG2_1 (((UWord*)ARG2)[1])
448 # define ARG2_2 (((UWord*)ARG2)[2])
449 # define ARG2_3 (((UWord*)ARG2)[3])
450 # define ARG2_4 (((UWord*)ARG2)[4])
451 # define ARG2_5 (((UWord*)ARG2)[5])
452
453 *flags |= SfMayBlock;
454 PRINT("sys_socketcall ( %ld, %#lx )",ARG1,ARG2);
455 PRE_REG_READ2(long, "socketcall", int, call, unsigned long *, args);
456
457 switch (ARG1 /* request */) {
458
459 case VKI_SYS_SOCKETPAIR:
460 /* int socketpair(int d, int type, int protocol, int sv[2]); */
461 PRE_MEM_READ( "socketcall.socketpair(args)", ARG2, 4*sizeof(Addr) );
462 if (!ML_(valid_client_addr)(ARG2, 4*sizeof(Addr), tid, NULL)) {
463 SET_STATUS_Failure( VKI_EFAULT );
464 break;
465 }
466 ML_(generic_PRE_sys_socketpair)( tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3 );
467 break;
468
469 case VKI_SYS_SOCKET:
470 /* int socket(int domain, int type, int protocol); */
471 PRE_MEM_READ( "socketcall.socket(args)", ARG2, 3*sizeof(Addr) );
472 if (!ML_(valid_client_addr)(ARG2, 3*sizeof(Addr), tid, NULL)) {
473 SET_STATUS_Failure( VKI_EFAULT );
474 break;
475 }
476 break;
477
478 case VKI_SYS_BIND:
479 /* int bind(int sockfd, struct sockaddr *my_addr,
480 int addrlen); */
481 PRE_MEM_READ( "socketcall.bind(args)", ARG2, 3*sizeof(Addr) );
482 if (!ML_(valid_client_addr)(ARG2, 3*sizeof(Addr), tid, NULL)) {
483 SET_STATUS_Failure( VKI_EFAULT );
484 break;
485 }
486 ML_(generic_PRE_sys_bind)( tid, ARG2_0, ARG2_1, ARG2_2 );
487 break;
488
489 case VKI_SYS_LISTEN:
490 /* int listen(int s, int backlog); */
491 PRE_MEM_READ( "socketcall.listen(args)", ARG2, 2*sizeof(Addr) );
492 if (!ML_(valid_client_addr)(ARG2, 2*sizeof(Addr), tid, NULL)) {
493 SET_STATUS_Failure( VKI_EFAULT );
494 break;
495 }
496 break;
497
498 case VKI_SYS_ACCEPT: {
499 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
500 PRE_MEM_READ( "socketcall.accept(args)", ARG2, 3*sizeof(Addr) );
501 if (!ML_(valid_client_addr)(ARG2, 3*sizeof(Addr), tid, NULL)) {
502 SET_STATUS_Failure( VKI_EFAULT );
503 break;
504 }
505 ML_(generic_PRE_sys_accept)( tid, ARG2_0, ARG2_1, ARG2_2 );
506 break;
507 }
508
509 case VKI_SYS_SENDTO:
510 /* int sendto(int s, const void *msg, int len,
511 unsigned int flags,
512 const struct sockaddr *to, int tolen); */
513 PRE_MEM_READ( "socketcall.sendto(args)", ARG2, 6*sizeof(Addr) );
514 if (!ML_(valid_client_addr)(ARG2, 6*sizeof(Addr), tid, NULL)) {
515 SET_STATUS_Failure( VKI_EFAULT );
516 break;
517 }
518 ML_(generic_PRE_sys_sendto)( tid, ARG2_0, ARG2_1, ARG2_2,
519 ARG2_3, ARG2_4, ARG2_5 );
520 break;
521
522 case VKI_SYS_SEND:
523 /* int send(int s, const void *msg, size_t len, int flags); */
524 PRE_MEM_READ( "socketcall.send(args)", ARG2, 4*sizeof(Addr) );
525 if (!ML_(valid_client_addr)(ARG2, 4*sizeof(Addr), tid, NULL)) {
526 SET_STATUS_Failure( VKI_EFAULT );
527 break;
528 }
529 ML_(generic_PRE_sys_send)( tid, ARG2_0, ARG2_1, ARG2_2 );
530 break;
531
532 case VKI_SYS_RECVFROM:
533 /* int recvfrom(int s, void *buf, int len, unsigned int flags,
534 struct sockaddr *from, int *fromlen); */
535 PRE_MEM_READ( "socketcall.recvfrom(args)", ARG2, 6*sizeof(Addr) );
536 if (!ML_(valid_client_addr)(ARG2, 6*sizeof(Addr), tid, NULL)) {
537 SET_STATUS_Failure( VKI_EFAULT );
538 break;
539 }
540 ML_(generic_PRE_sys_recvfrom)( tid, ARG2_0, ARG2_1, ARG2_2,
541 ARG2_3, ARG2_4, ARG2_5 );
542 break;
543
544 case VKI_SYS_RECV:
545 /* int recv(int s, void *buf, int len, unsigned int flags); */
546 /* man 2 recv says:
547 The recv call is normally used only on a connected socket
548 (see connect(2)) and is identical to recvfrom with a NULL
549 from parameter.
550 */
551 PRE_MEM_READ( "socketcall.recv(args)", ARG2, 4*sizeof(Addr) );
552 if (!ML_(valid_client_addr)(ARG2, 4*sizeof(Addr), tid, NULL)) {
553 SET_STATUS_Failure( VKI_EFAULT );
554 break;
555 }
556 ML_(generic_PRE_sys_recv)( tid, ARG2_0, ARG2_1, ARG2_2 );
557 break;
558
559 case VKI_SYS_CONNECT:
560 /* int connect(int sockfd,
561 struct sockaddr *serv_addr, int addrlen ); */
562 PRE_MEM_READ( "socketcall.connect(args)", ARG2, 3*sizeof(Addr) );
563 if (!ML_(valid_client_addr)(ARG2, 3*sizeof(Addr), tid, NULL)) {
564 SET_STATUS_Failure( VKI_EFAULT );
565 break;
566 }
567 ML_(generic_PRE_sys_connect)( tid, ARG2_0, ARG2_1, ARG2_2 );
568 break;
569
570 case VKI_SYS_SETSOCKOPT:
571 /* int setsockopt(int s, int level, int optname,
572 const void *optval, int optlen); */
573 PRE_MEM_READ( "socketcall.setsockopt(args)", ARG2, 5*sizeof(Addr) );
574 if (!ML_(valid_client_addr)(ARG2, 5*sizeof(Addr), tid, NULL)) {
575 SET_STATUS_Failure( VKI_EFAULT );
576 break;
577 }
578 ML_(generic_PRE_sys_setsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
579 ARG2_3, ARG2_4 );
580 break;
581
582 case VKI_SYS_GETSOCKOPT:
583 /* int getsockopt(int s, int level, int optname,
584 void *optval, socklen_t *optlen); */
585 PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) );
586 if (!ML_(valid_client_addr)(ARG2, 5*sizeof(Addr), tid, NULL)) {
587 SET_STATUS_Failure( VKI_EFAULT );
588 break;
589 }
590 ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2,
591 ARG2_3, ARG2_4 );
592 break;
593
594 case VKI_SYS_GETSOCKNAME:
595 /* int getsockname(int s, struct sockaddr* name, int* namelen) */
596 PRE_MEM_READ( "socketcall.getsockname(args)", ARG2, 3*sizeof(Addr) );
597 if (!ML_(valid_client_addr)(ARG2, 3*sizeof(Addr), tid, NULL)) {
598 SET_STATUS_Failure( VKI_EFAULT );
599 break;
600 }
601 ML_(generic_PRE_sys_getsockname)( tid, ARG2_0, ARG2_1, ARG2_2 );
602 break;
603
604 case VKI_SYS_GETPEERNAME:
605 /* int getpeername(int s, struct sockaddr* name, int* namelen) */
606 PRE_MEM_READ( "socketcall.getpeername(args)", ARG2, 3*sizeof(Addr) );
607 if (!ML_(valid_client_addr)(ARG2, 3*sizeof(Addr), tid, NULL)) {
608 SET_STATUS_Failure( VKI_EFAULT );
609 break;
610 }
611 ML_(generic_PRE_sys_getpeername)( tid, ARG2_0, ARG2_1, ARG2_2 );
612 break;
613
614 case VKI_SYS_SHUTDOWN:
615 /* int shutdown(int s, int how); */
616 PRE_MEM_READ( "socketcall.shutdown(args)", ARG2, 2*sizeof(Addr) );
617 if (!ML_(valid_client_addr)(ARG2, 2*sizeof(Addr), tid, NULL)) {
618 SET_STATUS_Failure( VKI_EFAULT );
619 break;
620 }
621 break;
622
623 case VKI_SYS_SENDMSG: {
624 /* int sendmsg(int s, const struct msghdr *msg, int flags); */
625 PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) );
626 if (!ML_(valid_client_addr)(ARG2, 3*sizeof(Addr), tid, NULL)) {
627 SET_STATUS_Failure( VKI_EFAULT );
628 break;
629 }
630 ML_(generic_PRE_sys_sendmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1 );
631 break;
632 }
633
634 case VKI_SYS_RECVMSG: {
635 /* int recvmsg(int s, struct msghdr *msg, int flags); */
636 PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) );
637 if (!ML_(valid_client_addr)(ARG2, 3*sizeof(Addr), tid, NULL)) {
638 SET_STATUS_Failure( VKI_EFAULT );
639 break;
640 }
641 ML_(generic_PRE_sys_recvmsg)( tid, "msg2", (struct vki_msghdr *)ARG2_1 );
642 break;
643 }
644
645 default:
646 VG_(message)(Vg_DebugMsg,"Warning: unhandled socketcall 0x%lx\n",ARG1);
647 SET_STATUS_Failure( VKI_EINVAL );
648 break;
649 }
650 # undef ARG2_0
651 # undef ARG2_1
652 # undef ARG2_2
653 # undef ARG2_3
654 # undef ARG2_4
655 # undef ARG2_5
656 }
657
POST(sys_socketcall)658 POST(sys_socketcall)
659 {
660 # define ARG2_0 (((UWord*)ARG2)[0])
661 # define ARG2_1 (((UWord*)ARG2)[1])
662 # define ARG2_2 (((UWord*)ARG2)[2])
663 # define ARG2_3 (((UWord*)ARG2)[3])
664 # define ARG2_4 (((UWord*)ARG2)[4])
665 # define ARG2_5 (((UWord*)ARG2)[5])
666
667 SysRes r;
668 vg_assert(SUCCESS);
669 switch (ARG1 /* request */) {
670
671 case VKI_SYS_SOCKETPAIR:
672 r = ML_(generic_POST_sys_socketpair)(
673 tid, VG_(mk_SysRes_Success)(RES),
674 ARG2_0, ARG2_1, ARG2_2, ARG2_3
675 );
676 SET_STATUS_from_SysRes(r);
677 break;
678
679 case VKI_SYS_SOCKET:
680 r = ML_(generic_POST_sys_socket)( tid, VG_(mk_SysRes_Success)(RES) );
681 SET_STATUS_from_SysRes(r);
682 break;
683
684 case VKI_SYS_BIND:
685 /* int bind(int sockfd, struct sockaddr *my_addr,
686 int addrlen); */
687 break;
688
689 case VKI_SYS_LISTEN:
690 /* int listen(int s, int backlog); */
691 break;
692
693 case VKI_SYS_ACCEPT:
694 /* int accept(int s, struct sockaddr *addr, int *addrlen); */
695 r = ML_(generic_POST_sys_accept)( tid, VG_(mk_SysRes_Success)(RES),
696 ARG2_0, ARG2_1, ARG2_2 );
697 SET_STATUS_from_SysRes(r);
698 break;
699
700 case VKI_SYS_SENDTO:
701 break;
702
703 case VKI_SYS_SEND:
704 break;
705
706 case VKI_SYS_RECVFROM:
707 ML_(generic_POST_sys_recvfrom)( tid, VG_(mk_SysRes_Success)(RES),
708 ARG2_0, ARG2_1, ARG2_2,
709 ARG2_3, ARG2_4, ARG2_5 );
710 break;
711
712 case VKI_SYS_RECV:
713 ML_(generic_POST_sys_recv)( tid, RES, ARG2_0, ARG2_1, ARG2_2 );
714 break;
715
716 case VKI_SYS_CONNECT:
717 break;
718
719 case VKI_SYS_SETSOCKOPT:
720 break;
721
722 case VKI_SYS_GETSOCKOPT:
723 ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES),
724 ARG2_0, ARG2_1,
725 ARG2_2, ARG2_3, ARG2_4 );
726 break;
727
728 case VKI_SYS_GETSOCKNAME:
729 ML_(generic_POST_sys_getsockname)( tid, VG_(mk_SysRes_Success)(RES),
730 ARG2_0, ARG2_1, ARG2_2 );
731 break;
732
733 case VKI_SYS_GETPEERNAME:
734 ML_(generic_POST_sys_getpeername)( tid, VG_(mk_SysRes_Success)(RES),
735 ARG2_0, ARG2_1, ARG2_2 );
736 break;
737
738 case VKI_SYS_SHUTDOWN:
739 break;
740
741 case VKI_SYS_SENDMSG:
742 break;
743
744 case VKI_SYS_RECVMSG:
745 ML_(generic_POST_sys_recvmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1, RES );
746 break;
747
748 default:
749 VG_(message)(Vg_DebugMsg,"FATAL: unhandled socketcall 0x%lx\n",ARG1);
750 VG_(core_panic)("... bye!\n");
751 break; /*NOTREACHED*/
752 }
753 # undef ARG2_0
754 # undef ARG2_1
755 # undef ARG2_2
756 # undef ARG2_3
757 # undef ARG2_4
758 # undef ARG2_5
759 }
760
PRE(sys_mmap)761 PRE(sys_mmap)
762 {
763 UWord a0, a1, a2, a3, a4, a5;
764 SysRes r;
765
766 UWord* args = (UWord*)ARG1;
767 PRE_REG_READ1(long, "sys_mmap", struct mmap_arg_struct *, args);
768 PRE_MEM_READ( "sys_mmap(args)", (Addr) args, 6*sizeof(UWord) );
769
770 a0 = args[0];
771 a1 = args[1];
772 a2 = args[2];
773 a3 = args[3];
774 a4 = args[4];
775 a5 = args[5];
776
777 PRINT("sys_mmap ( %#lx, %llu, %ld, %ld, %ld, %ld )",
778 a0, (ULong)a1, a2, a3, a4, a5 );
779
780 r = ML_(generic_PRE_sys_mmap)( tid, a0, a1, a2, a3, a4, (Off64T)a5 );
781 SET_STATUS_from_SysRes(r);
782 }
783
deref_Addr(ThreadId tid,Addr a,Char * s)784 static Addr deref_Addr ( ThreadId tid, Addr a, Char* s )
785 {
786 Addr* a_p = (Addr*)a;
787 PRE_MEM_READ( s, (Addr)a_p, sizeof(Addr) );
788 return *a_p;
789 }
790
PRE(sys_ipc)791 PRE(sys_ipc)
792 {
793 PRINT("sys_ipc ( %ld, %ld, %ld, %ld, %#lx, %ld )",
794 ARG1,ARG2,ARG3,ARG4,ARG5,ARG6);
795 // XXX: this is simplistic -- some args are not used in all circumstances.
796 PRE_REG_READ6(int, "ipc",
797 vki_uint, call, int, first, int, second, int, third,
798 void *, ptr, long, fifth)
799
800 switch (ARG1 /* call */) {
801 case VKI_SEMOP:
802 ML_(generic_PRE_sys_semop)( tid, ARG2, ARG5, ARG3 );
803 *flags |= SfMayBlock;
804 break;
805 case VKI_SEMGET:
806 break;
807 case VKI_SEMCTL:
808 {
809 UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
810 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
811 break;
812 }
813 case VKI_SEMTIMEDOP:
814 ML_(generic_PRE_sys_semtimedop)( tid, ARG2, ARG5, ARG3, ARG6 );
815 *flags |= SfMayBlock;
816 break;
817 case VKI_MSGSND:
818 ML_(linux_PRE_sys_msgsnd)( tid, ARG2, ARG5, ARG3, ARG4 );
819 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
820 *flags |= SfMayBlock;
821 break;
822 case VKI_MSGRCV:
823 {
824 Addr msgp;
825 Word msgtyp;
826
827 msgp = deref_Addr( tid,
828 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
829 "msgrcv(msgp)" );
830 msgtyp = deref_Addr( tid,
831 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
832 "msgrcv(msgp)" );
833
834 ML_(linux_PRE_sys_msgrcv)( tid, ARG2, msgp, ARG3, msgtyp, ARG4 );
835
836 if ((ARG4 & VKI_IPC_NOWAIT) == 0)
837 *flags |= SfMayBlock;
838 break;
839 }
840 case VKI_MSGGET:
841 break;
842 case VKI_MSGCTL:
843 ML_(linux_PRE_sys_msgctl)( tid, ARG2, ARG3, ARG5 );
844 break;
845 case VKI_SHMAT:
846 {
847 UWord w;
848 PRE_MEM_WRITE( "shmat(raddr)", ARG4, sizeof(Addr) );
849 w = ML_(generic_PRE_sys_shmat)( tid, ARG2, ARG5, ARG3 );
850 if (w == 0)
851 SET_STATUS_Failure( VKI_EINVAL );
852 else
853 ARG5 = w;
854 break;
855 }
856 case VKI_SHMDT:
857 if (!ML_(generic_PRE_sys_shmdt)(tid, ARG5))
858 SET_STATUS_Failure( VKI_EINVAL );
859 break;
860 case VKI_SHMGET:
861 break;
862 case VKI_SHMCTL: /* IPCOP_shmctl */
863 ML_(generic_PRE_sys_shmctl)( tid, ARG2, ARG3, ARG5 );
864 break;
865 default:
866 VG_(message)(Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %ld", ARG1 );
867 VG_(core_panic)("... bye!\n");
868 break; /*NOTREACHED*/
869 }
870 }
871
POST(sys_ipc)872 POST(sys_ipc)
873 {
874 vg_assert(SUCCESS);
875 switch (ARG1 /* call */) {
876 case VKI_SEMOP:
877 case VKI_SEMGET:
878 break;
879 case VKI_SEMCTL:
880 {
881 UWord arg = deref_Addr( tid, ARG5, "semctl(arg)" );
882 ML_(generic_PRE_sys_semctl)( tid, ARG2, ARG3, ARG4, arg );
883 break;
884 }
885 case VKI_SEMTIMEDOP:
886 case VKI_MSGSND:
887 break;
888 case VKI_MSGRCV:
889 {
890 Addr msgp;
891 Word msgtyp;
892
893 msgp = deref_Addr( tid,
894 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgp),
895 "msgrcv(msgp)" );
896 msgtyp = deref_Addr( tid,
897 (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp),
898 "msgrcv(msgp)" );
899
900 ML_(linux_POST_sys_msgrcv)( tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4 );
901 break;
902 }
903 case VKI_MSGGET:
904 break;
905 case VKI_MSGCTL:
906 ML_(linux_POST_sys_msgctl)( tid, RES, ARG2, ARG3, ARG5 );
907 break;
908 case VKI_SHMAT:
909 {
910 Addr addr;
911
912 /* force readability. before the syscall it is
913 * indeed uninitialized, as can be seen in
914 * glibc/sysdeps/unix/sysv/linux/shmat.c */
915 POST_MEM_WRITE( ARG4, sizeof( Addr ) );
916
917 addr = deref_Addr ( tid, ARG4, "shmat(addr)" );
918 ML_(generic_POST_sys_shmat)( tid, addr, ARG2, ARG5, ARG3 );
919 break;
920 }
921 case VKI_SHMDT:
922 ML_(generic_POST_sys_shmdt)( tid, RES, ARG5 );
923 break;
924 case VKI_SHMGET:
925 break;
926 case VKI_SHMCTL:
927 ML_(generic_POST_sys_shmctl)( tid, RES, ARG2, ARG3, ARG5 );
928 break;
929 default:
930 VG_(message)(Vg_DebugMsg,
931 "FATAL: unhandled syscall(ipc) %ld",
932 ARG1 );
933 VG_(core_panic)("... bye!\n");
934 break; /*NOTREACHED*/
935 }
936 }
937
PRE(sys_clone)938 PRE(sys_clone)
939 {
940 UInt cloneflags;
941
942 PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4, ARG5);
943 PRE_REG_READ2(int, "clone",
944 void *, child_stack,
945 unsigned long, flags);
946
947 if (ARG2 & VKI_CLONE_PARENT_SETTID) {
948 if (VG_(tdict).track_pre_reg_read)
949 PRA3("clone(parent_tidptr)", int *, parent_tidptr);
950 PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
951 if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),
952 VKI_PROT_WRITE)) {
953 SET_STATUS_Failure( VKI_EFAULT );
954 return;
955 }
956 }
957 if (ARG2 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
958 if (VG_(tdict).track_pre_reg_read)
959 PRA4("clone(child_tidptr)", int *, child_tidptr);
960 PRE_MEM_WRITE("clone(child_tidptr)", ARG4, sizeof(Int));
961 if (!VG_(am_is_valid_for_client)(ARG4, sizeof(Int),
962 VKI_PROT_WRITE)) {
963 SET_STATUS_Failure( VKI_EFAULT );
964 return;
965 }
966 }
967
968 /* The kernel simply copies reg6 (ARG5) into AR0 and AR1, no checks */
969 if (ARG2 & VKI_CLONE_SETTLS) {
970 if (VG_(tdict).track_pre_reg_read) {
971 PRA5("clone", Addr, tlsinfo);
972 }
973 }
974
975 cloneflags = ARG2;
976
977 if (!ML_(client_signal_OK)(ARG2 & VKI_CSIGNAL)) {
978 SET_STATUS_Failure( VKI_EINVAL );
979 return;
980 }
981
982 /* Only look at the flags we really care about */
983 switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
984 | VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
985 case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
986 /* thread creation */
987 SET_STATUS_from_SysRes(
988 do_clone(tid,
989 (Addr)ARG1, /* child SP */
990 ARG2, /* flags */
991 (Int *)ARG3, /* parent_tidptr */
992 (Int *)ARG4, /* child_tidptr */
993 (Addr)ARG5)); /* tlsaddr */
994 break;
995
996 case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
997 /* FALLTHROUGH - assume vfork == fork */
998 cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
999
1000 case 0: /* plain fork */
1001 SET_STATUS_from_SysRes(
1002 ML_(do_fork_clone)(tid,
1003 cloneflags, /* flags */
1004 (Int *)ARG3, /* parent_tidptr */
1005 (Int *)ARG4)); /* child_tidptr */
1006 break;
1007
1008 default:
1009 /* should we just ENOSYS? */
1010 VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx", ARG2);
1011 VG_(message)(Vg_UserMsg, "");
1012 VG_(message)(Vg_UserMsg, "The only supported clone() uses are:");
1013 VG_(message)(Vg_UserMsg, " - via a threads library (NPTL)");
1014 VG_(message)(Vg_UserMsg, " - via the implementation of fork or vfork");
1015 VG_(unimplemented)
1016 ("Valgrind does not support general clone().");
1017 }
1018
1019 if (SUCCESS) {
1020 if (ARG2 & VKI_CLONE_PARENT_SETTID)
1021 POST_MEM_WRITE(ARG3, sizeof(Int));
1022 if (ARG2 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
1023 POST_MEM_WRITE(ARG4, sizeof(Int));
1024
1025 /* Thread creation was successful; let the child have the chance
1026 to run */
1027 *flags |= SfYieldAfter;
1028 }
1029 }
1030
PRE(sys_sigreturn)1031 PRE(sys_sigreturn)
1032 {
1033 ThreadState* tst;
1034 PRINT("sys_sigreturn ( )");
1035
1036 vg_assert(VG_(is_valid_tid)(tid));
1037 vg_assert(tid >= 1 && tid < VG_N_THREADS);
1038 vg_assert(VG_(is_running_thread)(tid));
1039
1040 tst = VG_(get_ThreadState)(tid);
1041
1042 /* This is only so that the IA is (might be) useful to report if
1043 something goes wrong in the sigreturn */
1044 ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
1045
1046 /* Restore register state from frame and remove it */
1047 VG_(sigframe_destroy)(tid, False);
1048
1049 /* Tell the driver not to update the guest state with the "result",
1050 and set a bogus result to keep it happy. */
1051 *flags |= SfNoWriteResult;
1052 SET_STATUS_Success(0);
1053
1054 /* Check to see if any signals arose as a result of this. */
1055 *flags |= SfPollAfter;
1056 }
1057
1058
PRE(sys_rt_sigreturn)1059 PRE(sys_rt_sigreturn)
1060 {
1061 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
1062 an explanation of what follows. */
1063
1064 ThreadState* tst;
1065 PRINT("sys_rt_sigreturn ( )");
1066
1067 vg_assert(VG_(is_valid_tid)(tid));
1068 vg_assert(tid >= 1 && tid < VG_N_THREADS);
1069 vg_assert(VG_(is_running_thread)(tid));
1070
1071 tst = VG_(get_ThreadState)(tid);
1072
1073 /* This is only so that the IA is (might be) useful to report if
1074 something goes wrong in the sigreturn */
1075 ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
1076
1077 /* Restore register state from frame and remove it */
1078 VG_(sigframe_destroy)(tid, True);
1079
1080 /* Tell the driver not to update the guest state with the "result",
1081 and set a bogus result to keep it happy. */
1082 *flags |= SfNoWriteResult;
1083 SET_STATUS_Success(0);
1084
1085 /* Check to see if any signals arose as a result of this. */
1086 *flags |= SfPollAfter;
1087 }
1088
1089 /* we cant use the LINX_ version for 64 bit */
PRE(sys_fadvise64)1090 PRE(sys_fadvise64)
1091 {
1092 PRINT("sys_fadvise64 ( %ld, %ld, %ld, %ld )", ARG1,ARG2,ARG3,ARG4);
1093 PRE_REG_READ4(long, "fadvise64",
1094 int, fd, vki_loff_t, offset, vki_loff_t, len, int, advice);
1095 }
1096
1097 #undef PRE
1098 #undef POST
1099
1100 /* ---------------------------------------------------------------------
1101 The s390x/Linux syscall table
1102 ------------------------------------------------------------------ */
1103
1104 /* Add an s390x-linux specific wrapper to a syscall table. */
1105 #define PLAX_(sysno, name) WRAPPER_ENTRY_X_(s390x_linux, sysno, name)
1106 #define PLAXY(sysno, name) WRAPPER_ENTRY_XY(s390x_linux, sysno, name)
1107
1108 // This table maps from __NR_xxx syscall numbers from
1109 // linux/arch/s390/kernel/syscalls.S to the appropriate PRE/POST sys_foo()
1110 // wrappers on s390x. There are several unused numbers, which are only
1111 // defined on s390 (31bit mode) but no longer available on s390x (64 bit).
1112 // For those syscalls not handled by Valgrind, the annotation indicate its
1113 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
1114 // (unknown).
1115
1116 static SyscallTableEntry syscall_table[] = {
1117 GENX_(0, sys_ni_syscall), /* unimplemented (by the kernel) */ // 0
1118 GENX_(__NR_exit, sys_exit), // 1
1119 GENX_(__NR_fork, sys_fork), // 2
1120 GENXY(__NR_read, sys_read), // 3
1121 GENX_(__NR_write, sys_write), // 4
1122
1123 GENXY(__NR_open, sys_open), // 5
1124 GENXY(__NR_close, sys_close), // 6
1125 // ?????(__NR_restart_syscall, ), // 7
1126 GENXY(__NR_creat, sys_creat), // 8
1127 GENX_(__NR_link, sys_link), // 9
1128
1129 GENX_(__NR_unlink, sys_unlink), // 10
1130 GENX_(__NR_execve, sys_execve), // 11
1131 GENX_(__NR_chdir, sys_chdir), // 12
1132 GENX_(13, sys_ni_syscall), /* unimplemented (by the kernel) */ // 13
1133 GENX_(__NR_mknod, sys_mknod), // 14
1134
1135 GENX_(__NR_chmod, sys_chmod), // 15
1136 GENX_(16, sys_ni_syscall), /* unimplemented (by the kernel) */ // 16
1137 GENX_(17, sys_ni_syscall), /* unimplemented (by the kernel) */ // 17
1138 GENX_(18, sys_ni_syscall), /* unimplemented (by the kernel) */ // 18
1139 LINX_(__NR_lseek, sys_lseek), // 19
1140
1141 GENX_(__NR_getpid, sys_getpid), // 20
1142 LINX_(__NR_mount, sys_mount), // 21
1143 LINX_(__NR_umount, sys_oldumount), // 22
1144 GENX_(23, sys_ni_syscall), /* unimplemented (by the kernel) */ // 23
1145 GENX_(24, sys_ni_syscall), /* unimplemented (by the kernel) */ // 24
1146
1147 GENX_(25, sys_ni_syscall), /* unimplemented (by the kernel) */ // 25
1148 PLAXY(__NR_ptrace, sys_ptrace), // 26
1149 GENX_(__NR_alarm, sys_alarm), // 27
1150 GENX_(28, sys_ni_syscall), /* unimplemented (by the kernel) */ // 28
1151 GENX_(__NR_pause, sys_pause), // 29
1152
1153 LINX_(__NR_utime, sys_utime), // 30
1154 GENX_(31, sys_ni_syscall), /* unimplemented (by the kernel) */ // 31
1155 GENX_(32, sys_ni_syscall), /* unimplemented (by the kernel) */ // 32
1156 GENX_(__NR_access, sys_access), // 33
1157 GENX_(__NR_nice, sys_nice), // 34
1158
1159 GENX_(35, sys_ni_syscall), /* unimplemented (by the kernel) */ // 35
1160 GENX_(__NR_sync, sys_sync), // 36
1161 GENX_(__NR_kill, sys_kill), // 37
1162 GENX_(__NR_rename, sys_rename), // 38
1163 GENX_(__NR_mkdir, sys_mkdir), // 39
1164
1165 GENX_(__NR_rmdir, sys_rmdir), // 40
1166 GENXY(__NR_dup, sys_dup), // 41
1167 LINXY(__NR_pipe, sys_pipe), // 42
1168 GENXY(__NR_times, sys_times), // 43
1169 GENX_(44, sys_ni_syscall), /* unimplemented (by the kernel) */ // 44
1170
1171 GENX_(__NR_brk, sys_brk), // 45
1172 GENX_(46, sys_ni_syscall), /* unimplemented (by the kernel) */ // 46
1173 GENX_(47, sys_ni_syscall), /* unimplemented (by the kernel) */ // 47
1174 // ?????(__NR_signal, ), // 48
1175 GENX_(49, sys_ni_syscall), /* unimplemented (by the kernel) */ // 49
1176
1177 GENX_(50, sys_ni_syscall), /* unimplemented (by the kernel) */ // 50
1178 GENX_(__NR_acct, sys_acct), // 51
1179 LINX_(__NR_umount2, sys_umount), // 52
1180 GENX_(53, sys_ni_syscall), /* unimplemented (by the kernel) */ // 53
1181 LINXY(__NR_ioctl, sys_ioctl), // 54
1182
1183 LINXY(__NR_fcntl, sys_fcntl), // 55
1184 GENX_(56, sys_ni_syscall), /* unimplemented (by the kernel) */ // 56
1185 GENX_(__NR_setpgid, sys_setpgid), // 57
1186 GENX_(58, sys_ni_syscall), /* unimplemented (by the kernel) */ // 58
1187 GENX_(59, sys_ni_syscall), /* unimplemented (by the kernel) */ // 59
1188
1189 GENX_(__NR_umask, sys_umask), // 60
1190 GENX_(__NR_chroot, sys_chroot), // 61
1191 // ?????(__NR_ustat, sys_ustat), /* deprecated in favor of statfs */ // 62
1192 GENXY(__NR_dup2, sys_dup2), // 63
1193 GENX_(__NR_getppid, sys_getppid), // 64
1194
1195 GENX_(__NR_getpgrp, sys_getpgrp), // 65
1196 GENX_(__NR_setsid, sys_setsid), // 66
1197 // ?????(__NR_sigaction, ), /* userspace uses rt_sigaction */ // 67
1198 GENX_(68, sys_ni_syscall), /* unimplemented (by the kernel) */ // 68
1199 GENX_(69, sys_ni_syscall), /* unimplemented (by the kernel) */ // 69
1200
1201 GENX_(70, sys_ni_syscall), /* unimplemented (by the kernel) */ // 70
1202 GENX_(71, sys_ni_syscall), /* unimplemented (by the kernel) */ // 71
1203 // ?????(__NR_sigsuspend, ), // 72
1204 // ?????(__NR_sigpending, ), // 73
1205 // ?????(__NR_sethostname, ), // 74
1206
1207 GENX_(__NR_setrlimit, sys_setrlimit), // 75
1208 GENXY(76, sys_getrlimit), /* see also 191 */ // 76
1209 GENXY(__NR_getrusage, sys_getrusage), // 77
1210 GENXY(__NR_gettimeofday, sys_gettimeofday), // 78
1211 GENX_(__NR_settimeofday, sys_settimeofday), // 79
1212
1213 GENX_(80, sys_ni_syscall), /* unimplemented (by the kernel) */ // 80
1214 GENX_(81, sys_ni_syscall), /* unimplemented (by the kernel) */ // 81
1215 GENX_(82, sys_ni_syscall), /* unimplemented (by the kernel) */ // 82
1216 GENX_(__NR_symlink, sys_symlink), // 83
1217 GENX_(84, sys_ni_syscall), /* unimplemented (by the kernel) */ // 84
1218
1219 GENX_(__NR_readlink, sys_readlink), // 85
1220 // ?????(__NR_uselib, ), // 86
1221 // ?????(__NR_swapon, ), // 87
1222 // ?????(__NR_reboot, ), // 88
1223 GENX_(89, sys_ni_syscall), /* unimplemented (by the kernel) */ // 89
1224
1225 PLAX_(__NR_mmap, sys_mmap ), // 90
1226 GENXY(__NR_munmap, sys_munmap), // 91
1227 GENX_(__NR_truncate, sys_truncate), // 92
1228 GENX_(__NR_ftruncate, sys_ftruncate), // 93
1229 GENX_(__NR_fchmod, sys_fchmod), // 94
1230
1231 GENX_(95, sys_ni_syscall), /* unimplemented (by the kernel) */ // 95
1232 GENX_(__NR_getpriority, sys_getpriority), // 96
1233 GENX_(__NR_setpriority, sys_setpriority), // 97
1234 GENX_(98, sys_ni_syscall), /* unimplemented (by the kernel) */ // 98
1235 GENXY(__NR_statfs, sys_statfs), // 99
1236
1237 GENXY(__NR_fstatfs, sys_fstatfs), // 100
1238 GENX_(101, sys_ni_syscall), /* unimplemented (by the kernel) */ // 101
1239 PLAXY(__NR_socketcall, sys_socketcall), // 102
1240 LINXY(__NR_syslog, sys_syslog), // 103
1241 GENXY(__NR_setitimer, sys_setitimer), // 104
1242
1243 GENXY(__NR_getitimer, sys_getitimer), // 105
1244 GENXY(__NR_stat, sys_newstat), // 106
1245 GENXY(__NR_lstat, sys_newlstat), // 107
1246 GENXY(__NR_fstat, sys_newfstat), // 108
1247 GENX_(109, sys_ni_syscall), /* unimplemented (by the kernel) */ // 109
1248
1249 LINXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 110
1250 LINX_(__NR_vhangup, sys_vhangup), // 111
1251 GENX_(112, sys_ni_syscall), /* unimplemented (by the kernel) */ // 112
1252 GENX_(113, sys_ni_syscall), /* unimplemented (by the kernel) */ // 113
1253 GENXY(__NR_wait4, sys_wait4), // 114
1254
1255 // ?????(__NR_swapoff, ), // 115
1256 LINXY(__NR_sysinfo, sys_sysinfo), // 116
1257 PLAXY(__NR_ipc, sys_ipc), // 117
1258 GENX_(__NR_fsync, sys_fsync), // 118
1259 PLAX_(__NR_sigreturn, sys_sigreturn), // 119
1260
1261 PLAX_(__NR_clone, sys_clone), // 120
1262 // ?????(__NR_setdomainname, ), // 121
1263 GENXY(__NR_uname, sys_newuname), // 122
1264 GENX_(123, sys_ni_syscall), /* unimplemented (by the kernel) */ // 123
1265 // ?????(__NR_adjtimex, ), // 124
1266
1267 GENXY(__NR_mprotect, sys_mprotect), // 125
1268 // LINXY(__NR_sigprocmask, sys_sigprocmask), // 126
1269 GENX_(127, sys_ni_syscall), /* unimplemented (by the kernel) */ // 127
1270 LINX_(__NR_init_module, sys_init_module), // 128
1271 LINX_(__NR_delete_module, sys_delete_module), // 129
1272
1273 GENX_(130, sys_ni_syscall), /* unimplemented (by the kernel) */ // 130
1274 LINX_(__NR_quotactl, sys_quotactl), // 131
1275 GENX_(__NR_getpgid, sys_getpgid), // 132
1276 GENX_(__NR_fchdir, sys_fchdir), // 133
1277 // ?????(__NR_bdflush, ), // 134
1278
1279 // ?????(__NR_sysfs, ), // 135
1280 LINX_(__NR_personality, sys_personality), // 136
1281 GENX_(137, sys_ni_syscall), /* unimplemented (by the kernel) */ // 137
1282 GENX_(138, sys_ni_syscall), /* unimplemented (by the kernel) */ // 138
1283 GENX_(139, sys_ni_syscall), /* unimplemented (by the kernel) */ // 139
1284
1285 // LINXY(__NR__llseek, sys_llseek), /* 64 bit --> lseek */ // 140
1286 GENXY(__NR_getdents, sys_getdents), // 141
1287 GENX_(__NR_select, sys_select), // 142
1288 GENX_(__NR_flock, sys_flock), // 143
1289 GENX_(__NR_msync, sys_msync), // 144
1290
1291 GENXY(__NR_readv, sys_readv), // 145
1292 GENX_(__NR_writev, sys_writev), // 146
1293 GENX_(__NR_getsid, sys_getsid), // 147
1294 GENX_(__NR_fdatasync, sys_fdatasync), // 148
1295 LINXY(__NR__sysctl, sys_sysctl), // 149
1296
1297 GENX_(__NR_mlock, sys_mlock), // 150
1298 GENX_(__NR_munlock, sys_munlock), // 151
1299 GENX_(__NR_mlockall, sys_mlockall), // 152
1300 LINX_(__NR_munlockall, sys_munlockall), // 153
1301 LINXY(__NR_sched_setparam, sys_sched_setparam), // 154
1302
1303 LINXY(__NR_sched_getparam, sys_sched_getparam), // 155
1304 LINX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 156
1305 LINX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 157
1306 LINX_(__NR_sched_yield, sys_sched_yield), // 158
1307 LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max), // 159
1308
1309 LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min), // 160
1310 // ?????(__NR_sched_rr_get_interval, ), // 161
1311 GENXY(__NR_nanosleep, sys_nanosleep), // 162
1312 GENX_(__NR_mremap, sys_mremap), // 163
1313 GENX_(164, sys_ni_syscall), /* unimplemented (by the kernel) */ // 164
1314
1315 GENX_(165, sys_ni_syscall), /* unimplemented (by the kernel) */ // 165
1316 GENX_(166, sys_ni_syscall), /* unimplemented (by the kernel) */ // 166
1317 GENX_(167, sys_ni_syscall), /* unimplemented (by the kernel) */ // 167
1318 GENXY(__NR_poll, sys_poll), // 168
1319 // ?????(__NR_nfsservctl, ), // 169
1320
1321 GENX_(170, sys_ni_syscall), /* unimplemented (by the kernel) */ // 170
1322 GENX_(171, sys_ni_syscall), /* unimplemented (by the kernel) */ // 171
1323 LINXY(__NR_prctl, sys_prctl), // 172
1324 PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 173
1325 LINXY(__NR_rt_sigaction, sys_rt_sigaction), // 174
1326
1327 LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 175
1328 LINXY(__NR_rt_sigpending, sys_rt_sigpending), // 176
1329 LINXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait), // 177
1330 LINXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo), // 178
1331 LINX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 179
1332
1333 GENXY(__NR_pread64, sys_pread64), // 180
1334 GENX_(__NR_pwrite64, sys_pwrite64), // 181
1335 GENX_(182, sys_ni_syscall), /* unimplemented (by the kernel) */ // 182
1336 GENXY(__NR_getcwd, sys_getcwd), // 183
1337 LINXY(__NR_capget, sys_capget), // 184
1338
1339 LINX_(__NR_capset, sys_capset), // 185
1340 GENXY(__NR_sigaltstack, sys_sigaltstack), // 186
1341 LINXY(__NR_sendfile, sys_sendfile), // 187
1342 GENX_(188, sys_ni_syscall), /* unimplemented (by the kernel) */ // 188
1343 GENX_(189, sys_ni_syscall), /* unimplemented (by the kernel) */ // 189
1344
1345 GENX_(__NR_vfork, sys_fork), // 190
1346 GENXY(__NR_getrlimit, sys_getrlimit), // 191
1347 GENX_(192, sys_ni_syscall), /* not exported on 64bit*/ // 192
1348 GENX_(193, sys_ni_syscall), /* unimplemented (by the kernel) */ // 193
1349 GENX_(194, sys_ni_syscall), /* unimplemented (by the kernel) */ // 194
1350
1351 GENX_(195, sys_ni_syscall), /* unimplemented (by the kernel) */ // 195
1352 GENX_(196, sys_ni_syscall), /* unimplemented (by the kernel) */ // 196
1353 GENX_(197, sys_ni_syscall), /* unimplemented (by the kernel) */ // 197
1354 GENX_(__NR_lchown, sys_lchown), // 198
1355 GENX_(__NR_getuid, sys_getuid), // 199
1356
1357 GENX_(__NR_getgid, sys_getgid), // 200
1358 GENX_(__NR_geteuid, sys_geteuid), // 201
1359 GENX_(__NR_getegid, sys_getegid), // 202
1360 GENX_(__NR_setreuid, sys_setreuid), // 203
1361 GENX_(__NR_setregid, sys_setregid), // 204
1362
1363 GENXY(__NR_getgroups, sys_getgroups), // 205
1364 GENX_(__NR_setgroups, sys_setgroups), // 206
1365 GENX_(__NR_fchown, sys_fchown), // 207
1366 LINX_(__NR_setresuid, sys_setresuid), // 208
1367 LINXY(__NR_getresuid, sys_getresuid), // 209
1368
1369 LINX_(__NR_setresgid, sys_setresgid), // 210
1370 LINXY(__NR_getresgid, sys_getresgid), // 211
1371 GENX_(__NR_chown, sys_chown), // 212
1372 GENX_(__NR_setuid, sys_setuid), // 213
1373 GENX_(__NR_setgid, sys_setgid), // 214
1374
1375 LINX_(__NR_setfsuid, sys_setfsuid), // 215
1376 LINX_(__NR_setfsgid, sys_setfsgid), // 216
1377 // ?????(__NR_pivot_root, ),
1378 GENXY(__NR_mincore, sys_mincore), // 218
1379 GENX_(__NR_madvise, sys_madvise), // 219
1380
1381 GENXY(__NR_getdents64, sys_getdents64), // 220
1382 GENX_(221, sys_ni_syscall), /* unimplemented (by the kernel) */ // 221
1383 LINX_(__NR_readahead, sys_readahead), // 222
1384 GENX_(223, sys_ni_syscall), /* unimplemented (by the kernel) */ // 223
1385 LINX_(__NR_setxattr, sys_setxattr), // 224
1386
1387 LINX_(__NR_lsetxattr, sys_lsetxattr), // 225
1388 LINX_(__NR_fsetxattr, sys_fsetxattr), // 226
1389 LINXY(__NR_getxattr, sys_getxattr), // 227
1390 LINXY(__NR_lgetxattr, sys_lgetxattr), // 228
1391 LINXY(__NR_fgetxattr, sys_fgetxattr), // 229
1392
1393 LINXY(__NR_listxattr, sys_listxattr), // 230
1394 LINXY(__NR_llistxattr, sys_llistxattr), // 231
1395 LINXY(__NR_flistxattr, sys_flistxattr), // 232
1396 LINX_(__NR_removexattr, sys_removexattr), // 233
1397 LINX_(__NR_lremovexattr, sys_lremovexattr), // 234
1398
1399 LINX_(__NR_fremovexattr, sys_fremovexattr), // 235
1400 LINX_(__NR_gettid, sys_gettid), // 236
1401 LINXY(__NR_tkill, sys_tkill), // 237
1402 LINXY(__NR_futex, sys_futex), // 238
1403 LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 239
1404
1405 LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 240
1406 LINXY(__NR_tgkill, sys_tgkill), // 241
1407 GENX_(242, sys_ni_syscall), /* unimplemented (by the kernel) */ // 242
1408 LINXY(__NR_io_setup, sys_io_setup), // 243
1409 LINX_(__NR_io_destroy, sys_io_destroy), // 244
1410
1411 LINXY(__NR_io_getevents, sys_io_getevents), // 245
1412 LINX_(__NR_io_submit, sys_io_submit), // 246
1413 LINXY(__NR_io_cancel, sys_io_cancel), // 247
1414 LINX_(__NR_exit_group, sys_exit_group), // 248
1415 LINXY(__NR_epoll_create, sys_epoll_create), // 249
1416
1417 LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 250
1418 LINXY(__NR_epoll_wait, sys_epoll_wait), // 251
1419 LINX_(__NR_set_tid_address, sys_set_tid_address), // 252
1420 PLAX_(__NR_fadvise64, sys_fadvise64), // 253
1421 LINXY(__NR_timer_create, sys_timer_create), // 254
1422
1423 LINXY(__NR_timer_settime, sys_timer_settime), // 255
1424 LINXY(__NR_timer_gettime, sys_timer_gettime), // 256
1425 LINX_(__NR_timer_getoverrun, sys_timer_getoverrun), // 257
1426 LINX_(__NR_timer_delete, sys_timer_delete), // 258
1427 LINX_(__NR_clock_settime, sys_clock_settime), // 259
1428
1429 LINXY(__NR_clock_gettime, sys_clock_gettime), // 260
1430 LINXY(__NR_clock_getres, sys_clock_getres), // 261
1431 LINXY(__NR_clock_nanosleep, sys_clock_nanosleep), // 262
1432 GENX_(263, sys_ni_syscall), /* unimplemented (by the kernel) */ // 263
1433 GENX_(264, sys_ni_syscall), /* unimplemented (by the kernel) */ // 264
1434
1435 GENXY(__NR_statfs64, sys_statfs64), // 265
1436 GENXY(__NR_fstatfs64, sys_fstatfs64), // 266
1437 // ?????(__NR_remap_file_pages, ),
1438 GENX_(268, sys_ni_syscall), /* unimplemented (by the kernel) */ // 268
1439 GENX_(269, sys_ni_syscall), /* unimplemented (by the kernel) */ // 269
1440
1441 GENX_(270, sys_ni_syscall), /* unimplemented (by the kernel) */ // 270
1442 LINXY(__NR_mq_open, sys_mq_open), // 271
1443 LINX_(__NR_mq_unlink, sys_mq_unlink), // 272
1444 LINX_(__NR_mq_timedsend, sys_mq_timedsend), // 273
1445 LINXY(__NR_mq_timedreceive, sys_mq_timedreceive), // 274
1446
1447 LINX_(__NR_mq_notify, sys_mq_notify), // 275
1448 LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // 276
1449 // ?????(__NR_kexec_load, ),
1450 LINX_(__NR_add_key, sys_add_key), // 278
1451 LINX_(__NR_request_key, sys_request_key), // 279
1452
1453 LINXY(__NR_keyctl, sys_keyctl), // 280
1454 LINXY(__NR_waitid, sys_waitid), // 281
1455 LINX_(__NR_ioprio_set, sys_ioprio_set), // 282
1456 LINX_(__NR_ioprio_get, sys_ioprio_get), // 283
1457 LINX_(__NR_inotify_init, sys_inotify_init), // 284
1458
1459 LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 285
1460 LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 286
1461 GENX_(287, sys_ni_syscall), /* unimplemented (by the kernel) */ // 287
1462 LINXY(__NR_openat, sys_openat), // 288
1463 LINX_(__NR_mkdirat, sys_mkdirat), // 289
1464
1465 LINX_(__NR_mknodat, sys_mknodat), // 290
1466 LINX_(__NR_fchownat, sys_fchownat), // 291
1467 LINX_(__NR_futimesat, sys_futimesat), // 292
1468 LINXY(__NR_newfstatat, sys_newfstatat), // 293
1469 LINX_(__NR_unlinkat, sys_unlinkat), // 294
1470
1471 LINX_(__NR_renameat, sys_renameat), // 295
1472 LINX_(__NR_linkat, sys_linkat), // 296
1473 LINX_(__NR_symlinkat, sys_symlinkat), // 297
1474 LINX_(__NR_readlinkat, sys_readlinkat), // 298
1475 LINX_(__NR_fchmodat, sys_fchmodat), // 299
1476
1477 LINX_(__NR_faccessat, sys_faccessat), // 300
1478 LINX_(__NR_pselect6, sys_pselect6), // 301
1479 LINXY(__NR_ppoll, sys_ppoll), // 302
1480 // ?????(__NR_unshare, ),
1481 LINX_(__NR_set_robust_list, sys_set_robust_list), // 304
1482
1483 LINXY(__NR_get_robust_list, sys_get_robust_list), // 305
1484 // ?????(__NR_splice, ),
1485 LINX_(__NR_sync_file_range, sys_sync_file_range), // 307
1486 // ?????(__NR_tee, ),
1487 // ?????(__NR_vmsplice, ),
1488
1489 GENX_(310, sys_ni_syscall), /* unimplemented (by the kernel) */ // 310
1490 // ?????(__NR_getcpu, ),
1491 LINXY(__NR_epoll_pwait, sys_epoll_pwait), // 312
1492 GENX_(__NR_utimes, sys_utimes), // 313
1493 LINX_(__NR_fallocate, sys_fallocate), // 314
1494
1495 LINX_(__NR_utimensat, sys_utimensat), // 315
1496 LINXY(__NR_signalfd, sys_signalfd), // 316
1497 GENX_(317, sys_ni_syscall), /* unimplemented (by the kernel) */ // 317
1498 LINX_(__NR_eventfd, sys_eventfd), // 318
1499 LINXY(__NR_timerfd_create, sys_timerfd_create), // 319
1500
1501 LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 320
1502 LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 321
1503 LINXY(__NR_signalfd4, sys_signalfd4), // 322
1504 LINX_(__NR_eventfd2, sys_eventfd2), // 323
1505 LINXY(__NR_inotify_init1, sys_inotify_init1), // 324
1506
1507 LINXY(__NR_pipe2, sys_pipe2), // 325
1508 // (__NR_dup3, ),
1509 LINXY(__NR_epoll_create1, sys_epoll_create1), // 327
1510 LINXY(__NR_preadv, sys_preadv), // 328
1511 LINX_(__NR_pwritev, sys_pwritev), // 329
1512
1513 // ?????(__NR_rt_tgsigqueueinfo, ),
1514 LINXY(__NR_perf_event_open, sys_perf_event_open), // 331
1515 // ?????(__NR_fanotify_init, ), // 332
1516 // ?????(__NR_fanotify_mark, ), // 333
1517 LINXY(__NR_prlimit64, sys_prlimit64), // 334
1518 // ?????(__NR_name_to_handle_at, ), // 335
1519 // ?????(__NR_open_by_handle_at, ), // 336
1520 // ?????(__NR_clock_adjtime, ), // 337
1521 // ?????(__NR_syncfs, ), // 338
1522 // ?????(__NR_setns, ), // 339
1523 LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 340
1524 LINX_(__NR_process_vm_writev, sys_process_vm_writev), // 341
1525 };
1526
ML_(get_linux_syscall_entry)1527 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1528 {
1529 const UInt syscall_table_size
1530 = sizeof(syscall_table) / sizeof(syscall_table[0]);
1531
1532 /* Is it in the contiguous initial section of the table? */
1533 if (sysno < syscall_table_size) {
1534 SyscallTableEntry* sys = &syscall_table[sysno];
1535 if (sys->before == NULL)
1536 return NULL; /* no entry */
1537 else
1538 return sys;
1539 }
1540
1541 /* Can't find a wrapper */
1542 return NULL;
1543 }
1544
1545 #endif
1546
1547 /*--------------------------------------------------------------------*/
1548 /*--- end ---*/
1549 /*--------------------------------------------------------------------*/
1550