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