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