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