18eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 28eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*--------------------------------------------------------------------*/ 38eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*--- Platform-specific syscalls stuff. syswrap-x86-solaris.c ---*/ 48eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*--------------------------------------------------------------------*/ 58eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 68eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* 78eb8bab992e3998c33770b0cdb16059a8b918a06sewardj This file is part of Valgrind, a dynamic binary instrumentation 88eb8bab992e3998c33770b0cdb16059a8b918a06sewardj framework. 98eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 10b3a1e4bffbdbbf38304f216af405009868f43628sewardj Copyright (C) 2011-2015 Petr Pavlu 118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj setup@dagobah.cz 128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj This program is free software; you can redistribute it and/or 148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj modify it under the terms of the GNU General Public License as 158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj published by the Free Software Foundation; either version 2 of the 168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj License, or (at your option) any later version. 178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj This program is distributed in the hope that it will be useful, but 198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj WITHOUT ANY WARRANTY; without even the implied warranty of 208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj General Public License for more details. 228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj You should have received a copy of the GNU General Public License 248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj along with this program; if not, write to the Free Software 258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 02111-1307, USA. 278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj The GNU General Public License is contained in the file COPYING. 298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj*/ 308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#if defined(VGP_x86_solaris) 328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "libvex_guest_offsets.h" 348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_basics.h" 358eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_vki.h" 368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_threadstate.h" 378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_aspacemgr.h" 388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_xarray.h" 398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_clientstate.h" 408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_debuglog.h" 418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_libcassert.h" 428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_libcbase.h" 438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_libcfile.h" 448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_libcprint.h" 458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_libcsignal.h" 468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_machine.h" // VG_(get_SP) 478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_mallocfree.h" 488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_options.h" 498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_tooliface.h" 508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_signals.h" 518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_syscall.h" 528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_syswrap.h" 538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "priv_types_n_macros.h" 558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "priv_syswrap-generic.h" 568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "priv_syswrap-solaris.h" 578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* Call f(arg1), but first switch stacks, using 'stack' as the new stack, and 598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj use 'retaddr' as f's return-to address. Also, clear all the integer 608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj registers before entering f. */ 618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj__attribute__((noreturn)) 628eb8bab992e3998c33770b0cdb16059a8b918a06sewardjvoid ML_(call_on_new_stack_0_1)(Addr stack, /* 4(%esp) */ 638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Addr retaddr, /* 8(%esp) */ 648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj void (*f)(Word), /* 12(%esp) */ 658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Word arg1); /* 16(%esp) */ 668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj__asm__ ( 678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj".text\n" 688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj".globl vgModuleLocal_call_on_new_stack_0_1\n" 698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"vgModuleLocal_call_on_new_stack_0_1:\n" 708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj" movl %esp, %esi\n" /* remember old stack pointer */ 718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj" movl 4(%esi), %esp\n" /* set stack */ 728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj" pushl $0\n" /* align stack */ 738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj" pushl $0\n" /* align stack */ 748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj" pushl $0\n" /* align stack */ 758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj" pushl 16(%esi)\n" /* arg1 to stack */ 768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj" pushl 8(%esi)\n" /* retaddr to stack */ 778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj" pushl 12(%esi)\n" /* f to stack */ 788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj" movl $0, %eax\n" /* zero all GP regs */ 798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj" movl $0, %ebx\n" 808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj" movl $0, %ecx\n" 818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj" movl $0, %edx\n" 828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj" movl $0, %esi\n" 838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj" movl $0, %edi\n" 848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj" movl $0, %ebp\n" 858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj" ret\n" /* jump to f */ 868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj" ud2\n" /* should never get here */ 878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj".previous\n" 888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj); 898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* This function is called to setup a context of a new Valgrind thread (which 918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj will run the client code). */ 928eb8bab992e3998c33770b0cdb16059a8b918a06sewardjvoid ML_(setup_start_thread_context)(ThreadId tid, vki_ucontext_t *uc) 938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ThreadState *tst = VG_(get_ThreadState)(tid); 958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj UWord *stack = (UWord*)tst->os_state.valgrind_stack_init_SP; 968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj UShort cs, ds, ss, es, fs, gs; 978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(memset)(uc, 0, sizeof(*uc)); 998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_flags = VKI_UC_CPU | VKI_UC_SIGMASK; 1008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Start the thread with everything blocked. */ 1028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(sigfillset)(&uc->uc_sigmask); 1038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Set up the stack, it should be always 16-byte aligned before doing 1058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj a function call, i.e. the first parameter is also 16-byte aligned. */ 1068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(VG_IS_16_ALIGNED(stack)); 1078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj stack -= 1; 1088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj stack[0] = 0; /* bogus return value */ 1098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj stack[1] = (UWord)tst; /* the parameter */ 1108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Set up the registers. */ 1128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_EIP] = (UWord)ML_(start_thread_NORETURN); 1138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_UESP] = (UWord)stack; 1148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Copy segment registers. */ 1168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj __asm__ __volatile__( 1178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "movw %%cs, %[cs]\n" 1188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "movw %%ds, %[ds]\n" 1198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "movw %%ss, %[ss]\n" 1208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "movw %%es, %[es]\n" 1218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "movw %%fs, %[fs]\n" 1228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "movw %%gs, %[gs]\n" 1238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj : [cs] "=m" (cs), [ds] "=m" (ds), [ss] "=m" (ss), [es] "=m" (es), 1248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj [fs] "=m" (fs), [gs] "=m" (gs)); 1258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_CS] = cs; 1268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_DS] = ds; 1278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_SS] = ss; 1288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_ES] = es; 1298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_FS] = fs; 1308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_GS] = gs; 1318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 1328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* Architecture-specific part of VG_(save_context). */ 1348eb8bab992e3998c33770b0cdb16059a8b918a06sewardjvoid ML_(save_machine_context)(ThreadId tid, vki_ucontext_t *uc, 1358eb8bab992e3998c33770b0cdb16059a8b918a06sewardj CorePart part) 1368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 1378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ThreadState *tst = VG_(get_ThreadState)(tid); 1388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj struct vki_fpchip_state *fs 1398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj = &uc->uc_mcontext.fpregs.fp_reg_set.fpchip_state; 1408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT i; 1418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* CPU */ 1438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Common registers */ 1448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_EIP] = tst->arch.vex.guest_EIP; 1458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, OFFSET_x86_EIP, 1468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_EIP], sizeof(UWord)); 1478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_EAX] = tst->arch.vex.guest_EAX; 1488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, OFFSET_x86_EAX, 1498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_EAX], sizeof(UWord)); 1508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_EBX] = tst->arch.vex.guest_EBX; 1518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, OFFSET_x86_EBX, 1528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_EBX], sizeof(UWord)); 1538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_ECX] = tst->arch.vex.guest_ECX; 1548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, OFFSET_x86_ECX, 1558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_ECX], sizeof(UWord)); 1568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_EDX] = tst->arch.vex.guest_EDX; 1578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, OFFSET_x86_EDX, 1588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_EDX], sizeof(UWord)); 1598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_EBP] = tst->arch.vex.guest_EBP; 1608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, OFFSET_x86_EBP, 1618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_EBP], sizeof(UWord)); 1628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_ESI] = tst->arch.vex.guest_ESI; 1638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, OFFSET_x86_ESI, 1648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_ESI], sizeof(UWord)); 1658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_EDI] = tst->arch.vex.guest_EDI; 1668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, OFFSET_x86_EDI, 1678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_EDI], sizeof(UWord)); 1688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_UESP] = tst->arch.vex.guest_ESP; 1698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, OFFSET_x86_ESP, 1708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_UESP], sizeof(UWord)); 1718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_ESP] = 0; 1728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_mem_write, part, tid, (Addr)&uc->uc_mcontext.gregs[VKI_ESP], 1738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UWord)); 1748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* ERR and TRAPNO */ 1768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_ERR] = 0; 1778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_mem_write, part, tid, (Addr)&uc->uc_mcontext.gregs[VKI_ERR], 1788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UWord)); 1798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_TRAPNO] = 0; 1808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_mem_write, part, tid, (Addr)&uc->uc_mcontext.gregs[VKI_TRAPNO], 1818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UWord)); 1828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Segment registers */ 1848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Note that segment registers are 16b in VEX, but 32b in mcontext. Thus 1858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj we tell a tool that the lower 16 bits were copied and that the higher 16 1868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj bits were set (to zero). (This assumes a little-endian 1878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj architecture.) */ 1888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_CS] = tst->arch.vex.guest_CS; 1898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, OFFSET_x86_CS, 1908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_CS], sizeof(UShort)); 1918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_mem_write, part, tid, 1928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)(&uc->uc_mcontext.gregs[VKI_CS]) + 2, sizeof(UShort)); 1938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_DS] = tst->arch.vex.guest_DS; 1948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, OFFSET_x86_DS, 1958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_DS], sizeof(UShort)); 1968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_mem_write, part, tid, 1978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)(&uc->uc_mcontext.gregs[VKI_DS]) + 2, sizeof(UShort)); 1988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_SS] = tst->arch.vex.guest_SS; 1998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, OFFSET_x86_SS, 2008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_SS], sizeof(UShort)); 2018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_mem_write, part, tid, 2028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)(&uc->uc_mcontext.gregs[VKI_SS]) + 2, sizeof(UShort)); 2038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_ES] = tst->arch.vex.guest_ES; 2048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, OFFSET_x86_ES, 2058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_ES], sizeof(UShort)); 2068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_mem_write, part, tid, 2078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)(&uc->uc_mcontext.gregs[VKI_ES]) + 2, sizeof(UShort)); 2088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_FS] = tst->arch.vex.guest_FS; 2098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, OFFSET_x86_FS, 2108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_FS], sizeof(UShort)); 2118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_mem_write, part, tid, 2128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)(&uc->uc_mcontext.gregs[VKI_FS]) + 2, sizeof(UShort)); 2138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_GS] = tst->arch.vex.guest_GS; 2148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, OFFSET_x86_GS, 2158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_GS], sizeof(UShort)); 2168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_mem_write, part, tid, 2178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)(&uc->uc_mcontext.gregs[VKI_GS]) + 2, sizeof(UShort)); 2188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Handle eflags (optimistically make all flags defined). */ 2208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc->uc_mcontext.gregs[VKI_EFL] = 2218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj LibVEX_GuestX86_get_eflags(&tst->arch.vex); 2228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_mem_write, part, tid, (Addr)&uc->uc_mcontext.gregs[VKI_EFL], 2238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UWord)); 2248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* The LibVEX_GuestX86_get_eflags() call calculates eflags value from the 2258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj CC_OP, CC_DEP1, CC_DEP2, CC_NDEP, DFLAG, IDFLAG and ACFLAG guest state 2268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj values. The *FLAG values represent one-bit information and are saved 2278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj without loss of precision into eflags. However when CC_* values are 2288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj converted into eflags then precision is lost. What we do here is to 2298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj save unmodified CC_* values into unused ucontext members (the 'long 2308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uc_filler[5] and 'int fs->__pad[2]' arrays) so we can then restore the 2318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj context in ML_(restore_machine_context)() without the loss of precision. 2328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj This imposes a requirement on client programs to not use these two 2338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj members. Luckily this is never a case in Solaris-gate programs and 2348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj libraries. */ 2358eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* CC_OP and CC_NDEP are always defined, but we don't want to tell a tool 2368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj that we just defined uc_filler[0,1]. This helps if someone uses an 2378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uninitialized ucontext and tries to read (use) uc_filler[0,1]. Memcheck 2388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj in such a case should detect this error. */ 2398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_UC_GUEST_CC_OP(uc) = tst->arch.vex.guest_CC_OP; 2408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_UC_GUEST_CC_NDEP(uc) = tst->arch.vex.guest_CC_NDEP; 2418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* We want to copy shadow values of CC_DEP1 and CC_DEP2 so we have to tell 2428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj a tool about this copy. */ 2438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_UC_GUEST_CC_DEP1(uc) = tst->arch.vex.guest_CC_DEP1; 2448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, 2458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj offsetof(VexGuestX86State, guest_CC_DEP1), 2468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&VKI_UC_GUEST_CC_DEP1(uc), sizeof(UWord)); 2478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_UC_GUEST_CC_DEP2(uc) = tst->arch.vex.guest_CC_DEP2; 2488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, 2498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj offsetof(VexGuestX86State, guest_CC_DEP2), 2508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&VKI_UC_GUEST_CC_DEP2(uc), sizeof(UWord)); 2518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Make another copy of eflags. */ 2528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_UC_GUEST_EFLAGS_NEG(uc) = ~uc->uc_mcontext.gregs[VKI_EFL]; 2538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Calculate a checksum. */ 2548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj { 2558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj UInt buf[5]; 2568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj UInt checksum; 2578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj buf[0] = VKI_UC_GUEST_CC_OP(uc); 2598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj buf[1] = VKI_UC_GUEST_CC_NDEP(uc); 2608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj buf[2] = VKI_UC_GUEST_CC_DEP1(uc); 2618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj buf[3] = VKI_UC_GUEST_CC_DEP2(uc); 2628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj buf[4] = uc->uc_mcontext.gregs[VKI_EFL]; 2638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj checksum = ML_(fletcher32)((UShort*)&buf, sizeof(buf) / sizeof(UShort)); 2648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Store the checksum. */ 2658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_UC_GUEST_EFLAGS_CHECKSUM(uc) = checksum; 2668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 2678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* FPU */ 2698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* x87 */ 2708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(sizeof(fs->state) == 108); 2718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj LibVEX_GuestX86_get_x87(&tst->arch.vex, (UChar*)&fs->state); 2728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Flags and control words */ 2748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_mem_write, part, tid, (Addr)&fs->state, 28); 2758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* ST registers */ 2768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj for (i = 0; i < 8; i++) { 2778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Addr addr = (Addr)&fs->state + 28 + i * 10; 2788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* x87 uses 80b FP registers but VEX uses only 64b registers, thus we 2798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj have to lie here. :< */ 2808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, offsetof(VexGuestX86State, 2818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj guest_FPREG[i]), addr, sizeof(ULong)); 2828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, offsetof(VexGuestX86State, 2838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj guest_FPREG[i]), addr + 8, sizeof(UShort)); 2848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 2858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Status word (sw) at exception */ 2878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj fs->status = 0; 2888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_mem_write, part, tid, (Addr)&fs->status, sizeof(fs->status)); 2898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* SSE */ 2918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj fs->mxcsr = LibVEX_GuestX86_get_mxcsr(&tst->arch.vex); 2928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_mem_write, part, tid, (Addr)&fs->mxcsr, sizeof(fs->mxcsr)); 2938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* MXCSR at exception */ 2958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj fs->xstatus = 0; 2968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_mem_write, part, tid, (Addr)&fs->xstatus, 2978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(fs->xstatus)); 2988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* XMM registers */ 3008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#define COPY_OUT_XMM(dest, src) \ 3018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj do { \ 3028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj dest._l[0] = src[0]; \ 3038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj dest._l[1] = src[1]; \ 3048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj dest._l[2] = src[2]; \ 3058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj dest._l[3] = src[3]; \ 3068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } while (0) 3078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj COPY_OUT_XMM(fs->xmm[0], tst->arch.vex.guest_XMM0); 3088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, offsetof(VexGuestX86State, 3098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj guest_XMM0), (Addr)&fs->xmm[0], sizeof(U128)); 3108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj COPY_OUT_XMM(fs->xmm[1], tst->arch.vex.guest_XMM1); 3118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, offsetof(VexGuestX86State, 3128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj guest_XMM1), (Addr)&fs->xmm[1], sizeof(U128)); 3138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj COPY_OUT_XMM(fs->xmm[2], tst->arch.vex.guest_XMM2); 3148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, offsetof(VexGuestX86State, 3158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj guest_XMM2), (Addr)&fs->xmm[2], sizeof(U128)); 3168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj COPY_OUT_XMM(fs->xmm[3], tst->arch.vex.guest_XMM3); 3178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, offsetof(VexGuestX86State, 3188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj guest_XMM3), (Addr)&fs->xmm[3], sizeof(U128)); 3198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj COPY_OUT_XMM(fs->xmm[4], tst->arch.vex.guest_XMM4); 3208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, offsetof(VexGuestX86State, 3218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj guest_XMM4), (Addr)&fs->xmm[4], sizeof(U128)); 3228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj COPY_OUT_XMM(fs->xmm[5], tst->arch.vex.guest_XMM5); 3238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, offsetof(VexGuestX86State, 3248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj guest_XMM5), (Addr)&fs->xmm[5], sizeof(U128)); 3258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj COPY_OUT_XMM(fs->xmm[6], tst->arch.vex.guest_XMM6); 3268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, offsetof(VexGuestX86State, 3278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj guest_XMM6), (Addr)&fs->xmm[6], sizeof(U128)); 3288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj COPY_OUT_XMM(fs->xmm[7], tst->arch.vex.guest_XMM7); 3298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_reg_to_mem, part, tid, offsetof(VexGuestX86State, 3308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj guest_XMM7), (Addr)&fs->xmm[7], sizeof(U128)); 3318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#undef COPY_OUT_XMM 3328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 3338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 3348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* Architecture-specific part of VG_(restore_context). */ 3358eb8bab992e3998c33770b0cdb16059a8b918a06sewardjvoid ML_(restore_machine_context)(ThreadId tid, vki_ucontext_t *uc, 3368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj CorePart part, Bool esp_is_thrptr) 3378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 3388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ThreadState *tst = VG_(get_ThreadState)(tid); 3398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj struct vki_fpchip_state *fs 3408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj = &uc->uc_mcontext.fpregs.fp_reg_set.fpchip_state; 3418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 3428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* CPU */ 3438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (uc->uc_flags & VKI_UC_CPU) { 3448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Common registers */ 3458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_EIP = uc->uc_mcontext.gregs[VKI_EIP]; 3468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, 3478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_EIP], OFFSET_x86_EIP, 3488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UWord)); 3498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_EAX = uc->uc_mcontext.gregs[VKI_EAX]; 3508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, 3518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_EAX], OFFSET_x86_EAX, 3528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UWord)); 3538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_EBX = uc->uc_mcontext.gregs[VKI_EBX]; 3548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, 3558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_EBX], OFFSET_x86_EBX, 3568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UWord)); 3578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_ECX = uc->uc_mcontext.gregs[VKI_ECX]; 3588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, 3598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_ECX], OFFSET_x86_ECX, 3608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UWord)); 3618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_EDX = uc->uc_mcontext.gregs[VKI_EDX]; 3628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, 3638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_EDX], OFFSET_x86_EDX, 3648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UWord)); 3658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_EBP = uc->uc_mcontext.gregs[VKI_EBP]; 3668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, 3678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_EBP], OFFSET_x86_EBP, 3688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UWord)); 3698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_ESI = uc->uc_mcontext.gregs[VKI_ESI]; 3708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, 3718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_ESI], OFFSET_x86_ESI, 3728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UWord)); 3738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_EDI = uc->uc_mcontext.gregs[VKI_EDI]; 3748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, 3758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_EDI], OFFSET_x86_EDI, 3768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UWord)); 3778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_ESP = uc->uc_mcontext.gregs[VKI_UESP]; 3788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, 3798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_UESP], OFFSET_x86_ESP, 3808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UWord)); 3818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 3828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (esp_is_thrptr) { 3838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* The thrptr value is passed by libc to the kernel in the otherwise 3848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj unused ESP field. This is used when a new thread is created. */ 3858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(pre_mem_read, part, tid, 3868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "restore_machine_context(uc->uc_mcontext.gregs[VKI_ESP])", 3878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_ESP], sizeof(UWord)); 3888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (uc->uc_mcontext.gregs[VKI_ESP]) { 3898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->os_state.thrptr = uc->uc_mcontext.gregs[VKI_ESP]; 3908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ML_(update_gdt_lwpgs)(tid); 3918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 3928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 3938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 3948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Ignore ERR and TRAPNO. */ 3958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 3968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Segment registers */ 3978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_CS = uc->uc_mcontext.gregs[VKI_CS]; 3988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, 3998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_CS], OFFSET_x86_CS, 4008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UShort)); 4018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_DS = uc->uc_mcontext.gregs[VKI_DS]; 4028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, 4038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_DS], OFFSET_x86_DS, 4048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UShort)); 4058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_SS = uc->uc_mcontext.gregs[VKI_SS]; 4068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, 4078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_SS], OFFSET_x86_SS, 4088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UShort)); 4098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_ES = uc->uc_mcontext.gregs[VKI_ES]; 4108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, 4118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_ES], OFFSET_x86_ES, 4128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UShort)); 4138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_FS = uc->uc_mcontext.gregs[VKI_FS]; 4148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, 4158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_FS], OFFSET_x86_FS, 4168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UShort)); 4178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_GS = uc->uc_mcontext.gregs[VKI_GS]; 4188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, 4198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_GS], OFFSET_x86_GS, 4208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UShort)); 4218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Eflags */ 4238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj { 4248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj UInt eflags; 4258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj UInt orig_eflags; 4268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj UInt new_eflags; 4278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Bool ok_restore = False; 4288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(pre_mem_read, part, tid, 4308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "restore_machine_context(uc->uc_mcontext.gregs[VKI_EFL])", 4318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&uc->uc_mcontext.gregs[VKI_EFL], sizeof(UWord)); 4328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj eflags = uc->uc_mcontext.gregs[VKI_EFL]; 4338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj orig_eflags = LibVEX_GuestX86_get_eflags(&tst->arch.vex); 4348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj new_eflags = eflags; 4358eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* The kernel disallows the ID flag to be changed via the setcontext 4368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj call, thus do the same. */ 4378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (orig_eflags & VKI_EFLAGS_ID_BIT) 4388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj new_eflags |= VKI_EFLAGS_ID_BIT; 4398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj else 4408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj new_eflags &= ~VKI_EFLAGS_ID_BIT; 4418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj LibVEX_GuestX86_put_eflags(new_eflags, &tst->arch.vex); 4428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_reg_write, part, tid, 4438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj offsetof(VexGuestX86State, guest_CC_DEP1), sizeof(UWord)); 4448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_reg_write, part, tid, 4458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj offsetof(VexGuestX86State, guest_CC_DEP2), sizeof(UWord)); 4468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Check if this context was created by us in VG_(save_context). In 4488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj that case, try to restore the CC_OP, CC_DEP1, CC_DEP2 and CC_NDEP 4498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj values which we previously stashed into unused members of the 4508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj context. */ 4518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (eflags != ~VKI_UC_GUEST_EFLAGS_NEG(uc)) { 4528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(debugLog)(1, "syswrap-solaris", 4538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "The eflags value was restored from an " 454b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian "explicitly set value in thread %u.\n", tid); 4558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ok_restore = True; 4568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 4578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj else { 4588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj UInt buf[5]; 4598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj UInt checksum; 4608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj buf[0] = VKI_UC_GUEST_CC_OP(uc); 4628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj buf[1] = VKI_UC_GUEST_CC_NDEP(uc); 4638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj buf[2] = VKI_UC_GUEST_CC_DEP1(uc); 4648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj buf[3] = VKI_UC_GUEST_CC_DEP2(uc); 4658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj buf[4] = eflags; 4668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj checksum = ML_(fletcher32)((UShort*)&buf, 4678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(buf) / sizeof(UShort)); 4688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (checksum == VKI_UC_GUEST_EFLAGS_CHECKSUM(uc)) { 4698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Check ok, the full restoration is possible. */ 4708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(debugLog)(1, "syswrap-solaris", 4718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "The CC_* guest state values were fully " 472b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian "restored in thread %u.\n", tid); 4738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ok_restore = True; 4748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_CC_OP = VKI_UC_GUEST_CC_OP(uc); 4768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_CC_NDEP = VKI_UC_GUEST_CC_NDEP(uc); 4778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_CC_DEP1 = VKI_UC_GUEST_CC_DEP1(uc); 4788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, 4798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&VKI_UC_GUEST_CC_DEP1(uc), 4808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj offsetof(VexGuestX86State, guest_CC_DEP1), 4818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UWord)); 4828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_CC_DEP2 = VKI_UC_GUEST_CC_DEP2(uc); 4838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, 4848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&VKI_UC_GUEST_CC_DEP2(uc), 4858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj offsetof(VexGuestX86State, guest_CC_DEP2), 4868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UWord)); 4878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 4888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 4898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (!ok_restore) 4918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(debugLog)(1, "syswrap-solaris", 4928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "Cannot fully restore the CC_* guest state " 4938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "values, using approximate eflags in thread " 494b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian "%u.\n", tid); 4958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 4968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 4978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (uc->uc_flags & VKI_UC_FPU) { 4998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* FPU */ 5008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VexEmNote note; 5018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT i; 5028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* x87 */ 5048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Flags and control words */ 5058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(pre_mem_read, part, tid, 5068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "restore_machine_context(uc->uc_mcontext.fpregs..x87_state)", 5078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&fs->state, 28); 5088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* ST registers */ 5098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj for (i = 0; i < 8; i++) { 5108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Addr addr = (Addr)&fs->state + 28 + i * 10; 5118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, addr, 5128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj offsetof(VexGuestX86State, guest_FPREG[i]), sizeof(ULong)); 5138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 5148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj note = LibVEX_GuestX86_put_x87((UChar*)&fs->state, &tst->arch.vex); 5158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (note != EmNote_NONE) 5168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(message)(Vg_UserMsg, 517b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian "Error restoring x87 state in thread %u: %s.\n", 5188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tid, LibVEX_EmNote_string(note)); 5198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* SSE */ 5218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(pre_mem_read, part, tid, 5228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "restore_machine_context(uc->uc_mcontext.fpregs..mxcsr)", 5238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (Addr)&fs->mxcsr, sizeof(fs->mxcsr)); 5248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj note = LibVEX_GuestX86_put_mxcsr(fs->mxcsr, &tst->arch.vex); 5258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (note != EmNote_NONE) 5268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(message)(Vg_UserMsg, 527b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian "Error restoring mxcsr state in thread %u: %s.\n", 5288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tid, LibVEX_EmNote_string(note)); 5298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* XMM registers */ 5308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#define COPY_IN_XMM(src, dest) \ 5318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj do { \ 5328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj dest[0] = src._l[0]; \ 5338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj dest[1] = src._l[1]; \ 5348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj dest[2] = src._l[2]; \ 5358eb8bab992e3998c33770b0cdb16059a8b918a06sewardj dest[3] = src._l[3]; \ 5368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } while (0) 5378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj COPY_IN_XMM(fs->xmm[0], tst->arch.vex.guest_XMM0); 5388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, (Addr)&fs->xmm[0], 5398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj offsetof(VexGuestX86State, guest_XMM0), sizeof(U128)); 5408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj COPY_IN_XMM(fs->xmm[1], tst->arch.vex.guest_XMM1); 5418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, (Addr)&fs->xmm[1], 5428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj offsetof(VexGuestX86State, guest_XMM1), sizeof(U128)); 5438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj COPY_IN_XMM(fs->xmm[2], tst->arch.vex.guest_XMM2); 5448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, (Addr)&fs->xmm[2], 5458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj offsetof(VexGuestX86State, guest_XMM2), sizeof(U128)); 5468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj COPY_IN_XMM(fs->xmm[3], tst->arch.vex.guest_XMM3); 5478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, (Addr)&fs->xmm[3], 5488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj offsetof(VexGuestX86State, guest_XMM3), sizeof(U128)); 5498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj COPY_IN_XMM(fs->xmm[4], tst->arch.vex.guest_XMM4); 5508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, (Addr)&fs->xmm[4], 5518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj offsetof(VexGuestX86State, guest_XMM4), sizeof(U128)); 5528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj COPY_IN_XMM(fs->xmm[5], tst->arch.vex.guest_XMM5); 5538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, (Addr)&fs->xmm[5], 5548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj offsetof(VexGuestX86State, guest_XMM5), sizeof(U128)); 5558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj COPY_IN_XMM(fs->xmm[6], tst->arch.vex.guest_XMM6); 5568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, (Addr)&fs->xmm[6], 5578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj offsetof(VexGuestX86State, guest_XMM6), sizeof(U128)); 5588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj COPY_IN_XMM(fs->xmm[7], tst->arch.vex.guest_XMM7); 5598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(copy_mem_to_reg, part, tid, (Addr)&fs->xmm[7], 5608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj offsetof(VexGuestX86State, guest_XMM7), sizeof(U128)); 5618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#undef COPY_IN_XMM 5628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 5638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 5648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* Allocate GDT for a given thread. */ 5668eb8bab992e3998c33770b0cdb16059a8b918a06sewardjvoid ML_(setup_gdt)(VexGuestX86State *vex) 5678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 5688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Addr gdt = (Addr)VG_(calloc)("syswrap-solaris-x86.gdt", 5698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VEX_GUEST_X86_GDT_NENT, 5708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(VexGuestX86SegDescr)); 5718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vex->guest_GDT = gdt; 5728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 5738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* Deallocate GDT for a given thread. */ 5758eb8bab992e3998c33770b0cdb16059a8b918a06sewardjvoid ML_(cleanup_gdt)(VexGuestX86State *vex) 5768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 5778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (!vex->guest_GDT) 5788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj return; 5798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(free)((void*)vex->guest_GDT); 5808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vex->guest_GDT = 0; 5818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 5828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* For a given thread, update the LWPGS descriptor in the thread's GDT 5848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj according to the thread pointer. */ 5858eb8bab992e3998c33770b0cdb16059a8b918a06sewardjvoid ML_(update_gdt_lwpgs)(ThreadId tid) 5868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 5878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ThreadState *tst = VG_(get_ThreadState)(tid); 5888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Addr base = tst->os_state.thrptr; 5898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VexGuestX86SegDescr *gdt = (VexGuestX86SegDescr*)tst->arch.vex.guest_GDT; 5908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VexGuestX86SegDescr desc; 5918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(gdt); 5938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(memset)(&desc, 0, sizeof(desc)); 5958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (base) { 5968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj desc.LdtEnt.Bits.LimitLow = -1; 5978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj desc.LdtEnt.Bits.LimitHi = -1; 5988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj desc.LdtEnt.Bits.BaseLow = base & 0xffff; 5998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj desc.LdtEnt.Bits.BaseMid = (base >> 16) & 0xff; 6008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj desc.LdtEnt.Bits.BaseHi = (base >> 24) & 0xff; 6018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj desc.LdtEnt.Bits.Pres = 1; 6028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj desc.LdtEnt.Bits.Dpl = 3; /* SEL_UPL */ 6038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj desc.LdtEnt.Bits.Type = 19; /* SDT_MEMRWA */ 6048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj desc.LdtEnt.Bits.Granularity = 1; /* SDP_PAGES */ 6058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj desc.LdtEnt.Bits.Default_Big = 1; /* SDP_OP32 */ 6068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 6078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj gdt[VKI_GDT_LWPGS] = desc; 6098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Write %gs. */ 6118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj tst->arch.vex.guest_GS = VKI_LWPGS_SEL; 6128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_x86_GS, 6138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(UShort)); 6148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 6158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* --------------------------------------------------------------------- 6188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE/POST wrappers for x86/Solaris-specific syscalls 6198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ------------------------------------------------------------------ */ 6208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#define PRE(name) DEFN_PRE_TEMPLATE(x86_solaris, name) 6228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#define POST(name) DEFN_POST_TEMPLATE(x86_solaris, name) 6238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* implementation */ 6258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6268eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPRE(sys_fstatat64) 6278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 6288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* int fstatat64(int fildes, const char *path, struct stat64 *buf, 6298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj int flag); */ 630b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx, %ld )", SARG1, ARG2, 631b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian (HChar*)ARG2, ARG3, SARG4); 6328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_REG_READ4(long, "fstatat64", int, fildes, const char *, path, 6338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj struct stat64 *, buf, int, flag); 6348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (ARG2) 6358eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_MEM_RASCIIZ("fstatat64(path)", ARG2); 6368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_MEM_WRITE("fstatat64(buf)", ARG3, sizeof(struct vki_stat64)); 6378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Be strict. */ 6398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (ARG1 != VKI_AT_FDCWD && 6408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj !ML_(fd_allowed)(ARG1, "fstatat64", tid, False)) 6418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SET_STATUS_Failure(VKI_EBADF); 6428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 6438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6448eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPOST(sys_fstatat64) 6458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 6468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_MEM_WRITE(ARG3, sizeof(struct vki_stat64)); 6478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 6488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6498eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPRE(sys_openat64) 6508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 6518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* int openat64(int fildes, const char *filename, int flags); 6528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj int openat64(int fildes, const char *filename, int flags, mode_t mode); 6538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj */ 6548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *flags |= SfMayBlock; 6558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (ARG3 & VKI_O_CREAT) { 6578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* 4-arg version */ 658b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian PRINT("sys_openat64 ( %ld, %#lx(%s), %ld, %ld )", SARG1, ARG2, 659b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian (HChar*)ARG2, SARG3, SARG4); 6608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_REG_READ4(long, "openat64", int, fildes, const char *, filename, 6618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj int, flags, vki_mode_t, mode); 6628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 6638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj else { 6648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* 3-arg version */ 665b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian PRINT("sys_openat64 ( %ld, %#lx(%s), %ld )", SARG1, ARG2, (HChar*)ARG2, 666b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian SARG3); 6678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_REG_READ3(long, "openat64", int, fildes, const char *, filename, 6688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj int, flags); 6698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 6708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_MEM_RASCIIZ("openat64(filename)", ARG2); 6728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Be strict. */ 6748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (ARG1 != VKI_AT_FDCWD && !ML_(fd_allowed)(ARG1, "openat64", tid, False)) 6758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SET_STATUS_Failure(VKI_EBADF); 6768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 6778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6788eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPOST(sys_openat64) 6798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 6808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (!ML_(fd_allowed)(RES, "openat64", tid, True)) { 6818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(close)(RES); 6828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SET_STATUS_Failure(VKI_EMFILE); 6838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 6848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj else if (VG_(clo_track_fds)) 6858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG2); 6868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 6878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6888eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPRE(sys_llseek32) 6898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 6908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* offset_t llseek(int fildes, offset_t offset, int whence); */ 691b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian PRINT("sys_llseek32 ( %ld, %#lx, %#lx, %ld )", SARG1, ARG2, ARG3, SARG4); 6928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_REG_READ4(long, "llseek", int, fildes, vki_u32, offset_low, 6938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vki_u32, offset_high, int, whence); 6948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Stay sane. */ 6968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (!ML_(fd_allowed)(ARG1, "llseek", tid, False)) 6978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SET_STATUS_Failure(VKI_EBADF); 6988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 6998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7008eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPRE(sys_mmap64) 7018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 7028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* void *mmap64(void *addr, size_t len, int prot, int flags, 7038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj int fildes, uint32_t offlo, uint32_t offhi); */ 7048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Note this wrapper assumes a little-endian architecture, offlo and offhi 7058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj have to be swapped if a big-endian architecture is present. */ 7068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#if !defined(VG_LITTLEENDIAN) 7078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#error "Unexpected endianness." 7088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#endif /* !VG_LITTLEENDIAN */ 7098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SysRes r; 7118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ULong u; 7128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Off64T offset; 7138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Stay sane. */ 7158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(VKI_PAGE_SIZE == 4096); 7168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(sizeof(u) == sizeof(offset)); 7178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRINT("sys_mmap ( %#lx, %#lx, %#lx, %#lx, %ld, %#lx, %#lx )", 719b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian ARG1, ARG2, ARG3, ARG4, SARG5, ARG6, ARG7); 7208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_REG_READ7(long, "mmap", void *, start, vki_size_t, length, 7218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj int, prot, int, flags, int, fd, uint32_t, offlo, 7228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uint32_t, offhi); 7238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* The offlo and offhi values can actually represent a negative value. 7258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Make sure it's passed correctly to the generic mmap wrapper. */ 7268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj u = ((ULong)ARG7 << 32) + ARG6; 7278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj offset = *(Off64T*)&u; 7288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj r = ML_(generic_PRE_sys_mmap)(tid, ARG1, ARG2, ARG3, ARG4, ARG5, offset); 7308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SET_STATUS_from_SysRes(r); 7318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 7328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7338eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPRE(sys_stat64) 7348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 7358eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* int stat64(const char *path, struct stat64 *buf); */ 736b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian PRINT("sys_stat64 ( %#lx(%s), %#lx )", ARG1, (HChar*)ARG1, ARG2); 7378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_REG_READ2(long, "stat64", const char *, path, struct stat64 *, buf); 7388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_MEM_RASCIIZ("stat64(path)", ARG1); 7408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_MEM_WRITE("stat64(buf)", ARG2, sizeof(struct vki_stat64)); 7418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 7428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7438eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPOST(sys_stat64) 7448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 7458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_MEM_WRITE(ARG2, sizeof(struct vki_stat64)); 7468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 7478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7488eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPRE(sys_lstat64) 7498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 7508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* int lstat64(const char *path, struct stat64 *buf); */ 751b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian PRINT("sys_lstat64 ( %#lx(%s), %#lx )", ARG1, (HChar*)ARG1, ARG2); 7528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_REG_READ2(long, "lstat64", const char *, path, struct stat64 *, buf); 7538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_MEM_RASCIIZ("lstat64(path)", ARG1); 7558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_MEM_WRITE("lstat64(buf)", ARG2, sizeof(struct vki_stat64)); 7568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 7578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7588eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPOST(sys_lstat64) 7598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 7608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_MEM_WRITE(ARG2, sizeof(struct vki_stat64)); 7618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 7628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7638eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPRE(sys_fstat64) 7648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 7658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* int fstat64(int fildes, struct stat64 *buf); */ 766b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian PRINT("sys_fstat64 ( %ld, %#lx )", SARG1, ARG2); 7678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_REG_READ2(long, "fstat64", int, fildes, struct stat64 *, buf); 7688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_MEM_WRITE("fstat64(buf)", ARG2, sizeof(struct vki_stat64)); 7698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Be strict. */ 7718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (!ML_(fd_allowed)(ARG1, "fstat64", tid, False)) 7728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SET_STATUS_Failure(VKI_EBADF); 7738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 7748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7758eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPOST(sys_fstat64) 7768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 7778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_MEM_WRITE(ARG2, sizeof(struct vki_stat64)); 7788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 7798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7808eb8bab992e3998c33770b0cdb16059a8b918a06sewardjstatic void do_statvfs64_post(struct vki_statvfs64 *stats, ThreadId tid) 7818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 7828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_FIELD_WRITE(stats->f_bsize); 7838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_FIELD_WRITE(stats->f_frsize); 7848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_FIELD_WRITE(stats->f_blocks); 7858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_FIELD_WRITE(stats->f_bfree); 7868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_FIELD_WRITE(stats->f_bavail); 7878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_FIELD_WRITE(stats->f_files); 7888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_FIELD_WRITE(stats->f_ffree); 7898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_FIELD_WRITE(stats->f_favail); 7908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_FIELD_WRITE(stats->f_fsid); 7918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_MEM_WRITE((Addr) stats->f_basetype, VG_(strlen)(stats->f_basetype) + 1); 7928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_FIELD_WRITE(stats->f_flag); 7938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_FIELD_WRITE(stats->f_namemax); 7948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_MEM_WRITE((Addr) stats->f_fstr, VG_(strlen)(stats->f_fstr) + 1); 7958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 7968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7978eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPRE(sys_statvfs64) 7988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 7998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* int statvfs64(const char *path, struct statvfs64 *buf); */ 8008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *flags |= SfMayBlock; 8018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRINT("sys_statvfs64 ( %#lx(%s), %#lx )", ARG1, (HChar *) ARG1, ARG2); 8028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_REG_READ2(long, "statvfs64", const char *, path, 8038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj struct vki_statvfs64 *, buf); 8048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_MEM_RASCIIZ("statvfs64(path)", ARG1); 8058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_MEM_WRITE("statvfs64(buf)", ARG2, sizeof(struct vki_statvfs64)); 8068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 8078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8088eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPOST(sys_statvfs64) 8098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 8108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj do_statvfs64_post((struct vki_statvfs64 *) ARG2, tid); 8118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 8128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8138eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPRE(sys_fstatvfs64) 8148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 8158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* int fstatvfs64(int fd, struct statvfs64 *buf); */ 8168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *flags |= SfMayBlock; 817b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian PRINT("sys_fstatvfs64 ( %ld, %#lx )", SARG1, ARG2); 8188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_REG_READ2(long, "fstatvfs64", int, fd, struct vki_statvfs64 *, buf); 8198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_MEM_WRITE("fstatvfs64(buf)", ARG2, sizeof(struct vki_statvfs64)); 8208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Be strict. */ 8228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (!ML_(fd_allowed)(ARG1, "fstatvfs64", tid, False)) 8238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SET_STATUS_Failure(VKI_EBADF); 8248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 8258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8268eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPOST(sys_fstatvfs64) 8278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 8288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj do_statvfs64_post((struct vki_statvfs64 *) ARG2, tid); 8298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 8308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8318eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPRE(sys_setrlimit64) 8328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 8338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* int setrlimit64(int resource, struct rlimit64 *rlim); */ 8348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj struct vki_rlimit64 *limit = (struct vki_rlimit64 *)ARG2; 835b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian PRINT("sys_setrlimit64 ( %ld, %#lx )", SARG1, ARG2); 8368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_REG_READ2(long, "setrlimit64", int, resource, struct rlimit64 *, rlim); 8378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_MEM_READ("setrlimit64(rlim)", ARG2, sizeof(struct vki_rlimit64)); 8388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (limit && limit->rlim_cur > limit->rlim_max) 8408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SET_STATUS_Failure(VKI_EINVAL); 8418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj else if (ARG1 == VKI_RLIMIT_NOFILE) { 8428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (limit->rlim_cur > VG_(fd_hard_limit) || 8438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj limit->rlim_max != VG_(fd_hard_limit)) { 8448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SET_STATUS_Failure(VKI_EPERM); 8458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 8468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj else { 8478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(fd_soft_limit) = limit->rlim_cur; 8488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SET_STATUS_Success(0); 8498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 8508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 8518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj else if (ARG1 == VKI_RLIMIT_DATA) { 8528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (limit->rlim_cur > VG_(client_rlimit_data).rlim_max || 8538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj limit->rlim_max > VG_(client_rlimit_data).rlim_max) { 8548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SET_STATUS_Failure(VKI_EPERM); 8558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 8568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj else { 8578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(client_rlimit_data).rlim_max = limit->rlim_max; 8588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(client_rlimit_data).rlim_cur = limit->rlim_cur; 8598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SET_STATUS_Success(0); 8608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 8618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 8628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj else if (ARG1 == VKI_RLIMIT_STACK && tid == 1) { 8638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (limit->rlim_cur > VG_(client_rlimit_stack).rlim_max || 8648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj limit->rlim_max > VG_(client_rlimit_stack).rlim_max) { 8658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SET_STATUS_Failure(VKI_EPERM); 8668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 8678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj else { 8688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Change the value of client_stack_szB to the rlim_cur value but 8698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj only if it is smaller than the size of the allocated stack for the 8708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj client. */ 8718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (limit->rlim_cur <= VG_(clstk_max_size)) 8728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(threads)[tid].client_stack_szB = limit->rlim_cur; 8738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(client_rlimit_stack).rlim_max = limit->rlim_max; 8758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(client_rlimit_stack).rlim_cur = limit->rlim_cur; 8768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SET_STATUS_Success(0); 8778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 8788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 8798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 8808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8818eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPRE(sys_getrlimit64) 8828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 8838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* int getrlimit64(int resource, struct rlimit64 *rlim); */ 884b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian PRINT("sys_getrlimit64 ( %ld, %#lx )", SARG1, ARG2); 8858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_REG_READ2(long, "getrlimit64", 8868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj int, resource, struct rlimit64 *, rlim); 8878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_MEM_WRITE("getrlimit64(rlim)", ARG2, sizeof(struct vki_rlimit64)); 8888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 8898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8908eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPOST(sys_getrlimit64) 8918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 8928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Based on common_post_getrlimit() from syswrap-generic.c. */ 8938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj struct vki_rlimit64 *rlim = (struct vki_rlimit64*)ARG2; 8948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_MEM_WRITE(ARG2, sizeof(struct vki_rlimit64)); 8968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj switch (ARG1 /*resource*/) { 8988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj case VKI_RLIMIT_NOFILE: 8998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj rlim->rlim_cur = VG_(fd_soft_limit); 9008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj rlim->rlim_max = VG_(fd_hard_limit); 9018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj break; 9028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj case VKI_RLIMIT_DATA: 9038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj rlim->rlim_cur = VG_(client_rlimit_data).rlim_cur; 9048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj rlim->rlim_max = VG_(client_rlimit_data).rlim_max; 9058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj break; 9068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj case VKI_RLIMIT_STACK: 9078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj rlim->rlim_cur = VG_(client_rlimit_stack).rlim_cur; 9088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj rlim->rlim_max = VG_(client_rlimit_stack).rlim_max; 9098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj break; 9108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 9118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 9128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9138eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPRE(sys_pread64) 9148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 9158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* ssize32_t pread64(int fd, void *buf, size32_t count, 9168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uint32_t offset_1, uint32_t offset_2); 9178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj */ 9188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *flags |= SfMayBlock; 919b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian PRINT("sys_pread64 ( %ld, %#lx, %lu, %#lx, %#lx )", 920b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian SARG1, ARG2, ARG3, ARG4, ARG5); 9218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_REG_READ5(long, "pread64", int, fd, void *, buf, vki_size32_t, count, 9228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vki_uint32_t, offset_1, vki_uint32_t, offset_2); 9238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_MEM_WRITE("pread64(buf)", ARG2, ARG3); 9248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Be strict. */ 9268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (!ML_(fd_allowed)(ARG1, "pread64", tid, False)) 9278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SET_STATUS_Failure(VKI_EBADF); 9288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 9298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9308eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPOST(sys_pread64) 9318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 9328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj POST_MEM_WRITE(ARG2, RES); 9338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 9348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9358eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPRE(sys_pwrite64) 9368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 9378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* ssize32_t pwrite64(int fd, void *buf, size32_t count, 9388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj uint32_t offset_1, uint32_t offset_2); 9398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj */ 9408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *flags |= SfMayBlock; 941b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian PRINT("sys_pwrite64 ( %ld, %#lx, %lu, %#lx, %#lx )", 942b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian SARG1, ARG2, ARG3, ARG4, ARG5); 9438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_REG_READ5(long, "pwrite64", int, fd, void *, buf, vki_size32_t, count, 9448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vki_uint32_t, offset_1, vki_uint32_t, offset_2); 9458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_MEM_READ("pwrite64(buf)", ARG2, ARG3); 9468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Be strict. */ 9488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (!ML_(fd_allowed)(ARG1, "pwrite64", tid, False)) 9498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SET_STATUS_Failure(VKI_EBADF); 9508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 9518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9528eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPRE(sys_open64) 9538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 9548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* int open64(const char *filename, int flags); 9558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj int open64(const char *filename, int flags, mode_t mode); */ 9568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *flags |= SfMayBlock; 9578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (ARG2 & VKI_O_CREAT) { 9598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* 3-arg version */ 960b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian PRINT("sys_open64 ( %#lx(%s), %#lx, %ld )", ARG1, (HChar*)ARG1, ARG2, 961b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian SARG3); 9628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_REG_READ3(long, "open64", const char *, filename, int, flags, 9638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vki_mode_t, mode); 9648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 9658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj else { 9668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* 2-arg version */ 967b26101c4d128f0bfed780434c4e4f8d67f8aeee4florian PRINT("sys_open64 ( %#lx(%s), %#lx )", ARG1, (HChar*)ARG1, ARG2); 9688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_REG_READ2(long, "open64", const char *, filename, int, flags); 9698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 9708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj PRE_MEM_RASCIIZ("open(filename)", ARG1); 9718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 9728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9738eb8bab992e3998c33770b0cdb16059a8b918a06sewardjPOST(sys_open64) 9748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 9758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (!ML_(fd_allowed)(RES, "open64", tid, True)) { 9768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(close)(RES); 9778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SET_STATUS_Failure(VKI_EMFILE); 9788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 9798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj else if (VG_(clo_track_fds)) 9808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ML_(record_fd_open_with_given_name)(tid, RES, (HChar*)ARG1); 9818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 9828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#undef PRE 9848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#undef POST 9858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#endif // defined(VGP_x86_solaris) 9878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*--------------------------------------------------------------------*/ 9898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*--- end ---*/ 9908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*--------------------------------------------------------------------*/ 991