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-2017 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_threadstate.h"
42 #include "pub_core_aspacemgr.h"
43 #include "pub_core_debuglog.h"
44 #include "pub_core_libcbase.h"
45 #include "pub_core_libcassert.h"
46 #include "pub_core_libcprint.h"
47 #include "pub_core_libcproc.h"
48 #include "pub_core_libcsignal.h"
49 #include "pub_core_mallocfree.h"
50 #include "pub_core_options.h"
51 #include "pub_core_scheduler.h"
52 #include "pub_core_sigframe.h" // For VG_(sigframe_destroy)()
53 #include "pub_core_signals.h"
54 #include "pub_core_syscall.h"
55 #include "pub_core_syswrap.h"
56 #include "pub_core_tooliface.h"
57
58 #include "priv_types_n_macros.h"
59 #include "priv_syswrap-generic.h" /* for decls of generic wrappers */
60 #include "priv_syswrap-linux.h" /* for decls of linux-ish wrappers */
61 #include "priv_syswrap-linux-variants.h" /* decls of linux variant wrappers */
62 #include "priv_syswrap-main.h"
63
64
65 /* ---------------------------------------------------------------------
66 clone() handling
67 ------------------------------------------------------------------ */
68
69 /* Call f(arg1), but first switch stacks, using 'stack' as the new
70 stack, and use 'retaddr' as f's return-to address. Also, clear all
71 the integer registers before entering f.*/
72 __attribute__((noreturn))
73 void ML_(call_on_new_stack_0_1) ( Addr stack,
74 Addr retaddr,
75 void (*f)(Word),
76 Word arg1 );
77 // 4(%esp) == stack
78 // 8(%esp) == retaddr
79 // 12(%esp) == f
80 // 16(%esp) == arg1
81 asm(
82 ".text\n"
83 ".globl vgModuleLocal_call_on_new_stack_0_1\n"
84 "vgModuleLocal_call_on_new_stack_0_1:\n"
85 " movl %esp, %esi\n" // remember old stack pointer
86 " movl 4(%esi), %esp\n" // set stack, assume %esp is now 16-byte aligned
87 " subl $12, %esp\n" // skip 12 bytes
88 " pushl 16(%esi)\n" // arg1 to stack, %esp is 16-byte aligned
89 " pushl 8(%esi)\n" // retaddr to stack
90 " pushl 12(%esi)\n" // f to stack
91 " movl $0, %eax\n" // zero all GP regs
92 " movl $0, %ebx\n"
93 " movl $0, %ecx\n"
94 " movl $0, %edx\n"
95 " movl $0, %esi\n"
96 " movl $0, %edi\n"
97 " movl $0, %ebp\n"
98 " ret\n" // jump to f
99 " ud2\n" // should never get here
100 ".previous\n"
101 );
102
103
104 /*
105 Perform a clone system call. clone is strange because it has
106 fork()-like return-twice semantics, so it needs special
107 handling here.
108
109 Upon entry, we have:
110
111 int (fn)(void*) in 0+FSZ(%esp)
112 void* child_stack in 4+FSZ(%esp)
113 int flags in 8+FSZ(%esp)
114 void* arg in 12+FSZ(%esp)
115 pid_t* child_tid in 16+FSZ(%esp)
116 pid_t* parent_tid in 20+FSZ(%esp)
117 void* tls_ptr in 24+FSZ(%esp)
118
119 System call requires:
120
121 int $__NR_clone in %eax
122 int flags in %ebx
123 void* child_stack in %ecx
124 pid_t* parent_tid in %edx
125 pid_t* child_tid in %edi
126 void* tls_ptr in %esi
127
128 Returns an Int encoded in the linux-x86 way, not a SysRes.
129 */
130 #define FSZ "4+4+4+4" /* frame size = retaddr+ebx+edi+esi */
131 #define __NR_CLONE VG_STRINGIFY(__NR_clone)
132 #define __NR_EXIT VG_STRINGIFY(__NR_exit)
133
134 // See priv_syswrap-linux.h for arg profile.
135 asm(
136 ".text\n"
137 ".globl do_syscall_clone_x86_linux\n"
138 "do_syscall_clone_x86_linux:\n"
139 " push %ebx\n"
140 " push %edi\n"
141 " push %esi\n"
142
143 /* set up child stack with function and arg */
144 " movl 4+"FSZ"(%esp), %ecx\n" /* syscall arg2: child stack */
145 " movl 12+"FSZ"(%esp), %ebx\n" /* fn arg */
146 " movl 0+"FSZ"(%esp), %eax\n" /* fn */
147 " andl $-16, %ecx\n" /* align to 16-byte */
148 " lea -20(%ecx), %ecx\n" /* allocate 16*n+4 bytes on stack */
149 " movl %ebx, 4(%ecx)\n" /* fn arg */
150 " movl %eax, 0(%ecx)\n" /* fn */
151
152 /* get other args to clone */
153 " movl 8+"FSZ"(%esp), %ebx\n" /* syscall arg1: flags */
154 " movl 20+"FSZ"(%esp), %edx\n" /* syscall arg3: parent tid * */
155 " movl 16+"FSZ"(%esp), %edi\n" /* syscall arg5: child tid * */
156 " movl 24+"FSZ"(%esp), %esi\n" /* syscall arg4: tls_ptr * */
157 " movl $"__NR_CLONE", %eax\n"
158 " int $0x80\n" /* clone() */
159 " testl %eax, %eax\n" /* child if retval == 0 */
160 " jnz 1f\n"
161
162 /* CHILD - call thread function */
163 " popl %eax\n" /* child %esp is 16-byte aligned */
164 " call *%eax\n" /* call fn */
165
166 /* exit with result */
167 " movl %eax, %ebx\n" /* arg1: return value from fn */
168 " movl $"__NR_EXIT", %eax\n"
169 " int $0x80\n"
170
171 /* Hm, exit returned */
172 " ud2\n"
173
174 "1:\n" /* PARENT or ERROR */
175 " pop %esi\n"
176 " pop %edi\n"
177 " pop %ebx\n"
178 " ret\n"
179 ".previous\n"
180 );
181
182 #undef FSZ
183 #undef __NR_CLONE
184 #undef __NR_EXIT
185
186
187 /* ---------------------------------------------------------------------
188 LDT/GDT simulation
189 ------------------------------------------------------------------ */
190
191 /* Details of the LDT simulation
192 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
193
194 When a program runs natively, the linux kernel allows each *thread*
195 in it to have its own LDT. Almost all programs never do this --
196 it's wildly unportable, after all -- and so the kernel never
197 allocates the structure, which is just as well as an LDT occupies
198 64k of memory (8192 entries of size 8 bytes).
199
200 A thread may choose to modify its LDT entries, by doing the
201 __NR_modify_ldt syscall. In such a situation the kernel will then
202 allocate an LDT structure for it. Each LDT entry is basically a
203 (base, limit) pair. A virtual address in a specific segment is
204 translated to a linear address by adding the segment's base value.
205 In addition, the virtual address must not exceed the limit value.
206
207 To use an LDT entry, a thread loads one of the segment registers
208 (%cs, %ss, %ds, %es, %fs, %gs) with the index of the LDT entry (0
209 .. 8191) it wants to use. In fact, the required value is (index <<
210 3) + 7, but that's not important right now. Any normal instruction
211 which includes an addressing mode can then be made relative to that
212 LDT entry by prefixing the insn with a so-called segment-override
213 prefix, a byte which indicates which of the 6 segment registers
214 holds the LDT index.
215
216 Now, a key constraint is that valgrind's address checks operate in
217 terms of linear addresses. So we have to explicitly translate
218 virtual addrs into linear addrs, and that means doing a complete
219 LDT simulation.
220
221 Calls to modify_ldt are intercepted. For each thread, we maintain
222 an LDT (with the same normally-never-allocated optimisation that
223 the kernel does). This is updated as expected via calls to
224 modify_ldt.
225
226 When a thread does an amode calculation involving a segment
227 override prefix, the relevant LDT entry for the thread is
228 consulted. It all works.
229
230 There is a conceptual problem, which appears when switching back to
231 native execution, either temporarily to pass syscalls to the
232 kernel, or permanently, when debugging V. Problem at such points
233 is that it's pretty pointless to copy the simulated machine's
234 segment registers to the real machine, because we'd also need to
235 copy the simulated LDT into the real one, and that's prohibitively
236 expensive.
237
238 Fortunately it looks like no syscalls rely on the segment regs or
239 LDT being correct, so we can get away with it. Apart from that the
240 simulation is pretty straightforward. All 6 segment registers are
241 tracked, although only %ds, %es, %fs and %gs are allowed as
242 prefixes. Perhaps it could be restricted even more than that -- I
243 am not sure what is and isn't allowed in user-mode.
244 */
245
246 /* Translate a struct modify_ldt_ldt_s to a VexGuestX86SegDescr, using
247 the Linux kernel's logic (cut-n-paste of code in
248 linux/kernel/ldt.c). */
249
250 static
translate_to_hw_format(vki_modify_ldt_t * inn,VexGuestX86SegDescr * out,Int oldmode)251 void translate_to_hw_format ( /* IN */ vki_modify_ldt_t* inn,
252 /* OUT */ VexGuestX86SegDescr* out,
253 Int oldmode )
254 {
255 UInt entry_1, entry_2;
256 vg_assert(8 == sizeof(VexGuestX86SegDescr));
257
258 if (0)
259 VG_(printf)("translate_to_hw_format: base %#lx, limit %u\n",
260 inn->base_addr, inn->limit );
261
262 /* Allow LDTs to be cleared by the user. */
263 if (inn->base_addr == 0 && inn->limit == 0) {
264 if (oldmode ||
265 (inn->contents == 0 &&
266 inn->read_exec_only == 1 &&
267 inn->seg_32bit == 0 &&
268 inn->limit_in_pages == 0 &&
269 inn->seg_not_present == 1 &&
270 inn->useable == 0 )) {
271 entry_1 = 0;
272 entry_2 = 0;
273 goto install;
274 }
275 }
276
277 entry_1 = ((inn->base_addr & 0x0000ffff) << 16) |
278 (inn->limit & 0x0ffff);
279 entry_2 = (inn->base_addr & 0xff000000) |
280 ((inn->base_addr & 0x00ff0000) >> 16) |
281 (inn->limit & 0xf0000) |
282 ((inn->read_exec_only ^ 1) << 9) |
283 (inn->contents << 10) |
284 ((inn->seg_not_present ^ 1) << 15) |
285 (inn->seg_32bit << 22) |
286 (inn->limit_in_pages << 23) |
287 0x7000;
288 if (!oldmode)
289 entry_2 |= (inn->useable << 20);
290
291 /* Install the new entry ... */
292 install:
293 out->LdtEnt.Words.word1 = entry_1;
294 out->LdtEnt.Words.word2 = entry_2;
295 }
296
297 /* Create initial GDT. */
alloc_system_x86_GDT(void)298 static VexGuestX86SegDescr* alloc_system_x86_GDT ( void )
299 {
300 Int nbytes = VEX_GUEST_X86_GDT_NENT * sizeof(VexGuestX86SegDescr);
301 VexGuestX86SegDescr* gdt = VG_(calloc)("di.syswrap-x86.azxG.1", nbytes, 1);
302 vki_modify_ldt_t info;
303 UShort seg;
304
305 VG_(memset)(&info, 0, sizeof(info));
306 info.entry_number = 0;
307 info.base_addr = 0;
308 info.limit = 0xfffff;
309 info.seg_32bit = 1;
310 info.contents = 0;
311 info.read_exec_only = 0;
312 info.limit_in_pages = 1;
313 info.seg_not_present = 0;
314 info.useable = 0;
315 info.reserved = 0;
316
317 asm volatile("movw %%ds, %0" : : "m" (seg));
318 if (!(seg & 4)) translate_to_hw_format(&info, &gdt[seg >> 3], 0);
319 asm volatile("movw %%ss, %0" : : "m" (seg));
320 if (!(seg & 4)) translate_to_hw_format(&info, &gdt[seg >> 3], 0);
321
322 info.contents = 2;
323
324 asm volatile("movw %%cs, %0" : : "m" (seg));
325 if (!(seg & 4)) translate_to_hw_format(&info, &gdt[seg >> 3], 0);
326
327 return gdt;
328 }
329
330 /* Create a zeroed-out LDT. */
alloc_zeroed_x86_LDT(void)331 static VexGuestX86SegDescr* alloc_zeroed_x86_LDT ( void )
332 {
333 Int nbytes = VEX_GUEST_X86_LDT_NENT * sizeof(VexGuestX86SegDescr);
334 return VG_(calloc)("di.syswrap-x86.azxL.1", nbytes, 1);
335 }
336
337 /* Free up an LDT or GDT allocated by the above fns. */
free_LDT_or_GDT(VexGuestX86SegDescr * dt)338 static void free_LDT_or_GDT ( VexGuestX86SegDescr* dt )
339 {
340 vg_assert(dt);
341 VG_(free)(dt);
342 }
343
344 /* Copy contents between two existing LDTs. */
copy_LDT_from_to(VexGuestX86SegDescr * src,VexGuestX86SegDescr * dst)345 static void copy_LDT_from_to ( VexGuestX86SegDescr* src,
346 VexGuestX86SegDescr* dst )
347 {
348 Int i;
349 vg_assert(src);
350 vg_assert(dst);
351 for (i = 0; i < VEX_GUEST_X86_LDT_NENT; i++)
352 dst[i] = src[i];
353 }
354
355 /* Copy contents between two existing GDTs. */
copy_GDT_from_to(VexGuestX86SegDescr * src,VexGuestX86SegDescr * dst)356 static void copy_GDT_from_to ( VexGuestX86SegDescr* src,
357 VexGuestX86SegDescr* dst )
358 {
359 Int i;
360 vg_assert(src);
361 vg_assert(dst);
362 for (i = 0; i < VEX_GUEST_X86_GDT_NENT; i++)
363 dst[i] = src[i];
364 }
365
366 /* Free this thread's DTs, if it has any. */
deallocate_LGDTs_for_thread(VexGuestX86State * vex)367 static void deallocate_LGDTs_for_thread ( VexGuestX86State* vex )
368 {
369 vg_assert(sizeof(HWord) == sizeof(void*));
370
371 if (0)
372 VG_(printf)("deallocate_LGDTs_for_thread: "
373 "ldt = 0x%llx, gdt = 0x%llx\n",
374 vex->guest_LDT, vex->guest_GDT );
375
376 if (vex->guest_LDT != (HWord)NULL) {
377 free_LDT_or_GDT( (VexGuestX86SegDescr*)(HWord)vex->guest_LDT );
378 vex->guest_LDT = (HWord)NULL;
379 }
380
381 if (vex->guest_GDT != (HWord)NULL) {
382 free_LDT_or_GDT( (VexGuestX86SegDescr*)(HWord)vex->guest_GDT );
383 vex->guest_GDT = (HWord)NULL;
384 }
385 }
386
387
388 /*
389 * linux/kernel/ldt.c
390 *
391 * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
392 * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
393 */
394
395 /*
396 * read_ldt() is not really atomic - this is not a problem since
397 * synchronization of reads and writes done to the LDT has to be
398 * assured by user-space anyway. Writes are atomic, to protect
399 * the security checks done on new descriptors.
400 */
401 static
read_ldt(ThreadId tid,UChar * ptr,UInt bytecount)402 SysRes read_ldt ( ThreadId tid, UChar* ptr, UInt bytecount )
403 {
404 SysRes res;
405 UInt i, size;
406 UChar* ldt;
407
408 if (0)
409 VG_(printf)("read_ldt: tid = %u, ptr = %p, bytecount = %u\n",
410 tid, ptr, bytecount );
411
412 vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
413 vg_assert(8 == sizeof(VexGuestX86SegDescr));
414
415 ldt = (UChar*)(HWord)(VG_(threads)[tid].arch.vex.guest_LDT);
416 res = VG_(mk_SysRes_Success)( 0 );
417 if (ldt == NULL)
418 /* LDT not allocated, meaning all entries are null */
419 goto out;
420
421 size = VEX_GUEST_X86_LDT_NENT * sizeof(VexGuestX86SegDescr);
422 if (size > bytecount)
423 size = bytecount;
424
425 res = VG_(mk_SysRes_Success)( size );
426 for (i = 0; i < size; i++)
427 ptr[i] = ldt[i];
428
429 out:
430 return res;
431 }
432
433
434 static
write_ldt(ThreadId tid,void * ptr,UInt bytecount,Int oldmode)435 SysRes write_ldt ( ThreadId tid, void* ptr, UInt bytecount, Int oldmode )
436 {
437 SysRes res;
438 VexGuestX86SegDescr* ldt;
439 vki_modify_ldt_t* ldt_info;
440
441 if (0)
442 VG_(printf)("write_ldt: tid = %u, ptr = %p, "
443 "bytecount = %u, oldmode = %d\n",
444 tid, ptr, bytecount, oldmode );
445
446 vg_assert(8 == sizeof(VexGuestX86SegDescr));
447 vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
448
449 ldt = (VexGuestX86SegDescr*)(HWord)VG_(threads)[tid].arch.vex.guest_LDT;
450 ldt_info = (vki_modify_ldt_t*)ptr;
451
452 res = VG_(mk_SysRes_Error)( VKI_EINVAL );
453 if (bytecount != sizeof(vki_modify_ldt_t))
454 goto out;
455
456 res = VG_(mk_SysRes_Error)( VKI_EINVAL );
457 if (ldt_info->entry_number >= VEX_GUEST_X86_LDT_NENT)
458 goto out;
459 if (ldt_info->contents == 3) {
460 if (oldmode)
461 goto out;
462 if (ldt_info->seg_not_present == 0)
463 goto out;
464 }
465
466 /* If this thread doesn't have an LDT, we'd better allocate it
467 now. */
468 if (ldt == NULL) {
469 ldt = alloc_zeroed_x86_LDT();
470 VG_(threads)[tid].arch.vex.guest_LDT = (HWord)ldt;
471 }
472
473 /* Install the new entry ... */
474 translate_to_hw_format ( ldt_info, &ldt[ldt_info->entry_number], oldmode );
475 res = VG_(mk_SysRes_Success)( 0 );
476
477 out:
478 return res;
479 }
480
481
sys_modify_ldt(ThreadId tid,Int func,void * ptr,UInt bytecount)482 static SysRes sys_modify_ldt ( ThreadId tid,
483 Int func, void* ptr, UInt bytecount )
484 {
485 /* Set return value to something "safe". I think this will never
486 actually be returned, though. */
487 SysRes ret = VG_(mk_SysRes_Error)( VKI_ENOSYS );
488
489 if (func != 0 && func != 1 && func != 2 && func != 0x11) {
490 ret = VG_(mk_SysRes_Error)( VKI_ENOSYS );
491 } else if (ptr != NULL && ! ML_(safe_to_deref)(ptr, bytecount)) {
492 ret = VG_(mk_SysRes_Error)( VKI_EFAULT );
493 } else {
494 switch (func) {
495 case 0:
496 ret = read_ldt(tid, ptr, bytecount);
497 break;
498 case 1:
499 ret = write_ldt(tid, ptr, bytecount, 1);
500 break;
501 case 2:
502 ret = VG_(mk_SysRes_Error)( VKI_ENOSYS );
503 VG_(unimplemented)("sys_modify_ldt: func == 2");
504 /* god knows what this is about */
505 /* ret = read_default_ldt(ptr, bytecount); */
506 /*UNREACHED*/
507 break;
508 case 0x11:
509 ret = write_ldt(tid, ptr, bytecount, 0);
510 break;
511 }
512 }
513 return ret;
514 }
515
516
ML_(x86_sys_set_thread_area)517 SysRes ML_(x86_sys_set_thread_area) ( ThreadId tid, vki_modify_ldt_t* info )
518 {
519 Int idx;
520 VexGuestX86SegDescr* gdt;
521
522 vg_assert(8 == sizeof(VexGuestX86SegDescr));
523 vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
524
525 if (info == NULL || ! ML_(safe_to_deref)(info, sizeof(vki_modify_ldt_t))) {
526 VG_(umsg)("Warning: bad u_info address %p in set_thread_area\n", info);
527 return VG_(mk_SysRes_Error)( VKI_EFAULT );
528 }
529
530 gdt = (VexGuestX86SegDescr*)(HWord)VG_(threads)[tid].arch.vex.guest_GDT;
531
532 /* If the thread doesn't have a GDT, allocate it now. */
533 if (!gdt) {
534 gdt = alloc_system_x86_GDT();
535 VG_(threads)[tid].arch.vex.guest_GDT = (HWord)gdt;
536 }
537
538 idx = info->entry_number;
539
540 if (idx == -1) {
541 /* Find and use the first free entry. Don't allocate entry
542 zero, because the hardware will never do that, and apparently
543 doing so confuses some code (perhaps stuff running on
544 Wine). */
545 for (idx = 1; idx < VEX_GUEST_X86_GDT_NENT; idx++) {
546 if (gdt[idx].LdtEnt.Words.word1 == 0
547 && gdt[idx].LdtEnt.Words.word2 == 0)
548 break;
549 }
550
551 if (idx == VEX_GUEST_X86_GDT_NENT)
552 return VG_(mk_SysRes_Error)( VKI_ESRCH );
553 } else if (idx < 0 || idx == 0 || idx >= VEX_GUEST_X86_GDT_NENT) {
554 /* Similarly, reject attempts to use GDT[0]. */
555 return VG_(mk_SysRes_Error)( VKI_EINVAL );
556 }
557
558 translate_to_hw_format(info, &gdt[idx], 0);
559
560 VG_TRACK( pre_mem_write, Vg_CoreSysCall, tid,
561 "set_thread_area(info->entry)",
562 (Addr) & info->entry_number, sizeof(unsigned int) );
563 info->entry_number = idx;
564 VG_TRACK( post_mem_write, Vg_CoreSysCall, tid,
565 (Addr) & info->entry_number, sizeof(unsigned int) );
566
567 return VG_(mk_SysRes_Success)( 0 );
568 }
569
570
sys_get_thread_area(ThreadId tid,vki_modify_ldt_t * info)571 static SysRes sys_get_thread_area ( ThreadId tid, vki_modify_ldt_t* info )
572 {
573 Int idx;
574 VexGuestX86SegDescr* gdt;
575
576 vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
577 vg_assert(8 == sizeof(VexGuestX86SegDescr));
578
579 if (info == NULL || ! ML_(safe_to_deref)(info, sizeof(vki_modify_ldt_t))) {
580 VG_(umsg)("Warning: bad u_info address %p in get_thread_area\n", info);
581 return VG_(mk_SysRes_Error)( VKI_EFAULT );
582 }
583
584 idx = info->entry_number;
585
586 if (idx < 0 || idx >= VEX_GUEST_X86_GDT_NENT)
587 return VG_(mk_SysRes_Error)( VKI_EINVAL );
588
589 gdt = (VexGuestX86SegDescr*)(HWord)VG_(threads)[tid].arch.vex.guest_GDT;
590
591 /* If the thread doesn't have a GDT, allocate it now. */
592 if (!gdt) {
593 gdt = alloc_system_x86_GDT();
594 VG_(threads)[tid].arch.vex.guest_GDT = (HWord)gdt;
595 }
596
597 info->base_addr = ( gdt[idx].LdtEnt.Bits.BaseHi << 24 ) |
598 ( gdt[idx].LdtEnt.Bits.BaseMid << 16 ) |
599 gdt[idx].LdtEnt.Bits.BaseLow;
600 info->limit = ( gdt[idx].LdtEnt.Bits.LimitHi << 16 ) |
601 gdt[idx].LdtEnt.Bits.LimitLow;
602 info->seg_32bit = gdt[idx].LdtEnt.Bits.Default_Big;
603 info->contents = ( gdt[idx].LdtEnt.Bits.Type >> 2 ) & 0x3;
604 info->read_exec_only = ( gdt[idx].LdtEnt.Bits.Type & 0x1 ) ^ 0x1;
605 info->limit_in_pages = gdt[idx].LdtEnt.Bits.Granularity;
606 info->seg_not_present = gdt[idx].LdtEnt.Bits.Pres ^ 0x1;
607 info->useable = gdt[idx].LdtEnt.Bits.Sys;
608 info->reserved = 0;
609
610 return VG_(mk_SysRes_Success)( 0 );
611 }
612
613 /* ---------------------------------------------------------------------
614 More thread stuff
615 ------------------------------------------------------------------ */
616
VG_(cleanup_thread)617 void VG_(cleanup_thread) ( ThreadArchState* arch )
618 {
619 /* Release arch-specific resources held by this thread. */
620 /* On x86, we have to dump the LDT and GDT. */
621 deallocate_LGDTs_for_thread( &arch->vex );
622 }
623
624
ML_(x86_setup_LDT_GDT)625 void ML_(x86_setup_LDT_GDT) ( /*OUT*/ ThreadArchState *child,
626 /*IN*/ ThreadArchState *parent )
627 {
628 /* We inherit our parent's LDT. */
629 if (parent->vex.guest_LDT == (HWord)NULL) {
630 /* We hope this is the common case. */
631 child->vex.guest_LDT = (HWord)NULL;
632 } else {
633 /* No luck .. we have to take a copy of the parent's. */
634 child->vex.guest_LDT = (HWord)alloc_zeroed_x86_LDT();
635 copy_LDT_from_to( (VexGuestX86SegDescr*)(HWord)parent->vex.guest_LDT,
636 (VexGuestX86SegDescr*)(HWord)child->vex.guest_LDT );
637 }
638
639 /* Either we start with an empty GDT (the usual case) or inherit a
640 copy of our parents' one (Quadrics Elan3 driver -style clone
641 only). */
642 child->vex.guest_GDT = (HWord)NULL;
643
644 if (parent->vex.guest_GDT != (HWord)NULL) {
645 child->vex.guest_GDT = (HWord)alloc_system_x86_GDT();
646 copy_GDT_from_to( (VexGuestX86SegDescr*)(HWord)parent->vex.guest_GDT,
647 (VexGuestX86SegDescr*)(HWord)child->vex.guest_GDT );
648 }
649 }
650
651
652 /* ---------------------------------------------------------------------
653 PRE/POST wrappers for x86/Linux-specific syscalls
654 ------------------------------------------------------------------ */
655
656 #define PRE(name) DEFN_PRE_TEMPLATE(x86_linux, name)
657 #define POST(name) DEFN_POST_TEMPLATE(x86_linux, name)
658
659 /* Add prototypes for the wrappers declared here, so that gcc doesn't
660 harass us for not having prototypes. Really this is a kludge --
661 the right thing to do is to make these wrappers 'static' since they
662 aren't visible outside this file, but that requires even more macro
663 magic. */
664 DECL_TEMPLATE(x86_linux, sys_stat64);
665 DECL_TEMPLATE(x86_linux, sys_fstatat64);
666 DECL_TEMPLATE(x86_linux, sys_fstat64);
667 DECL_TEMPLATE(x86_linux, sys_lstat64);
668 DECL_TEMPLATE(x86_linux, old_mmap);
669 DECL_TEMPLATE(x86_linux, sys_mmap2);
670 DECL_TEMPLATE(x86_linux, sys_sigreturn);
671 DECL_TEMPLATE(x86_linux, sys_rt_sigreturn);
672 DECL_TEMPLATE(x86_linux, sys_modify_ldt);
673 DECL_TEMPLATE(x86_linux, sys_set_thread_area);
674 DECL_TEMPLATE(x86_linux, sys_get_thread_area);
675 DECL_TEMPLATE(x86_linux, sys_ptrace);
676 DECL_TEMPLATE(x86_linux, sys_sigsuspend);
677 DECL_TEMPLATE(x86_linux, old_select);
678 DECL_TEMPLATE(x86_linux, sys_vm86old);
679 DECL_TEMPLATE(x86_linux, sys_vm86);
680 DECL_TEMPLATE(x86_linux, sys_syscall223);
681
PRE(old_select)682 PRE(old_select)
683 {
684 /* struct sel_arg_struct {
685 unsigned long n;
686 fd_set *inp, *outp, *exp;
687 struct timeval *tvp;
688 };
689 */
690 PRE_REG_READ1(long, "old_select", struct sel_arg_struct *, args);
691 PRE_MEM_READ( "old_select(args)", ARG1, 5*sizeof(UWord) );
692 *flags |= SfMayBlock;
693 {
694 UInt* arg_struct = (UInt*)ARG1;
695 UInt a1, a2, a3, a4, a5;
696
697 a1 = arg_struct[0];
698 a2 = arg_struct[1];
699 a3 = arg_struct[2];
700 a4 = arg_struct[3];
701 a5 = arg_struct[4];
702
703 PRINT("old_select ( %d, %#x, %#x, %#x, %#x )", (Int)a1,a2,a3,a4,a5);
704 if (a2 != (Addr)NULL)
705 PRE_MEM_READ( "old_select(readfds)", a2, a1/8 /* __FD_SETSIZE/8 */ );
706 if (a3 != (Addr)NULL)
707 PRE_MEM_READ( "old_select(writefds)", a3, a1/8 /* __FD_SETSIZE/8 */ );
708 if (a4 != (Addr)NULL)
709 PRE_MEM_READ( "old_select(exceptfds)", a4, a1/8 /* __FD_SETSIZE/8 */ );
710 if (a5 != (Addr)NULL)
711 PRE_MEM_READ( "old_select(timeout)", a5, sizeof(struct vki_timeval) );
712 }
713 }
714
PRE(sys_sigreturn)715 PRE(sys_sigreturn)
716 {
717 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
718 an explanation of what follows. */
719
720 ThreadState* tst;
721 PRINT("sys_sigreturn ( )");
722
723 vg_assert(VG_(is_valid_tid)(tid));
724 vg_assert(tid >= 1 && tid < VG_N_THREADS);
725 vg_assert(VG_(is_running_thread)(tid));
726
727 /* Adjust esp to point to start of frame; skip back up over
728 sigreturn sequence's "popl %eax" and handler ret addr */
729 tst = VG_(get_ThreadState)(tid);
730 tst->arch.vex.guest_ESP -= sizeof(Addr)+sizeof(Word);
731 /* XXX why does ESP change differ from rt_sigreturn case below? */
732
733 /* This is only so that the EIP is (might be) useful to report if
734 something goes wrong in the sigreturn */
735 ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
736
737 /* Restore register state from frame and remove it */
738 VG_(sigframe_destroy)(tid, False);
739
740 /* Tell the driver not to update the guest state with the "result",
741 and set a bogus result to keep it happy. */
742 *flags |= SfNoWriteResult;
743 SET_STATUS_Success(0);
744
745 /* Check to see if any signals arose as a result of this. */
746 *flags |= SfPollAfter;
747 }
748
PRE(sys_rt_sigreturn)749 PRE(sys_rt_sigreturn)
750 {
751 /* See comments on PRE(sys_rt_sigreturn) in syswrap-amd64-linux.c for
752 an explanation of what follows. */
753
754 ThreadState* tst;
755 PRINT("sys_rt_sigreturn ( )");
756
757 vg_assert(VG_(is_valid_tid)(tid));
758 vg_assert(tid >= 1 && tid < VG_N_THREADS);
759 vg_assert(VG_(is_running_thread)(tid));
760
761 /* Adjust esp to point to start of frame; skip back up over handler
762 ret addr */
763 tst = VG_(get_ThreadState)(tid);
764 tst->arch.vex.guest_ESP -= sizeof(Addr);
765 /* XXX why does ESP change differ from sigreturn case above? */
766
767 /* This is only so that the EIP is (might be) useful to report if
768 something goes wrong in the sigreturn */
769 ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
770
771 /* Restore register state from frame and remove it */
772 VG_(sigframe_destroy)(tid, True);
773
774 /* Tell the driver not to update the guest state with the "result",
775 and set a bogus result to keep it happy. */
776 *flags |= SfNoWriteResult;
777 SET_STATUS_Success(0);
778
779 /* Check to see if any signals arose as a result of this. */
780 *flags |= SfPollAfter;
781 }
782
PRE(sys_modify_ldt)783 PRE(sys_modify_ldt)
784 {
785 PRINT("sys_modify_ldt ( %ld, %#lx, %lu )", SARG1, ARG2, ARG3);
786 PRE_REG_READ3(int, "modify_ldt", int, func, void *, ptr,
787 unsigned long, bytecount);
788
789 if (ARG1 == 0) {
790 /* read the LDT into ptr */
791 PRE_MEM_WRITE( "modify_ldt(ptr)", ARG2, ARG3 );
792 }
793 if (ARG1 == 1 || ARG1 == 0x11) {
794 /* write the LDT with the entry pointed at by ptr */
795 PRE_MEM_READ( "modify_ldt(ptr)", ARG2, sizeof(vki_modify_ldt_t) );
796 }
797 /* "do" the syscall ourselves; the kernel never sees it */
798 SET_STATUS_from_SysRes( sys_modify_ldt( tid, ARG1, (void*)ARG2, ARG3 ) );
799
800 if (ARG1 == 0 && SUCCESS && RES > 0) {
801 POST_MEM_WRITE( ARG2, RES );
802 }
803 }
804
PRE(sys_set_thread_area)805 PRE(sys_set_thread_area)
806 {
807 PRINT("sys_set_thread_area ( %#lx )", ARG1);
808 PRE_REG_READ1(int, "set_thread_area", struct user_desc *, u_info)
809 PRE_MEM_READ( "set_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
810
811 /* "do" the syscall ourselves; the kernel never sees it */
812 SET_STATUS_from_SysRes( ML_(x86_sys_set_thread_area)( tid, (void *)ARG1 ) );
813 }
814
PRE(sys_get_thread_area)815 PRE(sys_get_thread_area)
816 {
817 PRINT("sys_get_thread_area ( %#lx )", ARG1);
818 PRE_REG_READ1(int, "get_thread_area", struct user_desc *, u_info)
819 PRE_MEM_WRITE( "get_thread_area(u_info)", ARG1, sizeof(vki_modify_ldt_t) );
820
821 /* "do" the syscall ourselves; the kernel never sees it */
822 SET_STATUS_from_SysRes( sys_get_thread_area( tid, (void *)ARG1 ) );
823
824 if (SUCCESS) {
825 POST_MEM_WRITE( ARG1, sizeof(vki_modify_ldt_t) );
826 }
827 }
828
829 // Parts of this are x86-specific, but the *PEEK* cases are generic.
830 //
831 // ARG3 is only used for pointers into the traced process's address
832 // space and for offsets into the traced process's struct
833 // user_regs_struct. It is never a pointer into this process's memory
834 // space, and we should therefore not check anything it points to.
PRE(sys_ptrace)835 PRE(sys_ptrace)
836 {
837 PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", SARG1, SARG2, ARG3, ARG4);
838 PRE_REG_READ4(int, "ptrace",
839 long, request, long, pid, unsigned long, addr,
840 unsigned long, data);
841 switch (ARG1) {
842 case VKI_PTRACE_PEEKTEXT:
843 case VKI_PTRACE_PEEKDATA:
844 case VKI_PTRACE_PEEKUSR:
845 PRE_MEM_WRITE( "ptrace(peek)", ARG4,
846 sizeof (long));
847 break;
848 case VKI_PTRACE_GETREGS:
849 PRE_MEM_WRITE( "ptrace(getregs)", ARG4,
850 sizeof (struct vki_user_regs_struct));
851 break;
852 case VKI_PTRACE_GETFPREGS:
853 PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4,
854 sizeof (struct vki_user_i387_struct));
855 break;
856 case VKI_PTRACE_GETFPXREGS:
857 PRE_MEM_WRITE( "ptrace(getfpxregs)", ARG4,
858 sizeof(struct vki_user_fxsr_struct) );
859 break;
860 case VKI_PTRACE_GET_THREAD_AREA:
861 PRE_MEM_WRITE( "ptrace(get_thread_area)", ARG4,
862 sizeof(struct vki_user_desc) );
863 break;
864 case VKI_PTRACE_SETREGS:
865 PRE_MEM_READ( "ptrace(setregs)", ARG4,
866 sizeof (struct vki_user_regs_struct));
867 break;
868 case VKI_PTRACE_SETFPREGS:
869 PRE_MEM_READ( "ptrace(setfpregs)", ARG4,
870 sizeof (struct vki_user_i387_struct));
871 break;
872 case VKI_PTRACE_SETFPXREGS:
873 PRE_MEM_READ( "ptrace(setfpxregs)", ARG4,
874 sizeof(struct vki_user_fxsr_struct) );
875 break;
876 case VKI_PTRACE_SET_THREAD_AREA:
877 PRE_MEM_READ( "ptrace(set_thread_area)", ARG4,
878 sizeof(struct vki_user_desc) );
879 break;
880 case VKI_PTRACE_GETEVENTMSG:
881 PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
882 break;
883 case VKI_PTRACE_GETSIGINFO:
884 PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
885 break;
886 case VKI_PTRACE_SETSIGINFO:
887 PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
888 break;
889 case VKI_PTRACE_GETREGSET:
890 ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
891 break;
892 case VKI_PTRACE_SETREGSET:
893 ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
894 break;
895 default:
896 break;
897 }
898 }
899
POST(sys_ptrace)900 POST(sys_ptrace)
901 {
902 switch (ARG1) {
903 case VKI_PTRACE_TRACEME:
904 ML_(linux_POST_traceme)(tid);
905 break;
906 case VKI_PTRACE_PEEKTEXT:
907 case VKI_PTRACE_PEEKDATA:
908 case VKI_PTRACE_PEEKUSR:
909 POST_MEM_WRITE( ARG4, sizeof (long));
910 break;
911 case VKI_PTRACE_GETREGS:
912 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
913 break;
914 case VKI_PTRACE_GETFPREGS:
915 POST_MEM_WRITE( ARG4, sizeof (struct vki_user_i387_struct));
916 break;
917 case VKI_PTRACE_GETFPXREGS:
918 POST_MEM_WRITE( ARG4, sizeof(struct vki_user_fxsr_struct) );
919 break;
920 case VKI_PTRACE_GET_THREAD_AREA:
921 POST_MEM_WRITE( ARG4, sizeof(struct vki_user_desc) );
922 break;
923 case VKI_PTRACE_GETEVENTMSG:
924 POST_MEM_WRITE( ARG4, sizeof(unsigned long));
925 break;
926 case VKI_PTRACE_GETSIGINFO:
927 /* XXX: This is a simplification. Different parts of the
928 * siginfo_t are valid depending on the type of signal.
929 */
930 POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
931 break;
932 case VKI_PTRACE_GETREGSET:
933 ML_(linux_POST_getregset)(tid, ARG3, ARG4);
934 break;
935 default:
936 break;
937 }
938 }
939
PRE(old_mmap)940 PRE(old_mmap)
941 {
942 /* struct mmap_arg_struct {
943 unsigned long addr;
944 unsigned long len;
945 unsigned long prot;
946 unsigned long flags;
947 unsigned long fd;
948 unsigned long offset;
949 }; */
950 UWord a1, a2, a3, a4, a5, a6;
951 SysRes r;
952
953 UWord* args = (UWord*)ARG1;
954 PRE_REG_READ1(long, "old_mmap", struct mmap_arg_struct *, args);
955 PRE_MEM_READ( "old_mmap(args)", (Addr)args, 6*sizeof(UWord) );
956
957 a1 = args[1-1];
958 a2 = args[2-1];
959 a3 = args[3-1];
960 a4 = args[4-1];
961 a5 = args[5-1];
962 a6 = args[6-1];
963
964 PRINT("old_mmap ( %#lx, %lu, %ld, %ld, %ld, %ld )",
965 a1, a2, (Word)a3, (Word)a4, (Word)a5, (Word)a6 );
966
967 r = ML_(generic_PRE_sys_mmap)( tid, a1, a2, a3, a4, a5, (Off64T)a6 );
968 SET_STATUS_from_SysRes(r);
969 }
970
PRE(sys_mmap2)971 PRE(sys_mmap2)
972 {
973 SysRes r;
974
975 // Exactly like old_mmap() except:
976 // - all 6 args are passed in regs, rather than in a memory-block.
977 // - the file offset is specified in pagesize units rather than bytes,
978 // so that it can be used for files bigger than 2^32 bytes.
979 // pagesize or 4K-size units in offset? For ppc32/64-linux, this is
980 // 4K-sized. Assert that the page size is 4K here for safety.
981 vg_assert(VKI_PAGE_SIZE == 4096);
982 PRINT("sys_mmap2 ( %#lx, %lu, %lu, %lu, %lu, %lu )",
983 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
984 PRE_REG_READ6(long, "mmap2",
985 unsigned long, start, unsigned long, length,
986 unsigned long, prot, unsigned long, flags,
987 unsigned long, fd, unsigned long, offset);
988
989 r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5,
990 4096 * (Off64T)ARG6 );
991 SET_STATUS_from_SysRes(r);
992 }
993
994 // XXX: lstat64/fstat64/stat64 are generic, but not necessarily
995 // applicable to every architecture -- I think only to 32-bit archs.
996 // We're going to need something like linux/core_os32.h for such
997 // things, eventually, I think. --njn
PRE(sys_lstat64)998 PRE(sys_lstat64)
999 {
1000 PRINT("sys_lstat64 ( %#lx(%s), %#lx )", ARG1, (HChar*)ARG1, ARG2);
1001 PRE_REG_READ2(long, "lstat64", char *, file_name, struct stat64 *, buf);
1002 PRE_MEM_RASCIIZ( "lstat64(file_name)", ARG1 );
1003 PRE_MEM_WRITE( "lstat64(buf)", ARG2, sizeof(struct vki_stat64) );
1004 }
1005
POST(sys_lstat64)1006 POST(sys_lstat64)
1007 {
1008 vg_assert(SUCCESS);
1009 if (RES == 0) {
1010 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1011 }
1012 }
1013
PRE(sys_stat64)1014 PRE(sys_stat64)
1015 {
1016 FUSE_COMPATIBLE_MAY_BLOCK();
1017 PRINT("sys_stat64 ( %#lx(%s), %#lx )", ARG1, (HChar*)ARG1, ARG2);
1018 PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf);
1019 PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 );
1020 PRE_MEM_WRITE( "stat64(buf)", ARG2, sizeof(struct vki_stat64) );
1021 }
1022
POST(sys_stat64)1023 POST(sys_stat64)
1024 {
1025 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1026 }
1027
PRE(sys_fstatat64)1028 PRE(sys_fstatat64)
1029 {
1030 FUSE_COMPATIBLE_MAY_BLOCK();
1031 // ARG4 = int flags; Flags are or'ed together, therefore writing them
1032 // as a hex constant is more meaningful.
1033 PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx, %#lx )",
1034 SARG1, ARG2, (HChar*)ARG2, ARG3, ARG4);
1035 PRE_REG_READ4(long, "fstatat64",
1036 int, dfd, char *, file_name, struct stat64 *, buf, int, flags);
1037 PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 );
1038 PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) );
1039 }
1040
POST(sys_fstatat64)1041 POST(sys_fstatat64)
1042 {
1043 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) );
1044 }
1045
PRE(sys_fstat64)1046 PRE(sys_fstat64)
1047 {
1048 PRINT("sys_fstat64 ( %lu, %#lx )", ARG1, ARG2);
1049 PRE_REG_READ2(long, "fstat64", unsigned long, fd, struct stat64 *, buf);
1050 PRE_MEM_WRITE( "fstat64(buf)", ARG2, sizeof(struct vki_stat64) );
1051 }
1052
POST(sys_fstat64)1053 POST(sys_fstat64)
1054 {
1055 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) );
1056 }
1057
1058 /* NB: arm-linux has a clone of this one, and ppc32-linux has an almost
1059 identical version. */
PRE(sys_sigsuspend)1060 PRE(sys_sigsuspend)
1061 {
1062 /* The C library interface to sigsuspend just takes a pointer to
1063 a signal mask but this system call has three arguments - the first
1064 two don't appear to be used by the kernel and are always passed as
1065 zero by glibc and the third is the first word of the signal mask
1066 so only 32 signals are supported.
1067
1068 In fact glibc normally uses rt_sigsuspend if it is available as
1069 that takes a pointer to the signal mask so supports more signals.
1070 */
1071 *flags |= SfMayBlock;
1072 PRINT("sys_sigsuspend ( %ld, %ld, %lu )", SARG1, SARG2, ARG3 );
1073 PRE_REG_READ3(int, "sigsuspend",
1074 int, history0, int, history1,
1075 vki_old_sigset_t, mask);
1076 }
1077
PRE(sys_vm86old)1078 PRE(sys_vm86old)
1079 {
1080 PRINT("sys_vm86old ( %#lx )", ARG1);
1081 PRE_REG_READ1(int, "vm86old", struct vm86_struct *, info);
1082 PRE_MEM_WRITE( "vm86old(info)", ARG1, sizeof(struct vki_vm86_struct));
1083 }
1084
POST(sys_vm86old)1085 POST(sys_vm86old)
1086 {
1087 POST_MEM_WRITE( ARG1, sizeof(struct vki_vm86_struct));
1088 }
1089
PRE(sys_vm86)1090 PRE(sys_vm86)
1091 {
1092 PRINT("sys_vm86 ( %lu, %#lx )", ARG1, ARG2);
1093 PRE_REG_READ2(int, "vm86", unsigned long, fn, struct vm86plus_struct *, v86);
1094 if (ARG1 == VKI_VM86_ENTER || ARG1 == VKI_VM86_ENTER_NO_BYPASS)
1095 PRE_MEM_WRITE( "vm86(v86)", ARG2, sizeof(struct vki_vm86plus_struct));
1096 }
1097
POST(sys_vm86)1098 POST(sys_vm86)
1099 {
1100 if (ARG1 == VKI_VM86_ENTER || ARG1 == VKI_VM86_ENTER_NO_BYPASS)
1101 POST_MEM_WRITE( ARG2, sizeof(struct vki_vm86plus_struct));
1102 }
1103
1104
1105 /* ---------------------------------------------------------------
1106 PRE/POST wrappers for x86/Linux-variant specific syscalls
1107 ------------------------------------------------------------ */
1108
PRE(sys_syscall223)1109 PRE(sys_syscall223)
1110 {
1111 Int err;
1112
1113 /* 223 is used by sys_bproc. If we're not on a declared bproc
1114 variant, fail in the usual way. */
1115
1116 if (!KernelVariantiS(KernelVariant_bproc, VG_(clo_kernel_variant))) {
1117 PRINT("non-existent syscall! (syscall 223)");
1118 PRE_REG_READ0(long, "ni_syscall(223)");
1119 SET_STATUS_Failure( VKI_ENOSYS );
1120 return;
1121 }
1122
1123 err = ML_(linux_variant_PRE_sys_bproc)( ARG1, ARG2, ARG3,
1124 ARG4, ARG5, ARG6 );
1125 if (err) {
1126 SET_STATUS_Failure( err );
1127 return;
1128 }
1129 /* Let it go through. */
1130 *flags |= SfMayBlock; /* who knows? play safe. */
1131 }
1132
POST(sys_syscall223)1133 POST(sys_syscall223)
1134 {
1135 ML_(linux_variant_POST_sys_bproc)( ARG1, ARG2, ARG3,
1136 ARG4, ARG5, ARG6 );
1137 }
1138
1139 #undef PRE
1140 #undef POST
1141
1142
1143 /* ---------------------------------------------------------------------
1144 The x86/Linux syscall table
1145 ------------------------------------------------------------------ */
1146
1147 /* Add an x86-linux specific wrapper to a syscall table. */
1148 #define PLAX_(sysno, name) WRAPPER_ENTRY_X_(x86_linux, sysno, name)
1149 #define PLAXY(sysno, name) WRAPPER_ENTRY_XY(x86_linux, sysno, name)
1150
1151
1152 // This table maps from __NR_xxx syscall numbers (from
1153 // linux/include/asm-i386/unistd.h) to the appropriate PRE/POST sys_foo()
1154 // wrappers on x86 (as per sys_call_table in linux/arch/i386/kernel/entry.S).
1155 //
1156 // For those syscalls not handled by Valgrind, the annotation indicate its
1157 // arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/?
1158 // (unknown).
1159
1160 static SyscallTableEntry syscall_table[] = {
1161 //zz // (restart_syscall) // 0
1162 GENX_(__NR_exit, sys_exit), // 1
1163 GENX_(__NR_fork, sys_fork), // 2
1164 GENXY(__NR_read, sys_read), // 3
1165 GENX_(__NR_write, sys_write), // 4
1166
1167 GENXY(__NR_open, sys_open), // 5
1168 GENXY(__NR_close, sys_close), // 6
1169 GENXY(__NR_waitpid, sys_waitpid), // 7
1170 GENXY(__NR_creat, sys_creat), // 8
1171 GENX_(__NR_link, sys_link), // 9
1172
1173 GENX_(__NR_unlink, sys_unlink), // 10
1174 GENX_(__NR_execve, sys_execve), // 11
1175 GENX_(__NR_chdir, sys_chdir), // 12
1176 GENXY(__NR_time, sys_time), // 13
1177 GENX_(__NR_mknod, sys_mknod), // 14
1178
1179 GENX_(__NR_chmod, sys_chmod), // 15
1180 //zz LINX_(__NR_lchown, sys_lchown16), // 16
1181 GENX_(__NR_break, sys_ni_syscall), // 17
1182 //zz // (__NR_oldstat, sys_stat), // 18 (obsolete)
1183 LINX_(__NR_lseek, sys_lseek), // 19
1184
1185 GENX_(__NR_getpid, sys_getpid), // 20
1186 LINX_(__NR_mount, sys_mount), // 21
1187 LINX_(__NR_umount, sys_oldumount), // 22
1188 LINX_(__NR_setuid, sys_setuid16), // 23 ## P
1189 LINX_(__NR_getuid, sys_getuid16), // 24 ## P
1190
1191 LINX_(__NR_stime, sys_stime), // 25 * (SVr4,SVID,X/OPEN)
1192 PLAXY(__NR_ptrace, sys_ptrace), // 26
1193 GENX_(__NR_alarm, sys_alarm), // 27
1194 //zz // (__NR_oldfstat, sys_fstat), // 28 * L -- obsolete
1195 GENX_(__NR_pause, sys_pause), // 29
1196
1197 LINX_(__NR_utime, sys_utime), // 30
1198 GENX_(__NR_stty, sys_ni_syscall), // 31
1199 GENX_(__NR_gtty, sys_ni_syscall), // 32
1200 GENX_(__NR_access, sys_access), // 33
1201 GENX_(__NR_nice, sys_nice), // 34
1202
1203 GENX_(__NR_ftime, sys_ni_syscall), // 35
1204 GENX_(__NR_sync, sys_sync), // 36
1205 GENX_(__NR_kill, sys_kill), // 37
1206 GENX_(__NR_rename, sys_rename), // 38
1207 GENX_(__NR_mkdir, sys_mkdir), // 39
1208
1209 GENX_(__NR_rmdir, sys_rmdir), // 40
1210 GENXY(__NR_dup, sys_dup), // 41
1211 LINXY(__NR_pipe, sys_pipe), // 42
1212 GENXY(__NR_times, sys_times), // 43
1213 GENX_(__NR_prof, sys_ni_syscall), // 44
1214 //zz
1215 GENX_(__NR_brk, sys_brk), // 45
1216 LINX_(__NR_setgid, sys_setgid16), // 46
1217 LINX_(__NR_getgid, sys_getgid16), // 47
1218 //zz // (__NR_signal, sys_signal), // 48 */* (ANSI C)
1219 LINX_(__NR_geteuid, sys_geteuid16), // 49
1220
1221 LINX_(__NR_getegid, sys_getegid16), // 50
1222 GENX_(__NR_acct, sys_acct), // 51
1223 LINX_(__NR_umount2, sys_umount), // 52
1224 GENX_(__NR_lock, sys_ni_syscall), // 53
1225 LINXY(__NR_ioctl, sys_ioctl), // 54
1226
1227 LINXY(__NR_fcntl, sys_fcntl), // 55
1228 GENX_(__NR_mpx, sys_ni_syscall), // 56
1229 GENX_(__NR_setpgid, sys_setpgid), // 57
1230 GENX_(__NR_ulimit, sys_ni_syscall), // 58
1231 //zz // (__NR_oldolduname, sys_olduname), // 59 Linux -- obsolete
1232 //zz
1233 GENX_(__NR_umask, sys_umask), // 60
1234 GENX_(__NR_chroot, sys_chroot), // 61
1235 //zz // (__NR_ustat, sys_ustat) // 62 SVr4 -- deprecated
1236 GENXY(__NR_dup2, sys_dup2), // 63
1237 GENX_(__NR_getppid, sys_getppid), // 64
1238
1239 GENX_(__NR_getpgrp, sys_getpgrp), // 65
1240 GENX_(__NR_setsid, sys_setsid), // 66
1241 LINXY(__NR_sigaction, sys_sigaction), // 67
1242 //zz // (__NR_sgetmask, sys_sgetmask), // 68 */* (ANSI C)
1243 //zz // (__NR_ssetmask, sys_ssetmask), // 69 */* (ANSI C)
1244 //zz
1245 LINX_(__NR_setreuid, sys_setreuid16), // 70
1246 LINX_(__NR_setregid, sys_setregid16), // 71
1247 PLAX_(__NR_sigsuspend, sys_sigsuspend), // 72
1248 LINXY(__NR_sigpending, sys_sigpending), // 73
1249 GENX_(__NR_sethostname, sys_sethostname), // 74
1250 //zz
1251 GENX_(__NR_setrlimit, sys_setrlimit), // 75
1252 GENXY(__NR_getrlimit, sys_old_getrlimit), // 76
1253 GENXY(__NR_getrusage, sys_getrusage), // 77
1254 GENXY(__NR_gettimeofday, sys_gettimeofday), // 78
1255 GENX_(__NR_settimeofday, sys_settimeofday), // 79
1256
1257 LINXY(__NR_getgroups, sys_getgroups16), // 80
1258 LINX_(__NR_setgroups, sys_setgroups16), // 81
1259 PLAX_(__NR_select, old_select), // 82
1260 GENX_(__NR_symlink, sys_symlink), // 83
1261 //zz // (__NR_oldlstat, sys_lstat), // 84 -- obsolete
1262 //zz
1263 GENX_(__NR_readlink, sys_readlink), // 85
1264 //zz // (__NR_uselib, sys_uselib), // 86 */Linux
1265 //zz // (__NR_swapon, sys_swapon), // 87 */Linux
1266 //zz // (__NR_reboot, sys_reboot), // 88 */Linux
1267 //zz // (__NR_readdir, old_readdir), // 89 -- superseded
1268 //zz
1269 PLAX_(__NR_mmap, old_mmap), // 90
1270 GENXY(__NR_munmap, sys_munmap), // 91
1271 GENX_(__NR_truncate, sys_truncate), // 92
1272 GENX_(__NR_ftruncate, sys_ftruncate), // 93
1273 GENX_(__NR_fchmod, sys_fchmod), // 94
1274
1275 LINX_(__NR_fchown, sys_fchown16), // 95
1276 GENX_(__NR_getpriority, sys_getpriority), // 96
1277 GENX_(__NR_setpriority, sys_setpriority), // 97
1278 GENX_(__NR_profil, sys_ni_syscall), // 98
1279 GENXY(__NR_statfs, sys_statfs), // 99
1280
1281 GENXY(__NR_fstatfs, sys_fstatfs), // 100
1282 LINX_(__NR_ioperm, sys_ioperm), // 101
1283 LINXY(__NR_socketcall, sys_socketcall), // 102 x86/Linux-only
1284 LINXY(__NR_syslog, sys_syslog), // 103
1285 GENXY(__NR_setitimer, sys_setitimer), // 104
1286
1287 GENXY(__NR_getitimer, sys_getitimer), // 105
1288 GENXY(__NR_stat, sys_newstat), // 106
1289 GENXY(__NR_lstat, sys_newlstat), // 107
1290 GENXY(__NR_fstat, sys_newfstat), // 108
1291 //zz // (__NR_olduname, sys_uname), // 109 -- obsolete
1292 //zz
1293 GENX_(__NR_iopl, sys_iopl), // 110
1294 LINX_(__NR_vhangup, sys_vhangup), // 111
1295 GENX_(__NR_idle, sys_ni_syscall), // 112
1296 PLAXY(__NR_vm86old, sys_vm86old), // 113 x86/Linux-only
1297 GENXY(__NR_wait4, sys_wait4), // 114
1298 //zz
1299 //zz // (__NR_swapoff, sys_swapoff), // 115 */Linux
1300 LINXY(__NR_sysinfo, sys_sysinfo), // 116
1301 LINXY(__NR_ipc, sys_ipc), // 117
1302 GENX_(__NR_fsync, sys_fsync), // 118
1303 PLAX_(__NR_sigreturn, sys_sigreturn), // 119 ?/Linux
1304
1305 LINX_(__NR_clone, sys_clone), // 120
1306 //zz // (__NR_setdomainname, sys_setdomainname), // 121 */*(?)
1307 GENXY(__NR_uname, sys_newuname), // 122
1308 PLAX_(__NR_modify_ldt, sys_modify_ldt), // 123
1309 LINXY(__NR_adjtimex, sys_adjtimex), // 124
1310
1311 GENXY(__NR_mprotect, sys_mprotect), // 125
1312 LINXY(__NR_sigprocmask, sys_sigprocmask), // 126
1313 //zz // Nb: create_module() was removed 2.4-->2.6
1314 GENX_(__NR_create_module, sys_ni_syscall), // 127
1315 LINX_(__NR_init_module, sys_init_module), // 128
1316 LINX_(__NR_delete_module, sys_delete_module), // 129
1317 //zz
1318 //zz // Nb: get_kernel_syms() was removed 2.4-->2.6
1319 GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130
1320 LINX_(__NR_quotactl, sys_quotactl), // 131
1321 GENX_(__NR_getpgid, sys_getpgid), // 132
1322 GENX_(__NR_fchdir, sys_fchdir), // 133
1323 //zz // (__NR_bdflush, sys_bdflush), // 134 */Linux
1324 //zz
1325 //zz // (__NR_sysfs, sys_sysfs), // 135 SVr4
1326 LINX_(__NR_personality, sys_personality), // 136
1327 GENX_(__NR_afs_syscall, sys_ni_syscall), // 137
1328 LINX_(__NR_setfsuid, sys_setfsuid16), // 138
1329 LINX_(__NR_setfsgid, sys_setfsgid16), // 139
1330
1331 LINXY(__NR__llseek, sys_llseek), // 140
1332 GENXY(__NR_getdents, sys_getdents), // 141
1333 GENX_(__NR__newselect, sys_select), // 142
1334 GENX_(__NR_flock, sys_flock), // 143
1335 GENX_(__NR_msync, sys_msync), // 144
1336
1337 GENXY(__NR_readv, sys_readv), // 145
1338 GENX_(__NR_writev, sys_writev), // 146
1339 GENX_(__NR_getsid, sys_getsid), // 147
1340 GENX_(__NR_fdatasync, sys_fdatasync), // 148
1341 LINXY(__NR__sysctl, sys_sysctl), // 149
1342
1343 GENX_(__NR_mlock, sys_mlock), // 150
1344 GENX_(__NR_munlock, sys_munlock), // 151
1345 GENX_(__NR_mlockall, sys_mlockall), // 152
1346 LINX_(__NR_munlockall, sys_munlockall), // 153
1347 LINXY(__NR_sched_setparam, sys_sched_setparam), // 154
1348
1349 LINXY(__NR_sched_getparam, sys_sched_getparam), // 155
1350 LINX_(__NR_sched_setscheduler, sys_sched_setscheduler), // 156
1351 LINX_(__NR_sched_getscheduler, sys_sched_getscheduler), // 157
1352 LINX_(__NR_sched_yield, sys_sched_yield), // 158
1353 LINX_(__NR_sched_get_priority_max, sys_sched_get_priority_max),// 159
1354
1355 LINX_(__NR_sched_get_priority_min, sys_sched_get_priority_min),// 160
1356 LINXY(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 161
1357 GENXY(__NR_nanosleep, sys_nanosleep), // 162
1358 GENX_(__NR_mremap, sys_mremap), // 163
1359 LINX_(__NR_setresuid, sys_setresuid16), // 164
1360
1361 LINXY(__NR_getresuid, sys_getresuid16), // 165
1362 PLAXY(__NR_vm86, sys_vm86), // 166 x86/Linux-only
1363 GENX_(__NR_query_module, sys_ni_syscall), // 167
1364 GENXY(__NR_poll, sys_poll), // 168
1365 //zz // (__NR_nfsservctl, sys_nfsservctl), // 169 */Linux
1366 //zz
1367 LINX_(__NR_setresgid, sys_setresgid16), // 170
1368 LINXY(__NR_getresgid, sys_getresgid16), // 171
1369 LINXY(__NR_prctl, sys_prctl), // 172
1370 PLAX_(__NR_rt_sigreturn, sys_rt_sigreturn), // 173 x86/Linux only?
1371 LINXY(__NR_rt_sigaction, sys_rt_sigaction), // 174
1372
1373 LINXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 175
1374 LINXY(__NR_rt_sigpending, sys_rt_sigpending), // 176
1375 LINXY(__NR_rt_sigtimedwait, sys_rt_sigtimedwait),// 177
1376 LINXY(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo),// 178
1377 LINX_(__NR_rt_sigsuspend, sys_rt_sigsuspend), // 179
1378
1379 GENXY(__NR_pread64, sys_pread64), // 180
1380 GENX_(__NR_pwrite64, sys_pwrite64), // 181
1381 LINX_(__NR_chown, sys_chown16), // 182
1382 GENXY(__NR_getcwd, sys_getcwd), // 183
1383 LINXY(__NR_capget, sys_capget), // 184
1384
1385 LINX_(__NR_capset, sys_capset), // 185
1386 GENXY(__NR_sigaltstack, sys_sigaltstack), // 186
1387 LINXY(__NR_sendfile, sys_sendfile), // 187
1388 GENXY(__NR_getpmsg, sys_getpmsg), // 188
1389 GENX_(__NR_putpmsg, sys_putpmsg), // 189
1390
1391 // Nb: we treat vfork as fork
1392 GENX_(__NR_vfork, sys_fork), // 190
1393 GENXY(__NR_ugetrlimit, sys_getrlimit), // 191
1394 PLAX_(__NR_mmap2, sys_mmap2), // 192
1395 GENX_(__NR_truncate64, sys_truncate64), // 193
1396 GENX_(__NR_ftruncate64, sys_ftruncate64), // 194
1397
1398 PLAXY(__NR_stat64, sys_stat64), // 195
1399 PLAXY(__NR_lstat64, sys_lstat64), // 196
1400 PLAXY(__NR_fstat64, sys_fstat64), // 197
1401 GENX_(__NR_lchown32, sys_lchown), // 198
1402 GENX_(__NR_getuid32, sys_getuid), // 199
1403
1404 GENX_(__NR_getgid32, sys_getgid), // 200
1405 GENX_(__NR_geteuid32, sys_geteuid), // 201
1406 GENX_(__NR_getegid32, sys_getegid), // 202
1407 GENX_(__NR_setreuid32, sys_setreuid), // 203
1408 GENX_(__NR_setregid32, sys_setregid), // 204
1409
1410 GENXY(__NR_getgroups32, sys_getgroups), // 205
1411 GENX_(__NR_setgroups32, sys_setgroups), // 206
1412 GENX_(__NR_fchown32, sys_fchown), // 207
1413 LINX_(__NR_setresuid32, sys_setresuid), // 208
1414 LINXY(__NR_getresuid32, sys_getresuid), // 209
1415
1416 LINX_(__NR_setresgid32, sys_setresgid), // 210
1417 LINXY(__NR_getresgid32, sys_getresgid), // 211
1418 GENX_(__NR_chown32, sys_chown), // 212
1419 GENX_(__NR_setuid32, sys_setuid), // 213
1420 GENX_(__NR_setgid32, sys_setgid), // 214
1421
1422 LINX_(__NR_setfsuid32, sys_setfsuid), // 215
1423 LINX_(__NR_setfsgid32, sys_setfsgid), // 216
1424 LINX_(__NR_pivot_root, sys_pivot_root), // 217
1425 GENXY(__NR_mincore, sys_mincore), // 218
1426 GENX_(__NR_madvise, sys_madvise), // 219
1427
1428 GENXY(__NR_getdents64, sys_getdents64), // 220
1429 LINXY(__NR_fcntl64, sys_fcntl64), // 221
1430 GENX_(222, sys_ni_syscall), // 222
1431 PLAXY(223, sys_syscall223), // 223 // sys_bproc?
1432 LINX_(__NR_gettid, sys_gettid), // 224
1433
1434 LINX_(__NR_readahead, sys_readahead), // 225 */Linux
1435 LINX_(__NR_setxattr, sys_setxattr), // 226
1436 LINX_(__NR_lsetxattr, sys_lsetxattr), // 227
1437 LINX_(__NR_fsetxattr, sys_fsetxattr), // 228
1438 LINXY(__NR_getxattr, sys_getxattr), // 229
1439
1440 LINXY(__NR_lgetxattr, sys_lgetxattr), // 230
1441 LINXY(__NR_fgetxattr, sys_fgetxattr), // 231
1442 LINXY(__NR_listxattr, sys_listxattr), // 232
1443 LINXY(__NR_llistxattr, sys_llistxattr), // 233
1444 LINXY(__NR_flistxattr, sys_flistxattr), // 234
1445
1446 LINX_(__NR_removexattr, sys_removexattr), // 235
1447 LINX_(__NR_lremovexattr, sys_lremovexattr), // 236
1448 LINX_(__NR_fremovexattr, sys_fremovexattr), // 237
1449 LINXY(__NR_tkill, sys_tkill), // 238 */Linux
1450 LINXY(__NR_sendfile64, sys_sendfile64), // 239
1451
1452 LINXY(__NR_futex, sys_futex), // 240
1453 LINX_(__NR_sched_setaffinity, sys_sched_setaffinity), // 241
1454 LINXY(__NR_sched_getaffinity, sys_sched_getaffinity), // 242
1455 PLAX_(__NR_set_thread_area, sys_set_thread_area), // 243
1456 PLAX_(__NR_get_thread_area, sys_get_thread_area), // 244
1457
1458 LINXY(__NR_io_setup, sys_io_setup), // 245
1459 LINX_(__NR_io_destroy, sys_io_destroy), // 246
1460 LINXY(__NR_io_getevents, sys_io_getevents), // 247
1461 LINX_(__NR_io_submit, sys_io_submit), // 248
1462 LINXY(__NR_io_cancel, sys_io_cancel), // 249
1463
1464 LINX_(__NR_fadvise64, sys_fadvise64), // 250 */(Linux?)
1465 GENX_(251, sys_ni_syscall), // 251
1466 LINX_(__NR_exit_group, sys_exit_group), // 252
1467 LINXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 253
1468 LINXY(__NR_epoll_create, sys_epoll_create), // 254
1469
1470 LINX_(__NR_epoll_ctl, sys_epoll_ctl), // 255
1471 LINXY(__NR_epoll_wait, sys_epoll_wait), // 256
1472 //zz // (__NR_remap_file_pages, sys_remap_file_pages), // 257 */Linux
1473 LINX_(__NR_set_tid_address, sys_set_tid_address), // 258
1474 LINXY(__NR_timer_create, sys_timer_create), // 259
1475
1476 LINXY(__NR_timer_settime, sys_timer_settime), // (timer_create+1)
1477 LINXY(__NR_timer_gettime, sys_timer_gettime), // (timer_create+2)
1478 LINX_(__NR_timer_getoverrun, sys_timer_getoverrun),//(timer_create+3)
1479 LINX_(__NR_timer_delete, sys_timer_delete), // (timer_create+4)
1480 LINX_(__NR_clock_settime, sys_clock_settime), // (timer_create+5)
1481
1482 LINXY(__NR_clock_gettime, sys_clock_gettime), // (timer_create+6)
1483 LINXY(__NR_clock_getres, sys_clock_getres), // (timer_create+7)
1484 LINXY(__NR_clock_nanosleep, sys_clock_nanosleep),// (timer_create+8) */*
1485 GENXY(__NR_statfs64, sys_statfs64), // 268
1486 GENXY(__NR_fstatfs64, sys_fstatfs64), // 269
1487
1488 LINX_(__NR_tgkill, sys_tgkill), // 270 */Linux
1489 GENX_(__NR_utimes, sys_utimes), // 271
1490 LINX_(__NR_fadvise64_64, sys_fadvise64_64), // 272 */(Linux?)
1491 GENX_(__NR_vserver, sys_ni_syscall), // 273
1492 LINX_(__NR_mbind, sys_mbind), // 274 ?/?
1493
1494 LINXY(__NR_get_mempolicy, sys_get_mempolicy), // 275 ?/?
1495 LINX_(__NR_set_mempolicy, sys_set_mempolicy), // 276 ?/?
1496 LINXY(__NR_mq_open, sys_mq_open), // 277
1497 LINX_(__NR_mq_unlink, sys_mq_unlink), // (mq_open+1)
1498 LINX_(__NR_mq_timedsend, sys_mq_timedsend), // (mq_open+2)
1499
1500 LINXY(__NR_mq_timedreceive, sys_mq_timedreceive),// (mq_open+3)
1501 LINX_(__NR_mq_notify, sys_mq_notify), // (mq_open+4)
1502 LINXY(__NR_mq_getsetattr, sys_mq_getsetattr), // (mq_open+5)
1503 GENX_(__NR_sys_kexec_load, sys_ni_syscall), // 283
1504 LINXY(__NR_waitid, sys_waitid), // 284
1505
1506 GENX_(285, sys_ni_syscall), // 285
1507 LINX_(__NR_add_key, sys_add_key), // 286
1508 LINX_(__NR_request_key, sys_request_key), // 287
1509 LINXY(__NR_keyctl, sys_keyctl), // 288
1510 LINX_(__NR_ioprio_set, sys_ioprio_set), // 289
1511
1512 LINX_(__NR_ioprio_get, sys_ioprio_get), // 290
1513 LINX_(__NR_inotify_init, sys_inotify_init), // 291
1514 LINX_(__NR_inotify_add_watch, sys_inotify_add_watch), // 292
1515 LINX_(__NR_inotify_rm_watch, sys_inotify_rm_watch), // 293
1516 // LINX_(__NR_migrate_pages, sys_migrate_pages), // 294
1517
1518 LINXY(__NR_openat, sys_openat), // 295
1519 LINX_(__NR_mkdirat, sys_mkdirat), // 296
1520 LINX_(__NR_mknodat, sys_mknodat), // 297
1521 LINX_(__NR_fchownat, sys_fchownat), // 298
1522 LINX_(__NR_futimesat, sys_futimesat), // 299
1523
1524 PLAXY(__NR_fstatat64, sys_fstatat64), // 300
1525 LINX_(__NR_unlinkat, sys_unlinkat), // 301
1526 LINX_(__NR_renameat, sys_renameat), // 302
1527 LINX_(__NR_linkat, sys_linkat), // 303
1528 LINX_(__NR_symlinkat, sys_symlinkat), // 304
1529
1530 LINX_(__NR_readlinkat, sys_readlinkat), // 305
1531 LINX_(__NR_fchmodat, sys_fchmodat), // 306
1532 LINX_(__NR_faccessat, sys_faccessat), // 307
1533 LINXY(__NR_pselect6, sys_pselect6), // 308
1534 LINXY(__NR_ppoll, sys_ppoll), // 309
1535
1536 LINX_(__NR_unshare, sys_unshare), // 310
1537 LINX_(__NR_set_robust_list, sys_set_robust_list), // 311
1538 LINXY(__NR_get_robust_list, sys_get_robust_list), // 312
1539 LINX_(__NR_splice, sys_splice), // 313
1540 LINX_(__NR_sync_file_range, sys_sync_file_range), // 314
1541
1542 LINX_(__NR_tee, sys_tee), // 315
1543 LINXY(__NR_vmsplice, sys_vmsplice), // 316
1544 LINXY(__NR_move_pages, sys_move_pages), // 317
1545 LINXY(__NR_getcpu, sys_getcpu), // 318
1546 LINXY(__NR_epoll_pwait, sys_epoll_pwait), // 319
1547
1548 LINX_(__NR_utimensat, sys_utimensat), // 320
1549 LINXY(__NR_signalfd, sys_signalfd), // 321
1550 LINXY(__NR_timerfd_create, sys_timerfd_create), // 322
1551 LINXY(__NR_eventfd, sys_eventfd), // 323
1552 LINX_(__NR_fallocate, sys_fallocate), // 324
1553
1554 LINXY(__NR_timerfd_settime, sys_timerfd_settime), // 325
1555 LINXY(__NR_timerfd_gettime, sys_timerfd_gettime), // 326
1556 LINXY(__NR_signalfd4, sys_signalfd4), // 327
1557 LINXY(__NR_eventfd2, sys_eventfd2), // 328
1558 LINXY(__NR_epoll_create1, sys_epoll_create1), // 329
1559
1560 LINXY(__NR_dup3, sys_dup3), // 330
1561 LINXY(__NR_pipe2, sys_pipe2), // 331
1562 LINXY(__NR_inotify_init1, sys_inotify_init1), // 332
1563 LINXY(__NR_preadv, sys_preadv), // 333
1564 LINX_(__NR_pwritev, sys_pwritev), // 334
1565
1566 LINXY(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo),// 335
1567 LINXY(__NR_perf_event_open, sys_perf_event_open), // 336
1568 LINXY(__NR_recvmmsg, sys_recvmmsg), // 337
1569 LINXY(__NR_fanotify_init, sys_fanotify_init), // 338
1570 LINX_(__NR_fanotify_mark, sys_fanotify_mark), // 339
1571
1572 LINXY(__NR_prlimit64, sys_prlimit64), // 340
1573 LINXY(__NR_name_to_handle_at, sys_name_to_handle_at),// 341
1574 LINXY(__NR_open_by_handle_at, sys_open_by_handle_at),// 342
1575 LINXY(__NR_clock_adjtime, sys_clock_adjtime), // 343
1576 LINX_(__NR_syncfs, sys_syncfs), // 344
1577
1578 LINXY(__NR_sendmmsg, sys_sendmmsg), // 345
1579 // LINX_(__NR_setns, sys_ni_syscall), // 346
1580 LINXY(__NR_process_vm_readv, sys_process_vm_readv), // 347
1581 LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 348
1582 LINX_(__NR_kcmp, sys_kcmp), // 349
1583
1584 // LIN__(__NR_finit_module, sys_ni_syscall), // 350
1585 // LIN__(__NR_sched_setattr, sys_ni_syscall), // 351
1586 // LIN__(__NR_sched_getattr, sys_ni_syscall), // 352
1587 LINX_(__NR_renameat2, sys_renameat2), // 353
1588 // LIN__(__NR_seccomp, sys_ni_syscall), // 354
1589
1590 LINXY(__NR_getrandom, sys_getrandom), // 355
1591 LINXY(__NR_memfd_create, sys_memfd_create), // 356
1592 // LIN__(__NR_bpf, sys_ni_syscall), // 357
1593 LINXY(__NR_socket, sys_socket), // 359
1594 LINXY(__NR_socketpair, sys_socketpair), // 360
1595 LINX_(__NR_bind, sys_bind), // 361
1596 LINX_(__NR_connect, sys_connect), // 362
1597 LINX_(__NR_listen, sys_listen), // 363
1598 LINXY(__NR_accept4, sys_accept4), // 364
1599 LINXY(__NR_getsockopt, sys_getsockopt), // 365
1600 LINX_(__NR_setsockopt, sys_setsockopt), // 366
1601 LINXY(__NR_getsockname, sys_getsockname), // 367
1602 LINXY(__NR_getpeername, sys_getpeername), // 368
1603 LINX_(__NR_sendto, sys_sendto), // 369
1604 LINX_(__NR_sendmsg, sys_sendmsg), // 370
1605 LINXY(__NR_recvfrom, sys_recvfrom), // 371
1606 LINXY(__NR_recvmsg, sys_recvmsg), // 372
1607 LINX_(__NR_shutdown, sys_shutdown) // 373
1608 };
1609
ML_(get_linux_syscall_entry)1610 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
1611 {
1612 const UInt syscall_table_size
1613 = sizeof(syscall_table) / sizeof(syscall_table[0]);
1614
1615 /* Is it in the contiguous initial section of the table? */
1616 if (sysno < syscall_table_size) {
1617 SyscallTableEntry* sys = &syscall_table[sysno];
1618 if (sys->before == NULL)
1619 return NULL; /* no entry */
1620 else
1621 return sys;
1622 }
1623
1624 /* Can't find a wrapper */
1625 return NULL;
1626 }
1627
1628 #endif // defined(VGP_x86_linux)
1629
1630 /*--------------------------------------------------------------------*/
1631 /*--- end ---*/
1632 /*--------------------------------------------------------------------*/
1633