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 (at) 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 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. */ 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. */ 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. */ 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. */ 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. */ 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. */ 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 (at) 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 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 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 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 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 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 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 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 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 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 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 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 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 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. 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 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 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 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 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 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 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 1023 POST(sys_stat64) 1024 { 1025 POST_MEM_WRITE( ARG2, sizeof(struct vki_stat64) ); 1026 } 1027 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 1041 POST(sys_fstatat64) 1042 { 1043 POST_MEM_WRITE( ARG3, sizeof(struct vki_stat64) ); 1044 } 1045 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 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. */ 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 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 1085 POST(sys_vm86old) 1086 { 1087 POST_MEM_WRITE( ARG1, sizeof(struct vki_vm86_struct)); 1088 } 1089 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 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 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 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 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