1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Low level interface to valgrind, for the remote server for GDB integrated
2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   in valgrind.
3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Copyright (C) 2011
4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Free Software Foundation, Inc.
5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   This file is part of VALGRIND.
7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   It has been inspired from a file from gdbserver in gdb 6.6.
8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   This program is free software; you can redistribute it and/or modify
10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   it under the terms of the GNU General Public License as published by
11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   the Free Software Foundation; either version 2 of the License, or
12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   (at your option) any later version.
13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   This program is distributed in the hope that it will be useful,
15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   but WITHOUT ANY WARRANTY; without even the implied warranty of
16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   GNU General Public License for more details.
18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   You should have received a copy of the GNU General Public License
20b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   along with this program; if not, write to the Free Software
21b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Foundation, Inc., 51 Franklin Street, Fifth Floor,
22b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Boston, MA 02110-1301, USA.  */
23b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
24b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "server.h"
25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "target.h"
26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "regdef.h"
27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "regcache.h"
28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_aspacemgr.h"
30b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_tool_machine.h"
31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_threadstate.h"
32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_transtab.h"
33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_gdbserver.h"
34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "valgrind_low.h"
36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "libvex_guest_x86.h"
38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* GDBTD: ??? have a cleaner way to get the f80 <> f64 conversion functions */
39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* below include needed for conversion f80 <> f64 */
40b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "../../VEX/priv/guest_generic_x87.h"
41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
43b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* below loosely inspired from  file generated with gdb regdat.sh  */
44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic struct reg regs[] = {
46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "eax", 0, 32 },
47b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "ecx", 32, 32 },
48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "edx", 64, 32 },
49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "ebx", 96, 32 },
50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "esp", 128, 32 },
51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "ebp", 160, 32 },
52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "esi", 192, 32 },
53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "edi", 224, 32 },
54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "eip", 256, 32 },
55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "eflags", 288, 32 },
56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "cs", 320, 32 },
57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "ss", 352, 32 },
58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "ds", 384, 32 },
59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "es", 416, 32 },
60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "fs", 448, 32 },
61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "gs", 480, 32 },
62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "st0", 512, 80 },
63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "st1", 592, 80 },
64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "st2", 672, 80 },
65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "st3", 752, 80 },
66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "st4", 832, 80 },
67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "st5", 912, 80 },
68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "st6", 992, 80 },
69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "st7", 1072, 80 },
70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "fctrl", 1152, 32 },
71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "fstat", 1184, 32 },
72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "ftag", 1216, 32 },
73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "fiseg", 1248, 32 },
74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "fioff", 1280, 32 },
75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "foseg", 1312, 32 },
76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "fooff", 1344, 32 },
77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "fop", 1376, 32 },
78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "xmm0", 1408, 128 },
79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "xmm1", 1536, 128 },
80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "xmm2", 1664, 128 },
81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "xmm3", 1792, 128 },
82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "xmm4", 1920, 128 },
83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "xmm5", 2048, 128 },
84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "xmm6", 2176, 128 },
85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "xmm7", 2304, 128 },
86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "mxcsr", 2432, 32 },
87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   { "orig_eax", 2464, 32 }
89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov};
91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic const char *expedite_regs[] = { "ebp", "esp", "eip", 0 };
92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define num_regs (sizeof (regs) / sizeof (regs[0]))
93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovCORE_ADDR get_pc (void)
96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   unsigned long pc;
98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   collect_register_by_name ("eip", &pc);
100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   dlog(1, "stop pc is %p\n", (void *) pc);
102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return pc;
103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid set_pc (CORE_ADDR newpc)
107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Bool mod;
109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   supply_register_by_name ("eip", &newpc, &mod);
110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (mod)
111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog(1, "set pc to %p\n", C2v (newpc));
112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   else
113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog(1, "set pc not changed %p\n", C2v (newpc));
114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* store registers in the guest state (gdbserver_to_valgrind)
117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   or fetch register from the guest state (valgrind_to_gdbserver). */
118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid transfer_register (ThreadId tid, int abs_regno, void * buf,
120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        transfer_direction dir, int size, Bool *mod)
121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ThreadState* tst = VG_(get_ThreadState)(tid);
123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int set = abs_regno / num_regs;
124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int regno = abs_regno % num_regs;
125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *mod = False;
126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VexGuestX86State* x86 = (VexGuestX86State*) get_arch (set, tst);
128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   switch (regno) {
130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   // numbers here have to match the order of regs above
131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   // Attention: gdb order does not match valgrind order.
132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 0:  VG_(transfer) (&x86->guest_EAX, buf, dir, size, mod); break;
133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 1:  VG_(transfer) (&x86->guest_ECX, buf, dir, size, mod); break;
134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 2:  VG_(transfer) (&x86->guest_EDX, buf, dir, size, mod); break;
135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 3:  VG_(transfer) (&x86->guest_EBX, buf, dir, size, mod); break;
136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 4:  VG_(transfer) (&x86->guest_ESP, buf, dir, size, mod); break;
137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 5:  VG_(transfer) (&x86->guest_EBP, buf, dir, size, mod); break;
138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 6:  VG_(transfer) (&x86->guest_ESI, buf, dir, size, mod); break;
139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 7:  VG_(transfer) (&x86->guest_EDI, buf, dir, size, mod); break;
140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 8:
141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(transfer) (&x86->guest_EIP, buf, dir, size, mod);
142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (*mod && VG_(debugLog_getLevel)() > 2) {
143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         char bufimage [2*sizeof(x86->guest_IP_AT_SYSCALL) + 1];
144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         heximage (bufimage,
145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                   (char *) &x86->guest_IP_AT_SYSCALL,
146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                   sizeof(x86->guest_IP_AT_SYSCALL));
147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         dlog(3, "guest_IP_AT_SYSCALL %s\n", bufimage);
148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      break;
150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 9:
151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (dir == valgrind_to_gdbserver) {
152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         UInt eflags;
153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* we can only retrieve the real flags (set 0)
154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            retrieving shadow flags is not ok */
155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (set == 0)
156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            eflags = LibVEX_GuestX86_get_eflags (x86);
157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         else
158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            eflags = 0;
159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(transfer) (&eflags, buf, dir, size, mod); break;
160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else {
161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         *mod = False; //GDBTD? how do we store eflags in libvex_guest_x86.h ???
162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      break;
164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 10: VG_(transfer) (&x86->guest_CS, buf, dir, size, mod); break;
165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 11: VG_(transfer) (&x86->guest_SS, buf, dir, size, mod); break;
166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 12: VG_(transfer) (&x86->guest_DS, buf, dir, size, mod); break;
167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 13: VG_(transfer) (&x86->guest_ES, buf, dir, size, mod); break;
168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 14: VG_(transfer) (&x86->guest_FS, buf, dir, size, mod); break;
169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 15: VG_(transfer) (&x86->guest_GS, buf, dir, size, mod); break;
170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 16:
171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 17:
172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 18:
173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 19: /* register 16 to 23 are float registers 80 bits but 64 bits in valgrind */
174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 20:
175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 21:
176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 22:
177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 23: {
178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (dir == valgrind_to_gdbserver) {
179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         UChar fpreg80[10];
180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         convert_f64le_to_f80le ((UChar *)&x86->guest_FPREG[regno-16],
181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                 fpreg80);
182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(transfer) (&fpreg80, buf, dir, sizeof(fpreg80), mod);
183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else {
184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         ULong fpreg64;
185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         convert_f80le_to_f64le (buf, (UChar *)&fpreg64);
186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(transfer) (&x86->guest_FPREG[regno-16], &fpreg64,
187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        dir, sizeof(fpreg64), mod);
188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      break;
190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 24:
192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (dir == valgrind_to_gdbserver) {
193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         // vex only models the rounding bits (see libvex_guest_x86.h)
194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         UWord value = 0x037f;
195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         value |= x86->guest_FPROUND << 10;
196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(transfer)(&value, buf, dir, size, mod);
197b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else {
198b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         *mod = False; // GDBTD???? VEX { "fctrl", 1152, 32 },
199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      break;
201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 25:
202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (dir == valgrind_to_gdbserver) {
203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         UWord value = x86->guest_FC3210;
204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         value |= (x86->guest_FTOP & 7) << 11;
205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(transfer)(&value, buf, dir, size, mod);
206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else {
207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         *mod = False; // GDBTD???? VEX { "fstat", 1184, 32 },
208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      break;
210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 26:
211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (dir == valgrind_to_gdbserver) {
212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         // vex doesn't model these precisely
213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         UWord value =
214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ((x86->guest_FPTAG[0] ? 0 : 3) << 0)  |
215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ((x86->guest_FPTAG[1] ? 0 : 3) << 2)  |
216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ((x86->guest_FPTAG[2] ? 0 : 3) << 4)  |
217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ((x86->guest_FPTAG[3] ? 0 : 3) << 6)  |
218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ((x86->guest_FPTAG[4] ? 0 : 3) << 8)  |
219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ((x86->guest_FPTAG[5] ? 0 : 3) << 10) |
220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ((x86->guest_FPTAG[6] ? 0 : 3) << 12) |
221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ((x86->guest_FPTAG[7] ? 0 : 3) << 14);
222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(transfer)(&value, buf, dir, size, mod);
223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else {
224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         *mod = False;  // GDBTD???? VEX { "ftag", 1216, 32 },
225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      break;
227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 27: *mod = False; break; // GDBTD???? VEX { "fiseg", 1248, 32 },
228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 28: *mod = False; break; // GDBTD???? VEX { "fioff", 1280, 32 },
229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 29: *mod = False; break; // GDBTD???? VEX { "foseg", 1312, 32 },
230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 30: *mod = False; break; // GDBTD???? VEX { "fooff", 1344, 32 },
231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 31: *mod = False; break; // GDBTD???? VEX { "fop", 1376, 32 },
232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 32: VG_(transfer) (&x86->guest_XMM0, buf, dir, size, mod); break;
233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 33: VG_(transfer) (&x86->guest_XMM1, buf, dir, size, mod); break;
234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 34: VG_(transfer) (&x86->guest_XMM2, buf, dir, size, mod); break;
235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 35: VG_(transfer) (&x86->guest_XMM3, buf, dir, size, mod); break;
236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 36: VG_(transfer) (&x86->guest_XMM4, buf, dir, size, mod); break;
237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 37: VG_(transfer) (&x86->guest_XMM5, buf, dir, size, mod); break;
238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 38: VG_(transfer) (&x86->guest_XMM6, buf, dir, size, mod); break;
239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 39: VG_(transfer) (&x86->guest_XMM7, buf, dir, size, mod); break;
240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 40:
241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (dir == valgrind_to_gdbserver) {
242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         // vex only models the rounding bits (see libvex_guest_x86.h)
243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         UWord value = 0x1f80;
244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         value |= x86->guest_SSEROUND << 13;
245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(transfer)(&value, buf, dir, size, mod);
246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else {
247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         *mod = False; // GDBTD???? VEX { "mxcsr", 2432, 32 },
248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      break;
250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 41: *mod = False; break; // GDBTD???? VEX { "orig_eax", 2464, 32 },
251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   default: vg_assert(0);
252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic struct valgrind_target_ops low_target = {
256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   num_regs,
257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   regs,
258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   4, //ESP
259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   transfer_register,
260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   get_pc,
261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   set_pc,
262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   "i386",
263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   NULL, // target_xml not needed.
264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   "i386-linux-valgrind.xml"
266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else
267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   "i386-coresse-valgrind.xml"
268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif
269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov};
270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid x86_init_architecture (struct valgrind_target_ops *target)
272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *target = low_target;
274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   set_register_cache (regs, num_regs);
275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   gdbserver_expedite_regs = expedite_regs;
276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
277